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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}