Example #1
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_listen(struct netconn *conn)
{
  struct api_msg *msg;

  if (conn == NULL) {
    return ERR_VAL;
  }

  if (conn->acceptmbox == SYS_MBOX_NULL) {
    conn->acceptmbox = sys_mbox_new();
    if (conn->acceptmbox == SYS_MBOX_NULL) {
      return ERR_MEM;
    }
  }
  
  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return (conn->err = ERR_MEM);
  }
  msg->type = API_MSG_LISTEN;
  msg->msg.conn = conn;
  api_msg_post(msg);
  sys_mbox_fetch(conn->mbox, NULL);
  memp_freep(MEMP_API_MSG, msg);
  return conn->err;
}
Example #2
0
/*-----------------------------------------------------------------------------------*/
struct
netconn *netconn_new(enum netconn_type t)
{
  struct netconn *conn;

  conn = memp_mallocp(MEMP_NETCONN);
  if (conn == NULL) {
    return NULL;
  }
  conn->type = t;
  conn->pcb.tcp = NULL;

  if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
    memp_freep(MEMP_NETCONN, conn);
    return NULL;
  }
  conn->recvmbox = SYS_MBOX_NULL;
  conn->acceptmbox = SYS_MBOX_NULL;
  conn->sem = SYS_SEM_NULL;
  conn->state = NETCONN_NONE;
  conn->socket = 0;
  conn->callback = 0;
  conn->recv_avail = 0;
  return conn;
}
Example #3
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_connect(struct netconn *conn, struct ip_addr *addr,
		   u16_t port)
{
  struct api_msg *msg;
  
  if (conn == NULL) {
    return ERR_VAL;
  }


  if (conn->recvmbox == SYS_MBOX_NULL) {
    if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
      return ERR_MEM;
    }
  }
  
  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return ERR_MEM;
  }
  msg->type = API_MSG_CONNECT;
  msg->msg.conn = conn;  
  msg->msg.msg.bc.ipaddr = addr;
  msg->msg.msg.bc.port = port;
  api_msg_post(msg);
  sys_mbox_fetch(conn->mbox, NULL);
  memp_freep(MEMP_API_MSG, msg);
  return conn->err;
}
Example #4
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_send(struct netconn *conn, struct netbuf *buf)
{
  struct api_msg *msg;

  if (conn == NULL) {
    return ERR_VAL;
  }

  if (conn->err != ERR_OK) {
    return conn->err;
  }

  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return (conn->err = ERR_MEM);
  }

  DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %ld bytes\n", buf->p->tot_len));
  msg->type = API_MSG_SEND;
  msg->msg.conn = conn;
  msg->msg.msg.p = buf->p;
  api_msg_post(msg);

  sys_mbox_fetch(conn->mbox, NULL);
  memp_freep(MEMP_API_MSG, msg);
  return conn->err;
}
Example #5
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_close(struct netconn *conn)
{
  struct api_msg *msg;

  if (conn == NULL) {
    return ERR_VAL;
  }
  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return (conn->err = ERR_MEM);
  }

  conn->state = NETCONN_CLOSE;
 again:
  msg->type = API_MSG_CLOSE;
  msg->msg.conn = conn;
  api_msg_post(msg);
  sys_mbox_fetch(conn->mbox, NULL);
  if (conn->err == ERR_MEM &&
     conn->sem != SYS_SEM_NULL) {
    sys_sem_wait(conn->sem);
    goto again;
  }
  conn->state = NETCONN_NONE;
  memp_freep(MEMP_API_MSG, msg);
  return conn->err;
}
Example #6
0
static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
   struct ip_addr *addr, u16_t port)
{
  struct netbuf *buf;
  struct netconn *conn;

  conn = arg;
  
  if (conn == NULL) {
    pbuf_free(p);
    return;
  }
  if (conn->recvmbox != SYS_MBOX_NULL) {
    buf = memp_mallocp(MEMP_NETBUF);
    if (buf == NULL) {
      pbuf_free(p);
      return;
    } else {
      buf->p = p;
      buf->ptr = p;
      buf->fromaddr = addr;
      buf->fromport = port;
    }

  conn->recv_avail += p->tot_len;
    /* Register event with callback */
    if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
    sys_mbox_post(conn->recvmbox, buf);
  }
}
Example #7
0
/*-----------------------------------------------------------------------------------*/
static err_t
accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  sys_mbox_t mbox;
  struct netconn *newconn;
  struct netconn *conn;
  
#if API_MSG_DEBUG
#if TCP_DEBUG
  tcp_debug_print_state(newpcb->state);
#endif /* TCP_DEBUG */
#endif /* API_MSG_DEBUG */
  conn = (struct netconn *)arg;
  mbox = conn->acceptmbox;
  newconn = memp_mallocp(MEMP_NETCONN);
  if (newconn == NULL) {
    return ERR_MEM;
  }
  newconn->type = NETCONN_TCP;
  newconn->pcb.tcp = newpcb;
  setup_tcp(newconn);
  newconn->recvmbox = sys_mbox_new();
  if (newconn->recvmbox == SYS_MBOX_NULL) {
    memp_free(MEMP_NETCONN, newconn);
    return ERR_MEM;
  }
  newconn->mbox = sys_mbox_new();
  if (newconn->mbox == SYS_MBOX_NULL) {
    sys_mbox_free(newconn->recvmbox);
    memp_free(MEMP_NETCONN, newconn);
    return ERR_MEM;
  }
  newconn->sem = sys_sem_new(0);
  if (newconn->sem == SYS_SEM_NULL) {
    sys_mbox_free(newconn->recvmbox);
    sys_mbox_free(newconn->mbox);
    memp_free(MEMP_NETCONN, newconn);
    return ERR_MEM;
  }
  newconn->acceptmbox = SYS_MBOX_NULL;
  newconn->err = err;
  /* Register event with callback */
  if (conn->callback)
  {
    (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
    /* We have to set the callback here even though
     * the new socket is unknown. Mark the socket as -1. */
    newconn->callback = conn->callback;
    newconn->socket = -1;
  }
  
  sys_mbox_post(mbox, newconn);
  return ERR_OK;
}
Example #8
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_delete(struct netconn *conn)
{
  struct api_msg *msg;
  void *mem;
  
  if (conn == NULL) {
    return ERR_OK;
  }
  
  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return ERR_MEM;
  }
  
  msg->type = API_MSG_DELCONN;
  msg->msg.conn = conn;
  api_msg_post(msg);  
  sys_mbox_fetch(conn->mbox, NULL);
  memp_freep(MEMP_API_MSG, msg);

  /* Drain the recvmbox. */
  if (conn->recvmbox != SYS_MBOX_NULL) {
    while (sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
      if (conn->type == NETCONN_TCP) {
	pbuf_free((struct pbuf *)mem);
      } else {
	netbuf_delete((struct netbuf *)mem);
      }
    }
    sys_mbox_free(conn->recvmbox);
    conn->recvmbox = SYS_MBOX_NULL;
  }
 

  /* Drain the acceptmbox. */
  if (conn->acceptmbox != SYS_MBOX_NULL) {
    while (sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != SYS_ARCH_TIMEOUT) {
      netconn_delete((struct netconn *)mem);
    }
    
    sys_mbox_free(conn->acceptmbox);
    conn->acceptmbox = SYS_MBOX_NULL;
  }

  sys_mbox_free(conn->mbox);
  conn->mbox = SYS_MBOX_NULL;
  if (conn->sem != SYS_SEM_NULL) {
    sys_sem_free(conn->sem);
  }
  /*  conn->sem = SYS_SEM_NULL;*/
  memp_free(MEMP_NETCONN, conn);
  return ERR_OK;
}
Example #9
0
/*-----------------------------------------------------------------------------------*/
void
tcpip_apimsg(struct api_msg *apimsg)
{
  struct tcpip_msg *msg;
  msg = memp_mallocp(MEMP_TCPIP_MSG);
  if (msg == NULL) {
    memp_free(MEMP_API_MSG, apimsg);
    return;
  }
  msg->type = TCPIP_MSG_API;
  msg->msg.apimsg = apimsg;
  sys_mbox_post(mbox, msg);
}
Example #10
0
/*-----------------------------------------------------------------------------------*/
struct
netbuf *netbuf_new(void)
{
  struct netbuf *buf;

  buf = memp_mallocp(MEMP_NETBUF);
  if (buf != NULL) {
    buf->p = NULL;
    buf->ptr = NULL;
    return buf;
  } else {
    return NULL;
  }
}
Example #11
0
/*-----------------------------------------------------------------------------------*/
err_t
tcpip_callback(void (*f)(void *ctx), void *ctx)
{
  struct tcpip_msg *msg;
  
  msg = memp_mallocp(MEMP_TCPIP_MSG);
  if (msg == NULL) {
    return ERR_MEM;  
  }
  
  msg->type = TCPIP_MSG_CALLBACK;
  msg->msg.cb.f = f;
  msg->msg.cb.ctx = ctx;
  sys_mbox_post(mbox, msg);
  return ERR_OK;
}
Example #12
0
/*-----------------------------------------------------------------------------------*/
err_t
tcpip_input(struct pbuf *p, struct netif *inp)
{
  struct tcpip_msg *msg;
  
  msg = memp_mallocp(MEMP_TCPIP_MSG);
  if (msg == NULL) {
    pbuf_free(p);    
    return ERR_MEM;  
  }
  
  msg->type = TCPIP_MSG_INPUT;
  msg->msg.inp.p = p;
  msg->msg.inp.netif = inp;
  sys_mbox_post(mbox, msg);
  return ERR_OK;
}
Example #13
0
err_t
netconn_disconnect(struct netconn *conn)
{
  struct api_msg *msg;
  
  if (conn == NULL) {
    return ERR_VAL;
  }

  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return ERR_MEM;
  }
  msg->type = API_MSG_DISCONNECT;
  msg->msg.conn = conn;  
  api_msg_post(msg);
  sys_mbox_fetch(conn->mbox, NULL);
  memp_freep(MEMP_API_MSG, msg);
  return conn->err;

}
Example #14
0
/**
 * Allocates a pbuf.
 *
 * The actual memory allocated for the pbuf is determined by the
 * layer at which the pbuf is allocated and the requested size
 * (from the size parameter).
 *
 * @param flag this parameter decides how and where the pbuf
 * should be allocated as follows:
 *
 * - PBUF_RAM: buffer memory for pbuf is allocated as one large
 *             chunk. This includes protocol headers as well.
 * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
 *             protocol headers. Additional headers must be prepended
 *             by allocating another pbuf and chain in to the front of
 *             the ROM pbuf. It is assumed that the memory used is really
 *             similar to ROM in that it is immutable and will not be
 *             changed. Memory which is dynamic should generally not
 *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
 * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
 *             protocol headers. It is assumed that the pbuf is only
 *             being used in a single thread. If the pbuf gets queued,
 *             then pbuf_take should be called to copy the buffer.
 * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
 *              the pbuf pool that is allocated during pbuf_init().
 *
 * @return the allocated pbuf. If multiple pbufs where allocated, this
 * is the first pbuf of a pbuf chain.
 */
struct pbuf *
pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
{
  struct pbuf *p, *q, *r;
  u16_t offset;
  s32_t rem_len; /* remaining length */

#ifdef PBUF_DEBUG
	char text[200];
#endif


  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u)\n", length));




  /* determine header offset */
  offset = 0;
  switch (l) {
  case PBUF_TRANSPORT:
    /* add room for transport (often TCP) layer header */
    offset += PBUF_TRANSPORT_HLEN;
    /* FALLTHROUGH */
  case PBUF_IP:
    /* add room for IP layer header */
    offset += PBUF_IP_HLEN;
    /* FALLTHROUGH */
  case PBUF_LINK:
    /* add room for link layer header */
    offset += PBUF_LINK_HLEN;
    break;
  case PBUF_RAW:
    break;
  default:
    LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
    return NULL;
  }

  /* add room for IPsec layer header */
  offset += IPSEC_HLEN;		/** *** CS *** add room for ESP and AH header */

  switch (flag) {
  case PBUF_POOL:
    /* allocate head of pbuf chain into p */
    p = pbuf_pool_alloc();
    LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
    if (p == NULL) {
#ifdef PBUF_STATS
      ++lwip_stats.pbuf.err;
#endif /* PBUF_STATS */
      return NULL;
    }
    p->next = NULL;

    /* make the payload pointer point 'offset' bytes into pbuf data memory */
    p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
    LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
            ((u32_t)p->payload % MEM_ALIGNMENT) == 0);
    /* the total length of the pbuf chain is the requested size */
    p->tot_len = length;
    /* set the length of the first pbuf in the chain */
    p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;
    /* set pbuf type */
    p->flags = PBUF_FLAG_POOL;
    /* set reference count (needed here in case we fail) */
    p->ref = 1;

    /* now allocate the tail of the pbuf chain */

    /* remember first pbuf for linkage in next iteration */
    r = p;
    /* remaining length to be allocated */
    rem_len = length - p->len;
    /* any remaining pbufs to be allocated? */
    while (rem_len > 0) {
      q = pbuf_pool_alloc();
      if (q == NULL) {
       LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));
#ifdef PBUF_STATS
        ++lwip_stats.pbuf.err;
#endif /* PBUF_STATS */
        /* free chain so far allocated */
        pbuf_free(p);
        /* bail out unsuccesfully */
        return NULL;
      }
      q->next = NULL;
      /* make previous pbuf point to this pbuf */
      r->next = q;
      /* set total length of this pbuf and next in chain */
      q->tot_len = rem_len;
      /* this pbuf length is pool size, unless smaller sized tail */
      q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
      q->flags = PBUF_FLAG_POOL;
      q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
      LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
              ((u32_t)q->payload % MEM_ALIGNMENT) == 0);
      q->ref = 1;
      /* calculate remaining length to be allocated */
      rem_len -= q->len;
      /* remember this pbuf for linkage in next iteration */
      r = q;
    }
    /* end of chain */
    //r->next = NULL;

    break;
  case PBUF_RAM:
    /* If pbuf is to be allocated in RAM, allocate memory for it. */
    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + length + offset));
    if (p == NULL) {
      return NULL;
    }
    /* Set up internal structure of the pbuf. */
    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));
    p->len = p->tot_len = length;
    p->next = NULL;
    p->flags = PBUF_FLAG_RAM;

    LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
           ((u32_t)p->payload % MEM_ALIGNMENT) == 0);
    break;
  /* pbuf references existing (static constant) ROM payload? */
  case PBUF_ROM:
  /* pbuf references existing (externally allocated) RAM payload? */
  case PBUF_REF:
    /* only allocate memory for the pbuf structure */
    p = memp_mallocp(MEMP_PBUF);
    if (p == NULL) {
      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", flag == PBUF_ROM?"ROM":"REF"));
      return NULL;
    }
    /* caller must set this field properly, afterwards */
    p->payload = NULL;
    p->len = p->tot_len = length;
    p->next = NULL;
    p->flags = (flag == PBUF_ROM? PBUF_FLAG_ROM: PBUF_FLAG_REF);
    break;
  default:
    LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);
    return NULL;
  }
  /* set reference count */
  p->ref = 1;
  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u) == %p\n", length, (void *)p));


#ifdef PBUF_DEBUG
	pbufstats_pbuf_counter++;
	sprintf(text, "pbuf_alloc: p=%p, flag=%s, layer=%s length=%d", p, pbufstats_text_pbuf_flags[flag],  pbufstats_text_pbuf_layers[l], length);
	pbufstats_print_pbuf_counter(text);
	pbufstats_addptr(p);
#endif

  return p;
}
Example #15
0
/*-----------------------------------------------------------------------------------*/
err_t
netconn_write(struct netconn *conn, void *dataptr, u32_t size, u8_t copy)
{
  struct api_msg *msg;
  u32_t len;
  
  if (conn == NULL) {
    return ERR_VAL;
  }

  if (conn->err != ERR_OK) {
    return conn->err;
  }
  
  if (conn->sem == SYS_SEM_NULL) {
    conn->sem = sys_sem_new(0);
    if (conn->sem == SYS_SEM_NULL) {
      return ERR_MEM;
    }
  }

  if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
    return (conn->err = ERR_MEM);
  }
  msg->type = API_MSG_WRITE;
  msg->msg.conn = conn;
        

  conn->state = NETCONN_WRITE;
  while (conn->err == ERR_OK && size > 0) {
    msg->msg.msg.w.dataptr = dataptr;
    msg->msg.msg.w.copy = copy;
    
    if (conn->type == NETCONN_TCP) {
      if (tcp_sndbuf(conn->pcb.tcp) == 0) {
	sys_sem_wait(conn->sem);
	if (conn->err != ERR_OK) {
	  goto ret;
	}
      }
      if (size > tcp_sndbuf(conn->pcb.tcp)) {
	/* We cannot send more than one send buffer's worth of data at a
	   time. */
	len = tcp_sndbuf(conn->pcb.tcp);
      } else {
	len = size;
      }
    } else {
      len = size;
    }
    
    DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %ld bytes (%d)\n", len, copy));
    msg->msg.msg.w.len = len;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox, NULL);    
    if (conn->err == ERR_OK) {
      dataptr = (void *)((char *)dataptr + len);
      size -= len;
    } else if (conn->err == ERR_MEM) {
      conn->err = ERR_OK;
      sys_sem_wait(conn->sem);
    } else {
      goto ret;
    }
  }
 ret:
  memp_freep(MEMP_API_MSG, msg);
  conn->state = NETCONN_NONE;
  if (conn->sem != SYS_SEM_NULL) {
    sys_sem_free(conn->sem);
    conn->sem = SYS_SEM_NULL;
  }
  
  return conn->err;
}
Example #16
0
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_alloc(pbuf_layer l, uint16_t size, pbuf_flag flag)
{
  struct pbuf *p, *q, *r;
  uint16_t offset;
  int32_t rsize;

  offset = 0;
  switch(l) {
	  case PBUF_TRANSPORT:
		  offset += PBUF_TRANSPORT_HLEN;
		  /* FALLTHROUGH */
	  case PBUF_IP:
		  offset += PBUF_IP_HLEN;
		  offset += PBUF_LINK_HLEN;
		  /* FALLTHROUGH */
	  case PBUF_LINK:
		  break;
	  case PBUF_RAW:
		  break;
	  default:
		  ASSERT("pbuf_alloc: bad pbuf layer", 0);
		  return NULL;
  }

  switch(flag)
  {
	  case PBUF_POOL:
		  /* Allocate head of pbuf chain into p. */
		  p = pbuf_pool_alloc();
		  if(p == NULL) {
#ifdef PBUF_STATS
			  ++stats.pbuf.err;
#endif /* PBUF_STATS */
			  return NULL;
		  }
		  p->next = NULL;

		  /* Set the payload pointer so that it points offset bytes into
			 pbuf data memory. */
		  p->payload = MEM_ALIGN((void *)((uint8_t *)p + (sizeof(struct pbuf) + offset)));

		  /* The total length of the pbuf is the requested size. */
		  p->tot_len = size;

		  /* Set the length of the first pbuf is the chain. */
		  p->len = size > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: size;

		  p->flags = PBUF_FLAG_POOL;

		  /* Allocate the tail of the pbuf chain. */
		  r = p;
		  rsize = size - p->len;
		  while(rsize > 0) {
			  q = pbuf_pool_alloc();
			  if(q == NULL) {
				  DEBUGF(PBUF_DEBUG, ("pbuf_alloc: Out of pbufs in pool,\n"));
#ifdef PBUF_STATS
				  ++stats.pbuf.err;
#endif /* PBUF_STATS */
				  pbuf_pool_free(p);
				  return NULL;
			  }
			  q->next = NULL;
			  r->next = q;
			  q->len = rsize > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rsize;
			  q->flags = PBUF_FLAG_POOL;
			  q->payload = (void *)((uint8_t *)q + sizeof(struct pbuf));
			  r = q;
			  q->ref = 1;
			  q = q->next;
			  rsize -= PBUF_POOL_BUFSIZE;
		  }
		  r->next = NULL;

		  ASSERT("pbuf_alloc: pbuf->payload properly aligned",
				  ((uint32_t)p->payload % MEM_ALIGNMENT) == 0);
		  break;
	  case PBUF_RAM:
		  /* If pbuf is to be allocated in RAM, allocate memory for it. */
		  p = (struct pbuf*)mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + size + offset));
		  if(p == NULL)
		  { return NULL; }

		  /* Set up internal structure of the pbuf. */
		  p->payload = MEM_ALIGN((void *)((uint8_t *)p + sizeof(struct pbuf) + offset));
		  p->len = p->tot_len = size;
		  p->next = NULL;
		  p->flags = PBUF_FLAG_RAM;

		  ASSERT("pbuf_alloc: pbuf->payload properly aligned",
				  ((uint32_t)p->payload % MEM_ALIGNMENT) == 0);
		  break;
	  case PBUF_ROM:
		  /* If the pbuf should point to ROM, we only need to allocate
			 memory for the pbuf structure. */
		  p = (struct pbuf*)memp_mallocp(MEMP_PBUF);
		  if(p == NULL) {
			  return NULL;
		  }
		  p->payload = NULL;
		  p->len = p->tot_len = size;
		  p->next = NULL;
		  p->flags = PBUF_FLAG_ROM;
		  break;
	  default:
		  ASSERT("pbuf_alloc: erroneous flag", 0);
		  return NULL;
  }
  p->ref = 1;
  return p;
}
Example #17
0
/*-----------------------------------------------------------------------------------*/
struct netbuf *
netconn_recv(struct netconn *conn)
{
  struct api_msg *msg;
  struct netbuf *buf;
  struct pbuf *p;
  u32_t len;
    
  if (conn == NULL) {
    return NULL;
  }
  
  if (conn->recvmbox == SYS_MBOX_NULL) {
    conn->err = ERR_CONN;
    return NULL;
  }

  if (conn->err != ERR_OK) {
    return NULL;
  }

  if (conn->type == NETCONN_TCP) {
    if (conn->pcb.tcp->state == LISTEN) {
      conn->err = ERR_CONN;
      return NULL;
    }


    buf = memp_mallocp(MEMP_NETBUF);

    if (buf == NULL) {
      conn->err = ERR_MEM;
      return NULL;
    }
    
    sys_mbox_fetch(conn->recvmbox, (void **)&p);

    if (p != NULL)
    {
        len = p->tot_len;
        conn->recv_avail -= len;
    }
    else
        len = 0;
    
    /* Register event with callback */
      if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);

    /* If we are closed, we indicate that we no longer wish to receive
       data by setting conn->recvmbox to SYS_MBOX_NULL. */
    if (p == NULL) {
      memp_freep(MEMP_NETBUF, buf);
      sys_mbox_free(conn->recvmbox);
      conn->recvmbox = SYS_MBOX_NULL;
      return NULL;
    }

    buf->p = p;
    buf->ptr = p;
    buf->fromport = 0;
    buf->fromaddr = NULL;

    /* Let the stack know that we have taken the data. */
    if ((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
      conn->err = ERR_MEM;
      return buf;
    }
    msg->type = API_MSG_RECV;
    msg->msg.conn = conn;
    if (buf != NULL) {
      msg->msg.msg.len = buf->p->tot_len;
    } else {
      msg->msg.msg.len = 1;
    }
    api_msg_post(msg);

    sys_mbox_fetch(conn->mbox, NULL);
    memp_freep(MEMP_API_MSG, msg);
  } else {
    sys_mbox_fetch(conn->recvmbox, (void **)&buf);
	conn->recv_avail -= buf->p->tot_len;
    /* Register event with callback */
    if (conn->callback)
        (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
  }

  

    
  DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));


  return buf;
}