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