예제 #1
0
nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr)
{
    // Validate parameters
    NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
    nsapi_error_t ret;
    if (handle == NULL) {
        MBED_ASSERT(false);
        return NSAPI_ERROR_NO_SOCKET;
    }

    NanostackLockGuard lock;

    if (addr.get_ip_version() != NSAPI_IPv6) {
        ret = NSAPI_ERROR_UNSUPPORTED;
        goto out;
    }

    if (socket->closed()) {
        ret = NSAPI_ERROR_NO_CONNECTION;
        goto out;
    }

    if (socket->is_connecting()) {
        ret = NSAPI_ERROR_ALREADY;
        goto out;
    }

    if (socket->is_connected()) {
        ret = NSAPI_ERROR_IS_CONNECTED;
        goto out;
    }

    ns_address_t ns_addr;

    convert_mbed_addr_to_ns(&ns_addr, &addr);
    if (::socket_connect(socket->socket_id, &ns_addr, 0) == 0) {
        if (socket->proto == SOCKET_TCP) {
            socket->set_connecting(&ns_addr);
            ret = NSAPI_ERROR_IN_PROGRESS;
        } else {
            ret = NSAPI_ERROR_OK;
        }
    } else {
        ret = NSAPI_ERROR_DEVICE_ERROR;
    }

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

    return ret;
}
예제 #2
0
nsapi_size_or_error_t NanostackInterface::do_sendto(void *handle, const ns_address_t *address, const void *data, 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() || (!address && !socket->is_connected())) {
        ret = NSAPI_ERROR_NO_CONNECTION;
        goto out;
    }

    if (address && socket->proto == SOCKET_TCP) {
        tr_error("socket_sendto() not supported with TCP!");
        ret = NSAPI_ERROR_IS_CONNECTED;
        goto out;
    }

    int retcode;
#if 0
    retcode = ::socket_sendto(socket->socket_id, address,
                                            data, size);
#else
    // Use sendmsg purely to get the new return style
    // of returning data written rather than 0 on success,
    // which means TCP can do partial writes. (Sadly,
    // it's the only call which takes flags so we can
    // leave the NS_MSG_LEGACY0 flag clear).
    ns_msghdr_t msg;
    ns_iovec_t iov;
    iov.iov_base = const_cast<void *>(data);
    iov.iov_len = size;
    msg.msg_name = const_cast<ns_address_t *>(address);
    msg.msg_namelen = address ? sizeof *address : 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    retcode = ::socket_sendmsg(socket->socket_id, &msg, 0);
#endif

    /*
     * \return length if entire amount written (which could be 0)
     * \return value >0 and <length if partial amount written (stream only)
     * \return NS_EWOULDBLOCK if nothing written due to lack of queue space.
     * \return -1 Invalid socket ID or message structure.
     * \return -2 Socket memory allocation fail.
     * \return -3 TCP state not established or address scope not defined .
     * \return -4 Socket TX process busy or unknown interface.
     * \return -5 Socket not connected
     * \return -6 Packet too short (ICMP raw socket error).
     * */
    if (retcode == NS_EWOULDBLOCK) {
        ret = NSAPI_ERROR_WOULD_BLOCK;
    } else if (retcode < 0) {
        tr_error("socket_sendmsg: error=%d", retcode);
        ret = NSAPI_ERROR_DEVICE_ERROR;
    } else {
        ret = retcode;
    }

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

    return ret;
}