// Internal "read" function static elua_net_size elua_net_recv_internal( int s, void* buf, elua_net_size maxsize, s16 readto, unsigned timer_id, u32 to_us, int with_buffer ) { volatile struct elua_uip_state *pstate = ( volatile struct elua_uip_state* )&( uip_conns[ s ].appstate ); u32 tmrstart = 0; int old_status; if( !ELUA_UIP_IS_SOCK_OK( s ) || !uip_conn_active( s ) ) return -1; if( maxsize == 0 ) return 0; elua_prep_socket_state( pstate, buf, maxsize, readto, with_buffer, ELUA_UIP_STATE_RECV ); if( to_us > 0 ) tmrstart = platform_timer_op( timer_id, PLATFORM_TIMER_OP_START, 0 ); while( 1 ) { if( pstate->state == ELUA_UIP_STATE_IDLE ) break; if( to_us > 0 && platform_timer_get_diff_us( timer_id, tmrstart, platform_timer_op( timer_id, PLATFORM_TIMER_OP_READ, 0 ) ) >= to_us ) { old_status = platform_cpu_set_global_interrupts( PLATFORM_CPU_DISABLE ); if( pstate->state != ELUA_UIP_STATE_IDLE ) { pstate->res = ELUA_NET_ERR_TIMEDOUT; pstate->state = ELUA_UIP_STATE_IDLE; } platform_cpu_set_global_interrupts( old_status ); break; } } return maxsize - pstate->len; }
// Close socket int elua_net_close( int s ) { volatile struct elua_uip_state *pstate = ( volatile struct elua_uip_state* )&( uip_conns[ s ].appstate ); if( !ELUA_UIP_IS_SOCK_OK( s ) || !uip_conn_active( s ) ) return -1; elua_prep_socket_state( pstate, NULL, 0, ELUA_NET_NO_LASTCHAR, ELUA_NET_ERR_OK, ELUA_UIP_STATE_CLOSE ); platform_eth_force_interrupt(); while( pstate->state != ELUA_UIP_STATE_IDLE ); return pstate->res == ELUA_NET_ERR_OK ? 0 : -1; }
// Return the socket associated with the "telnet" application (or -1 if it does // not exist). The socket only exists if a client connected to the board. int elua_net_get_telnet_socket() { int res = -1; #ifdef BUILD_CON_TCP if( elua_uip_telnet_socket != -1 ) if( uip_conn_active( elua_uip_telnet_socket ) ) res = elua_uip_telnet_socket; #endif return res; }
// Send data elua_net_size elua_net_send( int s, const void* buf, elua_net_size len ) { volatile struct elua_uip_state *pstate = ( volatile struct elua_uip_state* )&( uip_conns[ s ].appstate ); if( !ELUA_UIP_IS_SOCK_OK( s ) || !uip_conn_active( s ) ) return -1; if( len == 0 ) return 0; elua_prep_socket_state( pstate, ( void* )buf, len, ELUA_NET_NO_LASTCHAR, ELUA_NET_ERR_OK, ELUA_UIP_STATE_SEND ); platform_eth_force_interrupt(); while( pstate->state != ELUA_UIP_STATE_IDLE ); return len - pstate->len; }
/*---------------------------------------------------------------------------*/ static void eventhandler(process_event_t ev, process_data_t data) { #if UIP_TCP static unsigned char i; register struct listenport *l; #endif /*UIP_TCP*/ struct process *p; switch(ev) { case PROCESS_EVENT_EXITED: /* This is the event we get if a process has exited. We go through the TCP/IP tables to see if this process had any open connections or listening TCP ports. If so, we'll close those connections. */ p = (struct process *)data; #if UIP_TCP l = s.listenports; for(i = 0; i < UIP_LISTENPORTS; ++i) { if(l->p == p) { uip_unlisten(l->port); l->port = 0; l->p = PROCESS_NONE; } ++l; } { struct uip_conn *cptr; for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { if(cptr->appstate.p == p) { cptr->appstate.p = PROCESS_NONE; cptr->tcpstateflags = UIP_CLOSED; } } } #endif /* UIP_TCP */ #if UIP_UDP { struct uip_udp_conn *cptr; for(cptr = &uip_udp_conns[0]; cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { if(cptr->appstate.p == p) { cptr->lport = 0; } } } #endif /* UIP_UDP */ break; case PROCESS_EVENT_TIMER: /* We get this event if one of our timers have expired. */ { /* Check the clock so see if we should call the periodic uIP processing. */ if(data == &periodic && etimer_expired(&periodic)) { #if UIP_TCP for(i = 0; i < UIP_CONNS; ++i) { if(uip_conn_active(i)) { /* Only restart the timer if there are active connections. */ etimer_restart(&periodic); uip_periodic(i); #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else if(uip_len > 0) { PRINTF("tcpip_output from periodic len %d\n", uip_len); tcpip_output(); PRINTF("tcpip_output after periodic len %d\n", uip_len); } #endif /* UIP_CONF_IPV6 */ } } #endif /* UIP_TCP */ #if UIP_CONF_IP_FORWARD uip_fw_periodic(); #endif /* UIP_CONF_IP_FORWARD */ } #if UIP_CONF_IPV6 #if UIP_CONF_IPV6_REASSEMBLY /* * check the timer for reassembly */ if(data == &uip_reass_timer && etimer_expired(&uip_reass_timer)) { uip_reass_over(); tcpip_ipv6_output(); } #endif /* UIP_CONF_IPV6_REASSEMBLY */ /* * check the different timers for neighbor discovery and * stateless autoconfiguration */ /*if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); }*/ #if !UIP_CONF_ROUTER if(data == &uip_ds6_timer_rs && etimer_expired(&uip_ds6_timer_rs)) { uip_ds6_send_rs(); tcpip_ipv6_output(); } #endif /* !UIP_CONF_ROUTER */ if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); } #endif /* UIP_CONF_IPV6 */ } break; #if UIP_TCP case TCP_POLL: if(data != NULL) { uip_poll_conn(data); #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else /* UIP_CONF_IPV6 */ if(uip_len > 0) { PRINTF("tcpip_output from tcp poll len %d\n", uip_len); tcpip_output(); } #endif /* UIP_CONF_IPV6 */ /* Start the periodic polling, if it isn't already active. */ start_periodic_tcp_timer(); } break; #endif /* UIP_TCP */ #if UIP_UDP case UDP_POLL: if(data != NULL) { uip_udp_periodic_conn(data); #if UIP_CONF_IPV6 tcpip_ipv6_output(); #else if(uip_len > 0) { tcpip_output(); } #endif /* UIP_UDP */ } break; #endif /* UIP_UDP */ case PACKET_INPUT: packet_input(); break; }; }
/* ----------------------------------------------------------------------------- * Process periodical stuff. * * In contiki, this is handlet by the eventhandler of the tcpip.c file * with the process event "PROCESS_EVENT_TIMER". * -------------------------------------------------------------------------- */ void xtcp_process_timer(chanend mac_tx, xtcp_tmr_event_type_t event) { #if UIP_IGMP igmp_periodic(); if(uip_len > 0) { xtcp_tx_buffer(mac_tx); } #endif if(event == XTCP_TMR_PERIODIC) { #if UIP_TCP for(int i = 0; i < UIP_CONNS; ++i) { if(uip_conn_active(i)) { uip_periodic(i); #if UIP_CONF_IPV6 xtcpip_ipv6_output(mac_tx); #else if(uip_len > 0) { PRINTF("tcpip_output from periodic len %d\n", uip_len); tcpip_output(); PRINTF("tcpip_output after periodic len %d\n", uip_len); } #endif /* UIP_CONF_IPV6 */ } } #endif /* UIP_TCP */ #if UIP_CONF_IP_FORWARD uip_fw_periodic(); #endif /* UIP_CONF_IP_FORWARD */ } /*XXX CHSC HACK*/ #if UIP_CONF_IPV6 #if UIP_CONF_IPV6_REASSEMBLY /* * check the timer for reassembly */ if(etimer_expired(&uip_reass_timer)) { uip_reass_over(); tcpip_ipv6_output(); } #endif /* UIP_CONF_IPV6_REASSEMBLY */ /* * check the different timers for neighbor discovery and * stateless autoconfiguration */ /*if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); }*/ #if !UIP_CONF_ROUTER if(etimer_expired(&uip_ds6_timer_rs)) { uip_ds6_send_rs(); xtcpip_ipv6_output(mac_tx); } #endif /* !UIP_CONF_ROUTER */ if(etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); xtcpip_ipv6_output(mac_tx); } #endif /* UIP_CONF_IPV6 */ }
/*---------------------------------------------------------------------------*/ static void eventhandler(c_event_t ev, p_data_t data) { #if UIP_TCP static unsigned char i; // register struct listenport *l; #endif /*UIP_TCP*/ switch(ev) { case EVENT_TYPE_TIMER_EXP: /* We get this event if one of our timers have expired. */ { /* Check the clock so see if we should call the periodic uIP processing. */ if(data == &periodic && etimer_expired(&periodic)) { #if UIP_TCP for(i = 0; i < UIP_CONNS; ++i) { if(uip_conn_active(i)) { /* Only restart the timer if there are active connections. */ etimer_restart(&periodic); uip_periodic(i); #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else if(uip_len > 0) { PRINTF("tcpip_output from periodic len %d\n\r", uip_len); tcpip_output(); PRINTF("tcpip_output after periodic len %d\n\r", uip_len); } #endif /* NETSTACK_CONF_WITH_IPV6 */ } } #endif /* UIP_TCP */ #if UIP_CONF_IP_FORWARD uip_fw_periodic(); #endif /* UIP_CONF_IP_FORWARD */ } #if NETSTACK_CONF_WITH_IPV6 #if UIP_CONF_IPV6_REASSEMBLY /* * check the timer for reassembly */ if(data == &uip_reass_timer && etimer_expired(&uip_reass_timer)) { uip_reass_over(); tcpip_ipv6_output(); } #endif /* UIP_CONF_IPV6_REASSEMBLY */ /* * check the different timers for neighbor discovery and * stateless autoconfiguration */ /*if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); }*/ #if !UIP_CONF_ROUTER if(data == &uip_ds6_timer_rs && etimer_expired(&uip_ds6_timer_rs)) { uip_ds6_send_rs(); tcpip_ipv6_output(); } #endif /* !UIP_CONF_ROUTER */ if(data == &uip_ds6_timer_periodic && etimer_expired(&uip_ds6_timer_periodic)) { uip_ds6_periodic(); tcpip_ipv6_output(); } #endif /* NETSTACK_CONF_WITH_IPV6 */ } break; #if UIP_TCP case EVENT_TYPE_TCP_POLL: if(data != NULL) { uip_poll_conn(data); #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else /* NETSTACK_CONF_WITH_IPV6 */ if(uip_len > 0) { PRINTF("tcpip_output from tcp poll len %d\n\r", uip_len); tcpip_output(); } #endif /* NETSTACK_CONF_WITH_IPV6 */ /* Start the periodic polling, if it isn't already active. */ start_periodic_tcp_timer(); } break; #endif /* UIP_TCP */ #if UIP_UDP case EVENT_TYPE_UDP_POLL: if(data != NULL) { uip_udp_periodic_conn(data); #if NETSTACK_CONF_WITH_IPV6 tcpip_ipv6_output(); #else if(uip_len > 0) { tcpip_output(); } #endif /* UIP_UDP */ } break; #endif /* UIP_UDP */ case EVENT_TYPE_PCK_INPUT: packet_input(); break; }; }