示例#1
0
int
lwip_send(int s, void *data, int size, unsigned int flags)
{
  struct lwip_socket *sock;
  struct netbuf *buf;
  err_t err;

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));

  sock = get_socket(s);
  if (!sock) {
    set_errno(EBADF);
    return -1;
  }

  switch (netconn_type(sock->conn)) {
  case NETCONN_RAW:
  case NETCONN_UDP:
  case NETCONN_UDPLITE:
  case NETCONN_UDPNOCHKSUM:
    /* create a buffer */
    buf = netbuf_new();

    if (!buf) {
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
      sock_set_errno(sock, ENOBUFS);
      return -1;
    }

    /* make the buffer point to the data that should
       be sent */
    netbuf_ref(buf, data, size);

    /* send the data */
    err = netconn_send(sock->conn, buf);

    /* deallocated the buffer */
    netbuf_delete(buf);
    break;
  case NETCONN_TCP:
    err = netconn_write(sock->conn, data, size, NETCONN_COPY);
    break;
  default:
    err = ERR_ARG;
    break;
  }
  if (err != ERR_OK) {
    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
    sock_set_errno(sock, err_to_errno(err));
    return -1;
  }

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
  sock_set_errno(sock, 0);
  return size;
}
示例#2
0
int
lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
        struct sockaddr *from, socklen_t *fromlen)
{
  struct lwip_socket *sock;
  struct netbuf *buf;
  u16_t buflen, copylen;
  struct ip_addr *addr;
  u16_t port;


  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
  sock = get_socket(s);
  if (!sock) {
    set_errno(EBADF);
    return -1;
  }

  /* Check if there is data left from the last recv operation. */
  if (sock->lastdata) {
    buf = sock->lastdata;
  } else {
    /* If this is non-blocking call, then check first */
    if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK))
  && !sock->rcvevent)
    {
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));
      sock_set_errno(sock, EWOULDBLOCK);
      return -1;
    }

    /* No data was left from the previous operation, so we try to get
       some from the network. */
    buf = netconn_recv(sock->conn);

    if (!buf) {
      /* We should really do some error checking here. */
      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s));
      sock_set_errno(sock, 0);
      return 0;
    }
  }

  buflen = netbuf_len(buf);

  buflen -= sock->lastoffset;

  if (len > buflen) {
    copylen = buflen;
  } else {
    copylen = len;
  }

  /* copy the contents of the received buffer into
     the supplied memory pointer mem */
  netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);

  /* Check to see from where the data was. */
  if (from && fromlen) {
    struct sockaddr_in sin;

    addr = netbuf_fromaddr(buf);
    port = netbuf_fromport(buf);

    memset(&sin, 0, sizeof(sin));
    sin.sin_len = sizeof(sin);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = addr->addr;

    if (*fromlen > sizeof(sin))
      *fromlen = sizeof(sin);

    memcpy(from, &sin, *fromlen);

    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
    ip_addr_debug_print(SOCKETS_DEBUG, addr);
    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
  } else {
#if SOCKETS_DEBUG
    addr = netbuf_fromaddr(buf);
    port = netbuf_fromport(buf);

    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
    ip_addr_debug_print(SOCKETS_DEBUG, addr);
    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
#endif

  }

  /* If this is a TCP socket, check if there is data left in the
     buffer. If so, it should be saved in the sock structure for next
     time around. */
  if (netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
    sock->lastdata = buf;
    sock->lastoffset += copylen;
  } else {
    sock->lastdata = NULL;
    sock->lastoffset = 0;
    netbuf_delete(buf);
  }


  sock_set_errno(sock, 0);
  return copylen;
}
示例#3
0
文件: sip_api.c 项目: lzjsqn/19
int recvfrom(int s, void *mem, int len, unsigned int flags,
        struct sockaddr *from, socklen_t *fromlen)
{
	struct lwip_socket *sock;
	struct skbuff      *buf;
	u16_t               buflen, copylen, off = 0;
	struct ip_addr     *addr;
	u16_t               port;
	u8_t                done = 0;

	sock = get_socket(s);
	if (!sock)
		return -1;

	do {
		/* Check if there is data left from the last recv operation. */
		if (sock->lastdata) 
		{
			buf = sock->lastdata;
		} 
		else 
		{
			/* If this is non-blocking call, then check first */
			if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) && !sock->rcvevent) 
			{
				return -1;
			}

			/* No data was left from the previous operation, so we try to get
			some from the network. */
			sock->lastdata = buf = netconn_recv(sock->conn);

			if (!buf) 
			{
				/* We should really do some error checking here. */
				return 0;
			}
		}

		buflen = netbuf_len(buf);

		buflen -= sock->lastoffset;
		if (len > buflen) 
		{
			copylen = buflen;
		} 
		else 
		{
			copylen = len;
		}

		/* copy the contents of the received buffer into
		the supplied memory pointer mem */
		netbuf_copy_partial(buf, (u8_t*)mem + off, copylen, sock->lastoffset);
		off += copylen;

		if (netconn_type(sock->conn) == NETCONN_TCP) 
		{
			len -= copylen;
			if ( (len <= 0) || (buf->p->flags & PBUF_FLAG_PUSH) || !sock->rcvevent) 
			{
				done = 1;
			}
		} 
		else 
		{
			done = 1;
		}

		/* If we don't peek the incoming message... */
		if ((flags & MSG_PEEK)==0) 
		{
			/* If this is a TCP socket, check if there is data left in the
			buffer. If so, it should be saved in the sock structure for next
			time around. */
			if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) 
			{
				sock->lastdata = buf;
				sock->lastoffset += copylen;
			} 
			else 
			{
				sock->lastdata = NULL;
				sock->lastoffset = 0;
				netbuf_delete(buf);
			}
		} 
		else 
		{
			done = 1;
		}
	} while (!done);

	/* Check to see from where the data was.*/
	if (from && fromlen) 
	{
		struct sockaddr_in sin;

		if (netconn_type(sock->conn) == NETCONN_TCP) 
		{
			addr = (struct ip_addr*)&(sin.sin_addr.s_addr);
			netconn_getaddr(sock->conn, addr, &port, 0);
		} 
		else 
		{
			addr = netbuf_fromaddr(buf);
			port = netbuf_fromport(buf);
		}

		memset(&sin, 0, sizeof(sin));
		sin.sin_len = sizeof(sin);
		sin.sin_family = AF_INET;
		sin.sin_port = htons(port);
		sin.sin_addr.s_addr = addr->addr;

		if (*fromlen > sizeof(sin))
			*fromlen = sizeof(sin);

		SMEMCPY(from, &sin, *fromlen);
	} 

	return off;
}