Example #1
0
static size_t
read(void *ip, uint8_t *bp, size_t n)
{
  NetStream *sp = ip;
  err_t err;

  /* If last input buffer was completely consumed, wait for a new packet. */
  while (sp->inbuf == NULL)
    {
      /* Wait for new packet. */
      err = netconn_recv(sp->conn, &sp->inbuf);
      if (err != ERR_OK)
        {
          /* Connection closed (or any other errors). */
          return 0;
        }
    }

  netbuf_copy_partial(sp->inbuf, bp, n, sp->in_offset);
  sp->in_offset += n;

  /* Check if there is more data to read. */
  if (sp->in_offset >= netbuf_len(sp->inbuf))
    {
      n -= (sp->in_offset - netbuf_len(sp->inbuf));
      netbuf_delete(sp->inbuf);
      sp->in_offset = 0;
      sp->inbuf = NULL;
    }

  return n;
}
Example #2
0
static int lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, unsigned size)
{
    struct lwip_socket *s = (struct lwip_socket *)handle;

    if (!s->buf) {
        err_t err = netconn_recv(s->conn, &s->buf);
        s->offset = 0;

        if (err != ERR_OK) {
            return (err == ERR_CLSD) ? 0 : lwip_err_remap(err);
        }
    }

    u16_t recv = netbuf_copy_partial(s->buf, data, (u16_t)size, s->offset);
    s->offset += recv;

    if (s->offset >= netbuf_len(s->buf)) {
        netbuf_delete(s->buf);
        s->buf = 0;
    }

    return recv;
}
Example #3
0
nsapi_size_or_error_t LWIP::socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)
{
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;

    if (!s->buf) {
        err_t err = netconn_recv(s->conn, &s->buf);
        s->offset = 0;

        if (err != ERR_OK) {
            return err_remap(err);
        }
    }

    u16_t recv = netbuf_copy_partial(s->buf, data, (u16_t)size, s->offset);
    s->offset += recv;

    if (s->offset >= netbuf_len(s->buf)) {
        netbuf_delete(s->buf);
        s->buf = 0;
    }

    return recv;
}
Example #4
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;
}
Example #5
0
File: sip_api.c Project: 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;
}
void XMLRPCServer::UDPreceive(void* params)
{
    struct netconn *conn;
    struct netbuf *buf;
    err_t err;

    // Initialize memory (in stack) for message.
    char message[60]; // TODO: Set its size according to UDPMessage.
    os_printf("Test!\n");
    conn = netconn_new(NETCONN_UDP);
    for (;;) {
        // Check if connection was created successfully.
        if (conn != NULL) {
            err = netconn_bind(conn, IP_ADDR_ANY, UDP_RECEIVE_PORT);

            // Check if we were able to bind to port.
            if (err == ERR_OK) {
                portTickType xLastWakeTime;
                // Initialize the xLastWakeTime variable with the current time.
                xLastWakeTime = xTaskGetTickCount();

                // Start periodic loop.
                while (1) {
                    buf = netconn_recv(conn);
                    if (buf != NULL) {
                        struct ip_addr* ip;
                        uint16_t port;
                        ip = buf->addr;
                        port = buf->port;
                        //if(ip != NULL)
                        //os_printf("Received from %d:%d!\n", ip->addr, port);
                        // Copy received data into message.
                        uint16_t len = netbuf_len(buf);
                        if (len > 15) {
                            netbuf_copy (buf, &message, len);
                            uint32_t connectionID = *((uint32_t*)&message[0]);
                            TopicReader* tr = getTopicReader(connectionID);
                            if (tr != NULL) {
                                tr->enqueueMessage(&message[8]);
                                //os_printf("ConnectionID: %d, topic:%s\n", connectionID, tr->getTopic());
                            }
                        }
                        // Deallocate previously created memory.
                        netbuf_delete(buf);
                    }
                    // Use delay until to guarantee periodic execution of each loop iteration.
                    else {
                        os_printf("buf = NULL!\n");
                        vTaskDelayUntil(&xLastWakeTime, 30);
                    }
                }
            } else {
                os_printf("cannot bind netconn\n");
            }
        } else {
            os_printf("cannot create new UDP netconn\n");
            conn = netconn_new(NETCONN_UDP);
        }
        // If connection failed, wait for 50 ms before retrying.
        vTaskDelay(50);
    }
}
Example #7
0
static void dhcpserver_task(void *pxParameter)
{
    /* netif_list isn't assigned until after user_init completes, which is why we do it inside the task */
    state->server_if = netif_list; /* TODO: Make this configurable */

    state->nc = netconn_new (NETCONN_UDP);
    if(!state->nc) {
        printf("DHCP Server Error: Failed to allocate socket.\r\n");
        return;
    }

    netconn_bind(state->nc, IP_ADDR_ANY, DHCP_SERVER_PORT);

    while(1)
    {
        struct netbuf *netbuf;
        struct dhcp_msg received = { 0 };

        /* Receive a DHCP packet */
        err_t err = netconn_recv(state->nc, &netbuf);
        if(err != ERR_OK) {
            printf("DHCP Server Error: Failed to receive DHCP packet. err=%d\r\n", err);
            continue;
        }

        /* expire any leases that have passed */
        uint32_t now = xTaskGetTickCount();
        for(int i = 0; i < state->max_leases; i++) {
            uint32_t expires = state->leases[i].expires;
            if(expires && expires < now)
                state->leases[i].expires = 0;
        }

        ip_addr_t received_ip;
        u16_t port;
        netconn_addr(state->nc, &received_ip, &port);

        if(netbuf_len(netbuf) < offsetof(struct dhcp_msg, options)) {
            /* too short to be a valid DHCP client message */
            netbuf_delete(netbuf);
            continue;
        }
        if(netbuf_len(netbuf) >= sizeof(struct dhcp_msg)) {
           printf("DHCP Server Warning: Client sent more options than we know how to parse. len=%d\r\n", netbuf_len(netbuf));
        }

        netbuf_copy(netbuf, &received, sizeof(struct dhcp_msg));
        netbuf_delete(netbuf);

        uint8_t *message_type = find_dhcp_option(&received, DHCP_OPTION_MESSAGE_TYPE,
                                                 DHCP_OPTION_MESSAGE_TYPE_LEN, NULL);
        if(!message_type) {
            printf("DHCP Server Error: No message type field found");
            continue;
        }


        printf("State dump. Message type %d\n", *message_type);
        for(int i = 0; i < state->max_leases; i++) {
            dhcp_lease_t *lease = &state->leases[i];
            printf("lease slot %d expiry %d hwaddr %02x:%02x:%02x:%02x:%02x:%02x\r\n", i, lease->expires, lease->hwaddr[0],
                   lease->hwaddr[1], lease->hwaddr[2], lease->hwaddr[3], lease->hwaddr[4],
                   lease->hwaddr[5]);
        }

        switch(*message_type) {
        case DHCP_DISCOVER:
            handle_dhcp_discover(&received);
            break;
        case DHCP_REQUEST:
            handle_dhcp_request(&received);
            break;
        case DHCP_RELEASE:
            handle_dhcp_release(&received);
        default:
            printf("DHCP Server Error: Unsupported message type %d\r\n", *message_type);
            break;
        }
    }
}