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

📄 ppp.c

📁 PPP拨号协议简单实现 适用于MCU和无系统的嵌入式应用
💻 C
📖 第 1 页 / 共 2 页
字号:
			//--------------------------------------------------			//  		如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 + -