static void httpd_session_dynamic_task(pointer init_ptr, pointer creator) { HTTPD_SES_TASK_PARAM *param = (HTTPD_SES_TASK_PARAM*)init_ptr; HTTPD_SESSION_STRUCT *session; HTTPD_ASSERT(init_ptr); HTTPD_DEBUG(1, "session task start\n"); session = httpd_ses_alloc(param->server); if (session) { RTCS_task_resume_creator(creator, RTCS_OK); HTTPD_DEBUG(1, "session task run...\n"); httpd_ses_init(param->server, session, param->sock); while (HTTPD_SESSION_VALID == session->valid) { httpd_ses_process(param->server, session); } httpd_ses_free(session); } else { RTCS_task_resume_creator(creator, (uint_32) RTCS_ERROR); } HTTPD_FREE(init_ptr); _lwsem_post(&sem_session_counter); HTTPD_DEBUG(1, "session task stop\n"); }
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 */
/** server task - httpd run in one task and poll each session */ static void httpd_server_task(pointer init_ptr, pointer creator) { HTTPD_STRUCT *server = (HTTPD_STRUCT*)init_ptr; HTTPD_ASSERT(server); if (!server) goto ERROR; RTCS_task_resume_creator(creator, RTCS_OK); while (1) { httpd_server_poll(server, 1); } ERROR: RTCS_task_resume_creator(creator, (uint_32)RTCS_ERROR); }
/* * Task for reading from socket and sending data to output file descriptor. */ void telnetcln_in_task(void * v_context, void * creator) { TELNETCLN_CONTEXT *context; context = (TELNETCLN_CONTEXT *) v_context; context->rx_tid = _task_get_id(); RTCS_task_resume_creator(creator, RTCS_OK); _task_block(); while(context->valid == TELNETCLN_CONTEXT_VALID) { bool b_result = TRUE; #if MQX_USE_IO_OLD /* old IO (fio.h) fstatus() */ b_result = fstatus(context->telnetfd); #endif if(b_result && context->tx_tid) { int32_t c; c = (int32_t) fgetc(context->telnetfd); if(c == IO_EOF) { if (context->tx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } break; } fputc(c & 0x7F, context->params.fd_out); } else { /* * this executes only for old IO. * for NIO we expect fgetc() is blocking */ if (context->tx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } RTCS_time_delay(10); } } context->rx_tid = 0; #if !MQX_USE_IO_OLD ioctl(fileno(context->params.fd_in), IOCTL_ABORT, NULL); #endif }
/** session task */ static void httpd_session_static_task(pointer init_ptr, pointer creator) { extern HTTPD_SESSION_STRUCT* httpd_ses_alloc(HTTPD_STRUCT *server); extern void httpd_ses_poll(HTTPD_STRUCT *server, HTTPD_SESSION_STRUCT *session); HTTPD_SESSION_STRUCT *session; if (!init_ptr) goto ERROR; session = httpd_ses_alloc((HTTPD_STRUCT*)init_ptr); if (session) { RTCS_task_resume_creator(creator, RTCS_OK); httpd_ses_poll((HTTPD_STRUCT*)init_ptr, session); } else goto ERROR; return; ERROR: RTCS_task_resume_creator(creator, RTCS_ERROR); }
static void Clock_child_task ( #if CREATE_WITH_RTCS pointer param, pointer creator #else uint_32 sock #endif ) { #if CREATE_WITH_RTCS uint_32 sock = (uint_32) param; #endif int_32 size; char buffer[256]; TIME_STRUCT time; #if CREATE_WITH_RTCS RTCS_task_resume_creator(creator, RTCS_OK); #endif printf("Clock child: Servicing socket %x\n", sock); #if USE_RTCS_ATTACH_DETACH RTCS_attachsock(sock); #endif while (sock) { _time_get(&time); size = sprintf(buffer, "\r\nSeconds elapsed = %d.%03d", time.SECONDS, time.MILLISECONDS); size++; // account for null byte if (size != send(sock, buffer, size, 0)) { printf("\nClock child: closing socket %x\n",sock); shutdown(sock, FLAG_CLOSE_TX); sock=0; } else { _time_delay(5000); } } printf("Clock child: Terminating\n"); }
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_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 */
/* * Task for reading from input and sending data through socket. */ void telnetcln_out_task(void * v_context, void * creator) { TELNETCLN_CONTEXT *context; context = (TELNETCLN_CONTEXT *) v_context; context->tx_tid = _task_get_id(); RTCS_task_resume_creator(creator, RTCS_OK); while(context->valid == TELNETCLN_CONTEXT_VALID) { bool b_result = TRUE; #if MQX_USE_IO_OLD /* * old IO (fio.h) input might be polled UART driver * thus only for this case we check if a character is available. * is there is no character, sleep for a tick */ b_result = fstatus(context->params.fd_in); #endif if (b_result && context->rx_tid) { int32_t c; c = (int32_t) fgetc(context->params.fd_in); #if !MQX_USE_IO_OLD if (EOF == c) { clearerr(context->params.fd_in); if (context->rx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } break; } if (c == '\n') { c = '\r' ; } #endif if (fputc(c & 0x7F, context->telnetfd) == IO_EOF) { break; } } else { /* * this executes only for old IO uart driver. * for NIO tty, fgetc() above is blocking function. */ if (context->rx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } RTCS_time_delay(10); } } context->tx_tid = 0; }
void ftpsrv_server_task(void* init_ptr, void* creator) { FTPSRV_STRUCT* server = (FTPSRV_STRUCT*) init_ptr; _mqx_uint res; /* Task init start */ if (server == NULL) { RTCS_task_resume_creator(creator, (uint32_t)RTCS_ERROR); } server->server_tid = _task_get_id(); res = _lwsem_create(&server->ses_cnt, server->params.max_ses); if (res != MQX_OK) { server->server_tid = 0; RTCS_task_resume_creator(creator, (uint32_t)RTCS_ERROR); } RTCS_task_resume_creator(creator, RTCS_OK); /* Task init end */ while (server->run) { uint32_t conn_sock = 0; uint32_t new_sock = 0; _lwsem_wait(&server->ses_cnt); while (!conn_sock && server->run) { conn_sock = RTCS_selectset(&(server->sock_v4), 2, 250); } if (server->run) { unsigned short length = 0; struct sockaddr remote_addr; new_sock = accept(conn_sock, (sockaddr*) &remote_addr, &length); } else { break; } if (new_sock != RTCS_SOCKET_ERROR) { FTPSRV_SESSION_PARAM ses_param; ses_param.sock = new_sock; ses_param.server = server; /* Try to create task for session */ res = RTCS_task_create("ftpsrv session", server->params.server_prio, FTPSRV_SESSION_STACK_SIZE, ftpsrv_session_task, &ses_param); if (MQX_OK != res) { shutdown(new_sock, FLAG_ABORT_CONNECTION); _lwsem_post(&server->ses_cnt); } } else { _lwsem_post(&server->ses_cnt); /* We probably run out of sockets. Wait some arbitrary * time and then try again to prevent session tasks resource starvation. */ _time_delay(150); } } _lwsem_destroy(&server->ses_cnt); server->server_tid = 0; }
/* Task for reading/writing file */ void ftpsrv_transfer_task(void* init_ptr, void* creator) { FTPSRV_TRANSFER_PARAM* param = (FTPSRV_TRANSFER_PARAM*) init_ptr; MQX_FILE_PTR file = param->file; uint32_t mode = param->mode; uint32_t sock = param->sock; FTPSRV_SESSION_STRUCT* session = param->session; void* data_buffer; char* msg_str; if (session->state == FTPSRV_STATE_TRANSFER) { RTCS_task_resume_creator(creator, (uint32_t) RTCS_ERROR); return; } data_buffer = RTCS_mem_alloc(FTPSRVCFG_DATA_BUFFER_SIZE); if (data_buffer == NULL) { RTCS_task_resume_creator(creator, (uint32_t) RTCS_ERROR); return; } session->transfer_tid = _task_get_id(); session->state = FTPSRV_STATE_TRANSFER; RTCS_task_resume_creator(creator, (uint32_t) RTCS_OK); while (1) { FTPSRV_TRANSFER_MSG message; _mqx_uint retval; /* Reading from file */ if (mode == FTPSRV_MODE_READ) { uint32_t length; int32_t error; length = fread((void*) data_buffer, 1, FTPSRVCFG_DATA_BUFFER_SIZE, file); if ((length != FTPSRVCFG_DATA_BUFFER_SIZE) && ferror(file) && !feof(file)) { msg_str = (char*) ftpsrvmsg_locerr; break; } error = send(sock, data_buffer, length, 0); if (error == RTCS_ERROR) { msg_str = (char*) ftpsrvmsg_locerr; break; } if (feof(file)) { msg_str = (char*) ftpsrvmsg_trans_complete; break; } } /* Writing to file */ else if ((mode == FTPSRV_MODE_WRITE) || (mode == FTPSRV_MODE_APPEND)) { uint32_t length; int32_t received; received = recv(sock, data_buffer, FTPSRVCFG_DATA_BUFFER_SIZE, 0); if (received == RTCS_ERROR) { msg_str = (char*) ftpsrvmsg_trans_complete; break; } length = fwrite((void*) data_buffer, 1, received, file); if (length != received) { if (length == IO_ERROR) { msg_str = (char*) ftpsrvmsg_no_space; } else { msg_str = (char*) ftpsrvmsg_writefail; } break; } } retval = _lwmsgq_receive((void*) session->msg_queue, (uint32_t *)&message, LWMSGQ_TIMEOUT_FOR, 1, NULL); if (retval != MQX_OK) { continue; } if (message.command == FTPSRV_CMD_ABORT) { msg_str = (char*) ftpsrvmsg_trans_abort; break; } else if (message.command == FTPSRV_CMD_STAT) { /* TODO: Add code to print out transfer statistics */ } } _mem_free(data_buffer); fclose(file); ftpsrv_send_msg(session, msg_str); shutdown(sock, FLAG_CLOSE_TX); session->state = FTPSRV_STATE_IDLE; }
static void ftpsrv_session_task(void* init_ptr, void* creator) { FTPSRV_SESSION_STRUCT* session; FTPSRV_STRUCT* server = ((FTPSRV_SESSION_PARAM*) init_ptr)->server; uint32_t sock = ((FTPSRV_SESSION_PARAM*) init_ptr)->sock; uint32_t i; _task_id tid = _task_get_id(); _mqx_uint retval = 0; /* Find empty session */ _lwsem_wait(&server->tid_sem); for (i = 0; i < server->params.max_ses; i++) { if (server->session[i] == NULL) { break; } } if (i == server->params.max_ses) { RTCS_task_resume_creator(creator, (uint32_t) RTCS_ERROR); _lwsem_post(&server->tid_sem); _lwsem_post(&server->ses_cnt); return; } /* Save task ID - used for indication of running task */ server->ses_tid[i] = tid; /* Access to array done. Unblock other tasks. */ _lwsem_post(&server->tid_sem); /* Allocate session */ session = ftpsrv_ses_alloc(server); if (session) { server->session[i] = session; RTCS_task_resume_creator(creator, RTCS_OK); ftpsrv_ses_init(server, session, sock); ftpsrv_send_msg(session, ftpsrvmsg_banner); /* Read and process commands */ while (session->connected) { if (ftpsrv_read_cmd(session) != FTPSRV_OK) { _mem_zero(session->buffer, FTPSRV_BUF_SIZE); continue; } ftpsrv_process_cmd(session); _sched_yield(); } /* cleanup session */ ftpsrv_ses_close(session); ftpsrv_ses_free(session); server->session[i] = NULL; } else { RTCS_task_resume_creator(creator, (uint32_t) RTCS_ERROR); } /* Cleanup and end task */ _lwsem_post(&server->ses_cnt); /* Null tid => task is no longer running */ _lwsem_wait(&server->tid_sem); server->ses_tid[i] = 0; _lwsem_post(&server->tid_sem); }
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 */
/** server task - httpd main task which create new task for each new request */ static void httpd_server_task(pointer init_ptr, pointer creator) { HTTPD_STRUCT *server = (HTTPD_STRUCT*)init_ptr; int s; unsigned short len; struct sockaddr_in sin; HTTPD_SES_TASK_PARAM *param; _mqx_uint res; uint_32 stack; HTTPD_DEBUG(1, "server task start\n"); res = _lwsem_create(&sem_session_counter, server->params->max_ses); if (!server && res != MQX_OK) goto ERROR; RTCS_task_resume_creator(creator, RTCS_OK); HTTPD_DEBUG(1, "server task run...\n"); while (server->run) { // limit maximal opened sessions _lwsem_wait(&sem_session_counter); // allocate session task parameter structure param = _mem_alloc_system(sizeof(HTTPD_SES_TASK_PARAM)); if (param) { param->server = server; param->sock = accept(server->sock, &sin, &len); if (0 < param->sock) { // accept return corect socket number - no error // try create task for session res = RTCS_task_create("httpd session", server->params->ses_prio, server->params->ses_stack, httpd_session_dynamic_task, param); if (MQX_OK != res) { // session task creation failed, clean and wait... shutdown(param->sock, FLAG_ABORT_CONNECTION); // abort opened connection _mem_free(param); _lwsem_post(&sem_session_counter); _time_delay(1); } } else { // accept return error, clean and wait, then try again... _mem_free(param); _lwsem_post(&sem_session_counter); _time_delay(1); } } else { // allocation failed ?!?!? wait some time _time_delay(100); } } HTTPD_DEBUG(1, "server task stop\n"); ERROR: RTCS_task_resume_creator(creator, (uint_32)RTCS_ERROR); }
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 */