Esempio n. 1
0
void uip_tcpfree(struct uip_conn *conn)
{
#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
  struct uip_readahead_s *readahead;
#endif
  uip_lock_t flags;

  /* Because g_free_tcp_connections is accessed from user level and interrupt
   * level, code, it is necessary to keep interrupts disabled during this
   * operation.
   */

  DEBUGASSERT(conn->crefs == 0);
  flags = uip_lock();

  /* UIP_ALLOCATED means that that the connection is not in the active list
   * yet.
   */

  if (conn->tcpstateflags != UIP_ALLOCATED)
    {
      /* Remove the connection from the active list */

      dq_rem(&conn->node, &g_active_tcp_connections);
    }

  /* Release any read-ahead buffers attached to the connection */

#if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
  while ((readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead)) != NULL)
    {
      uip_tcpreadaheadrelease(readahead);
    }
#endif

  /* Remove any backlog attached to this connection */

#ifdef CONFIG_NET_TCPBACKLOG
  if (conn->backlog)
    {
      uip_backlogdestroy(conn);
    }

  /* If this connection is, itself, backlogged, then remove it from the
   * parent connection's backlog list.
   */

  if (conn->blparent)
    {
      uip_backlogdelete(conn->blparent, conn);
    }
#endif

  /* Mark the connection available and put it into the free list */

  conn->tcpstateflags = UIP_CLOSED;
  dq_addlast(&conn->node, &g_free_tcp_connections);
  uip_unlock(flags);
}
Esempio n. 2
0
static inline void recvfrom_readahead(struct recvfrom_s *pstate)
{
  FAR struct uip_conn        *conn = (FAR struct uip_conn *)pstate->rf_sock->s_conn;
  FAR struct uip_readahead_s *readahead;
  size_t                      recvlen;

  /* Check there is any TCP data already buffered in a read-ahead
   * buffer.
   */

  do
    {
      /* Get the read-ahead buffer at the head of the list (if any) */

      readahead = (struct uip_readahead_s *)sq_remfirst(&conn->readahead);
      if (readahead)
        {
          /* We have a new buffer... transfer that buffered data into
           * the user buffer.
           *
           * First, get the length of the data to transfer.
           */

          if (readahead->rh_nbytes > pstate->rf_buflen)
            {
              recvlen = pstate->rf_buflen;
            }
          else
            {
              recvlen = readahead->rh_nbytes;
            }

          if (recvlen > 0)
            {
              /* Copy the read-ahead data into the user buffer */

              memcpy(pstate->rf_buffer, readahead->rh_buffer, recvlen);
              nllvdbg("Received %d bytes (of %d)\n", recvlen, readahead->rh_nbytes);

              /* Update the accumulated size of the data read */

              pstate->rf_recvlen += recvlen;
              pstate->rf_buffer  += recvlen;
              pstate->rf_buflen  -= recvlen;
            }

          /* If the read-ahead buffer is empty, then release it.  If not, then
           * we will have to move the data down and return the buffer to the
           * front of the list.
           */

          if (recvlen < readahead->rh_nbytes)
            {
              readahead->rh_nbytes -= recvlen;
              memcpy(readahead->rh_buffer, &readahead->rh_buffer[recvlen],
                     readahead->rh_nbytes);
              sq_addfirst(&readahead->rh_node, &conn->readahead);
            }
          else
            {
              uip_tcpreadaheadrelease(readahead);
            }
        }
    }
  while (readahead && pstate->rf_buflen > 0);
}