⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp.c

📁 阿根廷教授编写的嵌入式internet的实验教程的高质量代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (index==2 && (c&0x01))		// if Protocol compressed, include it
      rx_buf[index++] = 0x00;
    rx_buf[index++] = c;				
    chksum = calc(c ^ chksum) ^ (chksum/256);
  }
}


void ppp_engine(void) {
  char userlen;
  char passlen;

  if (! timer_expired(ppptimer))
    return;
  switch(ppp_state) {
    case PPP_INITIAL_STATE:
    case LCP_ACK_SENT:
      memcpy(&tx_buf[4], &LCP_REQ[0], sizeof(LCP_REQ));
      tx_buf[5] = id++;						// id field
      ppp_send(LCP_PROTOCOL, sizeof(LCP_REQ));
      break;
    case LCP_OK:
    case PAP_REQ_SENT:						// we still sending PAP REQ ...
      userlen = strlen(isp.user);
      passlen = strlen(isp.pass);
      memcpy(&tx_buf[4], &PAP_REQ[0], 4);
      tx_buf[8] = userlen;			
      memcpy(&tx_buf[9], &isp.user[0], userlen);
      tx_buf[9+userlen] = passlen;
      memcpy(&tx_buf[10+userlen], &isp.pass[0], passlen);
      tx_buf[5] = id++;						// id field
      tx_buf[7] = 6 + userlen + passlen;
      ppp_send(PAP_PROTOCOL, tx_buf[7]);
      ppp_state=PAP_REQ_SENT;
      printf("PAP REQ Sent...");
      break;
    case PAP_ACK_RCVD:
    case IPCP_REQ1_SENT:
      memcpy(&tx_buf[4], &IPCP_REQ[0], sizeof(IPCP_REQ));			
      tx_buf[5] = id++;						// id field
      ppp_send(IPCP_PROTOCOL, sizeof(IPCP_REQ));
      ppp_state=IPCP_REQ1_SENT;
      break;
    case IPCP_NAK_RCVD:
    case IPCP_REQ2_SENT:
      memcpy(&IPCP_REQ[0x06], &rx_buf[0x0A], 4);	
      memcpy(&tx_buf[4], &IPCP_REQ[0], sizeof(IPCP_REQ));			
      tx_buf[5] = id++;						// id field
      ppp_send(IPCP_PROTOCOL, sizeof(IPCP_REQ));
      ppp_state=IPCP_REQ2_SENT;
      break;
    default:
      break;
  }
  timer_start(ppptimer, 1000);
}


void modem_response(void) {
  static char i ;
  static char first_char;
  static char second_char;

  if (c==0x0D || c==0x0A) {
    i=0;
    first_char = 0;
    second_char = 0;
    return;
  }
  if (c==0X20)
    return;
  i++;
  switch(i) {
    case 1:
      first_char = c;
      break;
    case 2:
      switch(c) {
	case 'K':
	  if (first_char=='O') {
  	    modem_status = MODEM_OK;
	    timer_stop(ppptimer);
          }
	  break;
	case 'R':
	  if (first_char=='E') {
	    modem_status = MODEM_ERROR;
	    timer_stop(ppptimer);
	  }
	  break;
	case 'U':
	  if (first_char=='B') {
	    modem_status = MODEM_BUSY;
	    timer_stop(ppptimer);
	  }
	  break;
	case 'O':
	  second_char=c;
	  break;
      }	
      break;
    case 3:
      if (first_char=='N' && second_char=='O' && c=='C') {
        modem_status = MODEM_NO_CARRIER;
        if (modem_state != MODEM_WAITING_DIAL)
	  timer_stop(ppptimer);
	if (modem_state == MODEM_CONNECTED)
	  printf("NO CARRIER\n");
      }
      if (first_char=='N' && second_char=='O' && c=='D') {
	modem_status = MODEM_NO_DIALTONE;
	timer_stop(ppptimer);
      }
      if (first_char=='C' && second_char=='O' && c=='N') {
        modem_state = MODEM_CONNECTED;
	timer_stop(ppptimer);
      }
      break;
  }
}


void modem_command(char command[]) {
  short i=0;

  while(command[i] != '\0') {
    putchar1(command[i++]);
  }
  putchar1(0x0D);
//  putchar1(0x0A);
}


void modem_disconnect(void) {
  if (ppp_state == PPP_OK) {
    tx_buf[4]=	TERM_REQ;
    tx_buf[5]=	id++;;
    tx_buf[6]=	0;
    tx_buf[7]=	4;
    ppp_send(LCP_PROTOCOL, ((tx_buf[6]<<8) + tx_buf[7]));
    ppp_state = PPP_INITIAL_STATE;
    printf("PPP Closed (requested by Device)\n");
    timer_start(ppptimer, 2000);
    modem_status = MODEM_NO_STATUS;
  }
  if (modem_status == MODEM_OK || modem_status == MODEM_NO_CARRIER) {
    modem_state = MODEM_DISCONNECTED;
    modem_status = MODEM_NO_STATUS;
    ppp_start_stop = PPP_NO_ACTION;
    if (PPP_STATUS_NO_ERROR)		   // ppp_status <= 0x02 indicates NO ERROR
      ppp_status = PPP_CLOSED;
    printf("Modem Disconnected!\n");
    return;
  }
  if (! timer_expired(ppptimer))
    return;
  modem_command("+++ATH");
  modem_state=MODEM_DISCONNECTING;
  modem_status = MODEM_NO_STATUS;
  timer_start(ppptimer, 5000);
}

void modem_connect(void) {
  static char retry=0;
  char dialstring[4+sizeof(isp.number)] = "ATDT";

  if (timer_expired(ppptimer) && modem_state != MODEM_WAITING_DIAL) {
    modem_status = MODEM_TIMEOUT;
    timer_stop(ppptimer);
    return;
  }	
  switch(modem_state) {
    case MODEM_DISCONNECTED:
      printf("Modem Reset...");
   //   modem_command("ATM0");			 // Silence command
      modem_command("ATZ");
      timer_start(ppptimer, 3000);
      modem_state = MODEM_RESETTING;
      modem_status = MODEM_NO_STATUS;
      break;
    case MODEM_RESETTING:
      if (modem_status == MODEM_NO_STATUS)
        break;
      if (modem_status == MODEM_OK) {
	printf("OK\n");
	modem_state = MODEM_RESET_OK;
      }else {
        if (modem_status == MODEM_TIMEOUT)
	  printf("NO RESPONSE\n");
        else
	  printf("ERROR\n");
	modem_state = MODEM_DISCONNECTED;
	modem_status = MODEM_NO_STATUS;
	ppp_start_stop = PPP_NO_ACTION;
	ppp_status = PPP_ERROR_MODEM;
      }
      break;
    case MODEM_RESET_OK:
      printf("Modem Dialing ");
      strcat(dialstring, isp.number);
      printf(dialstring);
      modem_command(dialstring);
      printf("...");
      if (retry > 0)
        printf("(Retry #%d) ", retry);
	modem_state = MODEM_DIALING;
	modem_status = MODEM_NO_STATUS;
	timer_start(ppptimer, 30000);	        // 30 sec for NO ANSWER detect, 60 sec for NO CARRIER detect	
	break;
    case MODEM_DIALING:
      if (modem_status == MODEM_BUSY) {
        printf("BUSY\n");
      }
      if (modem_status == MODEM_NO_CARRIER) {
        printf("NO CARRIER\n");
      }
      if (modem_status == MODEM_NO_DIALTONE) {
        printf("NO DIALTONE\n");
      }
      if (modem_status == MODEM_TIMEOUT) {
	modem_command("ATH");			// if NO ANSWER, stop dialing...
	printf("NO ANSWER\n");		
      }
      if (modem_status == MODEM_BUSY || modem_status == MODEM_NO_CARRIER ||
	modem_status == MODEM_NO_DIALTONE || modem_status == MODEM_TIMEOUT) {

        retry++;
	if (retry <= MAX_RETRIES) {
	  modem_state = MODEM_WAITING_DIAL;
	  timer_start(ppptimer,10000);
	}else {
          modem_state =	MODEM_DISCONNECTED;
	  switch(modem_status) {
	    case MODEM_BUSY:
	      ppp_status = PPP_ERROR_DIAL_BUSY;
	      break;
	    case MODEM_NO_CARRIER:
	      ppp_status = PPP_ERROR_DIAL_NO_CARRIER;
	      break;
	    case MODEM_NO_DIALTONE:
	      ppp_status = PPP_ERROR_DIAL_NO_DIALTONE;
	      break;
	    case MODEM_TIMEOUT:
	      ppp_status = PPP_ERROR_DIAL_NO_ANSWER;
	      break;
	  }
	  modem_status = MODEM_NO_STATUS;
	  ppp_start_stop = PPP_NO_ACTION;
	  retry = 0;
        }
      }	
      break;
    case MODEM_WAITING_DIAL:
      if (timer_expired(ppptimer)) {
        modem_state = MODEM_DISCONNECTED;   // re-start the sequence
	modem_status = MODEM_NO_STATUS;
      }
      break;
    case MODEM_CONNECTED:
      retry = 0;
      if (ppp_state != PPP_OK) {
        printf("Connected!\n");
	timer_start(ppptimer, 1000);        // start timer for the ppp_status
      }
      ppp_start_stop = PPP_NO_ACTION;
      break;
  }
}


/***********************************/
/*    PPP PUBLIC FUNCTIONS         */
/***********************************/
void ppp_poll(void) {

  c=getchar1();			// Scan the modem
  if (c != -1) {
    modem_response();
    if (modem_state == MODEM_CONNECTED) {
      if (modem_status == MODEM_NO_CARRIER) {
        if (ppp_state != PPP_OK)
	  ppp_status = PPP_ERROR_NEGOTIATION;
	else
	  ppp_status = PPP_ERROR_PHY_LINK;
	ppp_state = PPP_INITIAL_STATE;
	ppp_start_stop = PPP_STOP;
      }
      char_process();
    }			
  }
  if (ppp_start_stop == PPP_START)
    modem_connect();
  if (ppp_start_stop == PPP_STOP)
    modem_disconnect();
  if (modem_state==MODEM_CONNECTED && ppp_state!=PPP_OK) {
    ppp_engine();
  }
}


void ppp_open(char *number,char *user, char *pass) {

  if (ppp_status == PPP_CLOSED || PPP_STATUS_ERROR) { 	  // ppp_status > 0x02 indicates an error
    strncpy(isp.number, number, sizeof(isp.number));				
    strncpy(isp.user, user, sizeof(isp.user));
    strncpy(isp.pass, pass, sizeof(isp.pass));
    ppp_start_stop = PPP_START;
    ppp_status = PPP_WAIT;
  }
}


void ppp_close(void) {

  if (ppp_status == PPP_OPENED) {
    ppp_start_stop = PPP_STOP;
    ppp_status = PPP_WAIT;
  }
}

void ppp_send(unsigned short protocol, unsigned short tx_len) {
  int i;
  unsigned short ret;

  tx_len += 4;		  		// + Addr (1) + Ctrl (1) + Protocol (2)
  tx_buf[0] = 0xFF;
  tx_buf[1] = 0x03;
  tx_buf[2] = (protocol>>8)&0xFF;
  tx_buf[3] = protocol&0xFF;
  ret = tx_chksum(tx_len);
  tx_buf[tx_len++] = ret&0xFF;
  tx_buf[tx_len++] = (ret>>8)&0xFF;
#if debug_ppp
  if (protocol != IP_PROTOCOL) {
    printf("\nSent: ");
    switch(protocol) {
      case LCP_PROTOCOL:
	printf("LCP ");
	break;
      case PAP_PROTOCOL:
	printf("PAP ");
	break;
      case IPCP_PROTOCOL:
	printf("IPCP ");
	break;
      case CCP_PROTOCOL:
	printf("CCP ");
	break;
      default:
	printf("Unknown Protocol ");
	break;  	
    }
    switch(tx_buf[4]) {
      case 1:
        printf("REQ ID: %d\n",tx_buf[5]);
        break;
      case 2:
        printf("ACK ID: %d\n",tx_buf[5]);
	break;
      case 3:
        printf("NAK ID: %d\n",tx_buf[5]);
        break;
      case 4:
        printf("REJ ID: %d\n",tx_buf[5]);
	break;
      case 5:
        printf("TERM-REQ ID: %d\n",tx_buf[5]);
        break;
      case 6:
        printf("TERM-ACK ID: %d\n",tx_buf[5]);
        break;
      default:
        printf("Unknown type ID: %d\n",tx_buf[5]);
        break;	
    }
    ppp_display(&tx_buf[0]);
  }
#endif //debug_ppp
  putchar1(0x7E);
  for(i=0;i<tx_len;i++) {
    if (tx_buf[i]<0x20 || tx_buf[i]==0x7D || tx_buf[i]==0x7E) {
      putchar1(0x7D);
      tx_buf[i] ^= 0x20;
    }
    putchar1(tx_buf[i]);
  }
  putchar1(0x7E);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -