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; }
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; }
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; }
void netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len) { netbuf_copy_partial(buf, dataptr, len, 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; }
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; }