void TFTPSRV_task ( void *dummy, void *creator ) { /* Body */ TFTPSRV_STATE_STRUCT_PTR tftpsrv_ptr; sockaddr_in laddr; uint32_t i, numtrans, timeout; uint32_t error; tftpsrv_ptr = RTCS_mem_alloc_zero(sizeof(TFTPSRV_STATE_STRUCT)); if (tftpsrv_ptr == NULL) { RTCS_task_exit(creator, RTCSERR_OUT_OF_MEMORY); } /* Endif */ TFTPSRV_task_id = RTCS_task_getid(); #ifdef __MQX__ /* Set up exit handler and context so that we can clean up if the TFTP Server is terminated */ _task_set_environment( _task_get_id(), (void *) tftpsrv_ptr ); _task_set_exit_handler( _task_get_id(), TFTPSRV_Exit_handler ); #endif tftpsrv_ptr->SRV_SOCK = socket(PF_INET, SOCK_DGRAM, 0); if (tftpsrv_ptr->SRV_SOCK == RTCS_SOCKET_ERROR) { RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS); } /* Endif */ laddr.sin_family = AF_INET; laddr.sin_port = IPPORT_TFTP; laddr.sin_addr.s_addr = INADDR_ANY; error = bind(tftpsrv_ptr->SRV_SOCK, (const sockaddr *)&laddr, sizeof(laddr)); if (error != RTCS_OK) { RTCS_task_exit(creator, error); } /* Endif */ RTCS_task_resume_creator(creator, RTCS_OK); for (;;) { timeout = TFTPSRV_service_timer(tftpsrv_ptr); numtrans = tftpsrv_ptr->NUM_TRANSACTIONS; error = RTCS_selectset(&tftpsrv_ptr->SRV_SOCK, numtrans+1, timeout); if ((error == RTCS_OK) || (error == RTCS_SOCKET_ERROR)) { continue; } /* Endif */ if (error == tftpsrv_ptr->SRV_SOCK) { /* New request, service it */ TFTPSRV_service_request(tftpsrv_ptr); } else { for (i = 0; i < numtrans; i++) { if (error == tftpsrv_ptr->SOCKETS[i]) { TFTPSRV_service_transaction(tftpsrv_ptr, tftpsrv_ptr->TRANS_PTRS[i]); break; } /* Endif */ } /* Endfor */ } /* Endif */ } /* Endfor */ } /* Endbody */
static void SNTP_task ( void *init_ptr, void *creator ) { /* Body */ struct sntpclnt_init init = *(struct sntpclnt_init *)init_ptr; uint32_t sock, error_code, timeout; /* Setup socket and check parameters */ error_code = SNTP_setup(&sock, init.dest, init.poll); if (error_code != RTCS_OK) { RTCS_task_exit(creator, error_code); } else { RTCS_task_resume_creator(creator, RTCS_OK); } /* Endif */ /* ** Start an infinite loop and poll for time at regular intervals. */ while (TRUE) { timeout = init.poll * 1000; error_code = SNTP_timed_send_recv(sock, &init.dest, &timeout); RTCS_delay(timeout); } /* Endwhile */ } /* Endbody */
void DHCPSRV_task ( pointer dummy, pointer creator ) { /* Body */ DHCPSRV_STATE_STRUCT state; sockaddr_in addr; uint_32 timeout; uchar_ptr msgptr; uint_32 msglen; uchar msgtype; int_32 error; state.IP_AVAIL = NULL; state.IP_OFFERED = NULL; state.IP_LEASED = NULL; /* Start CR 1547 */ state.IP_TAKEN = NULL; state.FLAGS = DHCPSVR_FLAG_DO_PROBE; /* End CR 1547 */ RTCS_mutex_init(&state.IPLIST_SEM); state.SOCKET = socket(PF_INET, SOCK_DGRAM, 0); if (state.SOCKET == RTCS_SOCKET_ERROR) { RTCS_task_exit(creator, RTCSERR_OUT_OF_SOCKETS); } /* Endif */ addr.sin_family = AF_INET; addr.sin_port = IPPORT_BOOTPS; addr.sin_addr.s_addr = INADDR_ANY; error = bind(state.SOCKET, &addr, sizeof(sockaddr_in)); if (error != RTCS_OK) { RTCS_task_exit(creator, error); } /* Endif */ DHCPSRV_cfg = &state; RTCS_task_resume_creator(creator, RTCS_OK); for (;;) { /* Wait for a message */ timeout = DHCPSRV_expire(&state) * 1000; error = RTCS_selectset(&state.SOCKET, 1, timeout); if ((error == 0) || (error == RTCS_ERROR)) continue; /* Received a message, respond accordingly */ error = recvfrom(state.SOCKET, state.RCV_BUFFER, sizeof(state.RCV_BUFFER), 0, NULL, NULL); if (error == RTCS_ERROR) continue; /* The datagram must contain at least a header and a magic cookie */ if (error < sizeof(DHCP_HEADER) + DHCPSIZE_MAGIC) continue; msgptr = state.RCV_BUFFER + sizeof(DHCP_HEADER); if (ntohl(msgptr) != DHCP_MAGIC) continue; msgptr += DHCPSIZE_MAGIC; msglen = error - sizeof(DHCP_HEADER) - DHCPSIZE_MAGIC; state.RCV_BUFFER_LEN = error; /* Update the time before starting any new events */ DHCPSRV_expire(&state); /* Service the packet */ msgtype = DHCPSRV_find_msgtype(msgptr, msglen); switch (msgtype) { case DHCPTYPE_DHCPDISCOVER: DHCPSRV_service_discover(&state); break; case DHCPTYPE_DHCPREQUEST: DHCPSRV_service_request(&state); break; case DHCPTYPE_DHCPRELEASE: DHCPSRV_service_release(&state); break; case DHCPTYPE_DHCPDECLINE: DHCPSRV_service_decline(&state); break; } /* Endswitch */ } /* Endwhile */ } /* 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 TCPIP_task ( void *dummy, void *creator ) { /* Body */ TCPIP_CFG_STRUCT TCPIP_cfg; RTCS_DATA_PTR RTCS_data_ptr; uint32_t i; TCPIP_MESSAGE_PTR tcpip_msg; uint32_t timeout = 1, timebefore, timeafter, timedelta; uint32_t status; /* Return status */ _queue_id tcpip_qid; RTCSLOG_FNE2(RTCSLOG_FN_TCPIP_task, creator); RTCS_data_ptr = RTCS_get_data(); RTCS_setcfg(TCPIP, &TCPIP_cfg); TCPIP_cfg.status = RTCS_OK; tcpip_qid = RTCS_msgq_open(TCPIP_QUEUE, 0); if (tcpip_qid == 0) { RTCS_task_exit(creator, RTCSERR_OPEN_QUEUE_FAILED); } /* Endif */ RTCS_data_ptr->TCPIP_TASKID = RTCS_task_getid(); /* ** Initialize the Time Service */ TCP_tick = TCPIP_fake_tick; TCPIP_Event_init(); timebefore = RTCS_time_get(); /* ** Allocate a block of PCBs */ status = RTCSPCB_init(); if (status != RTCS_OK) { RTCS_task_exit(creator, status); } /* Endif */ IF_FREE = NULL; /* ** Initialize the protocols */ #if RTCSCFG_ENABLE_IP4 /********************************************* * Initialize IPv4 **********************************************/ status = IP_init(); if (status) { RTCS_task_exit(creator, status); } #if RTCSCFG_ENABLE_ICMP status = ICMP_init(); if (status) { RTCS_task_exit(creator, status); } #endif /* RTCSCFG_ENABLE_ICMP */ ARP_init(); BOOT_init(); #endif /* RTCSCFG_ENABLE_IP4 */ #if RTCSCFG_ENABLE_IP6 /********************************************* * Initialize IPv6 **********************************************/ status = IP6_init(); if (status) { RTCS_task_exit(creator, status); } /* Init ICMP6. */ status = ICMP6_init(); //TBD Add it to RTCS6_protocol_table if (status) { RTCS_task_exit(creator, status); } #endif /* RTCSCFG_ENABLE_IP6*/ #if (RTCSCFG_ENABLE_IP_REASSEMBLY && RTCSCFG_ENABLE_IP4) || (RTCSCFG_ENABLE_IP6_REASSEMBLY && RTCSCFG_ENABLE_IP6) /* Initialize the reassembler */ status = IP_reasm_init(); if (status) { RTCS_task_exit(creator, status); } #endif /* Add loopback interface.*/ status = IPLOCAL_init (); if (status) { RTCS_task_exit(creator, status); }; for (i = 0; RTCS_protocol_table[i]; i++) { status = (*RTCS_protocol_table[i])(); if (status) { RTCS_task_exit(creator, status); } /* Endif */ } /* Endfor */ _RTCS_initialized= TRUE; RTCS_task_resume_creator(creator, RTCS_OK); while (1) { TCPIP_EVENT_PTR queue = TCPIP_Event_head; tcpip_msg = (TCPIP_MESSAGE_PTR)RTCS_msgq_receive(tcpip_qid, timeout, RTCS_data_ptr->TCPIP_msg_pool); if (tcpip_msg) { if (NULL != tcpip_msg->COMMAND) { tcpip_msg->COMMAND(tcpip_msg->DATA); } RTCS_msg_free(tcpip_msg); } timeout = TCP_tick(); timeafter = RTCS_time_get(); /* If head changed set time delta to zero to prevent immidiate event */ if (queue == TCPIP_Event_head) { timedelta = RTCS_timer_get_interval(timebefore, timeafter); } else { timedelta = 0; } timebefore = timeafter; timedelta = TCPIP_Event_time(timedelta); if (timedelta != 0) { if ((timedelta < timeout) || (timeout == 0)) { timeout = timedelta; } } } } /* Endbody */