static void PPPFSM_timeout ( void *fsm_ptr, /* [IN/OUT] - State Machine */ PCB_PTR packet, /* [IN] - expired packet */ bool hard /* [IN] - TRUE if this is a hard timeout (TO- event) */ ) { /* Body */ PPPFSM_CFG_PTR fsm = fsm_ptr; PPP_mutex_lock(&fsm->MUTEX); switch (fsm->STATE) { case PPP_STATE_CLOSING: case PPP_STATE_STOPPING: if (hard) { /* We've waited for an ack long enough */ fsm->STATE -= 2; /* Stopping/Closing -> Stopped/Closed */ } /* Endif */ break; case PPP_STATE_REQ_SENT: case PPP_STATE_ACK_RCVD: case PPP_STATE_ACK_SENT: if (hard) { fsm->STATE = PPP_STATE_STOPPED; } else if (fsm->STATE == PPP_STATE_ACK_RCVD) { fsm->STATE = PPP_STATE_REQ_SENT; } /* Endif */ break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); } /* Endbody */
static boolean CCP_up ( PPPFSM_CFG_PTR fsm /* [IN] - State Machine */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = fsm->HANDLE; CCP_CFG_PTR ccp_ptr = fsm->PRIVATE; CP_CALL_PTR cprecv = ccp_ptr->RECV_OPT.CP; CP_CALL_PTR cpsend = ccp_ptr->SEND_OPT.CP; /* Initialize compression methods */ if (cprecv) { cprecv->CP_init(&ccp_ptr->RECV_DATA, &ccp_ptr->RECV_OPT); } /* Endif */ if (cpsend) { cpsend->CP_init(&ccp_ptr->SEND_DATA, &ccp_ptr->SEND_OPT); } /* Endif */ PPP_mutex_lock(&ppp_ptr->MUTEX); ppp_ptr->RECV_OPTIONS->CP = cprecv; ppp_ptr->SEND_OPTIONS->CP = cpsend; PPP_mutex_unlock(&ppp_ptr->MUTEX); return TRUE; } /* Endbody */
void PPPFSM_lowerup ( PPPFSM_CFG_PTR fsm /* [IN/OUT] - State Machine */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_mutex_lock(&fsm->MUTEX); switch(fsm->STATE) { case PPP_STATE_INITIAL: fsm->STATE = PPP_STATE_CLOSED; break; case PPP_STATE_STARTING: if (fsm->OPTIONS & PPP_OPT_SILENT) { fsm->STATE = PPP_STATE_STOPPED; } else { PPPFSM_sendconfreq(fsm, NULL); fsm->STATE = PPP_STATE_REQ_SENT; }/* Endif */ break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
uint32_t PPPFSM_destroy ( PPPFSM_CFG_PTR fsm /* [IN/OUT] - State Machine */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 uint32_t error = PPP_OK; PPP_mutex_lock(&fsm->MUTEX); if (fsm->STATE > PPP_STATE_CLOSED) { error = RTCSERR_PPP_FSM_ACTIVE; } else { fsm->STATE = PPP_STATE_INITIAL; } /* Endif */ PPP_mutex_unlock(&fsm->MUTEX); if (!error) { PPP_mutex_destroy(&fsm->MUTEX); } /* Endif */ return error; #else return RTCSERR_IP_IS_DISABLED; #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void PPPFSM_open ( PPPFSM_CFG_PTR fsm, /* [IN/OUT] - State Machine */ uint32_t options /* [IN] - Startup options */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_mutex_lock(&fsm->MUTEX); fsm->OPTIONS = options; switch (fsm->STATE) { case PPP_STATE_INITIAL: fsm->STATE = PPP_STATE_STARTING; break; case PPP_STATE_CLOSED: if (options & PPP_OPT_SILENT) { fsm->STATE = PPP_STATE_STOPPED; } else { /* Send an initial Configure-Request */ PPPFSM_sendconfreq(fsm, NULL); fsm->STATE = PPP_STATE_REQ_SENT; } /* Endif */ break; case PPP_STATE_CLOSING: fsm->STATE = PPP_STATE_STOPPING; /* fall through */ case PPP_STATE_STOPPING: case PPP_STATE_STOPPED: if (options & PPP_OPT_RESTART) { PPPFSM_sendconfreq(fsm, NULL); fsm->STATE = PPP_STATE_REQ_SENT; } /* Endif */ break; case PPP_STATE_OPENED: if (options & PPP_OPT_RESTART) { if (fsm->CALL->linkdown) { fsm->CALL->linkdown(fsm); } /* Endif */ PPPFSM_sendconfreq(fsm, NULL); fsm->STATE = PPP_STATE_REQ_SENT; } /* Endif */ break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void _iopcb_hdlc_rcv_unblock ( pointer param /* [IN] The semaphore to unblock when the message arrives */ ) { /* Body */ LWSEM_STRUCT _PTR_ sem = (LWSEM_STRUCT _PTR_)param; PPP_mutex_unlock(sem); } /* Endbody */
uint_32 PPP_register ( _ppp_handle handle, /* [IN] - the PPP state structure */ uint_16 protocol, /* [IN] - protocol */ void (_CODE_PTR_ callback)(PCB_PTR, pointer), /* [IN] - callback function */ pointer parameter /* [IN] - first parameter for callback function */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = handle; PROT_CALL_PTR prot_ptr; /* Do some error checking */ if (ppp_ptr->VALID != PPP_VALID) { return RTCSERR_PPP_INVALID_HANDLE; } else if (!(protocol&1) || (protocol&0x100)) { return RTCSERR_PPP_INVALID_PROTOCOL; } /* Endif */ /* Allocate a callback structure */ prot_ptr = _mem_alloc_system_zero(sizeof(PROT_CALL)); if (prot_ptr == NULL) { return RTCSERR_PPP_ALLOC_CALL_FAILED; } /* Endif */ protocol &= 0xFFFF; prot_ptr->PROTOCOL = protocol; prot_ptr->CALLBACK = callback; prot_ptr->PARAM = parameter; PPP_mutex_lock(&ppp_ptr->MUTEX); if (PPP_findprot(ppp_ptr, protocol)) { ppp_ptr->PROT_CALLS->CALLBACK = callback; ppp_ptr->PROT_CALLS->PARAM = parameter; } else { prot_ptr->NEXT = ppp_ptr->PROT_CALLS; ppp_ptr->PROT_CALLS = prot_ptr; prot_ptr = NULL; } /* Endif */ PPP_mutex_unlock(&ppp_ptr->MUTEX); if (prot_ptr) { _mem_free(prot_ptr); } /* Endif */ return PPP_OK; } /* Endbody */
uint_32 PPP_unregister ( _ppp_handle handle, /* [IN] - the PPP state structure */ uint_16 protocol /* [IN] - protocol */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_CFG_PTR ppp_ptr = handle; PROT_CALL_PTR prot_ptr; uint_32 error; /* Do some error checking */ if (ppp_ptr->VALID != PPP_VALID) { return RTCSERR_PPP_INVALID_HANDLE; } else if (!(protocol&1) || (protocol&0x100)) { return RTCSERR_PPP_INVALID_PROTOCOL; } else if (!(~protocol & 0xC000)) { /* Don't allow unregistering LCP */ return RTCSERR_PPP_INVALID_PROTOCOL; } /* Endif */ /* Remove structure from list */ protocol &= 0xFFFF; prot_ptr = NULL; error = RTCSERR_PPP_PROT_NOT_FOUND; PPP_mutex_lock(&ppp_ptr->MUTEX); if (PPP_findprot(ppp_ptr, protocol)) { prot_ptr = ppp_ptr->PROT_CALLS; ppp_ptr->PROT_CALLS = prot_ptr->NEXT; error = PPP_OK; } /* Endif */ PPP_mutex_unlock(&ppp_ptr->MUTEX); if (prot_ptr) { _mem_free(prot_ptr); } /* Endif */ return error; #else return RTCSERR_IP_IS_DISABLED; #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
static void PAP_up ( _ppp_handle handle /* [IN] - the PPP state structure */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = handle; PPP_mutex_lock(&ppp_ptr->MUTEX); ppp_ptr->LINK_AUTH = TRUE; PPP_mutex_unlock(&ppp_ptr->MUTEX); PPP_up(handle); } /* Endbody */
static void CCP_down ( PPPFSM_CFG_PTR fsm /* [IN] - State Machine */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = fsm->HANDLE; /* Restore default compression methods */ PPP_mutex_lock(&ppp_ptr->MUTEX); ppp_ptr->RECV_OPTIONS->CP = PPP_DEFAULT_OPTIONS.CP; ppp_ptr->SEND_OPTIONS->CP = PPP_DEFAULT_OPTIONS.CP; PPP_mutex_unlock(&ppp_ptr->MUTEX); } /* Endbody */
void PPPFSM_lowerdown ( PPPFSM_CFG_PTR fsm /* [IN/OUT] - State Machine */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_CFG_PTR ppp_ptr = fsm->HANDLE; PPP_mutex_lock(&fsm->MUTEX); switch(fsm->STATE) { case PPP_STATE_CLOSED: fsm->STATE = PPP_STATE_INITIAL; break; case PPP_STATE_STOPPED: fsm->STATE = PPP_STATE_STARTING; break; case PPP_STATE_CLOSING: fsm->STATE = PPP_STATE_INITIAL; PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL); break; case PPP_STATE_STOPPING: case PPP_STATE_REQ_SENT: case PPP_STATE_ACK_RCVD: case PPP_STATE_ACK_SENT: fsm->STATE = PPP_STATE_STARTING; PPP_send_stop(ppp_ptr, fsm->CALL->PROTOCOL); break; case PPP_STATE_OPENED: if (fsm->CALL->linkdown) { fsm->CALL->linkdown(fsm); } /* Endif */ fsm->STATE = PPP_STATE_STARTING; break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void PPPFSM_close ( PPPFSM_CFG_PTR fsm /* [IN/OUT] - State Machine */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_mutex_lock(&fsm->MUTEX); switch (fsm->STATE) { case PPP_STATE_STARTING: fsm->STATE = PPP_STATE_INITIAL; break; case PPP_STATE_STOPPED: fsm->STATE = PPP_STATE_CLOSED; break; case PPP_STATE_STOPPING: fsm->STATE = PPP_STATE_CLOSING; break; case PPP_STATE_OPENED: if (fsm->CALL->linkdown) { fsm->CALL->linkdown(fsm); } /* Endif */ /* fall through */ case PPP_STATE_REQ_SENT: case PPP_STATE_ACK_RCVD: case PPP_STATE_ACK_SENT: PPPFSM_sendtermreq(fsm, NULL); fsm->STATE = PPP_STATE_CLOSING; break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void PPP_rx_task ( pointer handle, /* [IN] - the PPP state structure */ pointer creator /* [IN] - the task create information */ ) { /* Body */ PPP_CFG_PTR ppp_ptr = handle; PCB_PTR pcb; boolean linkstate, linkauth; PPP_OPT opt; uint_16 protocol, len; void (_CODE_PTR_ callback)(PCB_PTR, pointer); pointer param; #if RTCS_PRINT_PPP_PACKETS /****/ uint_32 i; uchar_ptr a; /****/ #endif ppp_ptr->RX_TASKID = RTCS_task_getid(); RTCS_task_resume_creator(creator, PPP_OK); /* Wait for incoming packets */ for (;;) { /* new fix */ //check if app shutdown (STOP_RX == TRUE) if(ppp_ptr->STOP_RX) { break; } /***********/ /********************************************************** ** ** Wait for a frame ** */ /* Read a frame */ /*Lets use flag for send pointer to ppp_ptr->STOP_RX */ pcb = _iopcb_read(ppp_ptr->DEVICE, (uint_32)&(ppp_ptr->STOP_RX)); /* new fix */ if(NULL == pcb) { _time_delay(1); continue; } /***********/ #if RTCS_PRINT_PPP_PACKETS /* TBR */ /* This part print input packet */ a = pcb->FRAG[0].FRAGMENT; i=0; printf("receive 7E FF 03 "); while(i< (pcb->FRAG[0].LENGTH)+2) { if(*a < 0x10) { printf("0"); } printf("%X ",*a); i++; a++; } printf("7E\n"); /*******/ #endif len = pcb->FRAG[0].LENGTH; if (len < 2) { PCB_free(pcb); ppp_ptr->ST_RX_RUNT++; continue; } /* Endif */ protocol = ntohs(pcb->FRAG[0].FRAGMENT); /* Read the negotiated Receive options */ PPP_mutex_lock(&ppp_ptr->MUTEX); linkstate = ppp_ptr->LINK_STATE; linkauth = ppp_ptr->LINK_AUTH; opt = *ppp_ptr->RECV_OPTIONS; PPP_mutex_unlock(&ppp_ptr->MUTEX); /* Discard all non-LCP packets until the link is opened */ if (protocol != PPP_PROT_LCP) { if (!linkstate) { PCB_free(pcb); ppp_ptr->ST_RX_DISCARDED++; continue; } /* Endif */ /* and all non-AP packets until the link is authenticated */ if (protocol != opt.AP) { if (!linkauth) { PCB_free(pcb); ppp_ptr->ST_RX_DISCARDED++; continue; } /* Endif */ } /* Endif */ } /* Endif */ /* Decompress the packet if compression was negotiated */ if ((protocol == PPP_PROT_CP) && opt.CP) { pcb = opt.CP->CP_decomp(&ppp_ptr->CCP_STATE.RECV_DATA, pcb, ppp_ptr, &opt); protocol = ntohs(pcb->FRAG[0].FRAGMENT); } /* Endif */ /********************************************************** ** ** Forward the packet to higher-level protocol ** */ /* Find out where to send the packet */ ppp_ptr->ST_RX_RECEIVED++; /* ** We could put the known protocols in the PROT_CALLS ** list, but we don't because we always want them to ** work, even if someone tries to PPP_unregister() them. */ switch (protocol) { /* Got an LCP packet */ case PPP_PROT_LCP: LCP_input(pcb, &ppp_ptr->LCP_FSM); break; /* Got a CCP packet */ case PPP_PROT_CCP: CCP_input(pcb, &ppp_ptr->CCP_FSM); break; /* Got a PAP packet */ case PPP_PROT_PAP: PAP_input(pcb, ppp_ptr); break; /* Got a CHAP packet */ case PPP_PROT_CHAP: CHAP_input(pcb, ppp_ptr); break; default: callback = NULL; PPP_mutex_lock(&ppp_ptr->MUTEX); if (PPP_findprot(ppp_ptr, protocol)) { callback = ppp_ptr->PROT_CALLS->CALLBACK; param = ppp_ptr->PROT_CALLS->PARAM; } /* Endif */ PPP_mutex_unlock(&ppp_ptr->MUTEX); if (callback) { callback(pcb, param); } else { /* No callback found -- Send Protocol-Reject */ LCP_sendprotrej(pcb, &ppp_ptr->LCP_FSM); } /* Endif */ break; } /* Endswitch */ } /* Endfor */ /* We can start task again. (STOP_RX == FALSE) */ ppp_ptr->STOP_RX = FALSE; } /* Endbody */
uint32_t PPP_send ( _ppp_handle handle, /* [IN] - the PPP state structure */ uint16_t protocol, /* [IN] - protocol for the packet */ PCB_PTR pcb /* [IN] - the packet to send */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_CFG_PTR ppp_ptr = handle; PCB_FRAGMENT_PTR frag_ptr; uint32_t size, mru; uint32_t error; /* Do some error checking */ if (ppp_ptr->VALID != PPP_VALID) { PCB_free(pcb); return RTCSERR_PPP_INVALID_HANDLE; } else if (!(protocol&1) || (protocol&0x100)) { PCB_free(pcb); return RTCSERR_PPP_INVALID_PROTOCOL; } /* Endif */ error = PPP_OK; PPP_mutex_lock(&ppp_ptr->MUTEX); if (!ppp_ptr->LINK_STATE) { error = RTCSERR_PPP_LINK_NOT_OPEN; } else { /* SPR P122-0371-01 */ /* PCB includes 2-byte protocol field, but negotiated MRU doesn't */ mru = ppp_ptr->SEND_OPTIONS->MRU + 2; /* End SPR P122-0371-01 */ } /* Endif */ PPP_mutex_unlock(&ppp_ptr->MUTEX); if (error) { PCB_free(pcb); return error; } /* Endif */ /* ** Make sure the first fragment is long enough for the PPP protocol ** field. This isn't strictly necessary, but it's impractical ** to split a 2 byte field over multiple fragments. */ if (pcb->FRAG[0].LENGTH < 2) { PCB_free(pcb); return RTCSERR_PPP_PACKET_TOO_SHORT; } /* Endif */ /* ** Make sure that no fragment exceeds a maximum packet length. ** We check every fragment because we want to prevent something ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000. This ** situation would not be detected if we only check the total ** length. */ size = 0; for (frag_ptr = pcb->FRAG; frag_ptr->LENGTH; frag_ptr++) { if (frag_ptr->LENGTH > mru) { PCB_free(pcb); return RTCSERR_PPP_PACKET_TOO_LONG; } /* Endif */ size += frag_ptr->LENGTH; } /* Endfor */ /* ** Make sure that the total sum of the fragments doesn't exceed ** a maximum packet length. */ if (size > mru) { PCB_free(pcb); return RTCSERR_PPP_PACKET_TOO_LONG; } /* Endif */ /* ** Everything checks out -- send the packet to the Tx task. */ mqx_htons(pcb->FRAG[0].FRAGMENT, protocol); return PPP_send_one(ppp_ptr, protocol, pcb); #else return RTCSERR_IP_IS_DISABLED; #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void PPP_tx_task ( void *handle, /* [IN] - the PPP state structure */ void *creator /* [IN] - the creation information */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPP_CFG_PTR ppp_ptr = handle; uint32_t ctrl; bool state; PPP_OPT opt; PCB_PTR pcb; uint32_t pcbopt; PPP_MESSAGE_PTR message, xmithead, * xmitnode; uint32_t timebefore, timeafter; bool wait; int32_t timeout; uint16_t protocol; _queue_id queue; void *param; /* Obtain a message queue so that PPP_send() can reach us */ queue = RTCS_msgq_open(0, 0); if (queue == 0) { RTCS_task_exit(creator, RTCSERR_PPP_OPEN_QUEUE_FAILED); } /* Endif */ RTCS_task_resume_creator(creator, PPP_OK); ppp_ptr->MSG_QUEUE = queue; xmithead = NULL; timebefore = RTCS_time_get(); #define PPPTX_DISCARD(msg) \ (msg)->PCB->FREE = (msg)->ORIG_FREE; \ PCB_free((msg)->PCB); \ RTCS_msg_free(msg) for(;;) { /********************************************************** ** ** Wait for a packet to send ** */ wait = TRUE; timeout = 0; /* Check if a packet is waiting for retransmission */ if (xmithead) { /* Measure elapsed time */ timeafter = RTCS_time_get(); timeout = RTCS_timer_get_interval(timebefore, timeafter); timebefore = timeafter; xmithead->DELTA -= timeout; /* If its timer has expired, send it */ timeout = xmithead->DELTA; if (timeout <= 0) { message = NULL; wait = FALSE; } /* Endif */ } /* Endif */ /* ** There are three cases at this point: ** 1) Retransmission queue is empty ** (wait == TRUE, timeout == 0, message == ?) ** 2) Retransmission queue is nonempty, positive timeout ** (wait == TRUE, timeout > 0, message == ?) ** 3) Retransmission queue is nonempty, nonpositive timeout, ** i.e., head of retransmission queue timed out ** (wait == FALSE, timeout == 0, message == NULL) */ /* If there are no expired messages, block */ if (wait) { message = RTCS_msgq_receive(queue, timeout, ppp_ptr->MSG_POOL); } /* Endif */ /* ** There are two cases at this point: ** 1) We got a message from _msgq_receive ** (message != NULL) ** 2) Head of retransmission queue timed out ** (message == NULL) */ /* We got a packet to send */ if (message) { /* Control packets restart or stop retransmission */ ctrl = message->COMMAND; if (ctrl == PPPCMD_SHUTDOWN) { param = message->PARAM; /* Free the message we just got */ RTCS_msg_free(message); for (xmitnode = &xmithead;;){ if (*xmitnode == NULL) { break; } else { /* unlink */ message = *xmitnode; *xmitnode = message->NEXT; /* Free the message from the list */ PPPTX_DISCARD(message); } /* Endif */ } /* Endfor */ RTCS_msgq_close(queue); /* Unblock PPP_shutdown() */ RTCS_sem_post(param); /* Kill self */ return; } /* Endif */ if (ctrl != PPPCMD_SEND) { protocol = message->PROTOCOL; RTCS_msg_free(message); /* ** Search the retransmission queue for a packet ** matching the protocol field of the control message */ for (xmitnode = &xmithead;; xmitnode = &(*xmitnode)->NEXT) { if (*xmitnode == NULL) { break; } else if ((*xmitnode)->PROTOCOL == protocol) { message = *xmitnode; switch (ctrl) { case PPPCMD_RESTART: message->TIMEOUT = _PPP_MIN_XMIT_TIMEOUT; message->RETRY = _PPP_MAX_CONF_RETRIES; break; case PPPCMD_STOP: if (message->NEXT) { message->NEXT->DELTA += message->DELTA; } /* Endif */ *xmitnode = message->NEXT; PPPTX_DISCARD(message); break; } /* Endswitch */ break; } /* Endif */ } /* Endfor */ continue; } /* Endif */ /* Save the PCB's FREE field */ message->ORIG_FREE = message->PCB->FREE; if (message->TIMEOUT) { message->PCB->FREE = PPP_tx_pcbfree; } /* Endif */ /* Receive timed out -- get the head of the retransmission queue */ } else { message = xmithead; xmithead = message->NEXT; if (xmithead) { xmithead->DELTA += message->DELTA; } /* Endif */ /* Generate a TO event */ if (message->CALL) { message->CALL(message->PARAM, message->PCB, message->RETRY == 1); } /* Endif */ /* RETRY == 0 means retry forever */ if (message->RETRY) { /* When the retry count reaches zero, discard the packet */ if (!--message->RETRY) { PPPTX_DISCARD(message); continue; } /* Endif */ } /* Endif */ /* Use exponential backoff when retransmitting */ message->TIMEOUT <<= 1; if (message->TIMEOUT > _PPP_MAX_XMIT_TIMEOUT) { message->TIMEOUT = _PPP_MAX_XMIT_TIMEOUT; } /* Endif */ } /* Endif */ /********************************************************** ** ** We have a packet -- validate it ** */ /* Take a snapshot of the current state and send options */ PPP_mutex_lock(&ppp_ptr->MUTEX); state = ppp_ptr->LINK_STATE; opt = *ppp_ptr->SEND_OPTIONS; PPP_mutex_unlock(&ppp_ptr->MUTEX); /* Send the data packet (unless the link is not open) */ if (!state && message->PROTOCOL != PPP_PROT_LCP) { PPPTX_DISCARD(message); ppp_ptr->ST_TX_DISCARDED++; continue; } /* Endif */ /********************************************************** ** ** We have a valid packet -- send it ** */ /* LCP control packets are always sent with default options */ if (message->PROTOCOL == PPP_PROT_LCP && message->PCB->FRAG[0].FRAGMENT[2] >= 1 && message->PCB->FRAG[0].FRAGMENT[2] <= 7) { pcbopt = 1; } else { pcbopt = 0; } /* Endif */ pcb = message->PCB; /* Only data packets are compressed */ /* Start CR 2296 */ //if (((message->PROTOCOL & 0xC000) == 0) && opt.CP) { /* End CR 2296 */ // pcb = opt.CP->CP_comp(&ppp_ptr->CCP_STATE.SEND_DATA, pcb, ppp_ptr, &opt); // mqx_htons(pcb->FRAG[0].FRAGMENT, PPP_PROT_CP); //} /* Endif */ _iopcb_write(ppp_ptr->DEVICE, pcb, pcbopt); /********************************************************** ** ** Packet is sent -- update retransmission queue ** */ /* Free the buffer unless it may need to be retransmitted */ if (message->TIMEOUT) { /* Measure elapsed time */ timeafter = RTCS_time_get(); timeout = RTCS_timer_get_interval(timebefore, timeafter); timebefore = timeafter; if (xmithead) { xmithead->DELTA -= timeout; } /* Endif */ /* Insert packet into proper place in retransmission queue */ for (message->DELTA = message->TIMEOUT, xmitnode = &xmithead;; message->DELTA -= (*xmitnode)->DELTA, xmitnode = &(*xmitnode)->NEXT) { if (*xmitnode == NULL) { /* Add packet at tail of queue */ message->NEXT = NULL; *xmitnode = message; break; } else if ((*xmitnode)->DELTA > message->TIMEOUT) { /* Insert packet in middle (possibly head) of queue */ (*xmitnode)->DELTA -= message->DELTA; message->NEXT = *xmitnode; *xmitnode = message; break; } /* Endif */ } /* Endfor */ } else { /* PCB has already been freed by _iopcb_write() */ RTCS_msg_free(message); } /* Endif */ } /* Endfor */ #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */
void PPPFSM_input ( PCB_PTR pcb, /* [IN] - xCP packet */ void *fsm_data /* [IN/OUT] - State Machine */ ) { /* Body */ #if RTCSCFG_ENABLE_IP4 PPPFSM_CFG_PTR fsm = fsm_data; uint32_t *stat; unsigned char *inp; uint16_t pcblen, len; /* ** Parse header (code, id and length). ** If packet is too short, drop it. */ stat = NULL; fsm->PACKET = pcb; inp = pcb->FRAG[0].FRAGMENT + 2; /* skip the protocol field */ pcblen = pcb->FRAG[0].LENGTH - 2; PPP_mutex_lock(&fsm->MUTEX); if (pcblen < CP_HDR_LEN) { stat = &fsm->ST_CP_SHORT; } else { fsm->CODE = *inp++; fsm->ID = *inp++; len = *inp++ << 8; len += *inp++; if (len < CP_HDR_LEN) { stat = &fsm->ST_CP_SHORT; } else if (len > pcblen) { stat = &fsm->ST_CP_SHORT; } else if (fsm->STATE < PPP_STATE_CLOSED) { stat = &fsm->ST_CP_DOWN; } /* Endif */ } /* Endif */ if (stat) { PPP_mutex_unlock(&fsm->MUTEX); ++*stat; PCB_free(pcb); return; } /* Endif */ fsm->LENGTH = len - CP_HDR_LEN; fsm->DATA = inp; /* ** Action depends on code. */ switch (fsm->CODE) { case CP_CODE_CONF_REQ: PPPFSM_recvconfreq(fsm, fsm->HANDLE); break; case CP_CODE_CONF_ACK: PPPFSM_recvconfack(fsm); break; case CP_CODE_CONF_NAK: PPPFSM_recvconfnak(fsm, fsm->CALL->recvnak); break; case CP_CODE_CONF_REJ: PPPFSM_recvconfnak(fsm, fsm->CALL->recvrej); break; case CP_CODE_TERM_REQ: PPPFSM_recvtermreq(fsm); break; case CP_CODE_TERM_ACK: PPPFSM_recvtermack(fsm); break; case CP_CODE_CODE_REJ: PPPFSM_recvcoderej(fsm); break; default: if (!fsm->CALL->recvcode || !fsm->CALL->recvcode(fsm)) { PPPFSM_sendcoderej(fsm); } /* Endif */ break; } /* Endswitch */ PPP_mutex_unlock(&fsm->MUTEX); #else PCB_free(pcb); #endif /* RTCSCFG_ENABLE_IP4 */ } /* Endbody */