Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp@0:f269e3021894, 2016-10-23 (annotated)
- Committer:
- elessair
- Date:
- Sun Oct 23 15:10:02 2016 +0000
- Revision:
- 0:f269e3021894
Initial commit
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| elessair | 0:f269e3021894 | 1 | /* Nanostack implementation of NetworkSocketAPI |
| elessair | 0:f269e3021894 | 2 | * Copyright (c) 2016 ARM Limited |
| elessair | 0:f269e3021894 | 3 | * |
| elessair | 0:f269e3021894 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| elessair | 0:f269e3021894 | 5 | * you may not use this file except in compliance with the License. |
| elessair | 0:f269e3021894 | 6 | * You may obtain a copy of the License at |
| elessair | 0:f269e3021894 | 7 | * |
| elessair | 0:f269e3021894 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| elessair | 0:f269e3021894 | 9 | * |
| elessair | 0:f269e3021894 | 10 | * Unless required by applicable law or agreed to in writing, software |
| elessair | 0:f269e3021894 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| elessair | 0:f269e3021894 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| elessair | 0:f269e3021894 | 13 | * See the License for the specific language governing permissions and |
| elessair | 0:f269e3021894 | 14 | * limitations under the License. |
| elessair | 0:f269e3021894 | 15 | */ |
| elessair | 0:f269e3021894 | 16 | |
| elessair | 0:f269e3021894 | 17 | #include "mbed.h" |
| elessair | 0:f269e3021894 | 18 | #include "rtos.h" |
| elessair | 0:f269e3021894 | 19 | #include "NanostackInterface.h" |
| elessair | 0:f269e3021894 | 20 | |
| elessair | 0:f269e3021894 | 21 | #include "ns_address.h" |
| elessair | 0:f269e3021894 | 22 | #include "nsdynmemLIB.h" |
| elessair | 0:f269e3021894 | 23 | #include "eventOS_scheduler.h" |
| elessair | 0:f269e3021894 | 24 | #include "randLIB.h" |
| elessair | 0:f269e3021894 | 25 | |
| elessair | 0:f269e3021894 | 26 | #include "mbed-mesh-api/MeshInterfaceFactory.h" |
| elessair | 0:f269e3021894 | 27 | |
| elessair | 0:f269e3021894 | 28 | #include "mesh_system.h" // from inside mbed-mesh-api |
| elessair | 0:f269e3021894 | 29 | #include "socket_api.h" |
| elessair | 0:f269e3021894 | 30 | #include "net_interface.h" |
| elessair | 0:f269e3021894 | 31 | #include "ip6string.h" |
| elessair | 0:f269e3021894 | 32 | // Uncomment to enable trace |
| elessair | 0:f269e3021894 | 33 | //#define HAVE_DEBUG |
| elessair | 0:f269e3021894 | 34 | #include "ns_trace.h" |
| elessair | 0:f269e3021894 | 35 | #define TRACE_GROUP "nsif" |
| elessair | 0:f269e3021894 | 36 | |
| elessair | 0:f269e3021894 | 37 | #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX |
| elessair | 0:f269e3021894 | 38 | #define NANOSTACK_SOCKET_UDP 17 // same as nanostack SOCKET_UDP |
| elessair | 0:f269e3021894 | 39 | #define NANOSTACK_SOCKET_TCP 6 // same as nanostack SOCKET_TCP |
| elessair | 0:f269e3021894 | 40 | |
| elessair | 0:f269e3021894 | 41 | #define MALLOC ns_dyn_mem_alloc |
| elessair | 0:f269e3021894 | 42 | #define FREE ns_dyn_mem_free |
| elessair | 0:f269e3021894 | 43 | |
| elessair | 0:f269e3021894 | 44 | #define nanostack_lock() eventOS_scheduler_mutex_wait() |
| elessair | 0:f269e3021894 | 45 | #define nanostack_unlock() eventOS_scheduler_mutex_release() |
| elessair | 0:f269e3021894 | 46 | #define nanostack_assert_locked() //MBED_ASSERT(eventOS_scheduler_mutex_is_owner()) |
| elessair | 0:f269e3021894 | 47 | |
| elessair | 0:f269e3021894 | 48 | enum socket_mode_t { |
| elessair | 0:f269e3021894 | 49 | SOCKET_MODE_UNOPENED, // No socket ID |
| elessair | 0:f269e3021894 | 50 | SOCKET_MODE_OPENED, // Socket ID but no assigned use yet |
| elessair | 0:f269e3021894 | 51 | SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet |
| elessair | 0:f269e3021894 | 52 | SOCKET_MODE_DATAGRAM, // Socket is bound to a port and listening for datagrams |
| elessair | 0:f269e3021894 | 53 | SOCKET_MODE_STREAM, // Socket has an open stream |
| elessair | 0:f269e3021894 | 54 | SOCKET_MODE_CLOSED, // Socket is closed and resources are freed |
| elessair | 0:f269e3021894 | 55 | }; |
| elessair | 0:f269e3021894 | 56 | |
| elessair | 0:f269e3021894 | 57 | class NanostackBuffer { |
| elessair | 0:f269e3021894 | 58 | public: |
| elessair | 0:f269e3021894 | 59 | NanostackBuffer *next; /*<! next buffer */ |
| elessair | 0:f269e3021894 | 60 | ns_address_t ns_address; /*<! address where data is received */ |
| elessair | 0:f269e3021894 | 61 | uint16_t length; /*<! data length in this buffer */ |
| elessair | 0:f269e3021894 | 62 | uint8_t payload[1]; /*<! Trailing buffer data */ |
| elessair | 0:f269e3021894 | 63 | }; |
| elessair | 0:f269e3021894 | 64 | |
| elessair | 0:f269e3021894 | 65 | class NanostackSocket { |
| elessair | 0:f269e3021894 | 66 | public: |
| elessair | 0:f269e3021894 | 67 | static void socket_callback(void *cb); |
| elessair | 0:f269e3021894 | 68 | static void* operator new(std::size_t sz); |
| elessair | 0:f269e3021894 | 69 | static void operator delete(void* ptr); |
| elessair | 0:f269e3021894 | 70 | |
| elessair | 0:f269e3021894 | 71 | NanostackSocket(int8_t protocol); |
| elessair | 0:f269e3021894 | 72 | ~NanostackSocket(void); |
| elessair | 0:f269e3021894 | 73 | bool open(void); |
| elessair | 0:f269e3021894 | 74 | void close(void); |
| elessair | 0:f269e3021894 | 75 | bool closed(void) {return SOCKET_MODE_CLOSED == mode;} |
| elessair | 0:f269e3021894 | 76 | bool is_bound(void); |
| elessair | 0:f269e3021894 | 77 | void set_bound(void); |
| elessair | 0:f269e3021894 | 78 | bool is_connecting(void); |
| elessair | 0:f269e3021894 | 79 | void set_connecting(ns_address_t *addr); |
| elessair | 0:f269e3021894 | 80 | void set_connected(void); |
| elessair | 0:f269e3021894 | 81 | |
| elessair | 0:f269e3021894 | 82 | // Socket events from nanostack |
| elessair | 0:f269e3021894 | 83 | void event_data(socket_callback_t *sock_cb); |
| elessair | 0:f269e3021894 | 84 | void event_bind_done(socket_callback_t *sock_cb); |
| elessair | 0:f269e3021894 | 85 | void event_connnect_closed(socket_callback_t *sock_cb); |
| elessair | 0:f269e3021894 | 86 | void event_tx_done(socket_callback_t *sock_cb); |
| elessair | 0:f269e3021894 | 87 | |
| elessair | 0:f269e3021894 | 88 | // Run callback to signal the next layer of the NSAPI |
| elessair | 0:f269e3021894 | 89 | void signal_event(void); |
| elessair | 0:f269e3021894 | 90 | |
| elessair | 0:f269e3021894 | 91 | // Add or remove a socket to the listening socket |
| elessair | 0:f269e3021894 | 92 | void accept_list_add(NanostackSocket *socket); |
| elessair | 0:f269e3021894 | 93 | NanostackSocket * accept_list_remove(void); |
| elessair | 0:f269e3021894 | 94 | |
| elessair | 0:f269e3021894 | 95 | bool data_available(void); |
| elessair | 0:f269e3021894 | 96 | size_t data_copy_and_free(void *dest, size_t len, SocketAddress *address, bool stream); |
| elessair | 0:f269e3021894 | 97 | void data_free_all(void); |
| elessair | 0:f269e3021894 | 98 | void data_attach(NanostackBuffer *data_buf); |
| elessair | 0:f269e3021894 | 99 | |
| elessair | 0:f269e3021894 | 100 | void (*callback)(void *); |
| elessair | 0:f269e3021894 | 101 | void *callback_data; |
| elessair | 0:f269e3021894 | 102 | int8_t socket_id; /*!< allocated socket ID */ |
| elessair | 0:f269e3021894 | 103 | int8_t proto; /*!< UDP or TCP */ |
| elessair | 0:f269e3021894 | 104 | bool addr_valid; |
| elessair | 0:f269e3021894 | 105 | ns_address_t ns_address; |
| elessair | 0:f269e3021894 | 106 | private: |
| elessair | 0:f269e3021894 | 107 | NanostackBuffer *rxBufChain; /*!< Receive buffers */ |
| elessair | 0:f269e3021894 | 108 | socket_mode_t mode; |
| elessair | 0:f269e3021894 | 109 | }; |
| elessair | 0:f269e3021894 | 110 | |
| elessair | 0:f269e3021894 | 111 | static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; |
| elessair | 0:f269e3021894 | 112 | |
| elessair | 0:f269e3021894 | 113 | static int map_mesh_error(mesh_error_t err) |
| elessair | 0:f269e3021894 | 114 | { |
| elessair | 0:f269e3021894 | 115 | switch (err) { |
| elessair | 0:f269e3021894 | 116 | case MESH_ERROR_NONE: return 0; |
| elessair | 0:f269e3021894 | 117 | case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY; |
| elessair | 0:f269e3021894 | 118 | case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 119 | case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 120 | default: return NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 121 | } |
| elessair | 0:f269e3021894 | 122 | } |
| elessair | 0:f269e3021894 | 123 | |
| elessair | 0:f269e3021894 | 124 | static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, |
| elessair | 0:f269e3021894 | 125 | const SocketAddress *s_addr) |
| elessair | 0:f269e3021894 | 126 | { |
| elessair | 0:f269e3021894 | 127 | ns_addr->type = ADDRESS_IPV6; |
| elessair | 0:f269e3021894 | 128 | ns_addr->identifier = s_addr->get_port(); |
| elessair | 0:f269e3021894 | 129 | const char *str = s_addr->get_ip_address(); |
| elessair | 0:f269e3021894 | 130 | stoip6(str, strlen(str), ns_addr->address); |
| elessair | 0:f269e3021894 | 131 | } |
| elessair | 0:f269e3021894 | 132 | |
| elessair | 0:f269e3021894 | 133 | static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) |
| elessair | 0:f269e3021894 | 134 | { |
| elessair | 0:f269e3021894 | 135 | char str[40]; |
| elessair | 0:f269e3021894 | 136 | ip6tos(ns_addr->address, str); |
| elessair | 0:f269e3021894 | 137 | s_addr->set_port(ns_addr->identifier); |
| elessair | 0:f269e3021894 | 138 | s_addr->set_ip_address(str); |
| elessair | 0:f269e3021894 | 139 | } |
| elessair | 0:f269e3021894 | 140 | |
| elessair | 0:f269e3021894 | 141 | void* NanostackSocket::operator new(std::size_t sz) { |
| elessair | 0:f269e3021894 | 142 | return MALLOC(sz); |
| elessair | 0:f269e3021894 | 143 | } |
| elessair | 0:f269e3021894 | 144 | void NanostackSocket::operator delete(void* ptr) { |
| elessair | 0:f269e3021894 | 145 | FREE(ptr); |
| elessair | 0:f269e3021894 | 146 | } |
| elessair | 0:f269e3021894 | 147 | |
| elessair | 0:f269e3021894 | 148 | NanostackSocket::NanostackSocket(int8_t protocol) |
| elessair | 0:f269e3021894 | 149 | { |
| elessair | 0:f269e3021894 | 150 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 151 | |
| elessair | 0:f269e3021894 | 152 | callback = NULL; |
| elessair | 0:f269e3021894 | 153 | callback_data = NULL; |
| elessair | 0:f269e3021894 | 154 | socket_id = -1; |
| elessair | 0:f269e3021894 | 155 | rxBufChain = NULL; |
| elessair | 0:f269e3021894 | 156 | proto = protocol; |
| elessair | 0:f269e3021894 | 157 | addr_valid = false; |
| elessair | 0:f269e3021894 | 158 | memset(&ns_address, 0, sizeof(ns_address)); |
| elessair | 0:f269e3021894 | 159 | mode = SOCKET_MODE_UNOPENED; |
| elessair | 0:f269e3021894 | 160 | } |
| elessair | 0:f269e3021894 | 161 | |
| elessair | 0:f269e3021894 | 162 | NanostackSocket::~NanostackSocket() |
| elessair | 0:f269e3021894 | 163 | { |
| elessair | 0:f269e3021894 | 164 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 165 | |
| elessair | 0:f269e3021894 | 166 | if (mode != SOCKET_MODE_CLOSED) { |
| elessair | 0:f269e3021894 | 167 | close(); |
| elessair | 0:f269e3021894 | 168 | } |
| elessair | 0:f269e3021894 | 169 | if (socket_id >= 0) { |
| elessair | 0:f269e3021894 | 170 | int ret = socket_free(socket_id); |
| elessair | 0:f269e3021894 | 171 | MBED_ASSERT(0 == ret); |
| elessair | 0:f269e3021894 | 172 | MBED_ASSERT(socket_tbl[socket_id] == this); |
| elessair | 0:f269e3021894 | 173 | socket_tbl[socket_id] = NULL; |
| elessair | 0:f269e3021894 | 174 | socket_id = -1; |
| elessair | 0:f269e3021894 | 175 | data_free_all(); |
| elessair | 0:f269e3021894 | 176 | } |
| elessair | 0:f269e3021894 | 177 | |
| elessair | 0:f269e3021894 | 178 | } |
| elessair | 0:f269e3021894 | 179 | |
| elessair | 0:f269e3021894 | 180 | bool NanostackSocket::open(void) |
| elessair | 0:f269e3021894 | 181 | { |
| elessair | 0:f269e3021894 | 182 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 183 | MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); |
| elessair | 0:f269e3021894 | 184 | |
| elessair | 0:f269e3021894 | 185 | int temp_socket = socket_open(proto, 0, socket_callback); |
| elessair | 0:f269e3021894 | 186 | |
| elessair | 0:f269e3021894 | 187 | if (temp_socket < 0) { |
| elessair | 0:f269e3021894 | 188 | tr_error("NanostackSocket::open() failed"); |
| elessair | 0:f269e3021894 | 189 | return false; |
| elessair | 0:f269e3021894 | 190 | } |
| elessair | 0:f269e3021894 | 191 | if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) { |
| elessair | 0:f269e3021894 | 192 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 193 | return false; |
| elessair | 0:f269e3021894 | 194 | } |
| elessair | 0:f269e3021894 | 195 | if (socket_tbl[temp_socket] != NULL) { |
| elessair | 0:f269e3021894 | 196 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 197 | return false; |
| elessair | 0:f269e3021894 | 198 | } |
| elessair | 0:f269e3021894 | 199 | socket_id = temp_socket; |
| elessair | 0:f269e3021894 | 200 | socket_tbl[socket_id] = this; |
| elessair | 0:f269e3021894 | 201 | mode = SOCKET_MODE_OPENED; |
| elessair | 0:f269e3021894 | 202 | return true; |
| elessair | 0:f269e3021894 | 203 | |
| elessair | 0:f269e3021894 | 204 | } |
| elessair | 0:f269e3021894 | 205 | |
| elessair | 0:f269e3021894 | 206 | void NanostackSocket::close() |
| elessair | 0:f269e3021894 | 207 | { |
| elessair | 0:f269e3021894 | 208 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 209 | MBED_ASSERT(mode != SOCKET_MODE_CLOSED); |
| elessair | 0:f269e3021894 | 210 | |
| elessair | 0:f269e3021894 | 211 | if (socket_id >= 0) { |
| elessair | 0:f269e3021894 | 212 | int ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL)); |
| elessair | 0:f269e3021894 | 213 | MBED_ASSERT(0 == ret); |
| elessair | 0:f269e3021894 | 214 | } else { |
| elessair | 0:f269e3021894 | 215 | MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); |
| elessair | 0:f269e3021894 | 216 | } |
| elessair | 0:f269e3021894 | 217 | |
| elessair | 0:f269e3021894 | 218 | data_free_all(); |
| elessair | 0:f269e3021894 | 219 | |
| elessair | 0:f269e3021894 | 220 | mode = SOCKET_MODE_CLOSED; |
| elessair | 0:f269e3021894 | 221 | signal_event(); |
| elessair | 0:f269e3021894 | 222 | } |
| elessair | 0:f269e3021894 | 223 | |
| elessair | 0:f269e3021894 | 224 | bool NanostackSocket::is_bound() |
| elessair | 0:f269e3021894 | 225 | { |
| elessair | 0:f269e3021894 | 226 | return SOCKET_MODE_DATAGRAM == mode; |
| elessair | 0:f269e3021894 | 227 | } |
| elessair | 0:f269e3021894 | 228 | |
| elessair | 0:f269e3021894 | 229 | void NanostackSocket::set_bound() |
| elessair | 0:f269e3021894 | 230 | { |
| elessair | 0:f269e3021894 | 231 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 232 | MBED_ASSERT(SOCKET_MODE_OPENED == mode); |
| elessair | 0:f269e3021894 | 233 | if (SOCKET_UDP == proto) { |
| elessair | 0:f269e3021894 | 234 | mode = SOCKET_MODE_DATAGRAM; |
| elessair | 0:f269e3021894 | 235 | } |
| elessair | 0:f269e3021894 | 236 | } |
| elessair | 0:f269e3021894 | 237 | |
| elessair | 0:f269e3021894 | 238 | bool NanostackSocket::is_connecting() |
| elessair | 0:f269e3021894 | 239 | { |
| elessair | 0:f269e3021894 | 240 | return SOCKET_MODE_CONNECTING == mode; |
| elessair | 0:f269e3021894 | 241 | } |
| elessair | 0:f269e3021894 | 242 | |
| elessair | 0:f269e3021894 | 243 | void NanostackSocket::set_connecting(ns_address_t *addr) |
| elessair | 0:f269e3021894 | 244 | { |
| elessair | 0:f269e3021894 | 245 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 246 | MBED_ASSERT(SOCKET_MODE_OPENED == mode); |
| elessair | 0:f269e3021894 | 247 | |
| elessair | 0:f269e3021894 | 248 | memcpy(&ns_address, addr, sizeof(ns_address_t)); |
| elessair | 0:f269e3021894 | 249 | mode = SOCKET_MODE_CONNECTING; |
| elessair | 0:f269e3021894 | 250 | } |
| elessair | 0:f269e3021894 | 251 | |
| elessair | 0:f269e3021894 | 252 | void NanostackSocket::set_connected() |
| elessair | 0:f269e3021894 | 253 | { |
| elessair | 0:f269e3021894 | 254 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 255 | MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); |
| elessair | 0:f269e3021894 | 256 | |
| elessair | 0:f269e3021894 | 257 | mode = SOCKET_MODE_STREAM; |
| elessair | 0:f269e3021894 | 258 | } |
| elessair | 0:f269e3021894 | 259 | |
| elessair | 0:f269e3021894 | 260 | void NanostackSocket::signal_event() |
| elessair | 0:f269e3021894 | 261 | { |
| elessair | 0:f269e3021894 | 262 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 263 | |
| elessair | 0:f269e3021894 | 264 | if (callback != NULL) { |
| elessair | 0:f269e3021894 | 265 | callback(callback_data); |
| elessair | 0:f269e3021894 | 266 | } |
| elessair | 0:f269e3021894 | 267 | } |
| elessair | 0:f269e3021894 | 268 | |
| elessair | 0:f269e3021894 | 269 | void NanostackSocket::socket_callback(void *cb) { |
| elessair | 0:f269e3021894 | 270 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 271 | |
| elessair | 0:f269e3021894 | 272 | socket_callback_t *sock_cb = (socket_callback_t *) cb; |
| elessair | 0:f269e3021894 | 273 | NanostackSocket *socket = socket_tbl[sock_cb->socket_id]; |
| elessair | 0:f269e3021894 | 274 | MBED_ASSERT(socket != NULL); |
| elessair | 0:f269e3021894 | 275 | |
| elessair | 0:f269e3021894 | 276 | tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d", |
| elessair | 0:f269e3021894 | 277 | sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len); |
| elessair | 0:f269e3021894 | 278 | |
| elessair | 0:f269e3021894 | 279 | switch (sock_cb->event_type) { |
| elessair | 0:f269e3021894 | 280 | case SOCKET_DATA: |
| elessair | 0:f269e3021894 | 281 | tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len); |
| elessair | 0:f269e3021894 | 282 | socket->event_data(sock_cb); |
| elessair | 0:f269e3021894 | 283 | break; |
| elessair | 0:f269e3021894 | 284 | case SOCKET_BIND_DONE: |
| elessair | 0:f269e3021894 | 285 | tr_debug("SOCKET_BIND_DONE"); |
| elessair | 0:f269e3021894 | 286 | socket->event_bind_done(sock_cb); |
| elessair | 0:f269e3021894 | 287 | break; |
| elessair | 0:f269e3021894 | 288 | case SOCKET_BIND_FAIL: // Not used in NS |
| elessair | 0:f269e3021894 | 289 | tr_debug("SOCKET_BIND_FAIL"); |
| elessair | 0:f269e3021894 | 290 | break; |
| elessair | 0:f269e3021894 | 291 | case SOCKET_BIND_AUTH_FAIL: // Not used in NS |
| elessair | 0:f269e3021894 | 292 | tr_debug("SOCKET_BIND_AUTH_FAIL"); |
| elessair | 0:f269e3021894 | 293 | break; |
| elessair | 0:f269e3021894 | 294 | case SOCKET_SERVER_CONNECT_TO_CLIENT: // Not used in NS |
| elessair | 0:f269e3021894 | 295 | tr_debug("SOCKET_SERVER_CONNECT_TO_CLIENT"); |
| elessair | 0:f269e3021894 | 296 | break; |
| elessair | 0:f269e3021894 | 297 | case SOCKET_TX_FAIL: |
| elessair | 0:f269e3021894 | 298 | tr_debug("SOCKET_TX_FAIL"); |
| elessair | 0:f269e3021894 | 299 | break; |
| elessair | 0:f269e3021894 | 300 | case SOCKET_CONNECT_CLOSED: |
| elessair | 0:f269e3021894 | 301 | tr_debug("SOCKET_CONNECT_CLOSED"); |
| elessair | 0:f269e3021894 | 302 | socket->event_connnect_closed(sock_cb); |
| elessair | 0:f269e3021894 | 303 | break; |
| elessair | 0:f269e3021894 | 304 | case SOCKET_CONNECT_FAIL_CLOSED: // Not used in NS |
| elessair | 0:f269e3021894 | 305 | tr_debug("SOCKET_CONNECT_FAIL_CLOSED"); |
| elessair | 0:f269e3021894 | 306 | break; |
| elessair | 0:f269e3021894 | 307 | case SOCKET_NO_ROUTE: |
| elessair | 0:f269e3021894 | 308 | tr_debug("SOCKET_NO_ROUTE"); |
| elessair | 0:f269e3021894 | 309 | break; |
| elessair | 0:f269e3021894 | 310 | case SOCKET_TX_DONE: |
| elessair | 0:f269e3021894 | 311 | tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); |
| elessair | 0:f269e3021894 | 312 | socket->event_tx_done(sock_cb); |
| elessair | 0:f269e3021894 | 313 | break; |
| elessair | 0:f269e3021894 | 314 | default: |
| elessair | 0:f269e3021894 | 315 | // SOCKET_NO_RAM, error case for SOCKET_TX_DONE |
| elessair | 0:f269e3021894 | 316 | break; |
| elessair | 0:f269e3021894 | 317 | } |
| elessair | 0:f269e3021894 | 318 | } |
| elessair | 0:f269e3021894 | 319 | |
| elessair | 0:f269e3021894 | 320 | |
| elessair | 0:f269e3021894 | 321 | bool NanostackSocket::data_available() |
| elessair | 0:f269e3021894 | 322 | { |
| elessair | 0:f269e3021894 | 323 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 324 | MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || |
| elessair | 0:f269e3021894 | 325 | (SOCKET_MODE_CONNECTING == mode) || |
| elessair | 0:f269e3021894 | 326 | (SOCKET_MODE_STREAM == mode)); |
| elessair | 0:f269e3021894 | 327 | |
| elessair | 0:f269e3021894 | 328 | return (NULL == rxBufChain) ? false : true; |
| elessair | 0:f269e3021894 | 329 | } |
| elessair | 0:f269e3021894 | 330 | |
| elessair | 0:f269e3021894 | 331 | size_t NanostackSocket::data_copy_and_free(void *dest, size_t len, |
| elessair | 0:f269e3021894 | 332 | SocketAddress *address, bool stream) |
| elessair | 0:f269e3021894 | 333 | { |
| elessair | 0:f269e3021894 | 334 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 335 | MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || |
| elessair | 0:f269e3021894 | 336 | (mode == SOCKET_MODE_STREAM)); |
| elessair | 0:f269e3021894 | 337 | |
| elessair | 0:f269e3021894 | 338 | NanostackBuffer *data_buf = rxBufChain; |
| elessair | 0:f269e3021894 | 339 | if (NULL == data_buf) { |
| elessair | 0:f269e3021894 | 340 | // No data |
| elessair | 0:f269e3021894 | 341 | return 0; |
| elessair | 0:f269e3021894 | 342 | } |
| elessair | 0:f269e3021894 | 343 | |
| elessair | 0:f269e3021894 | 344 | if (address) { |
| elessair | 0:f269e3021894 | 345 | convert_ns_addr_to_mbed(address, &data_buf->ns_address); |
| elessair | 0:f269e3021894 | 346 | } |
| elessair | 0:f269e3021894 | 347 | |
| elessair | 0:f269e3021894 | 348 | size_t copy_size = (len > data_buf->length) ? data_buf->length : len; |
| elessair | 0:f269e3021894 | 349 | memcpy(dest, data_buf->payload, copy_size); |
| elessair | 0:f269e3021894 | 350 | |
| elessair | 0:f269e3021894 | 351 | if (stream && (copy_size < data_buf->length)) { |
| elessair | 0:f269e3021894 | 352 | // Update the size in the buffer |
| elessair | 0:f269e3021894 | 353 | size_t new_buf_size = data_buf->length - copy_size; |
| elessair | 0:f269e3021894 | 354 | memmove(data_buf->payload, data_buf->payload + copy_size, new_buf_size); |
| elessair | 0:f269e3021894 | 355 | data_buf->length = new_buf_size; |
| elessair | 0:f269e3021894 | 356 | } else { |
| elessair | 0:f269e3021894 | 357 | // Entire packet used so free it |
| elessair | 0:f269e3021894 | 358 | rxBufChain = data_buf->next; |
| elessair | 0:f269e3021894 | 359 | FREE(data_buf); |
| elessair | 0:f269e3021894 | 360 | } |
| elessair | 0:f269e3021894 | 361 | |
| elessair | 0:f269e3021894 | 362 | return copy_size; |
| elessair | 0:f269e3021894 | 363 | } |
| elessair | 0:f269e3021894 | 364 | |
| elessair | 0:f269e3021894 | 365 | void NanostackSocket::data_free_all(void) |
| elessair | 0:f269e3021894 | 366 | { |
| elessair | 0:f269e3021894 | 367 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 368 | // No mode requirement |
| elessair | 0:f269e3021894 | 369 | |
| elessair | 0:f269e3021894 | 370 | NanostackBuffer *buffer = rxBufChain; |
| elessair | 0:f269e3021894 | 371 | rxBufChain = NULL; |
| elessair | 0:f269e3021894 | 372 | while (buffer != NULL) { |
| elessair | 0:f269e3021894 | 373 | NanostackBuffer *next_buffer = buffer->next; |
| elessair | 0:f269e3021894 | 374 | FREE(buffer); |
| elessair | 0:f269e3021894 | 375 | buffer = next_buffer; |
| elessair | 0:f269e3021894 | 376 | } |
| elessair | 0:f269e3021894 | 377 | } |
| elessair | 0:f269e3021894 | 378 | |
| elessair | 0:f269e3021894 | 379 | void NanostackSocket::data_attach(NanostackBuffer *data_buf) |
| elessair | 0:f269e3021894 | 380 | { |
| elessair | 0:f269e3021894 | 381 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 382 | MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || |
| elessair | 0:f269e3021894 | 383 | (SOCKET_MODE_STREAM == mode)); |
| elessair | 0:f269e3021894 | 384 | |
| elessair | 0:f269e3021894 | 385 | // Add to linked list |
| elessair | 0:f269e3021894 | 386 | tr_debug("data_attach socket=%p", this); |
| elessair | 0:f269e3021894 | 387 | if (NULL == rxBufChain) { |
| elessair | 0:f269e3021894 | 388 | rxBufChain = data_buf; |
| elessair | 0:f269e3021894 | 389 | } else { |
| elessair | 0:f269e3021894 | 390 | NanostackBuffer *buf_tmp = rxBufChain; |
| elessair | 0:f269e3021894 | 391 | while (NULL != buf_tmp->next) { |
| elessair | 0:f269e3021894 | 392 | buf_tmp = buf_tmp->next; |
| elessair | 0:f269e3021894 | 393 | } |
| elessair | 0:f269e3021894 | 394 | buf_tmp->next = data_buf; |
| elessair | 0:f269e3021894 | 395 | } |
| elessair | 0:f269e3021894 | 396 | signal_event(); |
| elessair | 0:f269e3021894 | 397 | } |
| elessair | 0:f269e3021894 | 398 | |
| elessair | 0:f269e3021894 | 399 | void NanostackSocket::event_data(socket_callback_t *sock_cb) |
| elessair | 0:f269e3021894 | 400 | { |
| elessair | 0:f269e3021894 | 401 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 402 | MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || |
| elessair | 0:f269e3021894 | 403 | (SOCKET_MODE_STREAM == mode)); |
| elessair | 0:f269e3021894 | 404 | |
| elessair | 0:f269e3021894 | 405 | // Allocate buffer |
| elessair | 0:f269e3021894 | 406 | NanostackBuffer *recv_buff = (NanostackBuffer *) MALLOC( |
| elessair | 0:f269e3021894 | 407 | sizeof(NanostackBuffer) + sock_cb->d_len); |
| elessair | 0:f269e3021894 | 408 | if (NULL == recv_buff) { |
| elessair | 0:f269e3021894 | 409 | tr_error("alloc failed!"); |
| elessair | 0:f269e3021894 | 410 | return; |
| elessair | 0:f269e3021894 | 411 | } |
| elessair | 0:f269e3021894 | 412 | recv_buff->next = NULL; |
| elessair | 0:f269e3021894 | 413 | |
| elessair | 0:f269e3021894 | 414 | // Write data to buffer |
| elessair | 0:f269e3021894 | 415 | int16_t length = socket_read(sock_cb->socket_id, |
| elessair | 0:f269e3021894 | 416 | &recv_buff->ns_address, recv_buff->payload, |
| elessair | 0:f269e3021894 | 417 | sock_cb->d_len); |
| elessair | 0:f269e3021894 | 418 | if (length < 0) { |
| elessair | 0:f269e3021894 | 419 | tr_error("socket_read failed!"); |
| elessair | 0:f269e3021894 | 420 | FREE(recv_buff); |
| elessair | 0:f269e3021894 | 421 | return; |
| elessair | 0:f269e3021894 | 422 | } |
| elessair | 0:f269e3021894 | 423 | recv_buff->length = length; |
| elessair | 0:f269e3021894 | 424 | |
| elessair | 0:f269e3021894 | 425 | data_attach(recv_buff); |
| elessair | 0:f269e3021894 | 426 | } |
| elessair | 0:f269e3021894 | 427 | |
| elessair | 0:f269e3021894 | 428 | void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) |
| elessair | 0:f269e3021894 | 429 | { |
| elessair | 0:f269e3021894 | 430 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 431 | MBED_ASSERT((SOCKET_MODE_STREAM == mode) || |
| elessair | 0:f269e3021894 | 432 | (SOCKET_MODE_DATAGRAM == mode)); |
| elessair | 0:f269e3021894 | 433 | |
| elessair | 0:f269e3021894 | 434 | signal_event(); |
| elessair | 0:f269e3021894 | 435 | } |
| elessair | 0:f269e3021894 | 436 | |
| elessair | 0:f269e3021894 | 437 | void NanostackSocket::event_bind_done(socket_callback_t *sock_cb) |
| elessair | 0:f269e3021894 | 438 | { |
| elessair | 0:f269e3021894 | 439 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 440 | MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); |
| elessair | 0:f269e3021894 | 441 | |
| elessair | 0:f269e3021894 | 442 | set_connected(); |
| elessair | 0:f269e3021894 | 443 | signal_event(); |
| elessair | 0:f269e3021894 | 444 | } |
| elessair | 0:f269e3021894 | 445 | |
| elessair | 0:f269e3021894 | 446 | void NanostackSocket::event_connnect_closed(socket_callback_t *sock_cb) |
| elessair | 0:f269e3021894 | 447 | { |
| elessair | 0:f269e3021894 | 448 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 449 | |
| elessair | 0:f269e3021894 | 450 | // Only TCP sockets can be closed by the remote end |
| elessair | 0:f269e3021894 | 451 | MBED_ASSERT((SOCKET_MODE_STREAM == mode) || |
| elessair | 0:f269e3021894 | 452 | (SOCKET_MODE_CONNECTING == mode)); |
| elessair | 0:f269e3021894 | 453 | close(); |
| elessair | 0:f269e3021894 | 454 | } |
| elessair | 0:f269e3021894 | 455 | |
| elessair | 0:f269e3021894 | 456 | MeshInterfaceNanostack::MeshInterfaceNanostack() |
| elessair | 0:f269e3021894 | 457 | : phy(NULL), mesh_api(NULL), rf_device_id(-1), eui64(), |
| elessair | 0:f269e3021894 | 458 | ip_addr_str(), mac_addr_str(), connect_semaphore(0) |
| elessair | 0:f269e3021894 | 459 | { |
| elessair | 0:f269e3021894 | 460 | // Nothing to do |
| elessair | 0:f269e3021894 | 461 | } |
| elessair | 0:f269e3021894 | 462 | |
| elessair | 0:f269e3021894 | 463 | MeshInterfaceNanostack::MeshInterfaceNanostack(NanostackRfPhy *phy) |
| elessair | 0:f269e3021894 | 464 | : phy(phy), mesh_api(NULL), rf_device_id(-1), connect_semaphore(0) |
| elessair | 0:f269e3021894 | 465 | { |
| elessair | 0:f269e3021894 | 466 | // Nothing to do |
| elessair | 0:f269e3021894 | 467 | } |
| elessair | 0:f269e3021894 | 468 | |
| elessair | 0:f269e3021894 | 469 | int MeshInterfaceNanostack::initialize(NanostackRfPhy *phy) |
| elessair | 0:f269e3021894 | 470 | { |
| elessair | 0:f269e3021894 | 471 | if (this->phy != NULL) { |
| elessair | 0:f269e3021894 | 472 | error("Phy already set"); |
| elessair | 0:f269e3021894 | 473 | } |
| elessair | 0:f269e3021894 | 474 | this->phy = phy; |
| elessair | 0:f269e3021894 | 475 | return 0; |
| elessair | 0:f269e3021894 | 476 | } |
| elessair | 0:f269e3021894 | 477 | |
| elessair | 0:f269e3021894 | 478 | void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t status) |
| elessair | 0:f269e3021894 | 479 | { |
| elessair | 0:f269e3021894 | 480 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 481 | |
| elessair | 0:f269e3021894 | 482 | if (status == MESH_CONNECTED) { |
| elessair | 0:f269e3021894 | 483 | connect_semaphore.release(); |
| elessair | 0:f269e3021894 | 484 | } |
| elessair | 0:f269e3021894 | 485 | |
| elessair | 0:f269e3021894 | 486 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 487 | } |
| elessair | 0:f269e3021894 | 488 | |
| elessair | 0:f269e3021894 | 489 | int MeshInterfaceNanostack::register_rf() |
| elessair | 0:f269e3021894 | 490 | { |
| elessair | 0:f269e3021894 | 491 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 492 | |
| elessair | 0:f269e3021894 | 493 | rf_device_id = phy->rf_register(); |
| elessair | 0:f269e3021894 | 494 | if (rf_device_id < 0) { |
| elessair | 0:f269e3021894 | 495 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 496 | return -1; |
| elessair | 0:f269e3021894 | 497 | } |
| elessair | 0:f269e3021894 | 498 | // Read mac address after registering the device. |
| elessair | 0:f269e3021894 | 499 | phy->get_mac_address(eui64); |
| elessair | 0:f269e3021894 | 500 | sprintf(mac_addr_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", eui64[0], eui64[1], eui64[2], eui64[3], eui64[4], eui64[5], eui64[6], eui64[7]); |
| elessair | 0:f269e3021894 | 501 | |
| elessair | 0:f269e3021894 | 502 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 503 | |
| elessair | 0:f269e3021894 | 504 | return 0; |
| elessair | 0:f269e3021894 | 505 | } |
| elessair | 0:f269e3021894 | 506 | |
| elessair | 0:f269e3021894 | 507 | int MeshInterfaceNanostack::actual_connect() |
| elessair | 0:f269e3021894 | 508 | { |
| elessair | 0:f269e3021894 | 509 | nanostack_assert_locked(); |
| elessair | 0:f269e3021894 | 510 | |
| elessair | 0:f269e3021894 | 511 | mesh_error_t status = mesh_api->connect(); |
| elessair | 0:f269e3021894 | 512 | if (status != MESH_ERROR_NONE) { |
| elessair | 0:f269e3021894 | 513 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 514 | return map_mesh_error(status); |
| elessair | 0:f269e3021894 | 515 | } |
| elessair | 0:f269e3021894 | 516 | |
| elessair | 0:f269e3021894 | 517 | // Release mutex before blocking |
| elessair | 0:f269e3021894 | 518 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 519 | |
| elessair | 0:f269e3021894 | 520 | int32_t count = connect_semaphore.wait(30000); |
| elessair | 0:f269e3021894 | 521 | |
| elessair | 0:f269e3021894 | 522 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 523 | |
| elessair | 0:f269e3021894 | 524 | if (count <= 0) { |
| elessair | 0:f269e3021894 | 525 | return NSAPI_ERROR_DHCP_FAILURE; // sort of... |
| elessair | 0:f269e3021894 | 526 | } |
| elessair | 0:f269e3021894 | 527 | return 0; |
| elessair | 0:f269e3021894 | 528 | } |
| elessair | 0:f269e3021894 | 529 | |
| elessair | 0:f269e3021894 | 530 | NetworkStack * MeshInterfaceNanostack::get_stack() |
| elessair | 0:f269e3021894 | 531 | { |
| elessair | 0:f269e3021894 | 532 | return NanostackInterface::get_stack(); |
| elessair | 0:f269e3021894 | 533 | } |
| elessair | 0:f269e3021894 | 534 | |
| elessair | 0:f269e3021894 | 535 | int MeshInterfaceNanostack::disconnect() |
| elessair | 0:f269e3021894 | 536 | { |
| elessair | 0:f269e3021894 | 537 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 538 | |
| elessair | 0:f269e3021894 | 539 | mesh_error_t status = mesh_api->disconnect(); |
| elessair | 0:f269e3021894 | 540 | |
| elessair | 0:f269e3021894 | 541 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 542 | |
| elessair | 0:f269e3021894 | 543 | return map_mesh_error(status); |
| elessair | 0:f269e3021894 | 544 | } |
| elessair | 0:f269e3021894 | 545 | |
| elessair | 0:f269e3021894 | 546 | const char *MeshInterfaceNanostack::get_ip_address() |
| elessair | 0:f269e3021894 | 547 | { |
| elessair | 0:f269e3021894 | 548 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 549 | |
| elessair | 0:f269e3021894 | 550 | const char *ret = NULL; |
| elessair | 0:f269e3021894 | 551 | if (mesh_api && mesh_api->getOwnIpAddress(ip_addr_str, sizeof ip_addr_str)) { |
| elessair | 0:f269e3021894 | 552 | ret = ip_addr_str; |
| elessair | 0:f269e3021894 | 553 | } |
| elessair | 0:f269e3021894 | 554 | |
| elessair | 0:f269e3021894 | 555 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 556 | |
| elessair | 0:f269e3021894 | 557 | return ret; |
| elessair | 0:f269e3021894 | 558 | } |
| elessair | 0:f269e3021894 | 559 | |
| elessair | 0:f269e3021894 | 560 | const char *MeshInterfaceNanostack::get_mac_address() |
| elessair | 0:f269e3021894 | 561 | { |
| elessair | 0:f269e3021894 | 562 | return mac_addr_str; |
| elessair | 0:f269e3021894 | 563 | } |
| elessair | 0:f269e3021894 | 564 | |
| elessair | 0:f269e3021894 | 565 | int ThreadInterface::connect() |
| elessair | 0:f269e3021894 | 566 | { |
| elessair | 0:f269e3021894 | 567 | // initialize mesh networking resources, memory, timers, etc... |
| elessair | 0:f269e3021894 | 568 | mesh_system_init(); |
| elessair | 0:f269e3021894 | 569 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 570 | |
| elessair | 0:f269e3021894 | 571 | mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_THREAD); |
| elessair | 0:f269e3021894 | 572 | if (!mesh_api) { |
| elessair | 0:f269e3021894 | 573 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 574 | return NSAPI_ERROR_NO_MEMORY; |
| elessair | 0:f269e3021894 | 575 | } |
| elessair | 0:f269e3021894 | 576 | if (register_rf() < 0) { |
| elessair | 0:f269e3021894 | 577 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 578 | return NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 579 | } |
| elessair | 0:f269e3021894 | 580 | |
| elessair | 0:f269e3021894 | 581 | // After the RF is up, we can seed the random from it. |
| elessair | 0:f269e3021894 | 582 | randLIB_seed_random(); |
| elessair | 0:f269e3021894 | 583 | |
| elessair | 0:f269e3021894 | 584 | mesh_error_t status = ((MeshThread *)mesh_api)->init(rf_device_id, AbstractMesh::mesh_network_handler_t(static_cast<MeshInterfaceNanostack *>(this), &ThreadInterface::mesh_network_handler), eui64, NULL); |
| elessair | 0:f269e3021894 | 585 | if (status != MESH_ERROR_NONE) { |
| elessair | 0:f269e3021894 | 586 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 587 | return map_mesh_error(status); |
| elessair | 0:f269e3021894 | 588 | } |
| elessair | 0:f269e3021894 | 589 | int ret = this->actual_connect(); |
| elessair | 0:f269e3021894 | 590 | |
| elessair | 0:f269e3021894 | 591 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 592 | |
| elessair | 0:f269e3021894 | 593 | return ret; |
| elessair | 0:f269e3021894 | 594 | } |
| elessair | 0:f269e3021894 | 595 | |
| elessair | 0:f269e3021894 | 596 | int LoWPANNDInterface::connect() |
| elessair | 0:f269e3021894 | 597 | { |
| elessair | 0:f269e3021894 | 598 | // initialize mesh networking resources, memory, timers, etc... |
| elessair | 0:f269e3021894 | 599 | mesh_system_init(); |
| elessair | 0:f269e3021894 | 600 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 601 | |
| elessair | 0:f269e3021894 | 602 | mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_6LOWPAN_ND); |
| elessair | 0:f269e3021894 | 603 | if (!mesh_api) { |
| elessair | 0:f269e3021894 | 604 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 605 | return NSAPI_ERROR_NO_MEMORY; |
| elessair | 0:f269e3021894 | 606 | } |
| elessair | 0:f269e3021894 | 607 | if (register_rf() < 0) { |
| elessair | 0:f269e3021894 | 608 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 609 | return NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 610 | } |
| elessair | 0:f269e3021894 | 611 | |
| elessair | 0:f269e3021894 | 612 | // After the RF is up, we can seed the random from it. |
| elessair | 0:f269e3021894 | 613 | randLIB_seed_random(); |
| elessair | 0:f269e3021894 | 614 | |
| elessair | 0:f269e3021894 | 615 | mesh_error_t status = ((Mesh6LoWPAN_ND *)mesh_api)->init(rf_device_id, AbstractMesh::mesh_network_handler_t(static_cast<MeshInterfaceNanostack *>(this), &LoWPANNDInterface::mesh_network_handler)); |
| elessair | 0:f269e3021894 | 616 | if (status != MESH_ERROR_NONE) { |
| elessair | 0:f269e3021894 | 617 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 618 | return map_mesh_error(status); |
| elessair | 0:f269e3021894 | 619 | } |
| elessair | 0:f269e3021894 | 620 | int ret = this->actual_connect(); |
| elessair | 0:f269e3021894 | 621 | |
| elessair | 0:f269e3021894 | 622 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 623 | |
| elessair | 0:f269e3021894 | 624 | return ret; |
| elessair | 0:f269e3021894 | 625 | } |
| elessair | 0:f269e3021894 | 626 | |
| elessair | 0:f269e3021894 | 627 | NanostackInterface * NanostackInterface::_ns_interface; |
| elessair | 0:f269e3021894 | 628 | |
| elessair | 0:f269e3021894 | 629 | NanostackInterface * NanostackInterface::get_stack() |
| elessair | 0:f269e3021894 | 630 | { |
| elessair | 0:f269e3021894 | 631 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 632 | |
| elessair | 0:f269e3021894 | 633 | if (NULL == _ns_interface) { |
| elessair | 0:f269e3021894 | 634 | _ns_interface = new NanostackInterface(); |
| elessair | 0:f269e3021894 | 635 | } |
| elessair | 0:f269e3021894 | 636 | |
| elessair | 0:f269e3021894 | 637 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 638 | |
| elessair | 0:f269e3021894 | 639 | return _ns_interface; |
| elessair | 0:f269e3021894 | 640 | } |
| elessair | 0:f269e3021894 | 641 | |
| elessair | 0:f269e3021894 | 642 | |
| elessair | 0:f269e3021894 | 643 | const char * NanostackInterface::get_ip_address() |
| elessair | 0:f269e3021894 | 644 | { |
| elessair | 0:f269e3021894 | 645 | // Unsupported |
| elessair | 0:f269e3021894 | 646 | return NULL; |
| elessair | 0:f269e3021894 | 647 | } |
| elessair | 0:f269e3021894 | 648 | |
| elessair | 0:f269e3021894 | 649 | int NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) |
| elessair | 0:f269e3021894 | 650 | { |
| elessair | 0:f269e3021894 | 651 | // Validate parameters |
| elessair | 0:f269e3021894 | 652 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 653 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 654 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 655 | } |
| elessair | 0:f269e3021894 | 656 | int8_t ns_proto; |
| elessair | 0:f269e3021894 | 657 | if (NSAPI_UDP == protocol) { |
| elessair | 0:f269e3021894 | 658 | ns_proto = SOCKET_UDP; |
| elessair | 0:f269e3021894 | 659 | } else if (NSAPI_TCP == protocol) { |
| elessair | 0:f269e3021894 | 660 | ns_proto = SOCKET_TCP; |
| elessair | 0:f269e3021894 | 661 | } else { |
| elessair | 0:f269e3021894 | 662 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 663 | return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 664 | } |
| elessair | 0:f269e3021894 | 665 | *handle = (void*)NULL; |
| elessair | 0:f269e3021894 | 666 | |
| elessair | 0:f269e3021894 | 667 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 668 | |
| elessair | 0:f269e3021894 | 669 | NanostackSocket * socket = new NanostackSocket(ns_proto); |
| elessair | 0:f269e3021894 | 670 | if (NULL == socket) { |
| elessair | 0:f269e3021894 | 671 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 672 | tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY); |
| elessair | 0:f269e3021894 | 673 | return NSAPI_ERROR_NO_MEMORY; |
| elessair | 0:f269e3021894 | 674 | } |
| elessair | 0:f269e3021894 | 675 | if (!socket->open()) { |
| elessair | 0:f269e3021894 | 676 | delete socket; |
| elessair | 0:f269e3021894 | 677 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 678 | tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR); |
| elessair | 0:f269e3021894 | 679 | return NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 680 | } |
| elessair | 0:f269e3021894 | 681 | *handle = (void*)socket; |
| elessair | 0:f269e3021894 | 682 | |
| elessair | 0:f269e3021894 | 683 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 684 | |
| elessair | 0:f269e3021894 | 685 | tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); |
| elessair | 0:f269e3021894 | 686 | |
| elessair | 0:f269e3021894 | 687 | return 0; |
| elessair | 0:f269e3021894 | 688 | } |
| elessair | 0:f269e3021894 | 689 | |
| elessair | 0:f269e3021894 | 690 | int NanostackInterface::socket_close(void *handle) |
| elessair | 0:f269e3021894 | 691 | { |
| elessair | 0:f269e3021894 | 692 | // Validate parameters |
| elessair | 0:f269e3021894 | 693 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 694 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 695 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 696 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 697 | } |
| elessair | 0:f269e3021894 | 698 | tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); |
| elessair | 0:f269e3021894 | 699 | |
| elessair | 0:f269e3021894 | 700 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 701 | |
| elessair | 0:f269e3021894 | 702 | delete socket; |
| elessair | 0:f269e3021894 | 703 | |
| elessair | 0:f269e3021894 | 704 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 705 | |
| elessair | 0:f269e3021894 | 706 | return 0; |
| elessair | 0:f269e3021894 | 707 | |
| elessair | 0:f269e3021894 | 708 | } |
| elessair | 0:f269e3021894 | 709 | |
| elessair | 0:f269e3021894 | 710 | int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned int size) |
| elessair | 0:f269e3021894 | 711 | { |
| elessair | 0:f269e3021894 | 712 | // Validate parameters |
| elessair | 0:f269e3021894 | 713 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 714 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 715 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 716 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 717 | } |
| elessair | 0:f269e3021894 | 718 | |
| elessair | 0:f269e3021894 | 719 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 720 | |
| elessair | 0:f269e3021894 | 721 | int ret; |
| elessair | 0:f269e3021894 | 722 | if (socket->closed()) { |
| elessair | 0:f269e3021894 | 723 | ret = NSAPI_ERROR_NO_CONNECTION; |
| elessair | 0:f269e3021894 | 724 | } else if (NANOSTACK_SOCKET_TCP == socket->proto) { |
| elessair | 0:f269e3021894 | 725 | tr_error("socket_sendto() not supported with SOCKET_STREAM!"); |
| elessair | 0:f269e3021894 | 726 | ret = NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 727 | } else { |
| elessair | 0:f269e3021894 | 728 | ns_address_t ns_address; |
| elessair | 0:f269e3021894 | 729 | convert_mbed_addr_to_ns(&ns_address, &address); |
| elessair | 0:f269e3021894 | 730 | if (!socket->is_bound()) { |
| elessair | 0:f269e3021894 | 731 | socket->set_bound(); |
| elessair | 0:f269e3021894 | 732 | } |
| elessair | 0:f269e3021894 | 733 | int8_t send_to_status = ::socket_sendto(socket->socket_id, &ns_address, |
| elessair | 0:f269e3021894 | 734 | (uint8_t *)data, size); |
| elessair | 0:f269e3021894 | 735 | /* |
| elessair | 0:f269e3021894 | 736 | * \return 0 on success. |
| elessair | 0:f269e3021894 | 737 | * \return -1 invalid socket id. |
| elessair | 0:f269e3021894 | 738 | * \return -2 Socket memory allocation fail. |
| elessair | 0:f269e3021894 | 739 | * \return -3 TCP state not established. |
| elessair | 0:f269e3021894 | 740 | * \return -4 Socket tx process busy. |
| elessair | 0:f269e3021894 | 741 | * \return -5 TLS authentication not ready. |
| elessair | 0:f269e3021894 | 742 | * \return -6 Packet too short. |
| elessair | 0:f269e3021894 | 743 | * */ |
| elessair | 0:f269e3021894 | 744 | if (-4 == send_to_status) { |
| elessair | 0:f269e3021894 | 745 | ret = NSAPI_ERROR_WOULD_BLOCK; |
| elessair | 0:f269e3021894 | 746 | } else if (0 != send_to_status) { |
| elessair | 0:f269e3021894 | 747 | tr_error("socket_sendto: error=%d", send_to_status); |
| elessair | 0:f269e3021894 | 748 | ret = NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 749 | } else { |
| elessair | 0:f269e3021894 | 750 | ret = size; |
| elessair | 0:f269e3021894 | 751 | } |
| elessair | 0:f269e3021894 | 752 | } |
| elessair | 0:f269e3021894 | 753 | |
| elessair | 0:f269e3021894 | 754 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 755 | |
| elessair | 0:f269e3021894 | 756 | tr_debug("socket_sendto(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 757 | |
| elessair | 0:f269e3021894 | 758 | return ret; |
| elessair | 0:f269e3021894 | 759 | } |
| elessair | 0:f269e3021894 | 760 | |
| elessair | 0:f269e3021894 | 761 | int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) |
| elessair | 0:f269e3021894 | 762 | { |
| elessair | 0:f269e3021894 | 763 | // Validate parameters |
| elessair | 0:f269e3021894 | 764 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 765 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 766 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 767 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 768 | } |
| elessair | 0:f269e3021894 | 769 | if (NULL == buffer) { |
| elessair | 0:f269e3021894 | 770 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 771 | return NSAPI_ERROR_PARAMETER; |
| elessair | 0:f269e3021894 | 772 | } |
| elessair | 0:f269e3021894 | 773 | if (0 == size) { |
| elessair | 0:f269e3021894 | 774 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 775 | return NSAPI_ERROR_PARAMETER; |
| elessair | 0:f269e3021894 | 776 | } |
| elessair | 0:f269e3021894 | 777 | |
| elessair | 0:f269e3021894 | 778 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 779 | |
| elessair | 0:f269e3021894 | 780 | int ret; |
| elessair | 0:f269e3021894 | 781 | if (socket->closed()) { |
| elessair | 0:f269e3021894 | 782 | ret = NSAPI_ERROR_NO_CONNECTION; |
| elessair | 0:f269e3021894 | 783 | } else if (NANOSTACK_SOCKET_TCP == socket->proto) { |
| elessair | 0:f269e3021894 | 784 | tr_error("recv_from() not supported with SOCKET_STREAM!"); |
| elessair | 0:f269e3021894 | 785 | ret = NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 786 | } else if (!socket->data_available()) { |
| elessair | 0:f269e3021894 | 787 | ret = NSAPI_ERROR_WOULD_BLOCK; |
| elessair | 0:f269e3021894 | 788 | } else { |
| elessair | 0:f269e3021894 | 789 | ret = socket->data_copy_and_free(buffer, size, address, false); |
| elessair | 0:f269e3021894 | 790 | } |
| elessair | 0:f269e3021894 | 791 | |
| elessair | 0:f269e3021894 | 792 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 793 | |
| elessair | 0:f269e3021894 | 794 | tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 795 | |
| elessair | 0:f269e3021894 | 796 | return ret; |
| elessair | 0:f269e3021894 | 797 | } |
| elessair | 0:f269e3021894 | 798 | |
| elessair | 0:f269e3021894 | 799 | int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) |
| elessair | 0:f269e3021894 | 800 | { |
| elessair | 0:f269e3021894 | 801 | // Validate parameters |
| elessair | 0:f269e3021894 | 802 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 803 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 804 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 805 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 806 | } |
| elessair | 0:f269e3021894 | 807 | |
| elessair | 0:f269e3021894 | 808 | |
| elessair | 0:f269e3021894 | 809 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 810 | |
| elessair | 0:f269e3021894 | 811 | ns_address_t ns_address; |
| elessair | 0:f269e3021894 | 812 | ns_address.type = ADDRESS_IPV6; |
| elessair | 0:f269e3021894 | 813 | memset(ns_address.address, 0, sizeof ns_address.address); |
| elessair | 0:f269e3021894 | 814 | ns_address.identifier = address.get_port(); |
| elessair | 0:f269e3021894 | 815 | int ret = NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 816 | if (0 == ::socket_bind(socket->socket_id, &ns_address)) { |
| elessair | 0:f269e3021894 | 817 | socket->set_bound(); |
| elessair | 0:f269e3021894 | 818 | ret = 0; |
| elessair | 0:f269e3021894 | 819 | } |
| elessair | 0:f269e3021894 | 820 | |
| elessair | 0:f269e3021894 | 821 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 822 | |
| elessair | 0:f269e3021894 | 823 | tr_debug("socket_bind(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 824 | |
| elessair | 0:f269e3021894 | 825 | return ret; |
| elessair | 0:f269e3021894 | 826 | } |
| elessair | 0:f269e3021894 | 827 | |
| elessair | 0:f269e3021894 | 828 | int NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) |
| elessair | 0:f269e3021894 | 829 | { |
| elessair | 0:f269e3021894 | 830 | return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 831 | } |
| elessair | 0:f269e3021894 | 832 | |
| elessair | 0:f269e3021894 | 833 | int NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) |
| elessair | 0:f269e3021894 | 834 | { |
| elessair | 0:f269e3021894 | 835 | return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 836 | } |
| elessair | 0:f269e3021894 | 837 | |
| elessair | 0:f269e3021894 | 838 | int NanostackInterface::socket_listen(void *handle, int backlog) |
| elessair | 0:f269e3021894 | 839 | { |
| elessair | 0:f269e3021894 | 840 | return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 841 | } |
| elessair | 0:f269e3021894 | 842 | |
| elessair | 0:f269e3021894 | 843 | int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) |
| elessair | 0:f269e3021894 | 844 | { |
| elessair | 0:f269e3021894 | 845 | // Validate parameters |
| elessair | 0:f269e3021894 | 846 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 847 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 848 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 849 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 850 | } |
| elessair | 0:f269e3021894 | 851 | |
| elessair | 0:f269e3021894 | 852 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 853 | |
| elessair | 0:f269e3021894 | 854 | int ret; |
| elessair | 0:f269e3021894 | 855 | ns_address_t ns_addr; |
| elessair | 0:f269e3021894 | 856 | int random_port = socket->is_bound() ? 0 : 1; |
| elessair | 0:f269e3021894 | 857 | convert_mbed_addr_to_ns(&ns_addr, &addr); |
| elessair | 0:f269e3021894 | 858 | if (0 == ::socket_connect(socket->socket_id, &ns_addr, random_port)) { |
| elessair | 0:f269e3021894 | 859 | socket->set_connecting(&ns_addr); |
| elessair | 0:f269e3021894 | 860 | ret = 0; |
| elessair | 0:f269e3021894 | 861 | } else { |
| elessair | 0:f269e3021894 | 862 | ret = NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 863 | } |
| elessair | 0:f269e3021894 | 864 | |
| elessair | 0:f269e3021894 | 865 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 866 | |
| elessair | 0:f269e3021894 | 867 | tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 868 | |
| elessair | 0:f269e3021894 | 869 | return ret; |
| elessair | 0:f269e3021894 | 870 | } |
| elessair | 0:f269e3021894 | 871 | |
| elessair | 0:f269e3021894 | 872 | int NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) |
| elessair | 0:f269e3021894 | 873 | { |
| elessair | 0:f269e3021894 | 874 | return NSAPI_ERROR_UNSUPPORTED; |
| elessair | 0:f269e3021894 | 875 | } |
| elessair | 0:f269e3021894 | 876 | |
| elessair | 0:f269e3021894 | 877 | int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) |
| elessair | 0:f269e3021894 | 878 | { |
| elessair | 0:f269e3021894 | 879 | // Validate parameters |
| elessair | 0:f269e3021894 | 880 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 881 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 882 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 883 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 884 | } |
| elessair | 0:f269e3021894 | 885 | |
| elessair | 0:f269e3021894 | 886 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 887 | |
| elessair | 0:f269e3021894 | 888 | int ret; |
| elessair | 0:f269e3021894 | 889 | if (socket->closed()) { |
| elessair | 0:f269e3021894 | 890 | ret = NSAPI_ERROR_NO_CONNECTION; |
| elessair | 0:f269e3021894 | 891 | } else if (socket->is_connecting()) { |
| elessair | 0:f269e3021894 | 892 | ret = NSAPI_ERROR_WOULD_BLOCK; |
| elessair | 0:f269e3021894 | 893 | } else { |
| elessair | 0:f269e3021894 | 894 | ret = ::socket_sendto(socket->socket_id, &socket->ns_address, (uint8_t*)p, size); |
| elessair | 0:f269e3021894 | 895 | /* |
| elessair | 0:f269e3021894 | 896 | * \return 0 on success. |
| elessair | 0:f269e3021894 | 897 | * \return -1 invalid socket id. |
| elessair | 0:f269e3021894 | 898 | * \return -2 Socket memory allocation fail. |
| elessair | 0:f269e3021894 | 899 | * \return -3 TCP state not established. |
| elessair | 0:f269e3021894 | 900 | * \return -4 Socket tx process busy. |
| elessair | 0:f269e3021894 | 901 | * \return -5 TLS authentication not ready. |
| elessair | 0:f269e3021894 | 902 | * \return -6 Packet too short. |
| elessair | 0:f269e3021894 | 903 | * */ |
| elessair | 0:f269e3021894 | 904 | if (-4 == ret) { |
| elessair | 0:f269e3021894 | 905 | ret = NSAPI_ERROR_WOULD_BLOCK; |
| elessair | 0:f269e3021894 | 906 | } else if (ret != 0) { |
| elessair | 0:f269e3021894 | 907 | tr_warning("socket_sendto ret %i, socket_id %i", ret, socket->socket_id); |
| elessair | 0:f269e3021894 | 908 | ret = NSAPI_ERROR_DEVICE_ERROR; |
| elessair | 0:f269e3021894 | 909 | } else { |
| elessair | 0:f269e3021894 | 910 | ret = size; |
| elessair | 0:f269e3021894 | 911 | } |
| elessair | 0:f269e3021894 | 912 | } |
| elessair | 0:f269e3021894 | 913 | |
| elessair | 0:f269e3021894 | 914 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 915 | |
| elessair | 0:f269e3021894 | 916 | tr_debug("socket_send(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 917 | |
| elessair | 0:f269e3021894 | 918 | return ret; |
| elessair | 0:f269e3021894 | 919 | } |
| elessair | 0:f269e3021894 | 920 | |
| elessair | 0:f269e3021894 | 921 | int NanostackInterface::socket_recv(void *handle, void *data, unsigned size) |
| elessair | 0:f269e3021894 | 922 | { |
| elessair | 0:f269e3021894 | 923 | // Validate parameters |
| elessair | 0:f269e3021894 | 924 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 925 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 926 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 927 | return NSAPI_ERROR_NO_SOCKET; |
| elessair | 0:f269e3021894 | 928 | } |
| elessair | 0:f269e3021894 | 929 | |
| elessair | 0:f269e3021894 | 930 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 931 | |
| elessair | 0:f269e3021894 | 932 | int ret; |
| elessair | 0:f269e3021894 | 933 | if (socket->closed()) { |
| elessair | 0:f269e3021894 | 934 | ret = NSAPI_ERROR_NO_CONNECTION; |
| elessair | 0:f269e3021894 | 935 | } else if (socket->data_available()) { |
| elessair | 0:f269e3021894 | 936 | ret = socket->data_copy_and_free(data, size, NULL, true); |
| elessair | 0:f269e3021894 | 937 | } else { |
| elessair | 0:f269e3021894 | 938 | ret = NSAPI_ERROR_WOULD_BLOCK; |
| elessair | 0:f269e3021894 | 939 | } |
| elessair | 0:f269e3021894 | 940 | |
| elessair | 0:f269e3021894 | 941 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 942 | |
| elessair | 0:f269e3021894 | 943 | tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); |
| elessair | 0:f269e3021894 | 944 | |
| elessair | 0:f269e3021894 | 945 | return ret; |
| elessair | 0:f269e3021894 | 946 | } |
| elessair | 0:f269e3021894 | 947 | |
| elessair | 0:f269e3021894 | 948 | void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) |
| elessair | 0:f269e3021894 | 949 | { |
| elessair | 0:f269e3021894 | 950 | // Validate parameters |
| elessair | 0:f269e3021894 | 951 | NanostackSocket * socket = static_cast<NanostackSocket *>(handle); |
| elessair | 0:f269e3021894 | 952 | if (NULL == handle) { |
| elessair | 0:f269e3021894 | 953 | MBED_ASSERT(false); |
| elessair | 0:f269e3021894 | 954 | return; |
| elessair | 0:f269e3021894 | 955 | } |
| elessair | 0:f269e3021894 | 956 | |
| elessair | 0:f269e3021894 | 957 | nanostack_lock(); |
| elessair | 0:f269e3021894 | 958 | |
| elessair | 0:f269e3021894 | 959 | socket->callback = callback; |
| elessair | 0:f269e3021894 | 960 | socket->callback_data = id; |
| elessair | 0:f269e3021894 | 961 | |
| elessair | 0:f269e3021894 | 962 | nanostack_unlock(); |
| elessair | 0:f269e3021894 | 963 | |
| elessair | 0:f269e3021894 | 964 | tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); |
| elessair | 0:f269e3021894 | 965 | } |
