size_t NanostackSocket::data_copy_and_free(void *dest, size_t len, SocketAddress *address, bool stream) { nanostack_assert_locked(); MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || (mode == SOCKET_MODE_STREAM)); NanostackBuffer *data_buf = rxBufChain; if (NULL == data_buf) { // No data return 0; } if (address) { convert_ns_addr_to_mbed(address, &data_buf->ns_address); } size_t copy_size = (len > data_buf->length) ? data_buf->length : len; memcpy(dest, data_buf->payload, copy_size); if (stream && (copy_size < data_buf->length)) { // Update the size in the buffer size_t new_buf_size = data_buf->length - copy_size; memmove(data_buf->payload, data_buf->payload + copy_size, new_buf_size); data_buf->length = new_buf_size; } else { // Entire packet used so free it rxBufChain = data_buf->next; FREE(data_buf); } return copy_size; }
nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) { NanostackSocket * socket = static_cast<NanostackSocket *>(server); NanostackSocket *accepted_sock = NULL; nsapi_error_t ret; if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } NanostackLockGuard lock; if (!socket->is_listening()) { ret = NSAPI_ERROR_PARAMETER; goto out; } accepted_sock = new NanostackSocket(socket->proto); if (accepted_sock == NULL) { ret = NSAPI_ERROR_NO_MEMORY; goto out; } ns_address_t ns_addr; int retcode; retcode = socket->accept(accepted_sock, &ns_addr); if (retcode < 0) { delete accepted_sock; if (retcode == NS_EWOULDBLOCK) { ret = NSAPI_ERROR_WOULD_BLOCK; } else { ret = NSAPI_ERROR_DEVICE_ERROR; } goto out; } ret = NSAPI_ERROR_OK; if (address) { convert_ns_addr_to_mbed(address, &ns_addr); } *handle = accepted_sock; out: tr_debug("socket_accept() socket=%p, sock_id=%d, ret=%i", accepted_sock, accepted_sock ? accepted_sock->socket_id : -1, ret); return ret; }
nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size) { // Validate parameters NanostackSocket *socket = static_cast<NanostackSocket *>(handle); if (handle == NULL) { MBED_ASSERT(false); return NSAPI_ERROR_NO_SOCKET; } nsapi_size_or_error_t ret; NanostackLockGuard lock; if (socket->closed()) { ret = NSAPI_ERROR_NO_CONNECTION; goto out; } ns_address_t ns_address; int retcode; retcode = ::socket_recvfrom(socket->socket_id, buffer, size, 0, &ns_address); if (retcode == NS_EWOULDBLOCK) { ret = NSAPI_ERROR_WOULD_BLOCK; } else if (retcode < 0) { ret = NSAPI_ERROR_PARAMETER; } else { ret = retcode; if (address != NULL) { convert_ns_addr_to_mbed(address, &ns_address); } } out: if (address) { tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i, addr=[%s]:%i", socket, socket->socket_id, ret, trace_ipv6(address->get_ip_bytes()), address->get_port()); } else { tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); } return ret; }