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

📄 ppp.c

📁 在S3C2440上运行的"电子日历“(支持平年,闰年,星期自动调整). 开发环境是RVDS2.2
💻 C
字号:
/**---------------------版权 (c)----------------------------------------------------------***
***                     作者:颜章健                                                      ***
***                     邮件:jenkinyan@163.com                                           ***
***                                                                                       ***
***---------------------File Info---------------------------------------------------------***
*** 创 建 人:          颜章健                                                            ***
*** 创建日期:          2008-03-08                                                        ***
*** 创建版本:                                                                            ***
*** 文件描述:                                                                            ***
***---------------------------------------------------------------------------------------***
*** 修 订 人:                                                                            ***
*** 修订日期:                                                                            ***
*** 修订版本:                                                                            ***
*** 修订描述:                                                                            ***
***---------------------------------------------------------------------------------------**/
#include "config.h"
#define			PPP_USE_DYNAMIC_FRAME_BUFFER


LINK_LAYER		LinkLayer;
LINK_CFG		LinkCfg;
static	uint8	FrameBuffer[1536];

const uint16 FcsTab[256] = 
{
	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

uint16	PppFcs16Rx(uint8 *frame,uint16 len)
{
    uint8  *p,*ptab;
    union{uint16 w; uint8 b[2];}fcs;
    union{uint16 w; uint8 b[2];}tab;
    
    fcs.w = 0xffff;
    p = &fcs.b[1]; 
    ptab = &tab.b[0];
    
    while (len--)
    {
        tab.w = fcs.w ^ *frame++;
        fcs.w = *p ^ FcsTab[*ptab];
    }
    return (~fcs.w);
}

uint16	PppFcs16Tx(uint16 fcs,uint8 dat)
{
	fcs = (fcs >> 8) ^ FcsTab[(fcs ^ dat) & 0xff];
	return	fcs;
}



/********************************************************************************************
*** 函数名称:			
*** 函数描述:		
*** 入    口:		
*** 出    口:	无		
********************************************************************************************/
void	PppPutFrame(uint16 Protocol,NET_PKT *Packet)
{
	union	{uint16 w; uint8 b[2];}	fcs;
	uint16	i;
	uint8	out;	
	PPP_HEAD	head;
	
	fcs.w = 0xffff;	
	head.s.Addr = 0xff;
	head.s.Ctrl = 0x03;
	//head.s.Prot = Protocol;
	head.b[3] = Protocol;
	head.b[2] = Protocol >> 8;
	

	PhyLayer.Write(0x7e);			// 帧标志	

	for(i=0; i<4; i++)				// 帧头
	{
		out = head.b[i];
		fcs.w = PppFcs16Tx(fcs.w,out);
		if((out < 0x20) || (out == 0x7d) || (out == 0x7e))
		{
				PhyLayer.Write(0x7d);
				PhyLayer.Write(out ^ 0x20);
		}
		else	PhyLayer.Write(out);
	}
	
	while(Packet != NULL)			// 数据
	{
		for(i=0; i<Packet->Length; i++)
		{
			out = *Packet->Data++;

			fcs.w = PppFcs16Tx(fcs.w,out);
			if((out < 0x20) || (out == 0x7d) || (out == 0x7e))
			{
					PhyLayer.Write(0x7d);
					PhyLayer.Write(out ^ 0x20);
			}
			else	PhyLayer.Write(out);
			
		}
		Packet = Packet->Next;
	}	
		
	fcs.w = ~fcs.w;		
	for(i=0; i<2; i++)				// 校验值
	{
		out = fcs.b[i];
		if((out < 0x20) || (out == 0x7d) || (out == 0x7e))
		{
				PhyLayer.Write(0x7d);
				PhyLayer.Write(out ^ 0x20);	
		}
		else	PhyLayer.Write(out);
	}
	
	PhyLayer.Write(0x7e);			// 帧标志	

}

/********************************************************************************************
*** 函数名称:	PppGetFrame		
*** 函数描述:	从物理层的RxFifo接收数据,并解码出数据帧			
*** 入    口:				
*** 出    口:			
********************************************************************************************/
static void	PppGetFrame(uint8	*Rxbuf)
{
	uint8	dat;
	uint16	len;
	union	{uint16 w; uint8 b[2];}	fcs;
	
	LinkLayer.Rxd = Rxbuf;
	LinkLayer.Rxl = 0;
	
	if(RxFifo.DatLen < 8)		return;
	if(PhyLayer.Pop() != 0x7e)	return;
	if(PhyLayer.Pop() != 0xff)	return;
	*LinkLayer.Rxd++ = 0x7e;
	*LinkLayer.Rxd++ = 0xff;

	len = 2;
	while(1)
	{		
		while(RxFifo.DatLen == 0);
		dat = PhyLayer.Pop();
		if(dat == 0x7e)			break;
		else if(dat == 0x7d)	
		{
			while(RxFifo.DatLen == 0);
			*LinkLayer.Rxd++ = PhyLayer.Pop() ^ 0x20;
		}
		else	*LinkLayer.Rxd++ = dat;
		len++;
		if(len > 1508)
		{
			LinkLayer.Rxd = Rxbuf;
			LinkLayer.Rxl = 0;
		}	
	}
	*LinkLayer.Rxd++ = 0x7e;
	len++;
	
	fcs.w = PppFcs16Rx(Rxbuf+1,len-4);
	
	LinkLayer.Rxd = Rxbuf;
	if((fcs.b[0] == *(Rxbuf+len-3)) && (fcs.b[1] ==  *(Rxbuf+len-2)))
	{
		LinkLayer.Rxl = len - 3;	// 校验成功,去掉FCS字段和结束标志(0x7e),但保留起始标志
	}
	else
	{
		LinkLayer.Rxl = 0;			// 校验失败
		#ifdef	DEBUG
		_printf("PPP帧校验失败\r\n");	
		#endif
	}	
}


/********************************************************************************************
*** 函数名称:	PppReceiveTask		
*** 函数描述:	PPP协议接收任务,对数据包解析
*** 入    口:	无		
*** 出    口:	无		
********************************************************************************************/
void	PppReceiveTask(void)
{
	union {uint16 w;uint8 b[2];}	Protocol;
	

	PppGetFrame(FrameBuffer);	
	if(LinkLayer.Rxl == 0)	return;				// 没有收到数据帧或者数据帧校验失败
	Protocol.b[1]  = *(LinkLayer.Rxd + 3);
	Protocol.b[0]  = *(LinkLayer.Rxd + 4);
	LinkLayer.Rxd += 5;
	LinkLayer.Rxl -= 5;
	
	switch(Protocol.w)
	{
		case	PPPF_IP:
			//NetLayer.Rxd = LinkLayer.Rxd;
			//NetLayer.Rxl = LinkLayer.Rxl;			
			//IpReceiveTask();
			// changed by Yan Zhangjian @ 2008-04-10
			if((LinkLayer.Hook != NULL) && (LinkLayer.State == PPPS_OPENED))
			{
				LinkLayer.Hook(LinkLayer.Rxd,LinkLayer.Rxl);
			}
			break;
			
		case	PPPF_LCP:
			LcpProcess();
			break;
		
		case	PPPF_PAP:
			PapProcess();
			break;
			
		case	PPPF_NCP:
			NcpProcess();
			break;
		
		case	PPPF_CHAP:
			#ifdef	DEBUG
			_printf("CHAP-");	
			#endif
			ChapProcess();
			break;
		
		default:
			#ifdef	DEBUG
			_printf("未知数据包-");	
			#endif
			break;
	}
}


void	PppCloseRequest(void)
{
	const 	uint8 Datas[4] = {0x05, 0x05, 0x00, 0x04};
	NET_PKT	pkt;
	
	pkt.Data   = (uint8 *)Datas;
	pkt.Length = 4;
	pkt.Next   = NULL;
	
	PppPutFrame(PPPF_LCP,&pkt);
}


void	PppOpenRequest(void)
{
	if(PhyLayer.Open())
	{
		
	}
}

/********************************************************************************************
*** 函数名称:			
*** 函数描述:			
*** 入    口:			
*** 出    口:			
********************************************************************************************/
void	LinkLayerInit(void)
{
	
	LinkLayer.Config.Username[0] = 0;
	LinkLayer.Config.Password[0] = 0;
	
	LinkLayer.State		= PPPS_CLOSED;
	LinkLayer.PutFrame	= PppPutFrame;
	LinkLayer.Close     = PppCloseRequest;
	LinkLayer.Open      = PppOpenRequest;
	LinkLayer.Hook		= NULL;	// added by Yan Zhangjian @ 2008-04-10
}

/********************************************************************************************
*** 					文件结束														  ***	
********************************************************************************************/

⌨️ 快捷键说明

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