PES4 / Mbed OS Queue_02
Committer:
demayer
Date:
Sat Mar 28 15:28:19 2020 +0000
Revision:
0:6bf0743ece18
IMU Thread with an event-queue running parallel to handle tasks like a 5 times blinking LED. Button with interrupt detected.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
demayer 0:6bf0743ece18 1 /* Nanostack implementation of NetworkSocketAPI
demayer 0:6bf0743ece18 2 * Copyright (c) 2016 ARM Limited
demayer 0:6bf0743ece18 3 *
demayer 0:6bf0743ece18 4 * Licensed under the Apache License, Version 2.0 (the "License");
demayer 0:6bf0743ece18 5 * you may not use this file except in compliance with the License.
demayer 0:6bf0743ece18 6 * You may obtain a copy of the License at
demayer 0:6bf0743ece18 7 *
demayer 0:6bf0743ece18 8 * http://www.apache.org/licenses/LICENSE-2.0
demayer 0:6bf0743ece18 9 *
demayer 0:6bf0743ece18 10 * Unless required by applicable law or agreed to in writing, software
demayer 0:6bf0743ece18 11 * distributed under the License is distributed on an "AS IS" BASIS,
demayer 0:6bf0743ece18 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
demayer 0:6bf0743ece18 13 * See the License for the specific language governing permissions and
demayer 0:6bf0743ece18 14 * limitations under the License.
demayer 0:6bf0743ece18 15 */
demayer 0:6bf0743ece18 16
demayer 0:6bf0743ece18 17 #include "mbed.h"
demayer 0:6bf0743ece18 18 #include "rtos.h"
demayer 0:6bf0743ece18 19 #include "NanostackInterface.h"
demayer 0:6bf0743ece18 20 #include "NanostackLockGuard.h"
demayer 0:6bf0743ece18 21
demayer 0:6bf0743ece18 22 #include "ns_address.h"
demayer 0:6bf0743ece18 23 #include "nsdynmemLIB.h"
demayer 0:6bf0743ece18 24 #include "eventOS_scheduler.h"
demayer 0:6bf0743ece18 25 #include "randLIB.h"
demayer 0:6bf0743ece18 26 #include "ip6string.h"
demayer 0:6bf0743ece18 27
demayer 0:6bf0743ece18 28 #include "mesh_system.h" // from inside mbed-mesh-api
demayer 0:6bf0743ece18 29 #include "socket_api.h"
demayer 0:6bf0743ece18 30 #include "net_interface.h"
demayer 0:6bf0743ece18 31
demayer 0:6bf0743ece18 32 // Uncomment to enable trace
demayer 0:6bf0743ece18 33 //#define HAVE_DEBUG
demayer 0:6bf0743ece18 34 #include "ns_trace.h"
demayer 0:6bf0743ece18 35 #define TRACE_GROUP "nsif"
demayer 0:6bf0743ece18 36
demayer 0:6bf0743ece18 37 #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX
demayer 0:6bf0743ece18 38
demayer 0:6bf0743ece18 39 #define MALLOC ns_dyn_mem_alloc
demayer 0:6bf0743ece18 40 #define FREE ns_dyn_mem_free
demayer 0:6bf0743ece18 41
demayer 0:6bf0743ece18 42 // Socket state progressions:
demayer 0:6bf0743ece18 43 // UDP: UNOPENED -> DATAGRAM
demayer 0:6bf0743ece18 44 // TCP client: UNOPENED -> OPENED -> CONNECTING -> STREAM -> CLOSED
demayer 0:6bf0743ece18 45 // TCP server: UNOPENED -> OPENED -> LISTENING
demayer 0:6bf0743ece18 46 // TCP accept: UNOPENED -> STREAM -> CLOSED
demayer 0:6bf0743ece18 47 enum socket_mode_t {
demayer 0:6bf0743ece18 48 SOCKET_MODE_UNOPENED, // No socket ID
demayer 0:6bf0743ece18 49 SOCKET_MODE_DATAGRAM, // Socket is datagram type
demayer 0:6bf0743ece18 50 SOCKET_MODE_OPENED, // Socket ID but no assigned use yet
demayer 0:6bf0743ece18 51 SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet
demayer 0:6bf0743ece18 52 SOCKET_MODE_STREAM, // Socket has an open stream
demayer 0:6bf0743ece18 53 SOCKET_MODE_CLOSED, // Socket is closed and resources are freed
demayer 0:6bf0743ece18 54 SOCKET_MODE_LISTENING, // Socket is listening for connections
demayer 0:6bf0743ece18 55 };
demayer 0:6bf0743ece18 56
demayer 0:6bf0743ece18 57
demayer 0:6bf0743ece18 58 class NanostackSocket {
demayer 0:6bf0743ece18 59 public:
demayer 0:6bf0743ece18 60 static void socket_callback(void *cb);
demayer 0:6bf0743ece18 61 static void* operator new(std::size_t sz);
demayer 0:6bf0743ece18 62 static void operator delete(void* ptr);
demayer 0:6bf0743ece18 63
demayer 0:6bf0743ece18 64 NanostackSocket(int8_t protocol);
demayer 0:6bf0743ece18 65 ~NanostackSocket(void);
demayer 0:6bf0743ece18 66 bool open(void);
demayer 0:6bf0743ece18 67 int accept(NanostackSocket *accepted_socket, ns_address_t *addr);
demayer 0:6bf0743ece18 68 void close(void);
demayer 0:6bf0743ece18 69 bool closed(void) {return SOCKET_MODE_CLOSED == mode;}
demayer 0:6bf0743ece18 70 bool is_connecting(void);
demayer 0:6bf0743ece18 71 void set_connecting(ns_address_t *addr);
demayer 0:6bf0743ece18 72 bool is_connected(void);
demayer 0:6bf0743ece18 73 void set_connected(void);
demayer 0:6bf0743ece18 74 bool is_listening(void);
demayer 0:6bf0743ece18 75 void set_listening(void);
demayer 0:6bf0743ece18 76
demayer 0:6bf0743ece18 77 // Socket events from nanostack
demayer 0:6bf0743ece18 78 void event_data(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 79 void event_connect_done(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 80 void event_connect_fail(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 81 void event_connect_closed(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 82 void event_connection_reset(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 83 void event_tx_done(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 84 void event_tx_fail(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 85 void event_incoming_connection(socket_callback_t *sock_cb);
demayer 0:6bf0743ece18 86
demayer 0:6bf0743ece18 87 // Run callback to signal the next layer of the NSAPI
demayer 0:6bf0743ece18 88 void signal_event(void);
demayer 0:6bf0743ece18 89
demayer 0:6bf0743ece18 90 void (*callback)(void *);
demayer 0:6bf0743ece18 91 void *callback_data;
demayer 0:6bf0743ece18 92 int8_t socket_id; /*!< allocated socket ID */
demayer 0:6bf0743ece18 93 int8_t proto; /*!< UDP or TCP */
demayer 0:6bf0743ece18 94 bool addr_valid;
demayer 0:6bf0743ece18 95 ns_address_t ns_address;
demayer 0:6bf0743ece18 96 private:
demayer 0:6bf0743ece18 97 bool attach(int8_t socket_id);
demayer 0:6bf0743ece18 98 socket_mode_t mode;
demayer 0:6bf0743ece18 99 };
demayer 0:6bf0743ece18 100
demayer 0:6bf0743ece18 101 static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX];
demayer 0:6bf0743ece18 102
demayer 0:6bf0743ece18 103 nsapi_error_t map_mesh_error(mesh_error_t err)
demayer 0:6bf0743ece18 104 {
demayer 0:6bf0743ece18 105 switch (err) {
demayer 0:6bf0743ece18 106 case MESH_ERROR_NONE: return 0;
demayer 0:6bf0743ece18 107 case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY;
demayer 0:6bf0743ece18 108 case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED;
demayer 0:6bf0743ece18 109 case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 110 default: return NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 111 }
demayer 0:6bf0743ece18 112 }
demayer 0:6bf0743ece18 113
demayer 0:6bf0743ece18 114 static void convert_mbed_addr_to_ns(ns_address_t *ns_addr,
demayer 0:6bf0743ece18 115 const SocketAddress *s_addr)
demayer 0:6bf0743ece18 116 {
demayer 0:6bf0743ece18 117 ns_addr->type = ADDRESS_IPV6;
demayer 0:6bf0743ece18 118 ns_addr->identifier = s_addr->get_port();
demayer 0:6bf0743ece18 119 memcpy(ns_addr->address, s_addr->get_ip_bytes(), 16);
demayer 0:6bf0743ece18 120 }
demayer 0:6bf0743ece18 121
demayer 0:6bf0743ece18 122 static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr)
demayer 0:6bf0743ece18 123 {
demayer 0:6bf0743ece18 124 s_addr->set_port(ns_addr->identifier);
demayer 0:6bf0743ece18 125 s_addr->set_ip_bytes(ns_addr->address, NSAPI_IPv6);
demayer 0:6bf0743ece18 126 }
demayer 0:6bf0743ece18 127
demayer 0:6bf0743ece18 128 void* NanostackSocket::operator new(std::size_t sz) {
demayer 0:6bf0743ece18 129 return MALLOC(sz);
demayer 0:6bf0743ece18 130 }
demayer 0:6bf0743ece18 131 void NanostackSocket::operator delete(void* ptr) {
demayer 0:6bf0743ece18 132 FREE(ptr);
demayer 0:6bf0743ece18 133 }
demayer 0:6bf0743ece18 134
demayer 0:6bf0743ece18 135 NanostackSocket::NanostackSocket(int8_t protocol)
demayer 0:6bf0743ece18 136 {
demayer 0:6bf0743ece18 137 nanostack_assert_locked();
demayer 0:6bf0743ece18 138
demayer 0:6bf0743ece18 139 callback = NULL;
demayer 0:6bf0743ece18 140 callback_data = NULL;
demayer 0:6bf0743ece18 141 socket_id = -1;
demayer 0:6bf0743ece18 142 proto = protocol;
demayer 0:6bf0743ece18 143 addr_valid = false;
demayer 0:6bf0743ece18 144 memset(&ns_address, 0, sizeof(ns_address));
demayer 0:6bf0743ece18 145 mode = SOCKET_MODE_UNOPENED;
demayer 0:6bf0743ece18 146 }
demayer 0:6bf0743ece18 147
demayer 0:6bf0743ece18 148 NanostackSocket::~NanostackSocket()
demayer 0:6bf0743ece18 149 {
demayer 0:6bf0743ece18 150 nanostack_assert_locked();
demayer 0:6bf0743ece18 151
demayer 0:6bf0743ece18 152 if (mode != SOCKET_MODE_CLOSED) {
demayer 0:6bf0743ece18 153 close();
demayer 0:6bf0743ece18 154 }
demayer 0:6bf0743ece18 155 }
demayer 0:6bf0743ece18 156
demayer 0:6bf0743ece18 157 bool NanostackSocket::open(void)
demayer 0:6bf0743ece18 158 {
demayer 0:6bf0743ece18 159 nanostack_assert_locked();
demayer 0:6bf0743ece18 160 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);
demayer 0:6bf0743ece18 161
demayer 0:6bf0743ece18 162 int temp_socket = socket_open(proto, 0, socket_callback);
demayer 0:6bf0743ece18 163
demayer 0:6bf0743ece18 164 if (temp_socket < 0) {
demayer 0:6bf0743ece18 165 tr_error("NanostackSocket::open() failed");
demayer 0:6bf0743ece18 166 return false;
demayer 0:6bf0743ece18 167 }
demayer 0:6bf0743ece18 168
demayer 0:6bf0743ece18 169 if (proto == SOCKET_TCP) {
demayer 0:6bf0743ece18 170 /* Receive and send buffers enabled by default */
demayer 0:6bf0743ece18 171 mode = SOCKET_MODE_OPENED;
demayer 0:6bf0743ece18 172 } else {
demayer 0:6bf0743ece18 173 static const int32_t rcvbuf_size = 2048;
demayer 0:6bf0743ece18 174 socket_setsockopt(temp_socket, SOCKET_SOL_SOCKET, SOCKET_SO_RCVBUF, &rcvbuf_size, sizeof rcvbuf_size);
demayer 0:6bf0743ece18 175 mode = SOCKET_MODE_DATAGRAM;
demayer 0:6bf0743ece18 176 }
demayer 0:6bf0743ece18 177
demayer 0:6bf0743ece18 178 return attach(temp_socket);
demayer 0:6bf0743ece18 179 }
demayer 0:6bf0743ece18 180
demayer 0:6bf0743ece18 181 int NanostackSocket::accept(NanostackSocket *accepted_socket, ns_address_t *addr)
demayer 0:6bf0743ece18 182 {
demayer 0:6bf0743ece18 183 nanostack_assert_locked();
demayer 0:6bf0743ece18 184 MBED_ASSERT(SOCKET_MODE_LISTENING == mode && SOCKET_MODE_UNOPENED == accepted_socket->mode);
demayer 0:6bf0743ece18 185
demayer 0:6bf0743ece18 186 int temp_socket = socket_accept(socket_id, addr, socket_callback);
demayer 0:6bf0743ece18 187 if (temp_socket < 0) {
demayer 0:6bf0743ece18 188 tr_error("NanostackSocket::accept() failed");
demayer 0:6bf0743ece18 189 return temp_socket;
demayer 0:6bf0743ece18 190 }
demayer 0:6bf0743ece18 191 if (!accepted_socket->attach(temp_socket)) {
demayer 0:6bf0743ece18 192 return -1;
demayer 0:6bf0743ece18 193 }
demayer 0:6bf0743ece18 194 accepted_socket->mode = SOCKET_MODE_STREAM;
demayer 0:6bf0743ece18 195 return temp_socket;
demayer 0:6bf0743ece18 196 }
demayer 0:6bf0743ece18 197
demayer 0:6bf0743ece18 198 bool NanostackSocket::attach(int8_t temp_socket)
demayer 0:6bf0743ece18 199 {
demayer 0:6bf0743ece18 200 nanostack_assert_locked();
demayer 0:6bf0743ece18 201 if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) {
demayer 0:6bf0743ece18 202 MBED_ASSERT(false);
demayer 0:6bf0743ece18 203 return false;
demayer 0:6bf0743ece18 204 }
demayer 0:6bf0743ece18 205 if (socket_tbl[temp_socket] != NULL) {
demayer 0:6bf0743ece18 206 MBED_ASSERT(false);
demayer 0:6bf0743ece18 207 return false;
demayer 0:6bf0743ece18 208 }
demayer 0:6bf0743ece18 209 socket_id = temp_socket;
demayer 0:6bf0743ece18 210 socket_tbl[socket_id] = this;
demayer 0:6bf0743ece18 211 return true;
demayer 0:6bf0743ece18 212 }
demayer 0:6bf0743ece18 213
demayer 0:6bf0743ece18 214 void NanostackSocket::close()
demayer 0:6bf0743ece18 215 {
demayer 0:6bf0743ece18 216 nanostack_assert_locked();
demayer 0:6bf0743ece18 217 MBED_ASSERT(mode != SOCKET_MODE_CLOSED);
demayer 0:6bf0743ece18 218
demayer 0:6bf0743ece18 219 if (socket_id >= 0) {
demayer 0:6bf0743ece18 220 nsapi_error_t ret = socket_close(socket_id);
demayer 0:6bf0743ece18 221 MBED_ASSERT(0 == ret);
demayer 0:6bf0743ece18 222 MBED_ASSERT(socket_tbl[socket_id] == this);
demayer 0:6bf0743ece18 223 socket_tbl[socket_id] = NULL;
demayer 0:6bf0743ece18 224 socket_id = -1;
demayer 0:6bf0743ece18 225 } else {
demayer 0:6bf0743ece18 226 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode);
demayer 0:6bf0743ece18 227 }
demayer 0:6bf0743ece18 228
demayer 0:6bf0743ece18 229 mode = SOCKET_MODE_CLOSED;
demayer 0:6bf0743ece18 230 signal_event();
demayer 0:6bf0743ece18 231 }
demayer 0:6bf0743ece18 232
demayer 0:6bf0743ece18 233 bool NanostackSocket::is_connecting()
demayer 0:6bf0743ece18 234 {
demayer 0:6bf0743ece18 235 return SOCKET_MODE_CONNECTING == mode;
demayer 0:6bf0743ece18 236 }
demayer 0:6bf0743ece18 237
demayer 0:6bf0743ece18 238 void NanostackSocket::set_connecting(ns_address_t *addr)
demayer 0:6bf0743ece18 239 {
demayer 0:6bf0743ece18 240 nanostack_assert_locked();
demayer 0:6bf0743ece18 241 MBED_ASSERT(SOCKET_MODE_OPENED == mode);
demayer 0:6bf0743ece18 242
demayer 0:6bf0743ece18 243 memcpy(&ns_address, addr, sizeof(ns_address_t));
demayer 0:6bf0743ece18 244 mode = SOCKET_MODE_CONNECTING;
demayer 0:6bf0743ece18 245 }
demayer 0:6bf0743ece18 246
demayer 0:6bf0743ece18 247 bool NanostackSocket::is_connected()
demayer 0:6bf0743ece18 248 {
demayer 0:6bf0743ece18 249 return SOCKET_MODE_STREAM == mode;
demayer 0:6bf0743ece18 250 }
demayer 0:6bf0743ece18 251
demayer 0:6bf0743ece18 252 void NanostackSocket::set_connected()
demayer 0:6bf0743ece18 253 {
demayer 0:6bf0743ece18 254 nanostack_assert_locked();
demayer 0:6bf0743ece18 255 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode);
demayer 0:6bf0743ece18 256
demayer 0:6bf0743ece18 257 mode = SOCKET_MODE_STREAM;
demayer 0:6bf0743ece18 258 }
demayer 0:6bf0743ece18 259
demayer 0:6bf0743ece18 260 bool NanostackSocket::is_listening()
demayer 0:6bf0743ece18 261 {
demayer 0:6bf0743ece18 262 return SOCKET_MODE_LISTENING == mode;
demayer 0:6bf0743ece18 263 }
demayer 0:6bf0743ece18 264
demayer 0:6bf0743ece18 265 void NanostackSocket::set_listening()
demayer 0:6bf0743ece18 266 {
demayer 0:6bf0743ece18 267 nanostack_assert_locked();
demayer 0:6bf0743ece18 268 MBED_ASSERT(SOCKET_MODE_OPENED == mode);
demayer 0:6bf0743ece18 269
demayer 0:6bf0743ece18 270 mode = SOCKET_MODE_LISTENING;
demayer 0:6bf0743ece18 271 }
demayer 0:6bf0743ece18 272
demayer 0:6bf0743ece18 273 void NanostackSocket::signal_event()
demayer 0:6bf0743ece18 274 {
demayer 0:6bf0743ece18 275 nanostack_assert_locked();
demayer 0:6bf0743ece18 276
demayer 0:6bf0743ece18 277 if (callback != NULL) {
demayer 0:6bf0743ece18 278 callback(callback_data);
demayer 0:6bf0743ece18 279 }
demayer 0:6bf0743ece18 280 }
demayer 0:6bf0743ece18 281
demayer 0:6bf0743ece18 282 void NanostackSocket::socket_callback(void *cb) {
demayer 0:6bf0743ece18 283 nanostack_assert_locked();
demayer 0:6bf0743ece18 284
demayer 0:6bf0743ece18 285 socket_callback_t *sock_cb = (socket_callback_t *) cb;
demayer 0:6bf0743ece18 286 NanostackSocket *socket = socket_tbl[sock_cb->socket_id];
demayer 0:6bf0743ece18 287 MBED_ASSERT(socket != NULL);
demayer 0:6bf0743ece18 288
demayer 0:6bf0743ece18 289 tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d",
demayer 0:6bf0743ece18 290 sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len);
demayer 0:6bf0743ece18 291
demayer 0:6bf0743ece18 292 switch (sock_cb->event_type) {
demayer 0:6bf0743ece18 293 case SOCKET_DATA:
demayer 0:6bf0743ece18 294 tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len);
demayer 0:6bf0743ece18 295 socket->event_data(sock_cb);
demayer 0:6bf0743ece18 296 break;
demayer 0:6bf0743ece18 297 case SOCKET_CONNECT_DONE:
demayer 0:6bf0743ece18 298 tr_debug("SOCKET_CONNECT_DONE");
demayer 0:6bf0743ece18 299 socket->event_connect_done(sock_cb);
demayer 0:6bf0743ece18 300 break;
demayer 0:6bf0743ece18 301 case SOCKET_CONNECT_FAIL:
demayer 0:6bf0743ece18 302 tr_debug("SOCKET_CONNECT_FAIL");
demayer 0:6bf0743ece18 303 socket->event_connect_fail(sock_cb);
demayer 0:6bf0743ece18 304 break;
demayer 0:6bf0743ece18 305 case SOCKET_CONNECT_AUTH_FAIL:
demayer 0:6bf0743ece18 306 tr_debug("SOCKET_CONNECT_AUTH_FAIL");
demayer 0:6bf0743ece18 307 break;
demayer 0:6bf0743ece18 308 case SOCKET_INCOMING_CONNECTION:
demayer 0:6bf0743ece18 309 tr_debug("SOCKET_INCOMING_CONNECTION");
demayer 0:6bf0743ece18 310 socket->event_incoming_connection(sock_cb);
demayer 0:6bf0743ece18 311 break;
demayer 0:6bf0743ece18 312 case SOCKET_TX_FAIL:
demayer 0:6bf0743ece18 313 tr_debug("SOCKET_TX_FAIL");
demayer 0:6bf0743ece18 314 socket->event_tx_fail(sock_cb);
demayer 0:6bf0743ece18 315 break;
demayer 0:6bf0743ece18 316 case SOCKET_CONNECT_CLOSED:
demayer 0:6bf0743ece18 317 tr_debug("SOCKET_CONNECT_CLOSED");
demayer 0:6bf0743ece18 318 socket->event_connect_closed(sock_cb);
demayer 0:6bf0743ece18 319 break;
demayer 0:6bf0743ece18 320 case SOCKET_CONNECTION_RESET:
demayer 0:6bf0743ece18 321 tr_debug("SOCKET_CONNECTION_RESET");
demayer 0:6bf0743ece18 322 socket->event_connection_reset(sock_cb);
demayer 0:6bf0743ece18 323 break;
demayer 0:6bf0743ece18 324 case SOCKET_NO_ROUTE:
demayer 0:6bf0743ece18 325 tr_debug("SOCKET_NO_ROUTE");
demayer 0:6bf0743ece18 326 socket->event_tx_fail(sock_cb);
demayer 0:6bf0743ece18 327 break;
demayer 0:6bf0743ece18 328 case SOCKET_TX_DONE:
demayer 0:6bf0743ece18 329 socket->event_tx_done(sock_cb);
demayer 0:6bf0743ece18 330 break;
demayer 0:6bf0743ece18 331 case SOCKET_NO_RAM:
demayer 0:6bf0743ece18 332 tr_debug("SOCKET_NO_RAM");
demayer 0:6bf0743ece18 333 socket->event_tx_fail(sock_cb);
demayer 0:6bf0743ece18 334 break;
demayer 0:6bf0743ece18 335 case SOCKET_CONNECTION_PROBLEM:
demayer 0:6bf0743ece18 336 tr_debug("SOCKET_CONNECTION_PROBLEM");
demayer 0:6bf0743ece18 337 break;
demayer 0:6bf0743ece18 338 default:
demayer 0:6bf0743ece18 339 break;
demayer 0:6bf0743ece18 340 }
demayer 0:6bf0743ece18 341 }
demayer 0:6bf0743ece18 342
demayer 0:6bf0743ece18 343
demayer 0:6bf0743ece18 344 void NanostackSocket::event_data(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 345 {
demayer 0:6bf0743ece18 346 nanostack_assert_locked();
demayer 0:6bf0743ece18 347 MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
demayer 0:6bf0743ece18 348 (SOCKET_MODE_DATAGRAM == mode));
demayer 0:6bf0743ece18 349
demayer 0:6bf0743ece18 350 signal_event();
demayer 0:6bf0743ece18 351 }
demayer 0:6bf0743ece18 352
demayer 0:6bf0743ece18 353 void NanostackSocket::event_tx_done(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 354 {
demayer 0:6bf0743ece18 355 nanostack_assert_locked();
demayer 0:6bf0743ece18 356 MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
demayer 0:6bf0743ece18 357 (SOCKET_MODE_DATAGRAM == mode));
demayer 0:6bf0743ece18 358
demayer 0:6bf0743ece18 359 if (mode == SOCKET_MODE_DATAGRAM) {
demayer 0:6bf0743ece18 360 tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len);
demayer 0:6bf0743ece18 361 } else if (mode == SOCKET_MODE_STREAM) {
demayer 0:6bf0743ece18 362 tr_debug("SOCKET_TX_DONE, %d bytes remaining", sock_cb->d_len);
demayer 0:6bf0743ece18 363 }
demayer 0:6bf0743ece18 364
demayer 0:6bf0743ece18 365 signal_event();
demayer 0:6bf0743ece18 366 }
demayer 0:6bf0743ece18 367
demayer 0:6bf0743ece18 368 void NanostackSocket::event_connect_done(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 369 {
demayer 0:6bf0743ece18 370 nanostack_assert_locked();
demayer 0:6bf0743ece18 371 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode);
demayer 0:6bf0743ece18 372
demayer 0:6bf0743ece18 373 set_connected();
demayer 0:6bf0743ece18 374 signal_event();
demayer 0:6bf0743ece18 375 }
demayer 0:6bf0743ece18 376
demayer 0:6bf0743ece18 377 void NanostackSocket::event_connect_fail(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 378 {
demayer 0:6bf0743ece18 379 nanostack_assert_locked();
demayer 0:6bf0743ece18 380 MBED_ASSERT(mode == SOCKET_MODE_CONNECTING);
demayer 0:6bf0743ece18 381 close();
demayer 0:6bf0743ece18 382 }
demayer 0:6bf0743ece18 383
demayer 0:6bf0743ece18 384 void NanostackSocket::event_incoming_connection(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 385 {
demayer 0:6bf0743ece18 386 nanostack_assert_locked();
demayer 0:6bf0743ece18 387 MBED_ASSERT(mode == SOCKET_MODE_LISTENING);
demayer 0:6bf0743ece18 388 signal_event();
demayer 0:6bf0743ece18 389 }
demayer 0:6bf0743ece18 390
demayer 0:6bf0743ece18 391 void NanostackSocket::event_connect_closed(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 392 {
demayer 0:6bf0743ece18 393 nanostack_assert_locked();
demayer 0:6bf0743ece18 394
demayer 0:6bf0743ece18 395 // Can happen if we have an orderly close()
demayer 0:6bf0743ece18 396 // Might never happen as we have not implemented shutdown() in abstraction layer.
demayer 0:6bf0743ece18 397 MBED_ASSERT(mode == SOCKET_MODE_STREAM);
demayer 0:6bf0743ece18 398 close();
demayer 0:6bf0743ece18 399 }
demayer 0:6bf0743ece18 400
demayer 0:6bf0743ece18 401 void NanostackSocket::event_tx_fail(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 402 {
demayer 0:6bf0743ece18 403 nanostack_assert_locked();
demayer 0:6bf0743ece18 404
demayer 0:6bf0743ece18 405 switch (mode) {
demayer 0:6bf0743ece18 406 case SOCKET_MODE_CONNECTING:
demayer 0:6bf0743ece18 407 case SOCKET_MODE_STREAM:
demayer 0:6bf0743ece18 408 // TX_FAIL is fatal for stream sockets
demayer 0:6bf0743ece18 409 close();
demayer 0:6bf0743ece18 410 break;
demayer 0:6bf0743ece18 411 case SOCKET_MODE_DATAGRAM:
demayer 0:6bf0743ece18 412 // TX_FAIL is non-fatal for datagram sockets
demayer 0:6bf0743ece18 413 break;
demayer 0:6bf0743ece18 414 default:
demayer 0:6bf0743ece18 415 MBED_ASSERT(false);
demayer 0:6bf0743ece18 416 break;
demayer 0:6bf0743ece18 417 }
demayer 0:6bf0743ece18 418 }
demayer 0:6bf0743ece18 419
demayer 0:6bf0743ece18 420 void NanostackSocket::event_connection_reset(socket_callback_t *sock_cb)
demayer 0:6bf0743ece18 421 {
demayer 0:6bf0743ece18 422 nanostack_assert_locked();
demayer 0:6bf0743ece18 423
demayer 0:6bf0743ece18 424 // Only TCP sockets can be closed by the remote end
demayer 0:6bf0743ece18 425 MBED_ASSERT((SOCKET_MODE_STREAM == mode) ||
demayer 0:6bf0743ece18 426 (SOCKET_MODE_CONNECTING == mode));
demayer 0:6bf0743ece18 427 close();
demayer 0:6bf0743ece18 428 }
demayer 0:6bf0743ece18 429
demayer 0:6bf0743ece18 430 NanostackInterface *NanostackInterface::_ns_interface;
demayer 0:6bf0743ece18 431
demayer 0:6bf0743ece18 432 NanostackInterface *NanostackInterface::get_stack()
demayer 0:6bf0743ece18 433 {
demayer 0:6bf0743ece18 434 NanostackLockGuard lock;
demayer 0:6bf0743ece18 435
demayer 0:6bf0743ece18 436 if (NULL == _ns_interface) {
demayer 0:6bf0743ece18 437 _ns_interface = new NanostackInterface();
demayer 0:6bf0743ece18 438 }
demayer 0:6bf0743ece18 439
demayer 0:6bf0743ece18 440 return _ns_interface;
demayer 0:6bf0743ece18 441 }
demayer 0:6bf0743ece18 442
demayer 0:6bf0743ece18 443 const char * NanostackInterface::get_ip_address()
demayer 0:6bf0743ece18 444 {
demayer 0:6bf0743ece18 445 NanostackLockGuard lock;
demayer 0:6bf0743ece18 446
demayer 0:6bf0743ece18 447 for (int if_id = 1; if_id <= 127; if_id++) {
demayer 0:6bf0743ece18 448 uint8_t address[16];
demayer 0:6bf0743ece18 449 int ret = arm_net_address_get(if_id, ADDR_IPV6_GP, address);
demayer 0:6bf0743ece18 450 if (ret == 0) {
demayer 0:6bf0743ece18 451 ip6tos(address, text_ip_address);
demayer 0:6bf0743ece18 452 return text_ip_address;
demayer 0:6bf0743ece18 453 }
demayer 0:6bf0743ece18 454 }
demayer 0:6bf0743ece18 455 // Must result a valid IPv6 address
demayer 0:6bf0743ece18 456 // For gethostbyname() to detect IP version.
demayer 0:6bf0743ece18 457 return "::";
demayer 0:6bf0743ece18 458 }
demayer 0:6bf0743ece18 459
demayer 0:6bf0743ece18 460 nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol)
demayer 0:6bf0743ece18 461 {
demayer 0:6bf0743ece18 462 // Validate parameters
demayer 0:6bf0743ece18 463 if (NULL == handle) {
demayer 0:6bf0743ece18 464 MBED_ASSERT(false);
demayer 0:6bf0743ece18 465 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 466 }
demayer 0:6bf0743ece18 467 int8_t ns_proto;
demayer 0:6bf0743ece18 468 if (NSAPI_UDP == protocol) {
demayer 0:6bf0743ece18 469 ns_proto = SOCKET_UDP;
demayer 0:6bf0743ece18 470 } else if (NSAPI_TCP == protocol) {
demayer 0:6bf0743ece18 471 ns_proto = SOCKET_TCP;
demayer 0:6bf0743ece18 472 } else {
demayer 0:6bf0743ece18 473 MBED_ASSERT(false);
demayer 0:6bf0743ece18 474 return NSAPI_ERROR_UNSUPPORTED;
demayer 0:6bf0743ece18 475 }
demayer 0:6bf0743ece18 476 *handle = (void*)NULL;
demayer 0:6bf0743ece18 477
demayer 0:6bf0743ece18 478 NanostackLockGuard lock;
demayer 0:6bf0743ece18 479
demayer 0:6bf0743ece18 480 NanostackSocket * socket = new NanostackSocket(ns_proto);
demayer 0:6bf0743ece18 481 if (socket == NULL) {
demayer 0:6bf0743ece18 482 tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY);
demayer 0:6bf0743ece18 483 return NSAPI_ERROR_NO_MEMORY;
demayer 0:6bf0743ece18 484 }
demayer 0:6bf0743ece18 485 if (!socket->open()) {
demayer 0:6bf0743ece18 486 delete socket;
demayer 0:6bf0743ece18 487 tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR);
demayer 0:6bf0743ece18 488 return NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 489 }
demayer 0:6bf0743ece18 490 *handle = (void*)socket;
demayer 0:6bf0743ece18 491
demayer 0:6bf0743ece18 492 tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id);
demayer 0:6bf0743ece18 493
demayer 0:6bf0743ece18 494 return NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 495 }
demayer 0:6bf0743ece18 496
demayer 0:6bf0743ece18 497 nsapi_error_t NanostackInterface::socket_close(void *handle)
demayer 0:6bf0743ece18 498 {
demayer 0:6bf0743ece18 499 NanostackLockGuard lock;
demayer 0:6bf0743ece18 500 // Validate parameters
demayer 0:6bf0743ece18 501 NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 502 if (NULL == handle) {
demayer 0:6bf0743ece18 503 MBED_ASSERT(false);
demayer 0:6bf0743ece18 504 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 505 }
demayer 0:6bf0743ece18 506 tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id);
demayer 0:6bf0743ece18 507
demayer 0:6bf0743ece18 508 delete socket;
demayer 0:6bf0743ece18 509
demayer 0:6bf0743ece18 510 return 0;
demayer 0:6bf0743ece18 511
demayer 0:6bf0743ece18 512 }
demayer 0:6bf0743ece18 513
demayer 0:6bf0743ece18 514 nsapi_size_or_error_t NanostackInterface::do_sendto(void *handle, const ns_address_t *address, const void *data, nsapi_size_t size)
demayer 0:6bf0743ece18 515 {
demayer 0:6bf0743ece18 516 // Validate parameters
demayer 0:6bf0743ece18 517 NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 518 if (handle == NULL) {
demayer 0:6bf0743ece18 519 MBED_ASSERT(false);
demayer 0:6bf0743ece18 520 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 521 }
demayer 0:6bf0743ece18 522
demayer 0:6bf0743ece18 523 nsapi_size_or_error_t ret;
demayer 0:6bf0743ece18 524
demayer 0:6bf0743ece18 525 NanostackLockGuard lock;
demayer 0:6bf0743ece18 526
demayer 0:6bf0743ece18 527 if (socket->closed() || (!address && !socket->is_connected())) {
demayer 0:6bf0743ece18 528 ret = NSAPI_ERROR_NO_CONNECTION;
demayer 0:6bf0743ece18 529 goto out;
demayer 0:6bf0743ece18 530 }
demayer 0:6bf0743ece18 531
demayer 0:6bf0743ece18 532 if (address && socket->proto == SOCKET_TCP) {
demayer 0:6bf0743ece18 533 tr_error("socket_sendto() not supported with TCP!");
demayer 0:6bf0743ece18 534 ret = NSAPI_ERROR_IS_CONNECTED;
demayer 0:6bf0743ece18 535 goto out;
demayer 0:6bf0743ece18 536 }
demayer 0:6bf0743ece18 537
demayer 0:6bf0743ece18 538 int retcode;
demayer 0:6bf0743ece18 539 #if 0
demayer 0:6bf0743ece18 540 retcode = ::socket_sendto(socket->socket_id, address,
demayer 0:6bf0743ece18 541 data, size);
demayer 0:6bf0743ece18 542 #else
demayer 0:6bf0743ece18 543 // Use sendmsg purely to get the new return style
demayer 0:6bf0743ece18 544 // of returning data written rather than 0 on success,
demayer 0:6bf0743ece18 545 // which means TCP can do partial writes. (Sadly,
demayer 0:6bf0743ece18 546 // it's the only call which takes flags so we can
demayer 0:6bf0743ece18 547 // leave the NS_MSG_LEGACY0 flag clear).
demayer 0:6bf0743ece18 548 ns_msghdr_t msg;
demayer 0:6bf0743ece18 549 ns_iovec_t iov;
demayer 0:6bf0743ece18 550 iov.iov_base = const_cast<void *>(data);
demayer 0:6bf0743ece18 551 iov.iov_len = size;
demayer 0:6bf0743ece18 552 msg.msg_name = const_cast<ns_address_t *>(address);
demayer 0:6bf0743ece18 553 msg.msg_namelen = address ? sizeof *address : 0;
demayer 0:6bf0743ece18 554 msg.msg_iov = &iov;
demayer 0:6bf0743ece18 555 msg.msg_iovlen = 1;
demayer 0:6bf0743ece18 556 msg.msg_control = NULL;
demayer 0:6bf0743ece18 557 msg.msg_controllen = 0;
demayer 0:6bf0743ece18 558 retcode = ::socket_sendmsg(socket->socket_id, &msg, 0);
demayer 0:6bf0743ece18 559 #endif
demayer 0:6bf0743ece18 560
demayer 0:6bf0743ece18 561 /*
demayer 0:6bf0743ece18 562 * \return length if entire amount written (which could be 0)
demayer 0:6bf0743ece18 563 * \return value >0 and <length if partial amount written (stream only)
demayer 0:6bf0743ece18 564 * \return NS_EWOULDBLOCK if nothing written due to lack of queue space.
demayer 0:6bf0743ece18 565 * \return -1 Invalid socket ID or message structure.
demayer 0:6bf0743ece18 566 * \return -2 Socket memory allocation fail.
demayer 0:6bf0743ece18 567 * \return -3 TCP state not established or address scope not defined .
demayer 0:6bf0743ece18 568 * \return -4 Socket TX process busy or unknown interface.
demayer 0:6bf0743ece18 569 * \return -5 Socket not connected
demayer 0:6bf0743ece18 570 * \return -6 Packet too short (ICMP raw socket error).
demayer 0:6bf0743ece18 571 * */
demayer 0:6bf0743ece18 572 if (retcode == NS_EWOULDBLOCK) {
demayer 0:6bf0743ece18 573 ret = NSAPI_ERROR_WOULD_BLOCK;
demayer 0:6bf0743ece18 574 } else if (retcode < 0) {
demayer 0:6bf0743ece18 575 tr_error("socket_sendmsg: error=%d", retcode);
demayer 0:6bf0743ece18 576 ret = NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 577 } else {
demayer 0:6bf0743ece18 578 ret = retcode;
demayer 0:6bf0743ece18 579 }
demayer 0:6bf0743ece18 580
demayer 0:6bf0743ece18 581 out:
demayer 0:6bf0743ece18 582 tr_debug("socket_sendto(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret);
demayer 0:6bf0743ece18 583
demayer 0:6bf0743ece18 584 return ret;
demayer 0:6bf0743ece18 585 }
demayer 0:6bf0743ece18 586
demayer 0:6bf0743ece18 587 nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size)
demayer 0:6bf0743ece18 588 {
demayer 0:6bf0743ece18 589 if (address.get_ip_version() != NSAPI_IPv6) {
demayer 0:6bf0743ece18 590 return NSAPI_ERROR_UNSUPPORTED;
demayer 0:6bf0743ece18 591 }
demayer 0:6bf0743ece18 592
demayer 0:6bf0743ece18 593 ns_address_t ns_address;
demayer 0:6bf0743ece18 594 convert_mbed_addr_to_ns(&ns_address, &address);
demayer 0:6bf0743ece18 595 /*No lock gaurd needed here as do_sendto() will handle locks.*/
demayer 0:6bf0743ece18 596 return do_sendto(handle, &ns_address, data, size);
demayer 0:6bf0743ece18 597 }
demayer 0:6bf0743ece18 598
demayer 0:6bf0743ece18 599 nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size)
demayer 0:6bf0743ece18 600 {
demayer 0:6bf0743ece18 601 // Validate parameters
demayer 0:6bf0743ece18 602 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 603 if (handle == NULL) {
demayer 0:6bf0743ece18 604 MBED_ASSERT(false);
demayer 0:6bf0743ece18 605 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 606 }
demayer 0:6bf0743ece18 607
demayer 0:6bf0743ece18 608 nsapi_size_or_error_t ret;
demayer 0:6bf0743ece18 609
demayer 0:6bf0743ece18 610 NanostackLockGuard lock;
demayer 0:6bf0743ece18 611
demayer 0:6bf0743ece18 612 if (socket->closed()) {
demayer 0:6bf0743ece18 613 ret = NSAPI_ERROR_NO_CONNECTION;
demayer 0:6bf0743ece18 614 goto out;
demayer 0:6bf0743ece18 615 }
demayer 0:6bf0743ece18 616
demayer 0:6bf0743ece18 617 ns_address_t ns_address;
demayer 0:6bf0743ece18 618
demayer 0:6bf0743ece18 619 int retcode;
demayer 0:6bf0743ece18 620 retcode = ::socket_recvfrom(socket->socket_id, buffer, size, 0, &ns_address);
demayer 0:6bf0743ece18 621
demayer 0:6bf0743ece18 622 if (retcode == NS_EWOULDBLOCK) {
demayer 0:6bf0743ece18 623 ret = NSAPI_ERROR_WOULD_BLOCK;
demayer 0:6bf0743ece18 624 } else if (retcode < 0) {
demayer 0:6bf0743ece18 625 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 626 } else {
demayer 0:6bf0743ece18 627 ret = retcode;
demayer 0:6bf0743ece18 628 if (address != NULL) {
demayer 0:6bf0743ece18 629 convert_ns_addr_to_mbed(address, &ns_address);
demayer 0:6bf0743ece18 630 }
demayer 0:6bf0743ece18 631 }
demayer 0:6bf0743ece18 632
demayer 0:6bf0743ece18 633 out:
demayer 0:6bf0743ece18 634 if (address) {
demayer 0:6bf0743ece18 635 tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i, addr=[%s]:%i", socket, socket->socket_id, ret,
demayer 0:6bf0743ece18 636 trace_ipv6(address->get_ip_bytes()), address->get_port());
demayer 0:6bf0743ece18 637 } else {
demayer 0:6bf0743ece18 638 tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret);
demayer 0:6bf0743ece18 639 }
demayer 0:6bf0743ece18 640
demayer 0:6bf0743ece18 641 return ret;
demayer 0:6bf0743ece18 642 }
demayer 0:6bf0743ece18 643
demayer 0:6bf0743ece18 644 nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address)
demayer 0:6bf0743ece18 645 {
demayer 0:6bf0743ece18 646 // Validate parameters
demayer 0:6bf0743ece18 647 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 648 if (handle == NULL) {
demayer 0:6bf0743ece18 649 MBED_ASSERT(false);
demayer 0:6bf0743ece18 650 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 651 }
demayer 0:6bf0743ece18 652
demayer 0:6bf0743ece18 653 const void *addr_field;
demayer 0:6bf0743ece18 654 switch (address.get_ip_version()) {
demayer 0:6bf0743ece18 655 case NSAPI_IPv6:
demayer 0:6bf0743ece18 656 addr_field = address.get_ip_bytes();
demayer 0:6bf0743ece18 657 break;
demayer 0:6bf0743ece18 658 case NSAPI_UNSPEC:
demayer 0:6bf0743ece18 659 addr_field = &ns_in6addr_any;
demayer 0:6bf0743ece18 660 break;
demayer 0:6bf0743ece18 661 default:
demayer 0:6bf0743ece18 662 return NSAPI_ERROR_UNSUPPORTED;
demayer 0:6bf0743ece18 663 }
demayer 0:6bf0743ece18 664
demayer 0:6bf0743ece18 665 NanostackLockGuard lock;
demayer 0:6bf0743ece18 666
demayer 0:6bf0743ece18 667 ns_address_t ns_address;
demayer 0:6bf0743ece18 668 ns_address.type = ADDRESS_IPV6;
demayer 0:6bf0743ece18 669 memcpy(ns_address.address, addr_field, sizeof ns_address.address);
demayer 0:6bf0743ece18 670 ns_address.identifier = address.get_port();
demayer 0:6bf0743ece18 671 nsapi_error_t ret;
demayer 0:6bf0743ece18 672 int retcode = ::socket_bind(socket->socket_id, &ns_address);
demayer 0:6bf0743ece18 673
demayer 0:6bf0743ece18 674 if (retcode == 0) {
demayer 0:6bf0743ece18 675 ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 676 } else {
demayer 0:6bf0743ece18 677 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 678 }
demayer 0:6bf0743ece18 679
demayer 0:6bf0743ece18 680 tr_debug("socket_bind(socket=%p) sock_id=%d, retcode=%i, ret=%i", socket, socket->socket_id, retcode, ret);
demayer 0:6bf0743ece18 681
demayer 0:6bf0743ece18 682 return ret;
demayer 0:6bf0743ece18 683 }
demayer 0:6bf0743ece18 684
demayer 0:6bf0743ece18 685 nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen)
demayer 0:6bf0743ece18 686 {
demayer 0:6bf0743ece18 687 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 688 if (handle == NULL) {
demayer 0:6bf0743ece18 689 MBED_ASSERT(false);
demayer 0:6bf0743ece18 690 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 691 }
demayer 0:6bf0743ece18 692
demayer 0:6bf0743ece18 693 nsapi_error_t ret;
demayer 0:6bf0743ece18 694
demayer 0:6bf0743ece18 695 NanostackLockGuard lock;
demayer 0:6bf0743ece18 696
demayer 0:6bf0743ece18 697 if (::socket_setsockopt(socket->socket_id, level, optname, optval, optlen) == 0) {
demayer 0:6bf0743ece18 698 ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 699 } else {
demayer 0:6bf0743ece18 700 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 701 }
demayer 0:6bf0743ece18 702
demayer 0:6bf0743ece18 703 return ret;
demayer 0:6bf0743ece18 704 }
demayer 0:6bf0743ece18 705
demayer 0:6bf0743ece18 706 nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
demayer 0:6bf0743ece18 707 {
demayer 0:6bf0743ece18 708 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 709 if (handle == NULL) {
demayer 0:6bf0743ece18 710 MBED_ASSERT(false);
demayer 0:6bf0743ece18 711 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 712 }
demayer 0:6bf0743ece18 713
demayer 0:6bf0743ece18 714 nsapi_error_t ret;
demayer 0:6bf0743ece18 715
demayer 0:6bf0743ece18 716 NanostackLockGuard lock;
demayer 0:6bf0743ece18 717
demayer 0:6bf0743ece18 718 uint16_t optlen16 = *optlen;
demayer 0:6bf0743ece18 719 if (::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16) == 0) {
demayer 0:6bf0743ece18 720 ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 721 *optlen = optlen16;
demayer 0:6bf0743ece18 722 } else {
demayer 0:6bf0743ece18 723 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 724 }
demayer 0:6bf0743ece18 725
demayer 0:6bf0743ece18 726 return ret;
demayer 0:6bf0743ece18 727 }
demayer 0:6bf0743ece18 728
demayer 0:6bf0743ece18 729 nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog)
demayer 0:6bf0743ece18 730 {
demayer 0:6bf0743ece18 731 //Check if socket exists
demayer 0:6bf0743ece18 732 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 733 if (handle == NULL) {
demayer 0:6bf0743ece18 734 MBED_ASSERT(false);
demayer 0:6bf0743ece18 735 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 736 }
demayer 0:6bf0743ece18 737
demayer 0:6bf0743ece18 738 nsapi_error_t ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 739
demayer 0:6bf0743ece18 740 NanostackLockGuard lock;
demayer 0:6bf0743ece18 741
demayer 0:6bf0743ece18 742 if(::socket_listen(socket->socket_id, backlog) < 0) {
demayer 0:6bf0743ece18 743 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 744 } else {
demayer 0:6bf0743ece18 745 socket->set_listening();
demayer 0:6bf0743ece18 746 }
demayer 0:6bf0743ece18 747
demayer 0:6bf0743ece18 748 return ret;
demayer 0:6bf0743ece18 749 }
demayer 0:6bf0743ece18 750
demayer 0:6bf0743ece18 751 nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr)
demayer 0:6bf0743ece18 752 {
demayer 0:6bf0743ece18 753 // Validate parameters
demayer 0:6bf0743ece18 754 NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 755 nsapi_error_t ret;
demayer 0:6bf0743ece18 756 if (handle == NULL) {
demayer 0:6bf0743ece18 757 MBED_ASSERT(false);
demayer 0:6bf0743ece18 758 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 759 }
demayer 0:6bf0743ece18 760
demayer 0:6bf0743ece18 761 NanostackLockGuard lock;
demayer 0:6bf0743ece18 762
demayer 0:6bf0743ece18 763 if (addr.get_ip_version() != NSAPI_IPv6) {
demayer 0:6bf0743ece18 764 ret = NSAPI_ERROR_UNSUPPORTED;
demayer 0:6bf0743ece18 765 goto out;
demayer 0:6bf0743ece18 766 }
demayer 0:6bf0743ece18 767
demayer 0:6bf0743ece18 768 if (socket->closed()) {
demayer 0:6bf0743ece18 769 ret = NSAPI_ERROR_NO_CONNECTION;
demayer 0:6bf0743ece18 770 goto out;
demayer 0:6bf0743ece18 771 }
demayer 0:6bf0743ece18 772
demayer 0:6bf0743ece18 773 if (socket->is_connecting()) {
demayer 0:6bf0743ece18 774 ret = NSAPI_ERROR_ALREADY;
demayer 0:6bf0743ece18 775 goto out;
demayer 0:6bf0743ece18 776 }
demayer 0:6bf0743ece18 777
demayer 0:6bf0743ece18 778 if (socket->is_connected()) {
demayer 0:6bf0743ece18 779 ret = NSAPI_ERROR_IS_CONNECTED;
demayer 0:6bf0743ece18 780 goto out;
demayer 0:6bf0743ece18 781 }
demayer 0:6bf0743ece18 782
demayer 0:6bf0743ece18 783 ns_address_t ns_addr;
demayer 0:6bf0743ece18 784
demayer 0:6bf0743ece18 785 convert_mbed_addr_to_ns(&ns_addr, &addr);
demayer 0:6bf0743ece18 786 if (::socket_connect(socket->socket_id, &ns_addr, 0) == 0) {
demayer 0:6bf0743ece18 787 if (socket->proto == SOCKET_TCP) {
demayer 0:6bf0743ece18 788 socket->set_connecting(&ns_addr);
demayer 0:6bf0743ece18 789 ret = NSAPI_ERROR_IN_PROGRESS;
demayer 0:6bf0743ece18 790 } else {
demayer 0:6bf0743ece18 791 ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 792 }
demayer 0:6bf0743ece18 793 } else {
demayer 0:6bf0743ece18 794 ret = NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 795 }
demayer 0:6bf0743ece18 796
demayer 0:6bf0743ece18 797 out:
demayer 0:6bf0743ece18 798 tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret);
demayer 0:6bf0743ece18 799
demayer 0:6bf0743ece18 800 return ret;
demayer 0:6bf0743ece18 801 }
demayer 0:6bf0743ece18 802
demayer 0:6bf0743ece18 803 nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address)
demayer 0:6bf0743ece18 804 {
demayer 0:6bf0743ece18 805 NanostackSocket * socket = static_cast<NanostackSocket *>(server);
demayer 0:6bf0743ece18 806 NanostackSocket *accepted_sock = NULL;
demayer 0:6bf0743ece18 807 nsapi_error_t ret;
demayer 0:6bf0743ece18 808
demayer 0:6bf0743ece18 809 if (handle == NULL) {
demayer 0:6bf0743ece18 810 MBED_ASSERT(false);
demayer 0:6bf0743ece18 811 return NSAPI_ERROR_NO_SOCKET;
demayer 0:6bf0743ece18 812 }
demayer 0:6bf0743ece18 813
demayer 0:6bf0743ece18 814 NanostackLockGuard lock;
demayer 0:6bf0743ece18 815
demayer 0:6bf0743ece18 816 if (!socket->is_listening()) {
demayer 0:6bf0743ece18 817 ret = NSAPI_ERROR_PARAMETER;
demayer 0:6bf0743ece18 818 goto out;
demayer 0:6bf0743ece18 819 }
demayer 0:6bf0743ece18 820
demayer 0:6bf0743ece18 821 accepted_sock = new NanostackSocket(socket->proto);
demayer 0:6bf0743ece18 822 if (accepted_sock == NULL) {
demayer 0:6bf0743ece18 823 ret = NSAPI_ERROR_NO_MEMORY;
demayer 0:6bf0743ece18 824 goto out;
demayer 0:6bf0743ece18 825 }
demayer 0:6bf0743ece18 826
demayer 0:6bf0743ece18 827 ns_address_t ns_addr;
demayer 0:6bf0743ece18 828 int retcode;
demayer 0:6bf0743ece18 829 retcode = socket->accept(accepted_sock, &ns_addr);
demayer 0:6bf0743ece18 830 if (retcode < 0) {
demayer 0:6bf0743ece18 831 delete accepted_sock;
demayer 0:6bf0743ece18 832 if (retcode == NS_EWOULDBLOCK) {
demayer 0:6bf0743ece18 833 ret = NSAPI_ERROR_WOULD_BLOCK;
demayer 0:6bf0743ece18 834 } else {
demayer 0:6bf0743ece18 835 ret = NSAPI_ERROR_DEVICE_ERROR;
demayer 0:6bf0743ece18 836 }
demayer 0:6bf0743ece18 837 goto out;
demayer 0:6bf0743ece18 838 }
demayer 0:6bf0743ece18 839 ret = NSAPI_ERROR_OK;
demayer 0:6bf0743ece18 840
demayer 0:6bf0743ece18 841 if (address) {
demayer 0:6bf0743ece18 842 convert_ns_addr_to_mbed(address, &ns_addr);
demayer 0:6bf0743ece18 843 }
demayer 0:6bf0743ece18 844
demayer 0:6bf0743ece18 845 *handle = accepted_sock;
demayer 0:6bf0743ece18 846
demayer 0:6bf0743ece18 847 out:
demayer 0:6bf0743ece18 848 tr_debug("socket_accept() socket=%p, sock_id=%d, ret=%i", accepted_sock, accepted_sock ? accepted_sock->socket_id : -1, ret);
demayer 0:6bf0743ece18 849
demayer 0:6bf0743ece18 850 return ret;
demayer 0:6bf0743ece18 851 }
demayer 0:6bf0743ece18 852
demayer 0:6bf0743ece18 853 nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *data, nsapi_size_t size)
demayer 0:6bf0743ece18 854 {
demayer 0:6bf0743ece18 855 return do_sendto(handle, NULL, data, size);
demayer 0:6bf0743ece18 856 }
demayer 0:6bf0743ece18 857
demayer 0:6bf0743ece18 858 nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size)
demayer 0:6bf0743ece18 859 {
demayer 0:6bf0743ece18 860 return socket_recvfrom(handle, NULL, data, size);
demayer 0:6bf0743ece18 861 }
demayer 0:6bf0743ece18 862
demayer 0:6bf0743ece18 863 void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id)
demayer 0:6bf0743ece18 864 {
demayer 0:6bf0743ece18 865 // Validate parameters
demayer 0:6bf0743ece18 866 NanostackSocket * socket = static_cast<NanostackSocket *>(handle);
demayer 0:6bf0743ece18 867 if (handle == NULL) {
demayer 0:6bf0743ece18 868 MBED_ASSERT(false);
demayer 0:6bf0743ece18 869 return;
demayer 0:6bf0743ece18 870 }
demayer 0:6bf0743ece18 871
demayer 0:6bf0743ece18 872 NanostackLockGuard lock;
demayer 0:6bf0743ece18 873
demayer 0:6bf0743ece18 874 socket->callback = callback;
demayer 0:6bf0743ece18 875 socket->callback_data = id;
demayer 0:6bf0743ece18 876
demayer 0:6bf0743ece18 877 tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id);
demayer 0:6bf0743ece18 878 }