void NanostackSocket::event_data(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) ||
                (SOCKET_MODE_STREAM == mode));

    // Allocate buffer
    NanostackBuffer *recv_buff = (NanostackBuffer *) MALLOC(
                                 sizeof(NanostackBuffer) + sock_cb->d_len);
    if (NULL == recv_buff) {
        tr_error("alloc failed!");
        return;
    }
    recv_buff->next = NULL;

    // Write data to buffer
    int16_t length = socket_read(sock_cb->socket_id,
                                 &recv_buff->ns_address, recv_buff->payload,
                                 sock_cb->d_len);
    if (length < 0) {
        tr_error("socket_read failed!");
        FREE(recv_buff);
        return;
    }
    recv_buff->length = length;

    data_attach(recv_buff);
}
void NanostackSocket::set_connected()
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_CONNECTING == mode);

    mode = SOCKET_MODE_STREAM;
}
bool NanostackSocket::open(void)
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);

    int temp_socket = socket_open(proto, 0, socket_callback);

    if (temp_socket < 0) {
        tr_error("NanostackSocket::open() failed");
        return false;
    }
    if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) {
        MBED_ASSERT(false);
        return false;
    }
    if (socket_tbl[temp_socket] != NULL) {
        MBED_ASSERT(false);
        return false;
    }
    socket_id = temp_socket;
    socket_tbl[socket_id] = this;
    mode = SOCKET_MODE_OPENED;
    return true;

}
void NanostackSocket::set_listening()
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_OPENED == mode);

    mode = SOCKET_MODE_LISTENING;
}
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;
}
void NanostackSocket::socket_callback(void *cb) {
    nanostack_assert_locked();

    socket_callback_t *sock_cb = (socket_callback_t *) cb;
    NanostackSocket *socket = socket_tbl[sock_cb->socket_id];
    MBED_ASSERT(socket != NULL);

    tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d",
                     sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len);

    switch (sock_cb->event_type) {
        case SOCKET_DATA:
            tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len);
            socket->event_data(sock_cb);
            break;
        case SOCKET_CONNECT_DONE:
            tr_debug("SOCKET_CONNECT_DONE");
            socket->event_connect_done(sock_cb);
            break;
        case SOCKET_CONNECT_FAIL:
            tr_debug("SOCKET_CONNECT_FAIL");
            socket->event_connect_fail(sock_cb);
            break;
        case SOCKET_CONNECT_AUTH_FAIL:
            tr_debug("SOCKET_CONNECT_AUTH_FAIL");
            break;
        case SOCKET_INCOMING_CONNECTION:
            tr_debug("SOCKET_INCOMING_CONNECTION");
            socket->event_incoming_connection(sock_cb);
            break;
        case SOCKET_TX_FAIL:
            tr_debug("SOCKET_TX_FAIL");
            socket->event_tx_fail(sock_cb);
            break;
        case SOCKET_CONNECT_CLOSED:
            tr_debug("SOCKET_CONNECT_CLOSED");
            socket->event_connect_closed(sock_cb);
            break;
        case SOCKET_CONNECTION_RESET:
            tr_debug("SOCKET_CONNECTION_RESET");
            socket->event_connection_reset(sock_cb);
            break;
        case SOCKET_NO_ROUTE:
            tr_debug("SOCKET_NO_ROUTE");
            socket->event_tx_fail(sock_cb);
            break;
        case SOCKET_TX_DONE:
            socket->event_tx_done(sock_cb);
            break;
        case SOCKET_NO_RAM:
            tr_debug("SOCKET_NO_RAM");
            socket->event_tx_fail(sock_cb);
            break;
        case SOCKET_CONNECTION_PROBLEM:
            tr_debug("SOCKET_CONNECTION_PROBLEM");
            break;
        default:
            break;
    }
}
void NanostackSocket::event_data(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
                (SOCKET_MODE_DATAGRAM == mode));

    signal_event();
}
NanostackSocket::~NanostackSocket()
{
    nanostack_assert_locked();

    if (mode != SOCKET_MODE_CLOSED) {
        close();
    }
}
void NanostackSocket::set_bound()
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_OPENED == mode);
    if (SOCKET_UDP == proto) {
        mode = SOCKET_MODE_DATAGRAM;
    }
}
Beispiel #10
0
void NanostackSocket::event_connect_done(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_CONNECTING == mode);

    set_connected();
    signal_event();
}
Beispiel #11
0
void NanostackSocket::signal_event()
{
    nanostack_assert_locked();

    if (callback != NULL) {
        callback(callback_data);
    }
}
Beispiel #12
0
void NanostackSocket::set_connecting(ns_address_t *addr)
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_OPENED == mode);

    memcpy(&ns_address, addr, sizeof(ns_address_t));
    mode = SOCKET_MODE_CONNECTING;
}
bool NanostackSocket::data_available()
{
    nanostack_assert_locked();
    MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) ||
                (SOCKET_MODE_CONNECTING == mode) ||
                (SOCKET_MODE_STREAM == mode));

    return (NULL == rxBufChain) ? false : true;
}
Beispiel #14
0
void NanostackSocket::event_connection_reset(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();

    // Only TCP sockets can be closed by the remote end
    MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
                (SOCKET_MODE_CONNECTING == mode));
    close();
}
Beispiel #15
0
void NanostackSocket::event_connect_closed(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();

    // Can happen if we have an orderly close()
    // Might never happen as we have not implemented shutdown() in abstraction layer.
    MBED_ASSERT(mode == SOCKET_MODE_STREAM);
    close();
}
Beispiel #16
0
NanostackSocket::NanostackSocket(int8_t protocol)
{
    nanostack_assert_locked();

    callback = NULL;
    callback_data = NULL;
    socket_id = -1;
    proto = protocol;
    addr_valid = false;
    memset(&ns_address, 0, sizeof(ns_address));
    mode = SOCKET_MODE_UNOPENED;
}
void NanostackSocket::data_free_all(void)
{
    nanostack_assert_locked();
    // No mode requirement

    NanostackBuffer *buffer = rxBufChain;
    rxBufChain = NULL;
    while (buffer != NULL) {
        NanostackBuffer *next_buffer = buffer->next;
        FREE(buffer);
        buffer = next_buffer;
    }
}
Beispiel #18
0
void NanostackSocket::event_tx_done(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
                (SOCKET_MODE_DATAGRAM == mode));

    if (mode == SOCKET_MODE_DATAGRAM) {
        tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len);
    } else if (mode == SOCKET_MODE_STREAM) {
        tr_debug("SOCKET_TX_DONE, %d bytes remaining", sock_cb->d_len);
    }

    signal_event();
}
void NanostackSocket::socket_callback(void *cb) {
    nanostack_assert_locked();

    socket_callback_t *sock_cb = (socket_callback_t *) cb;
    NanostackSocket *socket = socket_tbl[sock_cb->socket_id];
    MBED_ASSERT(socket != NULL);

    tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d",
                     sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len);

    switch (sock_cb->event_type) {
        case SOCKET_DATA:
            tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len);
            socket->event_data(sock_cb);
            break;
        case SOCKET_BIND_DONE:
            tr_debug("SOCKET_BIND_DONE");
            socket->event_bind_done(sock_cb);
            break;
        case SOCKET_BIND_FAIL: // Not used in NS
            tr_debug("SOCKET_BIND_FAIL");
            break;
        case SOCKET_BIND_AUTH_FAIL: // Not used in NS
            tr_debug("SOCKET_BIND_AUTH_FAIL");
            break;
        case SOCKET_SERVER_CONNECT_TO_CLIENT: // Not used in NS
            tr_debug("SOCKET_SERVER_CONNECT_TO_CLIENT");
            break;
        case SOCKET_TX_FAIL:
            tr_debug("SOCKET_TX_FAIL");
            break;
        case SOCKET_CONNECT_CLOSED:
            tr_debug("SOCKET_CONNECT_CLOSED");
            socket->event_connnect_closed(sock_cb);
            break;
        case SOCKET_CONNECT_FAIL_CLOSED: // Not used in NS
            tr_debug("SOCKET_CONNECT_FAIL_CLOSED");
            break;
        case SOCKET_NO_ROUTE:
            tr_debug("SOCKET_NO_ROUTE");
            break;
        case SOCKET_TX_DONE:
            tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len);
            socket->event_tx_done(sock_cb);
            break;
        default:
            // SOCKET_NO_RAM, error case for SOCKET_TX_DONE
            break;
    }
}
Beispiel #20
0
bool NanostackSocket::attach(int8_t temp_socket)
{
    nanostack_assert_locked();
    if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) {
        MBED_ASSERT(false);
        return false;
    }
    if (socket_tbl[temp_socket] != NULL) {
        MBED_ASSERT(false);
        return false;
    }
    socket_id = temp_socket;
    socket_tbl[socket_id] = this;
    return true;
}
NanostackSocket::~NanostackSocket()
{
    nanostack_assert_locked();

    if (mode != SOCKET_MODE_CLOSED) {
        close();
    }
    if (socket_id >= 0) {
        int ret = socket_free(socket_id);
        MBED_ASSERT(0 == ret);
        MBED_ASSERT(socket_tbl[socket_id] == this);
        socket_id = -1;
        data_free_all();
    }

}
Beispiel #22
0
int NanostackSocket::accept(NanostackSocket *accepted_socket, ns_address_t *addr)
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_LISTENING == mode && SOCKET_MODE_UNOPENED == accepted_socket->mode);

    int temp_socket = socket_accept(socket_id, addr, socket_callback);
    if (temp_socket < 0) {
        tr_error("NanostackSocket::accept() failed");
        return temp_socket;
    }
    if (!accepted_socket->attach(temp_socket)) {
        return -1;
    }
    accepted_socket->mode = SOCKET_MODE_STREAM;
    return temp_socket;
}
void NanostackSocket::close()
{
    nanostack_assert_locked();
    MBED_ASSERT(mode != SOCKET_MODE_CLOSED);

    if (socket_id >= 0) {
        int ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL));
        MBED_ASSERT(0 == ret);
    } else {
        MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);
    }

    data_free_all();

    mode = SOCKET_MODE_CLOSED;
    signal_event();
}
Beispiel #24
0
void NanostackSocket::event_tx_fail(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();

    switch (mode) {
        case SOCKET_MODE_CONNECTING:
        case SOCKET_MODE_STREAM:
            // TX_FAIL is fatal for stream sockets
            close();
            break;
        case SOCKET_MODE_DATAGRAM:
            // TX_FAIL is non-fatal for datagram sockets
            break;
        default:
            MBED_ASSERT(false);
            break;
    }
}
Beispiel #25
0
void NanostackSocket::close()
{
    nanostack_assert_locked();
    MBED_ASSERT(mode != SOCKET_MODE_CLOSED);

    if (socket_id >= 0) {
        nsapi_error_t ret = socket_close(socket_id);
        MBED_ASSERT(0 == ret);
        MBED_ASSERT(socket_tbl[socket_id] == this);
        socket_tbl[socket_id] = NULL;
        socket_id = -1;
    } else {
        MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);
    }

    mode = SOCKET_MODE_CLOSED;
    signal_event();
}
void NanostackSocket::data_attach(NanostackBuffer *data_buf)
{
    nanostack_assert_locked();
    MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) ||
                (SOCKET_MODE_STREAM == mode));

    // Add to linked list
    tr_debug("data_attach socket=%p", this);
    if (NULL == rxBufChain) {
        rxBufChain = data_buf;
    } else {
        NanostackBuffer *buf_tmp = rxBufChain;
        while (NULL != buf_tmp->next) {
            buf_tmp = buf_tmp->next;
        }
        buf_tmp->next = data_buf;
    }
    signal_event();
}
int MeshInterfaceNanostack::actual_connect()
{
    nanostack_assert_locked();

    mesh_error_t status = mesh_api->connect();
    if (status != MESH_ERROR_NONE) {
        nanostack_unlock();
        return map_mesh_error(status);
    }

    // Release mutex before blocking
    nanostack_unlock();

    int32_t count = connect_semaphore.wait(30000);

    nanostack_lock();

    if (count <= 0) {
        return NSAPI_ERROR_DHCP_FAILURE; // sort of...
    }
    return 0;
}
Beispiel #28
0
bool NanostackSocket::open(void)
{
    nanostack_assert_locked();
    MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);

    int temp_socket = socket_open(proto, 0, socket_callback);

    if (temp_socket < 0) {
        tr_error("NanostackSocket::open() failed");
        return false;
    }

    if (proto == SOCKET_TCP) {
        /* Receive and send buffers enabled by default */
        mode = SOCKET_MODE_OPENED;
    } else {
        static const int32_t rcvbuf_size = 2048;
        socket_setsockopt(temp_socket, SOCKET_SOL_SOCKET, SOCKET_SO_RCVBUF, &rcvbuf_size, sizeof rcvbuf_size);
        mode = SOCKET_MODE_DATAGRAM;
    }

    return attach(temp_socket);
}
Beispiel #29
0
void NanostackSocket::event_incoming_connection(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT(mode == SOCKET_MODE_LISTENING);
    signal_event();
}
Beispiel #30
0
void NanostackSocket::event_connect_fail(socket_callback_t *sock_cb)
{
    nanostack_assert_locked();
    MBED_ASSERT(mode == SOCKET_MODE_CONNECTING);
    close();
}