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.
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 "mbed-mesh-api/MeshInterfaceFactory.h" 00027 00028 #include "mesh_system.h" // from inside mbed-mesh-api 00029 #include "socket_api.h" 00030 #include "driverRFPhy.h" 00031 #include "net_interface.h" 00032 #include "ip6string.h" 00033 // Uncomment to enable trace 00034 //#define HAVE_DEBUG 00035 #include "ns_trace.h" 00036 #define TRACE_GROUP "nsif" 00037 00038 #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX 00039 #define NANOSTACK_SOCKET_UDP 17 // same as nanostack SOCKET_UDP 00040 #define NANOSTACK_SOCKET_TCP 6 // same as nanostack SOCKET_TCP 00041 00042 #define MALLOC ns_dyn_mem_alloc 00043 #define FREE ns_dyn_mem_free 00044 00045 #define nanostack_lock() eventOS_scheduler_mutex_wait() 00046 #define nanostack_unlock() eventOS_scheduler_mutex_release() 00047 #define nanostack_assert_locked() //MBED_ASSERT(eventOS_scheduler_mutex_is_owner()) 00048 00049 enum socket_mode_t { 00050 SOCKET_MODE_UNOPENED, // No socket ID 00051 SOCKET_MODE_OPENED, // Socket ID but no assigned use yet 00052 SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet 00053 SOCKET_MODE_DATAGRAM, // Socket is bound to a port and listening for datagrams 00054 SOCKET_MODE_STREAM, // Socket has an open stream 00055 SOCKET_MODE_CLOSED, // Socket is closed and resources are freed 00056 }; 00057 00058 class NanostackBuffer { 00059 public: 00060 NanostackBuffer *next; /*<! next buffer */ 00061 ns_address_t ns_address; /*<! address where data is received */ 00062 uint16_t length; /*<! data length in this buffer */ 00063 uint8_t payload[1]; /*<! Trailing buffer data */ 00064 }; 00065 00066 class NanostackSocket { 00067 public: 00068 static void socket_callback(void *cb); 00069 static void* operator new(std::size_t sz); 00070 static void operator delete(void* ptr); 00071 00072 NanostackSocket(int8_t protocol); 00073 ~NanostackSocket(void); 00074 bool open(void); 00075 void close(void); 00076 bool closed(void) {return SOCKET_MODE_CLOSED == mode;} 00077 bool is_bound(void); 00078 void set_bound(void); 00079 bool is_connecting(void); 00080 void set_connecting(ns_address_t *addr); 00081 void set_connected(void); 00082 00083 // Socket events from nanostack 00084 void event_data(socket_callback_t *sock_cb); 00085 void event_bind_done(socket_callback_t *sock_cb); 00086 void event_connnect_closed(socket_callback_t *sock_cb); 00087 void event_tx_done(socket_callback_t *sock_cb); 00088 00089 // Run callback to signal the next layer of the NSAPI 00090 void signal_event(void); 00091 00092 // Add or remove a socket to the listening socket 00093 void accept_list_add(NanostackSocket *socket); 00094 NanostackSocket * accept_list_remove(void); 00095 00096 bool data_available(void); 00097 size_t data_copy_and_free(void *dest, size_t len, SocketAddress *address, bool stream); 00098 void data_free_all(void); 00099 void data_attach(NanostackBuffer *data_buf); 00100 00101 void (*callback)(void *); 00102 void *callback_data; 00103 int8_t socket_id; /*!< allocated socket ID */ 00104 int8_t proto; /*!< UDP or TCP */ 00105 bool addr_valid; 00106 ns_address_t ns_address; 00107 private: 00108 NanostackBuffer *rxBufChain; /*!< Receive buffers */ 00109 socket_mode_t mode; 00110 }; 00111 00112 static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; 00113 00114 static int map_mesh_error(mesh_error_t err) 00115 { 00116 switch (err) { 00117 case MESH_ERROR_NONE: return 0; 00118 case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY; 00119 case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED; 00120 case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR; 00121 default: return NSAPI_ERROR_DEVICE_ERROR; 00122 } 00123 } 00124 00125 static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, 00126 const SocketAddress *s_addr) 00127 { 00128 ns_addr->type = ADDRESS_IPV6; 00129 ns_addr->identifier = s_addr->get_port(); 00130 const char *str = s_addr->get_ip_address(); 00131 stoip6(str, strlen(str), ns_addr->address); 00132 } 00133 00134 static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) 00135 { 00136 char str[40]; 00137 ip6tos(ns_addr->address, str); 00138 s_addr->set_port(ns_addr->identifier); 00139 s_addr->set_ip_address(str); 00140 } 00141 00142 void* NanostackSocket::operator new(std::size_t sz) { 00143 return MALLOC(sz); 00144 } 00145 void NanostackSocket::operator delete(void* ptr) { 00146 FREE(ptr); 00147 } 00148 00149 NanostackSocket::NanostackSocket(int8_t protocol) 00150 { 00151 nanostack_assert_locked(); 00152 00153 callback = NULL; 00154 callback_data = NULL; 00155 socket_id = -1; 00156 rxBufChain = NULL; 00157 proto = protocol; 00158 addr_valid = false; 00159 memset(&ns_address, 0, sizeof(ns_address)); 00160 mode = SOCKET_MODE_UNOPENED; 00161 } 00162 00163 NanostackSocket::~NanostackSocket() 00164 { 00165 nanostack_assert_locked(); 00166 00167 if (mode != SOCKET_MODE_CLOSED) { 00168 close(); 00169 } 00170 if (socket_id >= 0) { 00171 int ret = socket_free(socket_id); 00172 MBED_ASSERT(0 == ret); 00173 MBED_ASSERT(socket_tbl[socket_id] == this); 00174 socket_id = -1; 00175 data_free_all(); 00176 } 00177 00178 } 00179 00180 bool NanostackSocket::open(void) 00181 { 00182 nanostack_assert_locked(); 00183 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00184 00185 int temp_socket = socket_open(proto, 0, socket_callback); 00186 00187 if (temp_socket < 0) { 00188 tr_error("NanostackSocket::open() failed"); 00189 return false; 00190 } 00191 if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) { 00192 MBED_ASSERT(false); 00193 return false; 00194 } 00195 if (socket_tbl[temp_socket] != NULL) { 00196 MBED_ASSERT(false); 00197 return false; 00198 } 00199 socket_id = temp_socket; 00200 socket_tbl[socket_id] = this; 00201 mode = SOCKET_MODE_OPENED; 00202 return true; 00203 00204 } 00205 00206 void NanostackSocket::close() 00207 { 00208 nanostack_assert_locked(); 00209 MBED_ASSERT(mode != SOCKET_MODE_CLOSED); 00210 00211 if (socket_id >= 0) { 00212 int ret = socket_close(socket_id, (addr_valid ? &ns_address : NULL)); 00213 MBED_ASSERT(0 == ret); 00214 } else { 00215 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00216 } 00217 00218 data_free_all(); 00219 00220 mode = SOCKET_MODE_CLOSED; 00221 signal_event(); 00222 } 00223 00224 bool NanostackSocket::is_bound() 00225 { 00226 return SOCKET_MODE_DATAGRAM == mode; 00227 } 00228 00229 void NanostackSocket::set_bound() 00230 { 00231 nanostack_assert_locked(); 00232 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00233 if (SOCKET_UDP == proto) { 00234 mode = SOCKET_MODE_DATAGRAM; 00235 } 00236 } 00237 00238 bool NanostackSocket::is_connecting() 00239 { 00240 return SOCKET_MODE_CONNECTING == mode; 00241 } 00242 00243 void NanostackSocket::set_connecting(ns_address_t *addr) 00244 { 00245 nanostack_assert_locked(); 00246 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00247 00248 memcpy(&ns_address, addr, sizeof(ns_address_t)); 00249 mode = SOCKET_MODE_CONNECTING; 00250 } 00251 00252 void NanostackSocket::set_connected() 00253 { 00254 nanostack_assert_locked(); 00255 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); 00256 00257 mode = SOCKET_MODE_STREAM; 00258 } 00259 00260 void NanostackSocket::signal_event() 00261 { 00262 nanostack_assert_locked(); 00263 00264 if (callback != NULL) { 00265 callback(callback_data); 00266 } 00267 } 00268 00269 void NanostackSocket::socket_callback(void *cb) { 00270 nanostack_assert_locked(); 00271 00272 socket_callback_t *sock_cb = (socket_callback_t *) cb; 00273 NanostackSocket *socket = socket_tbl[sock_cb->socket_id]; 00274 MBED_ASSERT(socket != NULL); 00275 00276 tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d", 00277 sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len); 00278 00279 switch (sock_cb->event_type) { 00280 case SOCKET_DATA: 00281 tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len); 00282 socket->event_data(sock_cb); 00283 break; 00284 case SOCKET_BIND_DONE: 00285 tr_debug("SOCKET_BIND_DONE"); 00286 socket->event_bind_done(sock_cb); 00287 break; 00288 case SOCKET_BIND_FAIL: // Not used in NS 00289 tr_debug("SOCKET_BIND_FAIL"); 00290 break; 00291 case SOCKET_BIND_AUTH_FAIL: // Not used in NS 00292 tr_debug("SOCKET_BIND_AUTH_FAIL"); 00293 break; 00294 case SOCKET_SERVER_CONNECT_TO_CLIENT: // Not used in NS 00295 tr_debug("SOCKET_SERVER_CONNECT_TO_CLIENT"); 00296 break; 00297 case SOCKET_TX_FAIL: 00298 tr_debug("SOCKET_TX_FAIL"); 00299 break; 00300 case SOCKET_CONNECT_CLOSED: 00301 tr_debug("SOCKET_CONNECT_CLOSED"); 00302 socket->event_connnect_closed(sock_cb); 00303 break; 00304 case SOCKET_CONNECT_FAIL_CLOSED: // Not used in NS 00305 tr_debug("SOCKET_CONNECT_FAIL_CLOSED"); 00306 break; 00307 case SOCKET_NO_ROUTE: 00308 tr_debug("SOCKET_NO_ROUTE"); 00309 break; 00310 case SOCKET_TX_DONE: 00311 tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); 00312 socket->event_tx_done(sock_cb); 00313 break; 00314 default: 00315 // SOCKET_NO_RAM, error case for SOCKET_TX_DONE 00316 break; 00317 } 00318 } 00319 00320 00321 bool NanostackSocket::data_available() 00322 { 00323 nanostack_assert_locked(); 00324 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00325 (SOCKET_MODE_CONNECTING == mode) || 00326 (SOCKET_MODE_STREAM == mode)); 00327 00328 return (NULL == rxBufChain) ? false : true; 00329 } 00330 00331 size_t NanostackSocket::data_copy_and_free(void *dest, size_t len, 00332 SocketAddress *address, bool stream) 00333 { 00334 nanostack_assert_locked(); 00335 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00336 (mode == SOCKET_MODE_STREAM)); 00337 00338 NanostackBuffer *data_buf = rxBufChain; 00339 if (NULL == data_buf) { 00340 // No data 00341 return 0; 00342 } 00343 00344 if (address) { 00345 convert_ns_addr_to_mbed(address, &data_buf->ns_address); 00346 } 00347 00348 size_t copy_size = (len > data_buf->length) ? data_buf->length : len; 00349 memcpy(dest, data_buf->payload, copy_size); 00350 00351 if (stream && (copy_size < data_buf->length)) { 00352 // Update the size in the buffer 00353 size_t new_buf_size = data_buf->length - copy_size; 00354 memmove(data_buf->payload, data_buf->payload + copy_size, new_buf_size); 00355 data_buf->length = new_buf_size; 00356 } else { 00357 // Entire packet used so free it 00358 rxBufChain = data_buf->next; 00359 FREE(data_buf); 00360 } 00361 00362 return copy_size; 00363 } 00364 00365 void NanostackSocket::data_free_all(void) 00366 { 00367 nanostack_assert_locked(); 00368 // No mode requirement 00369 00370 NanostackBuffer *buffer = rxBufChain; 00371 rxBufChain = NULL; 00372 while (buffer != NULL) { 00373 NanostackBuffer *next_buffer = buffer->next; 00374 FREE(buffer); 00375 buffer = next_buffer; 00376 } 00377 } 00378 00379 void NanostackSocket::data_attach(NanostackBuffer *data_buf) 00380 { 00381 nanostack_assert_locked(); 00382 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00383 (SOCKET_MODE_STREAM == mode)); 00384 00385 // Add to linked list 00386 tr_debug("data_attach socket=%p", this); 00387 if (NULL == rxBufChain) { 00388 rxBufChain = data_buf; 00389 } else { 00390 NanostackBuffer *buf_tmp = rxBufChain; 00391 while (NULL != buf_tmp->next) { 00392 buf_tmp = buf_tmp->next; 00393 } 00394 buf_tmp->next = data_buf; 00395 } 00396 signal_event(); 00397 } 00398 00399 void NanostackSocket::event_data(socket_callback_t *sock_cb) 00400 { 00401 nanostack_assert_locked(); 00402 MBED_ASSERT((SOCKET_MODE_DATAGRAM == mode) || 00403 (SOCKET_MODE_STREAM == mode)); 00404 00405 // Allocate buffer 00406 NanostackBuffer *recv_buff = (NanostackBuffer *) MALLOC( 00407 sizeof(NanostackBuffer) + sock_cb->d_len); 00408 if (NULL == recv_buff) { 00409 tr_error("alloc failed!"); 00410 return; 00411 } 00412 recv_buff->next = NULL; 00413 00414 // Write data to buffer 00415 int16_t length = socket_read(sock_cb->socket_id, 00416 &recv_buff->ns_address, recv_buff->payload, 00417 sock_cb->d_len); 00418 if (length < 0) { 00419 tr_error("socket_read failed!"); 00420 FREE(recv_buff); 00421 return; 00422 } 00423 recv_buff->length = length; 00424 00425 data_attach(recv_buff); 00426 } 00427 00428 void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) 00429 { 00430 nanostack_assert_locked(); 00431 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00432 (SOCKET_MODE_DATAGRAM == mode)); 00433 00434 signal_event(); 00435 } 00436 00437 void NanostackSocket::event_bind_done(socket_callback_t *sock_cb) 00438 { 00439 nanostack_assert_locked(); 00440 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); 00441 00442 set_connected(); 00443 signal_event(); 00444 } 00445 00446 void NanostackSocket::event_connnect_closed(socket_callback_t *sock_cb) 00447 { 00448 nanostack_assert_locked(); 00449 00450 // Only TCP sockets can be closed by the remote end 00451 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00452 (SOCKET_MODE_CONNECTING == mode)); 00453 close(); 00454 } 00455 00456 void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t status) 00457 { 00458 nanostack_lock(); 00459 00460 if (status == MESH_CONNECTED) { 00461 connect_semaphore.release(); 00462 } 00463 00464 nanostack_unlock(); 00465 } 00466 00467 int MeshInterfaceNanostack::register_rf() 00468 { 00469 nanostack_lock(); 00470 00471 rf_device_id = rf_device_register(); 00472 if (rf_device_id < 0) { 00473 nanostack_unlock(); 00474 return -1; 00475 } 00476 // Read mac address after registering the device. 00477 rf_read_mac_address(eui64); 00478 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]); 00479 00480 nanostack_unlock(); 00481 00482 return 0; 00483 } 00484 00485 int MeshInterfaceNanostack::actual_connect() 00486 { 00487 nanostack_assert_locked(); 00488 00489 mesh_error_t status = mesh_api->connect(); 00490 if (status != MESH_ERROR_NONE) { 00491 nanostack_unlock(); 00492 return map_mesh_error(status); 00493 } 00494 00495 // Release mutex before blocking 00496 nanostack_unlock(); 00497 00498 int32_t count = connect_semaphore.wait(30000); 00499 00500 nanostack_lock(); 00501 00502 if (count <= 0) { 00503 return NSAPI_ERROR_DHCP_FAILURE; // sort of... 00504 } 00505 return 0; 00506 } 00507 00508 NetworkStack * MeshInterfaceNanostack::get_stack() 00509 { 00510 return NanostackInterface::get_stack(); 00511 } 00512 00513 int MeshInterfaceNanostack::disconnect() 00514 { 00515 nanostack_lock(); 00516 00517 mesh_error_t status = mesh_api->disconnect(); 00518 00519 nanostack_unlock(); 00520 00521 return map_mesh_error(status); 00522 } 00523 00524 const char *MeshInterfaceNanostack::get_ip_address() 00525 { 00526 nanostack_lock(); 00527 00528 const char *ret = NULL; 00529 if (mesh_api && mesh_api->getOwnIpAddress(ip_addr_str, sizeof ip_addr_str)) { 00530 ret = ip_addr_str; 00531 } 00532 00533 nanostack_unlock(); 00534 00535 return ret; 00536 } 00537 00538 const char *MeshInterfaceNanostack::get_mac_address() 00539 { 00540 return mac_addr_str; 00541 } 00542 00543 int ThreadInterface::connect() 00544 { 00545 // initialize mesh networking resources, memory, timers, etc... 00546 mesh_system_init(); 00547 nanostack_lock(); 00548 00549 mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_THREAD); 00550 if (!mesh_api) { 00551 nanostack_unlock(); 00552 return NSAPI_ERROR_NO_MEMORY; 00553 } 00554 if (register_rf() < 0) { 00555 nanostack_unlock(); 00556 return NSAPI_ERROR_DEVICE_ERROR; 00557 } 00558 00559 // After the RF is up, we can seed the random from it. 00560 randLIB_seed_random(); 00561 00562 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); 00563 if (status != MESH_ERROR_NONE) { 00564 nanostack_unlock(); 00565 return map_mesh_error(status); 00566 } 00567 int ret = this->actual_connect(); 00568 00569 nanostack_unlock(); 00570 00571 return ret; 00572 } 00573 00574 int LoWPANNDInterface::connect() 00575 { 00576 // initialize mesh networking resources, memory, timers, etc... 00577 mesh_system_init(); 00578 nanostack_lock(); 00579 00580 mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_6LOWPAN_ND); 00581 if (!mesh_api) { 00582 nanostack_unlock(); 00583 return NSAPI_ERROR_NO_MEMORY; 00584 } 00585 if (register_rf() < 0) { 00586 nanostack_unlock(); 00587 return NSAPI_ERROR_DEVICE_ERROR; 00588 } 00589 00590 // After the RF is up, we can seed the random from it. 00591 randLIB_seed_random(); 00592 00593 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)); 00594 if (status != MESH_ERROR_NONE) { 00595 nanostack_unlock(); 00596 return map_mesh_error(status); 00597 } 00598 int ret = this->actual_connect(); 00599 00600 nanostack_unlock(); 00601 00602 return ret; 00603 } 00604 00605 NanostackInterface * NanostackInterface::_ns_interface; 00606 00607 NanostackInterface * NanostackInterface::get_stack() 00608 { 00609 nanostack_lock(); 00610 00611 if (NULL == _ns_interface) { 00612 _ns_interface = new NanostackInterface(); 00613 } 00614 00615 nanostack_unlock(); 00616 00617 return _ns_interface; 00618 } 00619 00620 00621 const char * NanostackInterface::get_ip_address() 00622 { 00623 // Unsupported 00624 return NULL; 00625 } 00626 00627 int NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) 00628 { 00629 // Validate parameters 00630 if (NULL == handle) { 00631 MBED_ASSERT(false); 00632 return NSAPI_ERROR_NO_SOCKET; 00633 } 00634 int8_t ns_proto; 00635 if (NSAPI_UDP == protocol) { 00636 ns_proto = SOCKET_UDP; 00637 } else if (NSAPI_TCP == protocol) { 00638 ns_proto = SOCKET_TCP; 00639 } else { 00640 MBED_ASSERT(false); 00641 return NSAPI_ERROR_UNSUPPORTED; 00642 } 00643 *handle = (void*)NULL; 00644 00645 nanostack_lock(); 00646 00647 NanostackSocket * socket = new NanostackSocket(ns_proto); 00648 if (NULL == socket) { 00649 nanostack_unlock(); 00650 tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY); 00651 return NSAPI_ERROR_NO_MEMORY; 00652 } 00653 if (!socket->open()) { 00654 delete socket; 00655 nanostack_unlock(); 00656 tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR); 00657 return NSAPI_ERROR_DEVICE_ERROR; 00658 } 00659 *handle = (void*)socket; 00660 00661 nanostack_unlock(); 00662 00663 tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); 00664 00665 return 0; 00666 } 00667 00668 int NanostackInterface::socket_close(void *handle) 00669 { 00670 // Validate parameters 00671 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00672 if (NULL == handle) { 00673 MBED_ASSERT(false); 00674 return NSAPI_ERROR_NO_SOCKET; 00675 } 00676 tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); 00677 00678 nanostack_lock(); 00679 00680 delete socket; 00681 00682 nanostack_unlock(); 00683 00684 return 0; 00685 00686 } 00687 00688 int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned int size) 00689 { 00690 // Validate parameters 00691 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00692 if (NULL == handle) { 00693 MBED_ASSERT(false); 00694 return NSAPI_ERROR_NO_SOCKET; 00695 } 00696 00697 nanostack_lock(); 00698 00699 int ret; 00700 if (socket->closed()) { 00701 ret = NSAPI_ERROR_NO_CONNECTION; 00702 } else if (NANOSTACK_SOCKET_TCP == socket->proto) { 00703 tr_error("socket_sendto() not supported with SOCKET_STREAM!"); 00704 ret = NSAPI_ERROR_UNSUPPORTED; 00705 } else { 00706 ns_address_t ns_address; 00707 convert_mbed_addr_to_ns(&ns_address, &address); 00708 if (!socket->is_bound()) { 00709 socket->set_bound(); 00710 } 00711 int8_t send_to_status = ::socket_sendto(socket->socket_id, &ns_address, 00712 (uint8_t *)data, size); 00713 /* 00714 * \return 0 on success. 00715 * \return -1 invalid socket id. 00716 * \return -2 Socket memory allocation fail. 00717 * \return -3 TCP state not established. 00718 * \return -4 Socket tx process busy. 00719 * \return -5 TLS authentication not ready. 00720 * \return -6 Packet too short. 00721 * */ 00722 if (-4 == send_to_status) { 00723 ret = NSAPI_ERROR_WOULD_BLOCK; 00724 } else if (0 != send_to_status) { 00725 tr_error("socket_sendto: error=%d", send_to_status); 00726 ret = NSAPI_ERROR_DEVICE_ERROR; 00727 } else { 00728 ret = size; 00729 } 00730 } 00731 00732 nanostack_unlock(); 00733 00734 tr_debug("socket_sendto(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00735 00736 return ret; 00737 } 00738 00739 int NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) 00740 { 00741 // Validate parameters 00742 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00743 if (NULL == handle) { 00744 MBED_ASSERT(false); 00745 return NSAPI_ERROR_NO_SOCKET; 00746 } 00747 if (NULL == buffer) { 00748 MBED_ASSERT(false); 00749 return NSAPI_ERROR_PARAMETER; 00750 } 00751 if (0 == size) { 00752 MBED_ASSERT(false); 00753 return NSAPI_ERROR_PARAMETER; 00754 } 00755 00756 nanostack_lock(); 00757 00758 int ret; 00759 if (socket->closed()) { 00760 ret = NSAPI_ERROR_NO_CONNECTION; 00761 } else if (NANOSTACK_SOCKET_TCP == socket->proto) { 00762 tr_error("recv_from() not supported with SOCKET_STREAM!"); 00763 ret = NSAPI_ERROR_UNSUPPORTED; 00764 } else if (!socket->data_available()) { 00765 ret = NSAPI_ERROR_WOULD_BLOCK; 00766 } else { 00767 ret = socket->data_copy_and_free(buffer, size, address, false); 00768 } 00769 00770 nanostack_unlock(); 00771 00772 tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00773 00774 return ret; 00775 } 00776 00777 int NanostackInterface::socket_bind(void *handle, const SocketAddress &address) 00778 { 00779 // Validate parameters 00780 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00781 if (NULL == handle) { 00782 MBED_ASSERT(false); 00783 return NSAPI_ERROR_NO_SOCKET; 00784 } 00785 00786 00787 nanostack_lock(); 00788 00789 ns_address_t ns_address; 00790 ns_address.type = ADDRESS_IPV6; 00791 memset(ns_address.address, 0, sizeof ns_address.address); 00792 ns_address.identifier = address.get_port(); 00793 int ret = NSAPI_ERROR_DEVICE_ERROR; 00794 if (0 == ::socket_bind(socket->socket_id, &ns_address)) { 00795 socket->set_bound(); 00796 ret = 0; 00797 } 00798 00799 nanostack_unlock(); 00800 00801 tr_debug("socket_bind(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00802 00803 return ret; 00804 } 00805 00806 int NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00807 { 00808 return NSAPI_ERROR_UNSUPPORTED; 00809 } 00810 00811 int NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00812 { 00813 return NSAPI_ERROR_UNSUPPORTED; 00814 } 00815 00816 int NanostackInterface::socket_listen(void *handle, int backlog) 00817 { 00818 return NSAPI_ERROR_UNSUPPORTED; 00819 } 00820 00821 int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) 00822 { 00823 // Validate parameters 00824 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00825 if (NULL == handle) { 00826 MBED_ASSERT(false); 00827 return NSAPI_ERROR_NO_SOCKET; 00828 } 00829 00830 nanostack_lock(); 00831 00832 int ret; 00833 ns_address_t ns_addr; 00834 int random_port = socket->is_bound() ? 0 : 1; 00835 convert_mbed_addr_to_ns(&ns_addr, &addr); 00836 if (0 == ::socket_connect(socket->socket_id, &ns_addr, random_port)) { 00837 socket->set_connecting(&ns_addr); 00838 ret = 0; 00839 } else { 00840 ret = NSAPI_ERROR_DEVICE_ERROR; 00841 } 00842 00843 nanostack_unlock(); 00844 00845 tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00846 00847 return ret; 00848 } 00849 00850 int NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) 00851 { 00852 return NSAPI_ERROR_UNSUPPORTED; 00853 } 00854 00855 int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) 00856 { 00857 // Validate parameters 00858 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00859 if (NULL == handle) { 00860 MBED_ASSERT(false); 00861 return NSAPI_ERROR_NO_SOCKET; 00862 } 00863 00864 nanostack_lock(); 00865 00866 int ret; 00867 if (socket->closed()) { 00868 ret = NSAPI_ERROR_NO_CONNECTION; 00869 } else if (socket->is_connecting()) { 00870 ret = NSAPI_ERROR_WOULD_BLOCK; 00871 } else { 00872 ret = ::socket_sendto(socket->socket_id, &socket->ns_address, (uint8_t*)p, size); 00873 /* 00874 * \return 0 on success. 00875 * \return -1 invalid socket id. 00876 * \return -2 Socket memory allocation fail. 00877 * \return -3 TCP state not established. 00878 * \return -4 Socket tx process busy. 00879 * \return -5 TLS authentication not ready. 00880 * \return -6 Packet too short. 00881 * */ 00882 if (-4 == ret) { 00883 ret = NSAPI_ERROR_WOULD_BLOCK; 00884 } else if (ret != 0) { 00885 tr_warning("socket_sendto ret %i, socket_id %i", ret, socket->socket_id); 00886 ret = NSAPI_ERROR_DEVICE_ERROR; 00887 } else { 00888 ret = size; 00889 } 00890 } 00891 00892 nanostack_unlock(); 00893 00894 tr_debug("socket_send(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00895 00896 return ret; 00897 } 00898 00899 int NanostackInterface::socket_recv(void *handle, void *data, unsigned size) 00900 { 00901 // Validate parameters 00902 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00903 if (NULL == handle) { 00904 MBED_ASSERT(false); 00905 return NSAPI_ERROR_NO_SOCKET; 00906 } 00907 00908 nanostack_lock(); 00909 00910 int ret; 00911 if (socket->closed()) { 00912 ret = NSAPI_ERROR_NO_CONNECTION; 00913 } else if (socket->data_available()) { 00914 ret = socket->data_copy_and_free(data, size, NULL, true); 00915 } else { 00916 ret = NSAPI_ERROR_WOULD_BLOCK; 00917 } 00918 00919 nanostack_unlock(); 00920 00921 tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00922 00923 return ret; 00924 } 00925 00926 void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) 00927 { 00928 // Validate parameters 00929 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00930 if (NULL == handle) { 00931 MBED_ASSERT(false); 00932 return; 00933 } 00934 00935 nanostack_lock(); 00936 00937 socket->callback = callback; 00938 socket->callback_data = id; 00939 00940 nanostack_unlock(); 00941 00942 tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); 00943 }
Generated on Tue Jul 12 2022 12:58:32 by
1.7.2