📄 tskppp.c
字号:
pbuf = PPPTxWorkBuf + 8;
}
for(i=0; i< OpLen; i++){
*pbuf++ = pO[i];
}
PPPTxFrameSize += OpLen;
((PPP_FRAME *)PPPTxWorkBuf)->Length += OpLen;
}
if(Len > OpLen) { //If there is still other option
Len -= OpLen; //refresh data
pO = pO + OpLen;
}
else break;
}
if(PPPTxFrameSize != 0){
PPPSendPacket(PPPTxWorkBuf, PPPTxWorkBuf[7]+4);
}
if(((PPP_FRAME *)PPPTxWorkBuf)->Code == ACK) return(0);
else return(1);
}
//The FCS part has been tested
void Func_InitFCS(void){
FCS = 0xffff;
}
void Func_AddFCS(INT8U c){
FCS = (FCS >> 8) ^ fcstab[(FCS ^ c) & 0xff];
}
INT16U Func_GetFCS(void){ //use this to produce the FCS. we should place the low byte of FCS into the buffer in front of the hight byte
//that is, we can place the FCS as a int, for in MCC18, low byte first
return (~FCS);
}
INT16U Func_CheckFCS(void){ //use this function to check the FCS, if all bytes including FCS is calculated, the result shall be 0xf0b8
return(FCS);
}
void StartPPPTimer(void){
INT8U rom * pSml;
INT8U err;
pSml=OSMemGet(pMemSml,&err);
if(err == OS_NO_ERR){
((MSG_HEAD *)pSml)->Msg_ID=MSG_TIMER_START;
((MSG_HEAD *)pSml)->Origin=peventPPPHandler;
((MSG_HEAD *)pSml)->pmemME=pMemSml;
((MSG_HEAD *)pSml)->Attached=FALSE;
((MSG_HEAD *)pSml)->LenOfBody=4;
((TIMER_MESSAGE *)pSml)->TID=PPP_TIMEOUT;
((TIMER_MESSAGE *)pSml)->Val=PPPTIMEROUT;
OSQPost(peventTimer,pSml);
}
}
//This task receive and depack PPP frame, then send it to PPPHandler or IPHandler directly
void tskPPPReceiver(void * Pdata){
void rom * pMsg;
INT8U err;
INT8U rom * pTrans;
INT8U rom * pSml;
INT8U rom * pBuf;
INT8U rom * pData;
INT16U PackLen;
INT8U chrTemp;
INT16U len;
pBuf = NULL_PTR;
for(;;){
pMsg = OSQPend(peventPPPReceiver, 0, &err);
if(err == OS_NO_ERR){
if((INT24U)pMsg >= PTR_MAX){
if((INT24U)pMsg == MSG_PPP_CLEAR){
if(pBuf != NULL_PTR) {
OSMemPut(pMemLge, pBuf);
OSMemPut(pMemSml, pSml);
}
pBuf = NULL_PTR;
FStt = 0;
}
}
else{
if(((MSG_HEAD *)pMsg)->Msg_ID == MSG_MODULE_RECEIVE){
pData = ((MSG_HEAD *)pMsg)->pMem;
len = ((MSG_HEAD *)pMsg)->LenOfAttach;
while(len!=0){
if(pBuf == NULL_PTR){
//If the buffer has not applied, apply it
pBuf = OSMemGet(pMemHug, &err);
if(err == OS_NO_ERR){
pSml = OSMemGet(pMemSml, &err);
if(err != OS_NO_ERR){
OSMemPut(pMemHug, pBuf);
pBuf = NULL_PTR;
}
else{
((MSG_HEAD *)pSml)->Msg_ID = MSG_NDATA_PACKET;
((MSG_HEAD *)pSml)->Attached = TRUE;
((MSG_HEAD *)pSml)->pmemME = pMemSml;
((MSG_HEAD *)pSml)->pMem = pBuf;
((MSG_HEAD *)pSml)->pmemATT = pMemHug;
}
}
}
if((FStt & FS_START) == 0){
if(*pData == END){ //a frame is starting
FStt |= FS_START; //set the FS_START bit
FStt &= ~FS_ESC; //clear the FS_ESC bit
PackLen = 0; //zero the receiving frame length
pTrans = ((MSG_HEAD *)pSml)->pMem; //init the destination pointer
Func_InitFCS(); //initialize the FCS maker
}
}
else{//the frame has start
switch(*pData){
case END:
if(PackLen != 0){ //if there is something other than "0x7e" between two 0x7e
FStt &= ~FS_START;
if(Func_CheckFCS() == PPPGOODFCS16){ //if the frame is a good one...
((MSG_HEAD *)pSml)->LenOfAttach = PackLen -2; //for, FCS shall be ignored
if((((PPP_FRAME *)pBuf)->ProtocolH == 0x00) &&
(((PPP_FRAME *)pBuf)->ProtocolL== 0x21) ){ //if the packet is a IP data gram...
OSQPost(peventIPHandler, pSml);
}
else OSQPost(peventPPPHandler, pSml);
pBuf = NULL_PTR;
}
}
break;
case ESC:
FStt |= FS_ESC;
break;
default:
if((FStt & FS_ESC) != 0){
chrTemp = *pData ^ 0x20;
FStt &= ~FS_ESC;
}
else
chrTemp = *pData;
*pTrans++ = chrTemp;
Func_AddFCS(chrTemp);
PackLen++;
break;
}
}
len--;
pData++;
if(PackLen >= 255){
FStt &= ~FS_START; //Too big a frame, throw away
}
}//end of "while"
}//end of "if"
Func_Clear_Msg(pMsg);
}//end of "else"
}//end of "if(err == OS_NO_ERR)"
}//End of "for"
}//end of function
void tskPPPHandler(void * Pdata){ //actually this task process LCP, PAP and IPCP event.
void rom * pMsg;
INT8U err,i,Option,Size;
INT8U rom * pT;
INT16U protocol;
PPPInit();
for(;;){
pMsg = OSQPend(peventPPPHandler, 0, &err);
if(err == OS_NO_ERR){
if((INT24U)pMsg >= PTR_MAX){
switch((INT24U)pMsg){
case MSG_UPPER_CLOSE: //from upper layer
LCP_Down(); //tld
if( (PPPStt == ACK_SENT)||
(PPPStt == ACK_RCVD)||
(PPPStt == REQ_SENT)||
(PPPStt == OPENED )){
LCP_InitRC(TERMINATE); //irc
PPPTxID++;
LCP_SendTerminateReq(); //str
PPPRestartCounter--;
PPPStt = CLOSING;
}
else if(PPPStt == STARTING){
LCP_Finished(); //tlf
PPPStt = CLOSED;
}
break;
case MSG_UPPER_OPEN: //from upper layer
if(PPPStt == INITIAL)
LCP_Started();
break;
case MSG_LOW_UP: //from lower layer
PPPTxID = 1;
LCP_InitRC(REQ);
LCP_SendConfReq();
PPPRestartCounter--;
PPPStt = REQ_SENT;
break;
case MSG_LOW_DOWN:
LCP_Down();
PPPStt = INITIAL;
break;
}
}
else{
switch(((MSG_HEAD *)pMsg)->Msg_ID){
case MSG_NDATA_PACKET:
pT = ((MSG_HEAD *)pMsg)->pMem;
protocol = ((INT16U)(((PPP_FRAME *)pT)->ProtocolH))<<8;
protocol += (INT16U)(((PPP_FRAME *)pT)->ProtocolL);
switch (protocol){
case LCP:
switch(((PPP_FRAME *)pT)->Code){
case REQ:
if(Func_CheckLCPOption( &(((PPP_FRAME *)pT)->FirstOption),
((MSG_HEAD *)pMsg)->LenOfAttach-8,
((PPP_FRAME *)pT)->Id,
BIT_ACCM |BIT_MRU|BIT_AP) == 0){ //If all the option acceptable
if(PPPStt == ACK_RCVD){
PPPStt = OPENED; //actually the LCP is up, but we shall wait PAP and IPCP passing
PAP_SendConfReq(); //begin PAP process
}
else if(PPPStt == ACK_SENT){
}
else if(PPPStt == REQ_SENT){
PPPStt = ACK_SENT;
}
else if(PPPStt == OPENED){
LCP_Down();
PPPStt = ACK_SENT;
LCP_SendConfReq();
}
}
break;
case ACK:
if(((PPP_FRAME *)pT)->Id != PPPTxID) break;
if(PPPStt == OPENED){
LCP_Down();
LCP_SendConfReq();
PPPStt = REQ_SENT;//ACK_RCVD;
}
else if(PPPStt == ACK_SENT){
PPPStt = OPENED;
PAP_SendConfReq(); //begin PAP process
}
else if(PPPStt == ACK_RCVD){
LCP_SendConfReq();
PPPStt = REQ_SENT;
}
else if(PPPStt == REQ_SENT){
LCP_InitRC(REQ);
PPPStt = ACK_RCVD;
//PPPStt = OPENED;
//PAP_SendConfReq(); //begin PAP process
}
PPPTxID++;
break;
case NAK:
LCP_Down();
LCP_SendTerminateReq();
LCP_InitRC(TERMINATE);
PPPStt = CLOSING;
break;
case REJ:
LCP_Down();
LCP_SendTerminateReq();
LCP_InitRC(TERMINATE);
PPPStt = CLOSING;
break;
case TERMINATE:
LCP_Down();
LCP_SendTerminateAck();
PPPStt = CLOSED;
LCP_Finished();
break;
case TERMINATE_ACK:
LCP_Down();
PPPStt = CLOSED;
LCP_Finished();
break;
default: //unknown code and shall be reject
PPPTxID++;
PPPMakeHeader(PPPTxWorkBuf, LCP);
PPPTxWorkBuf[4] = CODE_REJ;
PPPTxWorkBuf[5] = PPPTxID;
PPPTxWorkBuf[6] = 0;
PPPTxWorkBuf[7] = 4+((MSG_HEAD *)pMsg)->LenOfAttach - 4;
pT = &(((PPP_FRAME *)pT)->Code);
for(i=0;i<((MSG_HEAD *)pMsg)->LenOfAttach - 4; i++){
PPPTxWorkBuf[11+i]= *pT++;
}
PPPSendPacket(PPPTxWorkBuf, 4+((MSG_HEAD *)pMsg)->LenOfAttach);
break;
}//End of Code switch
break;
case PAP:
if(((PPP_FRAME *)pT)->Code != ACK){
LCP_Down();
LCP_SendTerminateReq();
LCP_InitRC(TERMINATE);
PPPStt = CLOSING;
}
break;
case IPCP:
switch (((PPP_FRAME *)pT)->Code){
case REQ:
pT = &(((PPP_FRAME *)pT)->FirstOption);
if(((MSG_HEAD *)pMsg)->LenOfAttach > 8+6){ //there must be some unacceptable options
pT = ((MSG_HEAD *)pMsg)->pMem;
PPPMakeHeader(PPPTxWorkBuf, IPCP);
PPPTxWorkBuf[4] = REJ; // This will be REJ packet for now
PPPTxWorkBuf[5] = ((PPP_FRAME *)pT)->Id;
PPPTxWorkBuf[6] = ((PPP_FRAME *)pT)->LengthHigh;
PPPTxWorkBuf[7] = ((PPP_FRAME *)pT)->Length;
PPPTxFrameSize = 8;
err = ((MSG_HEAD *)pMsg)->LenOfAttach - 8;
///////// Ignore all but option #3 ///////
pT = &(((PPP_FRAME *)pT)->FirstOption);
while (err > 0) {
Option = *pT;
Size = *(pT + 1);
err -= Size;
if (Option == IPCP_IPADD) {
pT += Size;
PPPTxWorkBuf[7] -= Size; //Set New Packet size
}
else {
while (Size-- ) {
PPPTxWorkBuf[PPPTxFrameSize++] = *pT++;
}
}
}
PPPSendPacket(PPPTxWorkBuf, PPPTxFrameSize);
}
else if(*pT == IPCP_IPADD){
pT = ((MSG_HEAD *)pMsg)->pMem;
for(i=0; i<((MSG_HEAD *)pMsg)->LenOfAttach; i++){
PPPTxWorkBuf[i] = *pT++;
}
((PPP_FRAME *)PPPTxWorkBuf)->Code = ACK;
PPPSendPacket(PPPTxWorkBuf, ((MSG_HEAD *)pMsg)->LenOfAttach);
PPPTxID++;
IPCP_SendConfReq();
}
break;
case ACK:
pT = &(((PPP_FRAME *)pT)->FirstOption);
if(*pT == IPCP_IPADD){
IPAddress[0] = pT[2];
IPAddress[1] = pT[3];
IPAddress[2] = pT[4];
IPAddress[3] = pT[5];
}
//Now the link is available--UP
LCP_Up();
break;
case NAK:
pT = &(((PPP_FRAME *)pT)->FirstOption);
if(*pT == IPCP_IPADD){
IPAddress[0] = pT[2];
IPAddress[1] = pT[3];
IPAddress[2] = pT[4];
IPAddress[3] = pT[5];
}
PPPTxID++;
IPCP_SendConfReq();
break;
case REJ:
break;
}
break;
case CCP:
if(((PPP_FRAME *)pT)->Code == REQ){
//reject all the option results in an uncompressed link
for(i = 0; i <((MSG_HEAD *)pMsg)->LenOfAttach; i++){
PPPTxWorkBuf[i]=*pT;
pT++;
}
if(((PPP_FRAME *)pT)->Length > 4)
PPPTxWorkBuf[4] = REJ;
else
PPPTxWorkBuf[4] = ACK;
PPPSendPacket(PPPTxWorkBuf, i);
}
break;
default:
//unknown protocol, reject it
PPPMakeHeader(PPPTxWorkBuf, LCP);
PPPTxWorkBuf[4] = PROT_REJ;
PPPTxWorkBuf[5] = ((MSG_PPP *)pMsg)->Id;
PPPTxWorkBuf[6] = 0;
PPPTxWorkBuf[7] = 4+((MSG_HEAD *)pMsg)->LenOfAttach-2;
PPPTxFrameSize = 8;
pT += 2;
for(i=0;i<((MSG_HEAD *)pMsg)->LenOfAttach -2;i++){
PPPTxWorkBuf[PPPTxFrameSize++]=*pT;
pT++;
}
PPPSendPacket(PPPTxWorkBuf, PPPTxFrameSize);
break;
}//End of protocol switch
break;
case MSG_PPP_SETNUMBER: //set the dial number of a PPP link
for(i=0;i<((MSG_HEAD *)pMsg)->LenOfBody; i++){
DialNum[i] = ((MSG_DCONREQ *)pMsg)->Num[i];
}
break;
case MSG_TIMER_EXPIRE:
if(((TIMER_MESSAGE *)pMsg)->TID == PPP_TIMEOUT){
err = 0;
if(PPPRestartCounter != 0){ //TO+
if((PPPStt == CLOSING) || (PPPStt == STOPPING)){
err = 1;
LCP_SendTerminateReq();
}
else if ((PPPStt == REQ_SENT) ||(PPPStt == ACK_RCVD)){
err = 1;
LCP_SendConfReq();
PPPStt = REQ_SENT;
}
else if(PPPStt == ACK_SENT){
err = 1;
LCP_SendConfReq();
}
if(err != 0){
StartPPPTimer();
PPPRestartCounter --;
}
}
else{ //TO-
LCP_Down();
LCP_Finished();
PPPStt = CLOSED;
}
}
break;
}//End of message ID - switch
Func_Clear_Msg(pMsg);
}//End of pMsg type - if/else
}//End of err type - if
}//End of main loop - for
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -