Exemplo n.º 1
0
int
UIPClient::read(uint8_t *buf, size_t size)
{
  if (*this)
    {
      int remain = size;
      memhandle* p = &data->packets_in[0];
      if (*p == NOBLOCK)
        return 0;
      int read;
      do
        {
          read = UIPEthernet.network.readPacket(*p,0,buf+size-remain,remain);
          if (read == UIPEthernet.network.blockSize(*p))
            {
              remain -= read;
              _eatBlock(p);
              if (_uip_conn && uip_stopped(_uip_conn) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED)))
                data->state |= UIP_CLIENT_RESTART;
              if (*p == NOBLOCK)
                return size-remain;
            }
          else
            {
              UIPEthernet.network.resizeBlock(*p,read);
              break;
            }
        }
      while(remain > 0);
      return size;
    }
  return -1;
}
Exemplo n.º 2
0
int
UIPClient::read(uint8_t *buf, size_t size)
{
  if (*this)
    {
      uint16_t remain = size;
      if (data->packets_in[0] == NOBLOCK)
        return 0;
      uint16_t read;
      do
        {
          read = Enc28J60Network::readPacket(data->packets_in[0],0,buf+size-remain,remain);
          if (read == Enc28J60Network::blockSize(data->packets_in[0]))
            {
              remain -= read;
              _eatBlock(&data->packets_in[0]);
              if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED)))
                data->state |= UIP_CLIENT_RESTART;
              if (data->packets_in[0] == NOBLOCK)
                {
                  if (data->state & UIP_CLIENT_REMOTECLOSED)
                    {
                      data->state = 0;
                      data = NULL;
                    }
                  return size-remain;
                }
            }
          else
            {
              Enc28J60Network::resizeBlock(data->packets_in[0],read);
              break;
            }
        }
      while(remain > 0);
      return size;
    }
  return -1;
}
Exemplo n.º 3
0
void
UIPClient::uip_callback(uip_tcp_appstate_t *s)
{
  uip_userdata_t *u = (uip_userdata_t *) s->user;
  if (!u && uip_connected())
    {
#ifdef UIPETHERNET_DEBUG_CLIENT
      Serial.println("UIPClient uip_connected");
#endif
      // 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 (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)
                {
                  memhandle* p = _currentBlock(&u->packets_in[0]);
                  //if it's not the first packet
                  if (*p != NOBLOCK)
                    {
                      uint8_t slot = p - &u->packets_in[0];
                      if (slot < UIP_SOCKET_NUMPACKETS-1)
                        p++;
                      //if this is the last slot stop this connection
                      if (slot >= UIP_SOCKET_NUMPACKETS-2)
                        {
                          uip_stop();
                          //if there's no free slot left omit loosing this packet and (again) stop this connection
                          if (slot == UIP_SOCKET_NUMPACKETS-1)
                            goto reject_newdata;
                        }
                    }
                  UIPEthernet.network.copyPacket(newPacket,0,UIPEthernet.in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len);
                  *p = newPacket;
                  goto finish_newdata;
                }
reject_newdata:
              UIPEthernet.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("UIPClient uip_closed");
#endif
          // drop outgoing packets not sent yet:
          _flushBlocks(&u->packets_out[0]);
          if (u->packets_in[0] != NOBLOCK)
            {
              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;
                      break;
                    }
                  closed_conn_data++;
                }
            }
          u->state |= UIP_CLIENT_CLOSED;
          // disassociate appdata.
          s->user = NULL;
          goto nodata;
        }
      if (uip_acked())
        {
#ifdef UIPETHERNET_DEBUG_CLIENT
          Serial.println("UIPClient uip_acked");
#endif
          _eatBlock(&u->packets_out[0]);
        }
      if (uip_poll() || uip_rexmit())
        {
#ifdef UIPETHERNET_DEBUG_CLIENT
          Serial.println("UIPClient uip_poll");
#endif
          memhandle p = u->packets_out[0];
          if (p != NOBLOCK)
            {
              if (u->packets_out[1] == NOBLOCK)
                {
                  uip_len = u->out_pos;
                  if (uip_len > 0)
                    {
                      UIPEthernet.network.resizeBlock(p,0,uip_len);
                    }
                }
              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_len);
                  if (UIPEthernet.uip_packet != NOBLOCK)
                    {
                      UIPEthernet.network.copyPacket(UIPEthernet.uip_packet,UIPEthernet.uip_hdrlen,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)
        {
#ifdef UIPETHERNET_DEBUG_CLIENT
              Serial.print("UIPClient state UIP_CLIENT_CLOSE");
#endif
          if (u->packets_out[0] == NOBLOCK)
            {
#ifdef UIPETHERNET_DEBUG_CLIENT
              Serial.print("UIPClient state UIP_CLIENT_CLOSE -> free userdata");
#endif
              free(u);
              s->user = NULL;
              uip_close();
            }
          else
            uip_stop();
        }
    }
nodata:
  UIPEthernet.uip_packet = NOBLOCK;
  uip_len=0;
}