void yport_net_main(void) { if(uip_connected()) { if (yport_conn == NULL) { yport_conn = uip_conn; uip_conn->wnd = YPORT_BUFFER_LEN - 1; } else /* if we have already an connection, send an error */ uip_send("ERROR: Connection blocked\n", 27); } else if (uip_acked()) { /* If the peer is not our connection, close it */ if (yport_conn != uip_conn) uip_close(); else { /* Some data we have sent was acked, jipphie */ /* disable interrupts */ uint8_t sreg = SREG; cli(); yport_recv_buffer.len -= yport_recv_buffer.sent; /* We should use memmove, because the data may overlap */ memmove(yport_recv_buffer.data, yport_recv_buffer.data + yport_recv_buffer.sent, yport_recv_buffer.len); /* enable interrupts again */ SREG = sreg; } } else if (uip_closed() || uip_aborted() || uip_timedout()) { /* if the closed connection was our connection, clean yport_conn */ if (yport_conn == uip_conn) yport_conn = NULL; } else if (uip_newdata()) { if (uip_len <= YPORT_BUFFER_LEN && yport_rxstart(uip_appdata, uip_len) != 0) { /* Prevent the other side from sending more data */ uip_stop(); } } if (uip_poll() && uip_conn == yport_conn && uip_stopped(yport_conn) && yport_send_buffer.sent == yport_send_buffer.len) uip_restart(); /* Send data */ if ((uip_poll() || uip_acked() || uip_rexmit()) && yport_conn == uip_conn && yport_recv_buffer.len > 0) { /* We have recieved data, lets propagade it */ /* disable interrupts */ uint8_t sreg = SREG; cli(); /* Send the data */ uip_send(yport_recv_buffer.data, yport_recv_buffer.len); /* so many data was send */ yport_recv_buffer.sent = yport_recv_buffer.len; /* enable interrupts again */ SREG = sreg; } }
void elua_uip_appcall() { volatile struct elua_uip_state *s; elua_net_size temp; int sockno; // If uIP is not yet configured (DHCP response not received), do nothing if( !elua_uip_configured ) return; s = ( struct elua_uip_state* )&( uip_conn->appstate ); // Need to find the actual socket location, since UIP doesn't provide this ... for( temp = 0; temp < UIP_CONNS; temp ++ ) if( uip_conns + temp == uip_conn ) break; sockno = ( int )temp; if( uip_connected() ) { #ifdef BUILD_CON_TCP if( uip_conn->lport == HTONS( ELUA_NET_TELNET_PORT ) ) // special case: telnet server { if( elua_uip_telnet_socket != -1 ) { uip_close(); return; } else elua_uip_telnet_socket = sockno; } else #endif if( elua_uip_accept_request ) { elua_uip_accept_sock = sockno; elua_uip_accept_remote.ipwords[ 0 ] = uip_conn->ripaddr[ 0 ]; elua_uip_accept_remote.ipwords[ 1 ] = uip_conn->ripaddr[ 1 ]; elua_uip_accept_request = 0; } else if( s->state == ELUA_UIP_STATE_CONNECT ) s->state = ELUA_UIP_STATE_IDLE; uip_stop(); return; } if( s->state == ELUA_UIP_STATE_IDLE ) return; // Do we need to read? if( s->state == ELUA_UIP_STATE_RECV ) { // Re-enable data transfer on the socket and change state s->state = ELUA_UIP_STATE_RECV_2; uip_restart(); return; } if( uip_aborted() || uip_timedout() || uip_closed() ) { // Signal this error s->res = uip_aborted() ? ELUA_NET_ERR_ABORTED : ( uip_timedout() ? ELUA_NET_ERR_TIMEDOUT : ELUA_NET_ERR_CLOSED ); #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) elua_uip_telnet_socket = -1; #endif s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data send if( ( uip_acked() || uip_rexmit() || uip_poll() ) && ( s->state == ELUA_UIP_STATE_SEND ) ) { // Special translation for TELNET: prepend all '\n' with '\r' // We write directly in UIP's buffer if( uip_acked() ) { elua_net_size minlen = UMIN( s->len, uip_mss() ); s->len -= minlen; s->ptr += minlen; if( s->len == 0 ) s->state = ELUA_UIP_STATE_IDLE; } if( s->len > 0 ) // need to (re)transmit? { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { temp = elua_uip_telnet_prep_send( s->ptr, s->len ); uip_send( uip_sappdata, temp ); } else #endif uip_send( s->ptr, UMIN( s->len, uip_mss() ) ); } return; } // Handle close if( s->state == ELUA_UIP_STATE_CLOSE ) { uip_close(); s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data receive if( uip_newdata() ) { if( s->state == ELUA_UIP_STATE_RECV_2 ) { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { elua_uip_telnet_handle_input( s ); return; } #endif int lastfound = 0; // Check end of transmission if( uip_datalen() < UIP_RECEIVE_WINDOW ) lastfound = 1; // Check overflow if( s->len < uip_datalen() ) { s->res = ELUA_NET_ERR_OVERFLOW; temp = s->len; } else temp = uip_datalen(); if( s->readto != ELUA_NET_NO_LASTCHAR ) { char *tptr = ( char* )uip_appdata; char *last = ( char* )uip_appdata + temp - 1; luaL_Buffer *pbuf = ( luaL_Buffer* )s->ptr; char* dest = ( char* )s->ptr; while( tptr <= last ) { if( *tptr == s->readto ) { lastfound = 1; break; } if( *tptr != '\r' ) { if( s->res ) luaL_addchar( pbuf, *tptr ); else *dest ++ = *tptr; s->len --; } tptr ++; } } else { if( s->res ) luaL_addlstring( ( luaL_Buffer* )s->ptr, ( const char* )uip_appdata, temp ); else memcpy( ( char* )s->ptr, ( const char* )uip_appdata, temp ); s->len -= temp; } // Do we need to read another packet? if( s->len == 0 || lastfound ) { uip_stop(); s->res = ELUA_NET_ERR_OK; s->state = ELUA_UIP_STATE_IDLE; } } else uip_stop(); } }
void uipclient_appcall(void) { uint16_t send_len = 0; uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; if (!u && uip_connected()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_connected")); UIPClient::_dumpAllData(); #endif u = (uip_userdata_t*) UIPClient::_allocateData(); if (u) { uip_conn->appstate = u; #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient allocated state: ")); Serial.println(u->state,BIN); #endif } #ifdef UIPETHERNET_DEBUG_CLIENT else Serial.println(F("UIPClient allocation failed")); #endif } if (u) { if (uip_newdata()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient uip_newdata, uip_len:")); Serial.println(uip_len); #endif if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) { for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++) { if (u->packets_in[i] == NOBLOCK) { u->packets_in[i] = Enc28J60Network::allocBlock(uip_len); if (u->packets_in[i] != NOBLOCK) { Enc28J60Network::copyPacket(u->packets_in[i],0,UIPEthernetClass::in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); if (i == UIP_SOCKET_NUMPACKETS-1) uip_stop(); goto finish_newdata; } } } UIPEthernetClass::packetstate &= ~UIPETHERNET_FREEPACKET; uip_stop(); } } finish_newdata: if (u->state & UIP_CLIENT_RESTART) { u->state &= ~UIP_CLIENT_RESTART; uip_restart(); } // If the connection has been closed, save received but unread data. if (uip_closed() || uip_timedout()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_closed")); UIPClient::_dumpAllData(); #endif // drop outgoing packets not sent yet: UIPClient::_flushBlocks(&u->packets_out[0]); if (u->packets_in[0] != NOBLOCK) { ((uip_userdata_closed_t *)u)->lport = uip_conn->lport; u->state |= UIP_CLIENT_REMOTECLOSED; } else u->state = 0; // disassociate appdata. #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("after UIPClient uip_closed")); UIPClient::_dumpAllData(); #endif uip_conn->appstate = NULL; goto finish; } if (uip_acked()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_acked")); #endif UIPClient::_eatBlock(&u->packets_out[0]); } if (uip_poll() || uip_rexmit()) { #ifdef UIPETHERNET_DEBUG_CLIENT //Serial.println(F("UIPClient uip_poll")); #endif if (u->packets_out[0] != NOBLOCK) { if (u->packets_out[1] == NOBLOCK) { send_len = u->out_pos; if (send_len > 0) { Enc28J60Network::resizeBlock(u->packets_out[0],0,send_len); } } else send_len = Enc28J60Network::blockSize(u->packets_out[0]); if (send_len > 0) { UIPEthernetClass::uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; UIPEthernetClass::uip_packet = Enc28J60Network::allocBlock(UIPEthernetClass::uip_hdrlen+send_len); if (UIPEthernetClass::uip_packet != NOBLOCK) { Enc28J60Network::copyPacket(UIPEthernetClass::uip_packet,UIPEthernetClass::uip_hdrlen,u->packets_out[0],0,send_len); UIPEthernetClass::packetstate |= UIPETHERNET_SENDPACKET; } } goto finish; } } // don't close connection unless all outgoing packets are sent if (u->state & UIP_CLIENT_CLOSE) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient state UIP_CLIENT_CLOSE")); UIPClient::_dumpAllData(); #endif if (u->packets_out[0] == NOBLOCK) { u->state = 0; uip_conn->appstate = NULL; uip_close(); #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("no blocks out -> free userdata")); UIPClient::_dumpAllData(); #endif } else { uip_stop(); #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("blocks outstanding transfer -> uip_stop()")); #endif } } } finish: uip_send(uip_appdata,send_len); uip_len = send_len; }
void TCPIP_TCPCallback(void) { if (uip_acked()) Debug_Print("[ACK] "); if (uip_newdata()) { Debug_Print("New Data:\r\n"); TCPIP_QueueData(uip_appdata, uip_datalen()); if (TCPIP_IsDataQueueFull()) uip_stop(); } if (uip_connected()) { Debug_Print("Connected - Maximum Segment Size: 0x"); Debug_PrintHex(uip_mss() / 256); Debug_PrintHex(uip_mss() & 255); Debug_Print("\r\n"); } if (uip_closed()) { Debug_Print("Closed - Reconnecting..."); _delay_ms(1000); ConnectedState = LINKMANAGEMENT_STATE_ConnectToRemoteHost; } if (uip_aborted()) { Debug_Print("Aborted - Reconnecting... "); _delay_ms(1000); ConnectedState = LINKMANAGEMENT_STATE_ConnectToRemoteHost; } if (uip_timedout()) { Debug_Print("Timeout - Reconnecting..."); uip_abort(); _delay_ms(1000); ConnectedState = LINKMANAGEMENT_STATE_ConnectToRemoteHost; } if (uip_poll() && (SystemTicks > 3000)) { SystemTicks = 0; Debug_Print("\r\nSending GET\r\n"); TCPIP_SendGET(); } if (uip_rexmit()) { Debug_Print("\r\nRetransmit GET\r\n"); TCPIP_SendGET(); } if (uip_poll() && uip_stopped(TCPConnection)) { if (!(TCPIP_IsDataQueueFull())) uip_restart(); } }
void UIPClient::uip_callback(uip_tcp_appstate_t *s) { uip_userdata_t *u = (uip_userdata_t *) s->user; if (!u && uip_connected()) { // We want to store some data in our connections, so allocate some space // for it. The connection_data struct is defined in a separate .h file, // due to the way the Arduino IDE works. (typedefs come after function // definitions.) u = (uip_userdata_t*) malloc(sizeof(uip_userdata_t)); if (u) { memset(u,0,sizeof(uip_userdata_t)); s->user = u; } } if (u) { if (u->state & UIP_CLIENT_RESTART) { u->state &= ~UIP_CLIENT_RESTART; uip_restart(); } if (uip_newdata()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print("UIPClient uip_newdata, uip_len:"); Serial.println(uip_len); #endif if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) { memhandle newPacket = UIPEthernet.network.allocBlock(uip_len); if (newPacket != NOBLOCK) { uint8_t i = u->packet_in_end; //if it's not the first packet if (u->packets_in[i] != NOBLOCK) { i = i == UIP_SOCKET_NUMPACKETS-1 ? 0 : i+1; //if this is the last slot stop this connection if ((i == UIP_SOCKET_NUMPACKETS-1 ? 0 : i+1) == u->packet_in_start) { uip_stop(); } //if there's no free slot left omit loosing this packet and (again) stop this connection else if (i == u->packet_in_start) goto reject_newdata; } UIPEthernet.network.copyPacket(newPacket,0,UIPEthernet.in_packet,((uint8_t*)uip_appdata)-uip_buf+UIP_INPACKETOFFSET,uip_len); u->packets_in[i] = newPacket; u->packet_in_end = i; goto finish_newdata; } reject_newdata: UIPEthernet.packetstate &= ~UIPETHERNET_FREEPACKET; uip_stop(); } } finish_newdata: // If the connection has been closed, save received but unread data. if (uip_closed() || uip_timedout()) { // drop outgoing packets not sent yet: memhandle *p = &u->packets_out[0]; for (uip_socket_ptr i = 0; i < UIP_SOCKET_NUMPACKETS; i++) { if (*p != NOBLOCK) { UIPEthernet.network.freeBlock(*p); *p = NOBLOCK; } p++; } uip_userdata_closed_t** closed_conn_data = &UIPClient::closed_conns[0]; for (uip_socket_ptr i = 0; i < UIP_CONNS; i++) { if (!*closed_conn_data) { *closed_conn_data = (uip_userdata_closed_t*)u; (*closed_conn_data)->lport = uip_conn->lport; (*closed_conn_data)->state |= UIP_CLIENT_CLOSED; break; } closed_conn_data++; } // disassociate appdata. s->user = NULL; goto nodata; } if (uip_acked()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_acked"); #endif memhandle *p = &u->packets_out[u->packet_out_start]; if (*p != NOBLOCK) { UIPEthernet.network.freeBlock(*p); *p = NOBLOCK; u->packet_out_start = u->packet_out_start == UIP_SOCKET_NUMPACKETS-1 ? 0 : u->packet_out_start+1; } } if (uip_poll() || uip_rexmit()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_poll"); #endif memhandle p = u->packets_out[u->packet_out_start]; if (p != NOBLOCK) { if (u->packet_out_start == u->packet_out_end) { uip_len = u->out_pos; if (uip_len > 0) { UIPEthernet.network.resizeBlock(p,0,uip_len); u->packet_out_end = u->packet_out_end == UIP_SOCKET_NUMPACKETS-1 ? 0 : u->packet_out_end+1; } } else uip_len = UIPEthernet.network.blockSize(p); if (uip_len > 0) { UIPEthernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; UIPEthernet.uip_packet = UIPEthernet.network.allocBlock(UIPEthernet.uip_hdrlen+UIP_OUTPACKETOFFSET+uip_len); if (UIPEthernet.uip_packet != NOBLOCK) { UIPEthernet.network.copyPacket(UIPEthernet.uip_packet,UIPEthernet.uip_hdrlen+UIP_OUTPACKETOFFSET,p,0,uip_len); UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; uip_send(uip_appdata,uip_len); } return; } } } // don't close connection unless all outgoing packets are sent if (u->state & UIP_CLIENT_CLOSE) { if (u->packets_out[u->packet_out_start] == NOBLOCK) { free(u); s->user = NULL; uip_close(); } else uip_stop(); } } nodata: UIPEthernet.uip_packet = NOBLOCK; uip_len=0; }