📄 ppp.c
字号:
//-------------------------------------------------- // 如Server请求CHAP则NAK,并请求 PAP // //-------------------------------------------------- if ((in_buff [8] == 0x03) && (in_buff [10] == 0xC2)) { in_buff [4] = NAK; in_buff [10] = 0xC0; // We suggest PAP instead send_ppp (in_buff, (BYTE)(in_buff[7]+6)); } else //-------------------------------------------------- // 如SERVER请求PAP,则ACK,且发送PAP包进行密码认证 //-------------------------------------------------- if((in_buff[7]==0x08) && (in_buff[8]==0x03)){ in_buff[4]=ACK; send_ppp (in_buff, (BYTE)(in_buff [7] + 6)); Delay(100); //send_pap (REQ, (BYTE)(in_buff[5] + 1), a60i.User, a60i.Pass); send_pap (REQ, (BYTE)(in_buff[5] + 1), "gprs", "gprs"); } break; case ACK: break; case NAK: break; case REJ: break; case TERMINATE_ACK: // Terminate ACK! if (DebugMode) Debug("ASCEND-> TERMINATE_ACK"); break; } return LCP_NORMAL;}//接收PPP包字节,组包的过程.BYTE ppp_receive (BYTE c) { switch (c) { case ESC: // 0x7D if (build) isEsc = 1; break; case END: //7E isEsc=0; if (build) { if(frm_size==0) { memset(in_buff,0x00,PPP_BUFFER_SIZE + 1); frm_size = 0; build=0x01; }else { in_buff[frm_size] = 0; build=0x00; frm_size = 0; return 1; } } else{ memset(in_buff,0x00,PPP_BUFFER_SIZE + 1); frm_size = 0; build=0x01; } break; default: if (build){ if (isEsc){ in_buff[frm_size++]=0x20 ^ c; isEsc=0; }else{ in_buff[frm_size++] = c; } } break; } return 0;}//发送密码校验包void send_pap (BYTE Action, BYTE ID, char* user, char* password) { out_buff [0] = 0xFF; out_buff [1] = 0x03; out_buff [2] = 0xC0; // Format PAP packet header out_buff [3] = 0x23; out_buff [4] = Action; out_buff [5] = in_buff [5] + 1; // Increment ID out_buff [6] = 0; out_buff [7] = strlen (user) + strlen (password) + 6;// Set length of PAP out_buff [8] = strlen (user); // Set length of // Username lee //move (user, &out_buff [9], strlen (user)); // Store Username memcpy(&out_buff[9],user,strlen(user)); out_buff [9 + strlen (user)] = strlen (password); // Set length of // password lee //move (password, &out_buff [10 + strlen (user)], strlen (password)); memcpy(&out_buff [10 + strlen (user)],password,strlen(password)); send_ppp ((BYTE *)out_buff, (BYTE)(out_buff[7] + 6)); // Send PAP packet}//IPCP,分配IP地址.BYTE do_ipcp (void) { BYTE *dest = (BYTE *)&out_buff[8]; BYTE *ptr = (BYTE *)&in_buff[8];// char IPStr[40]; BYTE FrameSize; BYTE Option; BYTE Size; switch (in_buff [4] ) { case REQ: if ((in_buff [8] != 0x03) && (in_buff [7] > 0x0A)) { out_buff [0] = 0xFF; out_buff [1] = 0x03; out_buff [2] = 0x80; // Set IPCP protocol out_buff [3] = 0x21; out_buff [4] = REJ; // This will be a // REJ packet for now out_buff [5] = in_buff [5]; out_buff [6] = 0x00; FrameSize = in_buff[7] - 4; ///////// Ignore all but option #3 /////// while (FrameSize > 0) { Option = *ptr; Size = *(ptr + 1); FrameSize -= Size; if (Option == 3) { ptr += Size; //Set New Packet size out_buff [7] = in_buff [7] - Size; } else { while (Size-- ) { *dest++ = *ptr++; } } } } else { // Acknowledge IP Address // move (in_buff, out_buff, in_buff[7]+6); out_buff [4] = ACK; send_ppp ((BYTE *)out_buff, (BYTE)(out_buff[7] + 6)); // Now Request IP address to complete 3-way handshake out_buff [4] = REQ; // Request command out_buff [5] = out_buff [5] + 1; // Packet ID = ID + 1 out_buff [10] = 0; // IP address is set // to 0 so ISP server out_buff [11] = 0; // can assing us one out_buff [12] = 0; out_buff [13] = 0; } send_ppp ((BYTE *)out_buff, (BYTE)(out_buff[7] + 6)); break; case ACK: if (in_buff [8] == 3) { // Reply of the only IPCP // Request we can send IPAddress [0] = in_buff [10]; // ISP assigned IP IPAddress [1] = in_buff [11]; IPAddress [2] = in_buff [12]; IPAddress [3] = in_buff [13]; return PPP_OK; } break; case NAK: if ((in_buff [8] == 0x03) && (in_buff [7] <= 0x0A)) { /// Request IP Address //// move (in_buff, out_buff, in_buff[7]+8); out_buff [4] = 0x01; send_ppp ((BYTE *)out_buff, (BYTE)(out_buff[7] + 6)); } break; case REJ: break; } return IPCP_NORMAL;}//把打成PPP发送到串口void send_ppp (BYTE *Buffer, int len) { WORD Checksum; int i; Checksum=0; //添加校验位 Checksum = ppp_checksum (Buffer, len-2); Buffer [ len-2] = Checksum & 0xFF; Buffer [ len-1] = (Checksum >> 8) & 0xFF; if (DebugMode) { SendByte2UART0(0x01); SendByte2UART0(0x7E); SendBuf2UART0 (Buffer,len); SendByte2UART0(0x7E); } SendChar2Modem(0x7E);//起始位 //包内容 for (i=0;i<len;i++){ if (Buffer[i] < 0x20) {//小于0x20的字节需要转义,祥见PPP协议 msend (0x7D); msend ((BYTE)(Buffer[i] ^ 0x20)); } else { switch (Buffer[i]) { case 0x7E: msend (0x7D); msend (0x5E); break; case 0x7D: //转义符 msend (0x7D); msend (0x5D); break; default: msend (Buffer[i]); break; } } } SendChar2Modem (0x7E); //结束位.}static WORD PPPfcs16 (WORD fcs, BYTE *cp, int len) { while (len--) fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff]; return (fcs);}WORD ppp_checksum (register unsigned char *cp, register int len) { return ~PPPfcs16( PPPINITFCS16, cp, len );}//检测是否是断开回应包int ppp_disconnect(void){ switch (in_buff [4] ) {// case TERMINATE: //断开包,则回应ACK move (in_buff, out_buff, in_buff[7]+6); out_buff [4] = TERMINATE_ACK; send_ppp ((BYTE *)out_buff, (BYTE)(out_buff[7] + 6)); return 2; break; case TERMINATE_ACK://是断开回应包 return 1; break; default: break; } return 0;}//PPP断开,这里我们采用稍微复杂的流程,以确保PPP能断开int disconnect(void){ uint32 t; int i; char chr; ppp_terminate();//发送断开包 Debug("\r\n start disconnect.\r\n"); mstimeout(&t,0); //-------------------------------- //这里还存在挂不断的情况! //-------------------------------- while(1) { if (read_mb(&chr)) //检测是否有数据到达 { if (ppp_receive(chr)) //能组成一个完整的PPP包? { if (ppp_disconnect()) //处理收到的PPP包(目前只处理 teminate seq 和 teminate ack 包,其他的包置之不理) { //如果收到 teminate seq(则回应 teminate ack) 或 teminate ack check_at_return(40); //检测AT delay(1000); // return(1); } } } if (mstimeout(&t,5000))//5秒超时 { if (i==10) return 0; if (check_at_return(40))//检测AT是否返回 return 1; delay(400); ppp_terminate(); //AT没有返回则继续发送断开包 i++; } FeedWdt(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -