コード例 #1
0
ファイル: elua_uip.c プロジェクト: Linux-enCaja/robotica
// Utility function for TELNET: parse input buffer, skipping over
// TELNET specific sequences
// Returns the length of the buffer after processing
static void elua_uip_telnet_handle_input( volatile struct elua_uip_state* s )
{
  u8 *dptr = ( u8* )uip_appdata;
  char *orig = ( char* )s->ptr;
  int skip;
  elua_net_size maxsize = s->len;
  
  // Traverse the input buffer, skipping over TELNET sequences
  while( ( dptr < ( u8* )uip_appdata + uip_datalen() ) && ( s->ptr - orig < s->len ) )
  {
    if( *dptr != TELNET_IAC_CHAR ) // regular char, copy it to buffer
      *s->ptr ++ = *dptr ++;
    else
    {
      // Control sequence: 2 or 3 bytes?
      if( ( dptr[ 1 ] >= TELNET_IAC_3B_FIRST ) && ( dptr[ 1 ] <= TELNET_IAC_3B_LAST ) )
        skip = 3;
      else
      {
        // Check EOF indication
        if( dptr[ 1 ] == TELNET_EOF )
          *s->ptr ++ = STD_CTRLZ_CODE;
        skip = 2;
      }
      dptr += skip;
    }
  } 
  if( s->ptr > orig )
  {
    s->res = ELUA_NET_ERR_OK;
    s->len = maxsize - ( s->ptr - orig );
    uip_stop();
    s->state = ELUA_UIP_STATE_IDLE;
  }
}
コード例 #2
0
ファイル: yport_net.c プロジェクト: muccc/matemat
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;
  }
}
コード例 #3
0
ファイル: elua_uip.c プロジェクト: Linux-enCaja/robotica
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();
  }
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: uip_xtcp.c プロジェクト: ajwlucas/lib_xtcp
/* -----------------------------------------------------------------------------
 * xtcpd_appcall
 *
 * this function is called, when a package comes in for an upper layer
 * application.
 * -------------------------------------------------------------------------- */
void
xtcpd_appcall(void)
{
  xtcpd_state_t *s;

  /* --------------- DHCP (v4)  --------------- */
  if (uip_udpconnection() &&
      (uip_udp_conn->lport == HTONS(DHCPC_CLIENT_PORT) ||
       uip_udp_conn->lport == HTONS(DHCPC_SERVER_PORT))) {
#if UIP_USE_DHCP
    dhcpc_appcall();
#endif
    return;
  }

  /* --------- set up a new connection  ---------- */
  if (uip_udpconnection()){
    s = (xtcpd_state_t *) &(uip_udp_conn->appstate);
    if (uip_newdata()) {
    	// Set remote port to upper layer state
      s->conn.remote_port = HTONS(UDPBUF->srcport);
      uip_ipaddr_copy(s->conn.remote_addr.u8, BUF->srcipaddr.u8);
    }
  } else if (uip_conn == NULL) {
      // dodgy uip_conn
      return;
  } else {
    s = (xtcpd_state_t *) &(uip_conn->appstate);
  }

  /* ------ passing new connection event up to the upper xtcp layer  ---- */
  if (uip_connected()) {
    if (!uip_udpconnection()) {
      init_xtcpd_state(s,
                       XTCP_PROTOCOL_TCP,
                       *((xtcp_ipaddr_t *) (&uip_conn->ripaddr)),
                       uip_conn->lport,
                       uip_conn->rport,
                       uip_conn);
      xtcpd_event(XTCP_NEW_CONNECTION, s);
    } else {
      init_xtcpd_state(s,
                       XTCP_PROTOCOL_UDP,
                       *((xtcp_ipaddr_t *) (&uip_udp_conn->ripaddr)),
                       uip_udp_conn->lport,
                       uip_udp_conn->rport,
                       uip_udp_conn);
      xtcpd_event(XTCP_NEW_CONNECTION, s);
    }
  }

  /* --------------- new data event to deliver  --------------- */
  if (uip_newdata() && uip_len > 0) {
    if (s->linknum != -1) {
      xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr);
      xtcpd_recv(xtcp_cons.links, s->linknum, xtcp_cons.nr,
                 s,
                 uip_appdata,
                 uip_datalen());
      if (!uip_udpconnection() && s->s.ack_recv_mode) {
        uip_stop();
      }
    }
  } else if (uip_aborted()) {
    xtcpd_event(XTCP_ABORTED, s);
    return;
  } else if (uip_timedout()) {
    xtcpd_event(XTCP_TIMED_OUT, s);
    return;
  }

  /* ------------ passing acknowleg event to upper layer  ------------- */
  if (uip_acked()) {
    int len;
    if (s->linknum != -1) {
      len =
        do_xtcpd_send(xtcp_cons.links[s->linknum],
                      XTCP_SENT_DATA,
                      s,
                      uip_appdata,
                      uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss());

      uip_send(uip_appdata, len);
    }
  }

  /* -------------- retransmit the last package  -------------- */
  if (uip_rexmit()) {
    int len;
    if (s->linknum != -1) {
      xtcpd_service_clients_until_ready(s->linknum, xtcp_cons.links, xtcp_cons.nr);
#ifdef XTCP_ENABLE_PARTIAL_PACKET_ACK
      s->conn.outstanding = 0;
#endif
      len = xtcpd_send(xtcp_cons.links[s->linknum],
                       XTCP_RESEND_DATA,
                       s,
                       uip_appdata,
                       uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss());
      if (len != 0)
        uip_send(uip_appdata, len);
    }
  }

  /* --------------- poll a connection --------------- */
  if (uip_poll()) {
    uip_xtcpd_handle_poll(s);
  }

#if XTCP_ENABLE_PUSH_FLAG_NOTIFICATION
  if (uip_tcp_push()) {
    xtcpd_event(XTCP_PUSH_DATA, s);
  }
#endif

  /* ------------- connection close event  ------------ */
  if (uip_closed()) {
    if (!s->s.closed){
      s->s.closed = 1;

      xtcpd_event(XTCP_CLOSED, s);
    }
    return;
  }

}
コード例 #6
0
ファイル: TCPIP.c プロジェクト: disengaged/avrusbmodem
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();
	}
}
コード例 #7
0
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;
}
コード例 #8
0
ファイル: uip_xtcp.c プロジェクト: aritec/sc_xtcp
void
xtcpd_appcall(void)
{
    xtcpd_state_t *s;

    if (uip_udpconnection() &&
            (uip_udp_conn->lport == HTONS(DHCPC_CLIENT_PORT) ||
             uip_udp_conn->lport == HTONS(DHCPC_SERVER_PORT))) {
#if UIP_USE_DHCP
        dhcpc_appcall();
#endif
        return;
    }

    if (uip_udpconnection()) {
        s = (xtcpd_state_t *) &(uip_udp_conn->appstate);
        if (uip_newdata()) {
            s->conn.remote_port = HTONS(UDPBUF->srcport);
            uip_ipaddr_copy(s->conn.remote_addr, BUF->srcipaddr);
        }
    }
    else if (uip_conn == NULL) {
        // dodgy uip_conn
        return;
    }
    else
        s = (xtcpd_state_t *) &(uip_conn->appstate);




    //  if (!uip_udpconnection() && uip_connected()) {
    if (uip_connected()) {
        if (!uip_udpconnection()) {
            xtcpd_init_state(s,
                             XTCP_PROTOCOL_TCP,
                             (unsigned char *) uip_conn->ripaddr,
                             uip_conn->lport,
                             uip_conn->rport,
                             uip_conn);
            xtcpd_event(XTCP_NEW_CONNECTION, s);
        }
        else {
            xtcpd_init_state(s,
                             XTCP_PROTOCOL_UDP,
                             (unsigned char *) uip_udp_conn->ripaddr,
                             uip_udp_conn->lport,
                             uip_udp_conn->rport,
                             uip_udp_conn);
            xtcpd_event(XTCP_NEW_CONNECTION, s);

        }
    }

    if (uip_acked()) {
        int len;
        if (s->linknum != -1) {
            xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num);
            len = xtcpd_send(xtcp_links[s->linknum],
                             XTCP_SENT_DATA,
                             s,
                             uip_appdata,
                             uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss());
            if (len != 0)
                uip_send(uip_appdata, len);
        }
    }


    if (uip_newdata() && uip_len > 0) {
        if (s->linknum != -1) {
            if (!uip_udpconnection() && s->s.ack_recv_mode) {
                uip_stop();
            }
            xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num);

            xtcpd_recv(xtcp_links, s->linknum, xtcp_num,
                       s,
                       uip_appdata,
                       uip_datalen());
        }

    }

    else if (uip_aborted()) {
        xtcpd_event(XTCP_ABORTED, s);
        return;
    }
    else if (uip_timedout()) {
        xtcpd_event(XTCP_TIMED_OUT, s);
        return;
    }

    if (uip_rexmit()) {
        int len;
        if (s->linknum != -1) {
            xtcpd_service_clients_until_ready(s->linknum, xtcp_links, xtcp_num);
            len = xtcpd_send(xtcp_links[s->linknum],
                             XTCP_RESEND_DATA,
                             s,
                             uip_appdata,
                             uip_udpconnection() ? XTCP_CLIENT_BUF_SIZE : uip_mss());
            if (len != 0)
                uip_send(uip_appdata, len);
        }
    }

    if (uip_poll()) {
        uip_xtcpd_handle_poll(s);
    }

    if (uip_closed()) {
        if (!s->s.closed) {
            s->s.closed = 1;

            xtcpd_event(XTCP_CLOSED, s);
        }
        return;
    }

}