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.
Dependents: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
NanostackInterface.cpp
00001 /* Nanostack implementation of NetworkSocketAPI 00002 * Copyright (c) 2016 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "rtos.h" 00019 #include "NanostackInterface.h" 00020 00021 #include "ns_address.h" 00022 #include "nsdynmemLIB.h" 00023 #include "eventOS_scheduler.h" 00024 #include "randLIB.h" 00025 00026 #include "mesh_system.h" // from inside mbed-mesh-api 00027 #include "socket_api.h" 00028 #include "net_interface.h" 00029 00030 // Uncomment to enable trace 00031 //#define HAVE_DEBUG 00032 #include "ns_trace.h" 00033 #define TRACE_GROUP "nsif" 00034 00035 #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX 00036 #define NANOSTACK_SOCKET_UDP 17 // same as nanostack SOCKET_UDP 00037 #define NANOSTACK_SOCKET_TCP 6 // same as nanostack SOCKET_TCP 00038 00039 #define MALLOC ns_dyn_mem_alloc 00040 #define FREE ns_dyn_mem_free 00041 00042 enum socket_mode_t { 00043 SOCKET_MODE_UNOPENED, // No socket ID 00044 SOCKET_MODE_OPENED, // Socket ID but no assigned use yet 00045 SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet 00046 SOCKET_MODE_DATAGRAM, // Socket is bound to a port and listening for datagrams 00047 SOCKET_MODE_STREAM, // Socket has an open stream 00048 SOCKET_MODE_CLOSED, // Socket is closed and resources are freed 00049 }; 00050 00051 class NanostackBuffer { 00052 public: 00053 NanostackBuffer *next; /*<! next buffer */ 00054 ns_address_t ns_address; /*<! address where data is received */ 00055 uint16_t length; /*<! data length in this buffer */ 00056 uint8_t payload[1]; /*<! Trailing buffer data */ 00057 }; 00058 00059 class NanostackSocket { 00060 public: 00061 static void socket_callback(void *cb); 00062 static void* operator new(std::size_t sz); 00063 static void operator delete(void* ptr); 00064 00065 NanostackSocket(int8_t protocol); 00066 ~NanostackSocket(void); 00067 bool open(void); 00068 void close(void); 00069 bool closed(void) {return SOCKET_MODE_CLOSED == mode;} 00070 bool is_bound(void); 00071 void set_bound(void); 00072 bool is_connecting(void); 00073 void set_connecting(ns_address_t *addr); 00074 void set_connected(void); 00075 00076 // Socket events from nanostack 00077 void event_data(socket_callback_t *sock_cb); 00078 void event_bind_done(socket_callback_t *sock_cb); 00079 void event_connnect_closed(socket_callback_t *sock_cb); 00080 void event_tx_done(socket_callback_t *sock_cb); 00081 00082 // Run callback to signal the next layer of the NSAPI 00083 void signal_event(void); 00084 00085 // Add or remove a socket to the listening socket 00086 void accept_list_add(NanostackSocket *socket); 00087 NanostackSocket * accept_list_remove(void); 00088 00089 bool data_available(void); 00090 size_t data_copy_and_free(void *dest, size_t len, SocketAddress *address, bool stream); 00091 void data_free_all(void); 00092 void data_attach(NanostackBuffer *data_buf); 00093 00094 void (*callback)(void *); 00095 void *callback_data; 00096 int8_t socket_id; /*!< allocated socket ID */ 00097 int8_t proto; /*!< UDP or TCP */ 00098 bool addr_valid; 00099 ns_address_t ns_address; 00100 private: 00101 NanostackBuffer *rxBufChain; /*!< Receive buffers */ 00102 socket_mode_t mode; 00103 }; 00104 00105 static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; 00106 00107 nsapi_error_t map_mesh_error(mesh_error_t err) 00108 { 00109 switch (err) { 00110 case MESH_ERROR_NONE: return 0; 00111 case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY ; 00112 case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED ; 00113 case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR ; 00114 default: return NSAPI_ERROR_DEVICE_ERROR ; 00115 } 00116 } 00117 00118 static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, 00119 const SocketAddress *s_addr) 00120 { 00121 ns_addr->type = ADDRESS_IPV6; 00122 ns_addr->identifier = s_addr->get_port(); 00123 memcpy(ns_addr->address, s_addr->get_ip_bytes(), 16); 00124 } 00125 00126 static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) 00127 { 00128 s_addr->set_port(ns_addr->identifier); 00129 s_addr->set_ip_bytes(ns_addr->address, NSAPI_IPv6 ); 00130 } 00131 00132 void* NanostackSocket::operator new(std::size_t sz) { 00133 return MALLOC(sz); 00134 } 00135 void NanostackSocket::operator delete(void* ptr) { 00136 FREE(ptr); 00137 } 00138 00139 NanostackSocket::NanostackSocket(int8_t protocol) 00140 { 00141 nanostack_assert_locked(); 00142 00143 callback = NULL; 00144 callback_data = NULL; 00145 socket_id = -1; 00146 rxBufChain = NULL; 00147 proto = protocol; 00148 addr_valid = false; 00149 memset(&ns_address, 0, sizeof(ns_address)); 00150 mode = SOCKET_MODE_UNOPENED; 00151 } 00152 00153 NanostackSocket::~NanostackSocket() 00154 { 00155 nanostack_assert_locked(); 00156 00157 if (mode != SOCKET_MODE_CLOSED) { 00158 close(); 00159 } 00160 data_free_all(); 00161 } 00162 00163 bool NanostackSocket::open(void) 00164 { 00165 nanostack_assert_locked(); 00166 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00167 00168 int temp_socket = socket_open(proto, 0, socket_callback); 00169 00170 if (temp_socket < 0) { 00171 tr_error("NanostackSocket::open() failed"); 00172 return false; 00173 } 00174 if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) { 00175 MBED_ASSERT(false); 00176 return false; 00177 } 00178 if (socket_tbl[temp_socket] != NULL) { 00179 MBED_ASSERT(false); 00180 return false; 00181 } 00182 socket_id = temp_socket; 00183 socket_tbl[socket_id] = this; 00184 mode = SOCKET_MODE_OPENED; 00185 return true; 00186 00187 } 00188 00189 void NanostackSocket::close() 00190 { 00191 nanostack_assert_locked(); 00192 MBED_ASSERT(mode != SOCKET_MODE_CLOSED); 00193 00194 if (socket_id >= 0) { 00195 nsapi_error_t ret = socket_close(socket_id); 00196 MBED_ASSERT(0 == ret); 00197 MBED_ASSERT(socket_tbl[socket_id] == this); 00198 socket_tbl[socket_id] = NULL; 00199 socket_id = -1; 00200 } else { 00201 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00202 } 00203 00204 data_free_all(); 00205 00206 mode = SOCKET_MODE_CLOSED; 00207 signal_event(); 00208 } 00209 00210 bool NanostackSocket::is_bound() 00211 { 00212 return SOCKET_MODE_DATAGRAM == mode; 00213 } 00214 00215 void NanostackSocket::set_bound() 00216 { 00217 nanostack_assert_locked(); 00218 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00219 if (SOCKET_UDP == proto) { 00220 mode = SOCKET_MODE_DATAGRAM; 00221 } 00222 } 00223 00224 bool NanostackSocket::is_connecting() 00225 { 00226 return SOCKET_MODE_CONNECTING == mode; 00227 } 00228 00229 void NanostackSocket::set_connecting(ns_address_t *addr) 00230 { 00231 nanostack_assert_locked(); 00232 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00233 00234 memcpy(&ns_address, addr, sizeof(ns_address_t)); 00235 mode = SOCKET_MODE_CONNECTING; 00236 } 00237 00238 void NanostackSocket::set_connected() 00239 { 00240 nanostack_assert_locked(); 00241 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); 00242 00243 mode = SOCKET_MODE_STREAM; 00244 } 00245 00246 void NanostackSocket::signal_event() 00247 { 00248 nanostack_assert_locked(); 00249 00250 if (callback != NULL) { 00251 callback(callback_data); 00252 } 00253 } 00254 00255 void NanostackSocket::socket_callback(void *cb) { 00256 nanostack_assert_locked(); 00257 00258 socket_callback_t *sock_cb = (socket_callback_t *) cb; 00259 NanostackSocket *socket = socket_tbl[sock_cb->socket_id]; 00260 MBED_ASSERT(socket != NULL); 00261 00262 tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d", 00263 sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len); 00264 00265 switch (sock_cb->event_type) { 00266 case SOCKET_DATA: 00267 tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len); 00268 socket->event_data(sock_cb); 00269 break; 00270 case SOCKET_BIND_DONE: 00271 tr_debug("SOCKET_BIND_DONE"); 00272 socket->event_bind_done(sock_cb); 00273 break; 00274 case SOCKET_BIND_FAIL: 00275 tr_debug("SOCKET_BIND_FAIL"); 00276 break; 00277 case SOCKET_BIND_AUTH_FAIL: 00278 tr_debug("SOCKET_BIND_AUTH_FAIL"); 00279 break; 00280 case SOCKET_INCOMING_CONNECTION: 00281 tr_debug("SOCKET_INCOMING_CONNECTION"); 00282 break; 00283 case SOCKET_TX_FAIL: 00284 tr_debug("SOCKET_TX_FAIL"); 00285 break; 00286 case SOCKET_CONNECT_CLOSED: 00287 tr_debug("SOCKET_CONNECT_CLOSED"); 00288 socket->event_connnect_closed(sock_cb); 00289 break; 00290 case SOCKET_CONNECTION_RESET: 00291 tr_debug("SOCKET_CONNECTION_RESET"); 00292 break; 00293 case SOCKET_NO_ROUTE: 00294 tr_debug("SOCKET_NO_ROUTE"); 00295 break; 00296 case SOCKET_TX_DONE: 00297 tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); 00298 socket->event_tx_done(sock_cb); 00299 break; 00300 default: 00301 // SOCKET_NO_RAM, error case for SOCKET_TX_DONE 00302 break; 00303 } 00304 } 00305 00306 00307 bool NanostackSocket::data_available() 00308 { 00309 nanostack_assert_locked(); 00310 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00311 (SOCKET_MODE_CONNECTING == mode) || 00312 (SOCKET_MODE_STREAM == mode)); 00313 00314 return (NULL == rxBufChain) ? false : true; 00315 } 00316 00317 size_t NanostackSocket::data_copy_and_free(void *dest, size_t len, 00318 SocketAddress *address, bool stream) 00319 { 00320 nanostack_assert_locked(); 00321 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00322 (mode == SOCKET_MODE_STREAM)); 00323 00324 NanostackBuffer *data_buf = rxBufChain; 00325 if (NULL == data_buf) { 00326 // No data 00327 return 0; 00328 } 00329 00330 if (address) { 00331 convert_ns_addr_to_mbed(address, &data_buf->ns_address); 00332 } 00333 00334 size_t copy_size = (len > data_buf->length) ? data_buf->length : len; 00335 memcpy(dest, data_buf->payload, copy_size); 00336 00337 if (stream && (copy_size < data_buf->length)) { 00338 // Update the size in the buffer 00339 size_t new_buf_size = data_buf->length - copy_size; 00340 memmove(data_buf->payload, data_buf->payload + copy_size, new_buf_size); 00341 data_buf->length = new_buf_size; 00342 } else { 00343 // Entire packet used so free it 00344 rxBufChain = data_buf->next; 00345 FREE(data_buf); 00346 } 00347 00348 return copy_size; 00349 } 00350 00351 void NanostackSocket::data_free_all(void) 00352 { 00353 nanostack_assert_locked(); 00354 // No mode requirement 00355 00356 NanostackBuffer *buffer = rxBufChain; 00357 rxBufChain = NULL; 00358 while (buffer != NULL) { 00359 NanostackBuffer *next_buffer = buffer->next; 00360 FREE(buffer); 00361 buffer = next_buffer; 00362 } 00363 } 00364 00365 void NanostackSocket::data_attach(NanostackBuffer *data_buf) 00366 { 00367 nanostack_assert_locked(); 00368 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00369 (SOCKET_MODE_STREAM == mode)); 00370 00371 // Add to linked list 00372 tr_debug("data_attach socket=%p", this); 00373 if (NULL == rxBufChain) { 00374 rxBufChain = data_buf; 00375 } else { 00376 NanostackBuffer *buf_tmp = rxBufChain; 00377 while (NULL != buf_tmp->next) { 00378 buf_tmp = buf_tmp->next; 00379 } 00380 buf_tmp->next = data_buf; 00381 } 00382 signal_event(); 00383 } 00384 00385 void NanostackSocket::event_data(socket_callback_t *sock_cb) 00386 { 00387 nanostack_assert_locked(); 00388 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00389 (SOCKET_MODE_STREAM == mode)); 00390 00391 // Allocate buffer 00392 NanostackBuffer *recv_buff = (NanostackBuffer *) MALLOC( 00393 sizeof(NanostackBuffer) + sock_cb->d_len); 00394 if (NULL == recv_buff) { 00395 tr_error("alloc failed!"); 00396 return; 00397 } 00398 recv_buff->next = NULL; 00399 00400 // Write data to buffer 00401 int16_t length = socket_read(sock_cb->socket_id, 00402 &recv_buff->ns_address, recv_buff->payload, 00403 sock_cb->d_len); 00404 if (length < 0) { 00405 tr_error("socket_read failed!"); 00406 FREE(recv_buff); 00407 return; 00408 } 00409 recv_buff->length = length; 00410 00411 data_attach(recv_buff); 00412 } 00413 00414 void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) 00415 { 00416 nanostack_assert_locked(); 00417 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00418 (SOCKET_MODE_DATAGRAM == mode)); 00419 00420 signal_event(); 00421 } 00422 00423 void NanostackSocket::event_bind_done(socket_callback_t *sock_cb) 00424 { 00425 nanostack_assert_locked(); 00426 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); 00427 00428 set_connected(); 00429 signal_event(); 00430 } 00431 00432 void NanostackSocket::event_connnect_closed(socket_callback_t *sock_cb) 00433 { 00434 nanostack_assert_locked(); 00435 00436 // Only TCP sockets can be closed by the remote end 00437 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00438 (SOCKET_MODE_CONNECTING == mode)); 00439 close(); 00440 } 00441 00442 NanostackInterface * NanostackInterface::_ns_interface; 00443 00444 NanostackInterface * NanostackInterface::get_stack() 00445 { 00446 nanostack_lock(); 00447 00448 if (NULL == _ns_interface) { 00449 _ns_interface = new NanostackInterface(); 00450 } 00451 00452 nanostack_unlock(); 00453 00454 return _ns_interface; 00455 } 00456 00457 00458 const char * NanostackInterface::get_ip_address() 00459 { 00460 // Must result a valid IPv6 address 00461 // For gethostbyname() to detect IP version. 00462 static const char localhost[] = "::"; 00463 return localhost; 00464 } 00465 00466 nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) 00467 { 00468 // Validate parameters 00469 if (NULL == handle) { 00470 MBED_ASSERT(false); 00471 return NSAPI_ERROR_NO_SOCKET ; 00472 } 00473 int8_t ns_proto; 00474 if (NSAPI_UDP == protocol) { 00475 ns_proto = SOCKET_UDP; 00476 } else if (NSAPI_TCP == protocol) { 00477 ns_proto = SOCKET_TCP; 00478 } else { 00479 MBED_ASSERT(false); 00480 return NSAPI_ERROR_UNSUPPORTED ; 00481 } 00482 *handle = (void*)NULL; 00483 00484 nanostack_lock(); 00485 00486 NanostackSocket * socket = new NanostackSocket(ns_proto); 00487 if (NULL == socket) { 00488 nanostack_unlock(); 00489 tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY ); 00490 return NSAPI_ERROR_NO_MEMORY ; 00491 } 00492 if (!socket->open()) { 00493 delete socket; 00494 nanostack_unlock(); 00495 tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR ); 00496 return NSAPI_ERROR_DEVICE_ERROR ; 00497 } 00498 *handle = (void*)socket; 00499 00500 nanostack_unlock(); 00501 00502 tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); 00503 00504 return 0; 00505 } 00506 00507 nsapi_error_t NanostackInterface::socket_close(void *handle) 00508 { 00509 // Validate parameters 00510 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00511 if (NULL == handle) { 00512 MBED_ASSERT(false); 00513 return NSAPI_ERROR_NO_SOCKET ; 00514 } 00515 tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); 00516 00517 nanostack_lock(); 00518 00519 delete socket; 00520 00521 nanostack_unlock(); 00522 00523 return 0; 00524 00525 } 00526 00527 nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size) 00528 { 00529 // Validate parameters 00530 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00531 if (NULL == handle) { 00532 MBED_ASSERT(false); 00533 return NSAPI_ERROR_NO_SOCKET ; 00534 } 00535 00536 if (address.get_ip_version() != NSAPI_IPv6 ) { 00537 return NSAPI_ERROR_UNSUPPORTED ; 00538 } 00539 00540 nanostack_lock(); 00541 00542 nsapi_size_or_error_t ret; 00543 if (socket->closed()) { 00544 ret = NSAPI_ERROR_NO_CONNECTION ; 00545 } else if (NANOSTACK_SOCKET_TCP == socket->proto) { 00546 tr_error("socket_sendto() not supported with SOCKET_STREAM!"); 00547 ret = NSAPI_ERROR_UNSUPPORTED ; 00548 } else { 00549 ns_address_t ns_address; 00550 convert_mbed_addr_to_ns(&ns_address, &address); 00551 if (!socket->is_bound()) { 00552 socket->set_bound(); 00553 } 00554 int8_t send_to_status = ::socket_sendto(socket->socket_id, &ns_address, 00555 (uint8_t *)data, size); 00556 /* 00557 * \return 0 on success. 00558 * \return -1 invalid socket id. 00559 * \return -2 Socket memory allocation fail. 00560 * \return -3 TCP state not established. 00561 * \return -4 Socket tx process busy. 00562 * \return -5 TLS authentication not ready. 00563 * \return -6 Packet too short. 00564 * */ 00565 if (-4 == send_to_status) { 00566 ret = NSAPI_ERROR_WOULD_BLOCK ; 00567 } else if (0 != send_to_status) { 00568 tr_error("socket_sendto: error=%d", send_to_status); 00569 ret = NSAPI_ERROR_DEVICE_ERROR ; 00570 } else { 00571 ret = size; 00572 } 00573 } 00574 00575 nanostack_unlock(); 00576 00577 tr_debug("socket_sendto(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00578 00579 return ret; 00580 } 00581 00582 nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size) 00583 { 00584 // Validate parameters 00585 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00586 if (NULL == handle) { 00587 MBED_ASSERT(false); 00588 return NSAPI_ERROR_NO_SOCKET ; 00589 } 00590 if (NULL == buffer) { 00591 MBED_ASSERT(false); 00592 return NSAPI_ERROR_PARAMETER ; 00593 } 00594 if (0 == size) { 00595 MBED_ASSERT(false); 00596 return NSAPI_ERROR_PARAMETER ; 00597 } 00598 00599 nanostack_lock(); 00600 00601 nsapi_size_or_error_t ret; 00602 if (socket->closed()) { 00603 ret = NSAPI_ERROR_NO_CONNECTION ; 00604 } else if (NANOSTACK_SOCKET_TCP == socket->proto) { 00605 tr_error("recv_from() not supported with SOCKET_STREAM!"); 00606 ret = NSAPI_ERROR_UNSUPPORTED ; 00607 } else if (!socket->data_available()) { 00608 ret = NSAPI_ERROR_WOULD_BLOCK ; 00609 } else { 00610 ret = socket->data_copy_and_free(buffer, size, address, false); 00611 } 00612 00613 nanostack_unlock(); 00614 00615 tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00616 00617 return ret; 00618 } 00619 00620 nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address) 00621 { 00622 // Validate parameters 00623 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00624 if (NULL == handle) { 00625 MBED_ASSERT(false); 00626 return NSAPI_ERROR_NO_SOCKET ; 00627 } 00628 00629 const void *addr_field; 00630 switch (address.get_ip_version()) { 00631 case NSAPI_IPv6 : 00632 addr_field = address.get_ip_bytes(); 00633 break; 00634 case NSAPI_UNSPEC : 00635 addr_field = &ns_in6addr_any; 00636 break; 00637 default: 00638 return NSAPI_ERROR_UNSUPPORTED ; 00639 } 00640 00641 nanostack_lock(); 00642 00643 ns_address_t ns_address; 00644 ns_address.type = ADDRESS_IPV6; 00645 memcpy(ns_address.address, addr_field, sizeof ns_address.address); 00646 ns_address.identifier = address.get_port(); 00647 nsapi_error_t ret = NSAPI_ERROR_DEVICE_ERROR ; 00648 if (0 == ::socket_bind(socket->socket_id, &ns_address)) { 00649 socket->set_bound(); 00650 ret = 0; 00651 } 00652 00653 nanostack_unlock(); 00654 00655 tr_debug("socket_bind(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00656 00657 return ret; 00658 } 00659 00660 nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00661 { 00662 return NSAPI_ERROR_UNSUPPORTED ; 00663 } 00664 00665 nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00666 { 00667 return NSAPI_ERROR_UNSUPPORTED ; 00668 } 00669 00670 nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog) 00671 { 00672 return NSAPI_ERROR_UNSUPPORTED ; 00673 } 00674 00675 nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) 00676 { 00677 // Validate parameters 00678 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00679 if (NULL == handle) { 00680 MBED_ASSERT(false); 00681 return NSAPI_ERROR_NO_SOCKET ; 00682 } 00683 00684 if (addr.get_ip_version() != NSAPI_IPv6 ) { 00685 return NSAPI_ERROR_UNSUPPORTED ; 00686 } 00687 00688 nanostack_lock(); 00689 00690 nsapi_error_t ret; 00691 ns_address_t ns_addr; 00692 int random_port = socket->is_bound() ? 0 : 1; 00693 convert_mbed_addr_to_ns(&ns_addr, &addr); 00694 if (0 == ::socket_connect(socket->socket_id, &ns_addr, random_port)) { 00695 socket->set_connecting(&ns_addr); 00696 ret = 0; 00697 } else { 00698 ret = NSAPI_ERROR_DEVICE_ERROR ; 00699 } 00700 00701 nanostack_unlock(); 00702 00703 tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00704 00705 return ret; 00706 } 00707 00708 nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) 00709 { 00710 return NSAPI_ERROR_UNSUPPORTED ; 00711 } 00712 00713 nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *p, nsapi_size_t size) 00714 { 00715 // Validate parameters 00716 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00717 if (NULL == handle) { 00718 MBED_ASSERT(false); 00719 return NSAPI_ERROR_NO_SOCKET ; 00720 } 00721 00722 nanostack_lock(); 00723 00724 nsapi_size_or_error_t ret; 00725 if (socket->closed()) { 00726 ret = NSAPI_ERROR_NO_CONNECTION ; 00727 } else if (socket->is_connecting()) { 00728 ret = NSAPI_ERROR_WOULD_BLOCK ; 00729 } else { 00730 ret = ::socket_sendto(socket->socket_id, &socket->ns_address, (uint8_t*)p, size); 00731 /* 00732 * \return 0 on success. 00733 * \return -1 invalid socket id. 00734 * \return -2 Socket memory allocation fail. 00735 * \return -3 TCP state not established. 00736 * \return -4 Socket tx process busy. 00737 * \return -5 TLS authentication not ready. 00738 * \return -6 Packet too short. 00739 * */ 00740 if (-4 == ret) { 00741 ret = NSAPI_ERROR_WOULD_BLOCK ; 00742 } else if (ret != 0) { 00743 tr_warning("socket_sendto ret %i, socket_id %i", ret, socket->socket_id); 00744 ret = NSAPI_ERROR_DEVICE_ERROR ; 00745 } else { 00746 ret = size; 00747 } 00748 } 00749 00750 nanostack_unlock(); 00751 00752 tr_debug("socket_send(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00753 00754 return ret; 00755 } 00756 00757 nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size) 00758 { 00759 // Validate parameters 00760 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00761 if (NULL == handle) { 00762 MBED_ASSERT(false); 00763 return NSAPI_ERROR_NO_SOCKET ; 00764 } 00765 00766 nanostack_lock(); 00767 00768 nsapi_size_or_error_t ret; 00769 if (socket->closed()) { 00770 ret = NSAPI_ERROR_NO_CONNECTION ; 00771 } else if (socket->data_available()) { 00772 ret = socket->data_copy_and_free(data, size, NULL, true); 00773 } else { 00774 ret = NSAPI_ERROR_WOULD_BLOCK ; 00775 } 00776 00777 nanostack_unlock(); 00778 00779 tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00780 00781 return ret; 00782 } 00783 00784 void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) 00785 { 00786 // Validate parameters 00787 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00788 if (NULL == handle) { 00789 MBED_ASSERT(false); 00790 return; 00791 } 00792 00793 nanostack_lock(); 00794 00795 socket->callback = callback; 00796 socket->callback_data = id; 00797 00798 nanostack_unlock(); 00799 00800 tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); 00801 }
Generated on Tue Jul 12 2022 11:02:47 by
