int NanostackInterface::socket_recv(void *handle, void *data, unsigned size)
{
    // Validate parameters
    NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
    if (NULL == handle) {
        MBED_ASSERT(false);
        return NSAPI_ERROR_NO_SOCKET;
    }

    nanostack_lock();

    int ret;
    if (socket->closed()) {
        ret = NSAPI_ERROR_NO_CONNECTION;
    } else if (socket->data_available()) {
        ret = socket->data_copy_and_free(data, size, NULL, true);
    } else {
        ret = NSAPI_ERROR_WOULD_BLOCK;
    }

    nanostack_unlock();

    tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret);

    return ret;
}
int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size)
{
    // Validate parameters
    NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
    if (NULL == handle) {
        MBED_ASSERT(false);
        return NSAPI_ERROR_NO_SOCKET;
    }
    if (NULL == buffer) {
        MBED_ASSERT(false);
        return NSAPI_ERROR_PARAMETER;
    }
    if (0 == size) {
        MBED_ASSERT(false);
        return NSAPI_ERROR_PARAMETER;
    }

    nanostack_lock();

    int ret;
    if (socket->closed()) {
        ret = NSAPI_ERROR_NO_CONNECTION;
    } else if (NANOSTACK_SOCKET_TCP == socket->proto) {
        tr_error("recv_from() not supported with SOCKET_STREAM!");
        ret = NSAPI_ERROR_UNSUPPORTED;
    } else if (!socket->data_available()) {
        ret = NSAPI_ERROR_WOULD_BLOCK;
    } else {
        ret = socket->data_copy_and_free(buffer, size, address, false);
    }

    nanostack_unlock();

    tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret);

    return ret;
}