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::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;
    }
}