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 #include "ip6string.h" 00032 // Uncomment to enable trace 00033 //#define HAVE_DEBUG 00034 #include "ns_trace.h" 00035 #define TRACE_GROUP "nsif" 00036 00037 #define NS_INTERFACE_SOCKETS_MAX 16 //same as NanoStack SOCKET_MAX 00038 #define NANOSTACK_SOCKET_UDP 17 // same as nanostack SOCKET_UDP 00039 #define NANOSTACK_SOCKET_TCP 6 // same as nanostack SOCKET_TCP 00040 00041 #define MALLOC ns_dyn_mem_alloc 00042 #define FREE ns_dyn_mem_free 00043 00044 #define nanostack_lock() eventOS_scheduler_mutex_wait() 00045 #define nanostack_unlock() eventOS_scheduler_mutex_release() 00046 #define nanostack_assert_locked() //MBED_ASSERT(eventOS_scheduler_mutex_is_owner()) 00047 00048 enum socket_mode_t { 00049 SOCKET_MODE_UNOPENED, // No socket ID 00050 SOCKET_MODE_OPENED, // Socket ID but no assigned use yet 00051 SOCKET_MODE_CONNECTING, // Socket is connecting but not open yet 00052 SOCKET_MODE_DATAGRAM, // Socket is bound to a port and listening for datagrams 00053 SOCKET_MODE_STREAM, // Socket has an open stream 00054 SOCKET_MODE_CLOSED, // Socket is closed and resources are freed 00055 }; 00056 00057 class NanostackBuffer { 00058 public: 00059 NanostackBuffer *next; /*<! next buffer */ 00060 ns_address_t ns_address; /*<! address where data is received */ 00061 uint16_t length; /*<! data length in this buffer */ 00062 uint8_t payload[1]; /*<! Trailing buffer data */ 00063 }; 00064 00065 class NanostackSocket { 00066 public: 00067 static void socket_callback(void *cb); 00068 static void* operator new(std::size_t sz); 00069 static void operator delete(void* ptr); 00070 00071 NanostackSocket(int8_t protocol); 00072 ~NanostackSocket(void); 00073 bool open(void); 00074 void close(void); 00075 bool closed(void) {return SOCKET_MODE_CLOSED == mode;} 00076 bool is_bound(void); 00077 void set_bound(void); 00078 bool is_connecting(void); 00079 void set_connecting(ns_address_t *addr); 00080 void set_connected(void); 00081 00082 // Socket events from nanostack 00083 void event_data(socket_callback_t *sock_cb); 00084 void event_bind_done(socket_callback_t *sock_cb); 00085 void event_connnect_closed(socket_callback_t *sock_cb); 00086 void event_tx_done(socket_callback_t *sock_cb); 00087 00088 // Run callback to signal the next layer of the NSAPI 00089 void signal_event(void); 00090 00091 // Add or remove a socket to the listening socket 00092 void accept_list_add(NanostackSocket *socket); 00093 NanostackSocket * accept_list_remove(void); 00094 00095 bool data_available(void); 00096 size_t data_copy_and_free(void *dest, size_t len, SocketAddress *address, bool stream); 00097 void data_free_all(void); 00098 void data_attach(NanostackBuffer *data_buf); 00099 00100 void (*callback)(void *); 00101 void *callback_data; 00102 int8_t socket_id; /*!< allocated socket ID */ 00103 int8_t proto; /*!< UDP or TCP */ 00104 bool addr_valid; 00105 ns_address_t ns_address; 00106 private: 00107 NanostackBuffer *rxBufChain; /*!< Receive buffers */ 00108 socket_mode_t mode; 00109 }; 00110 00111 static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; 00112 00113 static int map_mesh_error(mesh_error_t err) 00114 { 00115 switch (err) { 00116 case MESH_ERROR_NONE: return 0; 00117 case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY ; 00118 case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED ; 00119 case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR ; 00120 default: return NSAPI_ERROR_DEVICE_ERROR ; 00121 } 00122 } 00123 00124 static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, 00125 const SocketAddress *s_addr) 00126 { 00127 ns_addr->type = ADDRESS_IPV6; 00128 ns_addr->identifier = s_addr->get_port(); 00129 const char *str = s_addr->get_ip_address(); 00130 stoip6(str, strlen(str), ns_addr->address); 00131 } 00132 00133 static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) 00134 { 00135 char str[40]; 00136 ip6tos(ns_addr->address, str); 00137 s_addr->set_port(ns_addr->identifier); 00138 s_addr->set_ip_address(str); 00139 } 00140 00141 void* NanostackSocket::operator new(std::size_t sz) { 00142 return MALLOC(sz); 00143 } 00144 void NanostackSocket::operator delete(void* ptr) { 00145 FREE(ptr); 00146 } 00147 00148 NanostackSocket::NanostackSocket(int8_t protocol) 00149 { 00150 nanostack_assert_locked(); 00151 00152 callback = NULL; 00153 callback_data = NULL; 00154 socket_id = -1; 00155 rxBufChain = NULL; 00156 proto = protocol; 00157 addr_valid = false; 00158 memset(&ns_address, 0, sizeof(ns_address)); 00159 mode = SOCKET_MODE_UNOPENED; 00160 } 00161 00162 NanostackSocket::~NanostackSocket() 00163 { 00164 nanostack_assert_locked(); 00165 00166 if (mode != SOCKET_MODE_CLOSED) { 00167 close(); 00168 } 00169 if (socket_id >= 0) { 00170 int ret = socket_free(socket_id); 00171 MBED_ASSERT(0 == ret); 00172 MBED_ASSERT(socket_tbl[socket_id] == this); 00173 socket_tbl[socket_id] = NULL; 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 MeshInterfaceNanostack::MeshInterfaceNanostack() 00457 : phy(NULL), mesh_api(NULL), rf_device_id(-1), eui64(), 00458 ip_addr_str(), mac_addr_str(), connect_semaphore(0) 00459 { 00460 // Nothing to do 00461 } 00462 00463 MeshInterfaceNanostack::MeshInterfaceNanostack(NanostackRfPhy *phy) 00464 : phy(phy), mesh_api(NULL), rf_device_id(-1), connect_semaphore(0) 00465 { 00466 // Nothing to do 00467 } 00468 00469 int MeshInterfaceNanostack::initialize(NanostackRfPhy *phy) 00470 { 00471 if (this->phy != NULL) { 00472 error("Phy already set"); 00473 } 00474 this->phy = phy; 00475 return 0; 00476 } 00477 00478 void MeshInterfaceNanostack::mesh_network_handler(mesh_connection_status_t status) 00479 { 00480 nanostack_lock(); 00481 00482 if (status == MESH_CONNECTED) { 00483 connect_semaphore.release(); 00484 } 00485 00486 nanostack_unlock(); 00487 } 00488 00489 int MeshInterfaceNanostack::register_rf() 00490 { 00491 nanostack_lock(); 00492 00493 rf_device_id = phy->rf_register(); 00494 if (rf_device_id < 0) { 00495 nanostack_unlock(); 00496 return -1; 00497 } 00498 // Read mac address after registering the device. 00499 phy->get_mac_address(eui64); 00500 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]); 00501 00502 nanostack_unlock(); 00503 00504 return 0; 00505 } 00506 00507 int MeshInterfaceNanostack::actual_connect() 00508 { 00509 nanostack_assert_locked(); 00510 00511 mesh_error_t status = mesh_api->connect(); 00512 if (status != MESH_ERROR_NONE) { 00513 nanostack_unlock(); 00514 return map_mesh_error(status); 00515 } 00516 00517 // Release mutex before blocking 00518 nanostack_unlock(); 00519 00520 int32_t count = connect_semaphore.wait(30000); 00521 00522 nanostack_lock(); 00523 00524 if (count <= 0) { 00525 return NSAPI_ERROR_DHCP_FAILURE ; // sort of... 00526 } 00527 return 0; 00528 } 00529 00530 NetworkStack * MeshInterfaceNanostack::get_stack() 00531 { 00532 return NanostackInterface::get_stack(); 00533 } 00534 00535 int MeshInterfaceNanostack::disconnect() 00536 { 00537 nanostack_lock(); 00538 00539 mesh_error_t status = mesh_api->disconnect(); 00540 00541 nanostack_unlock(); 00542 00543 return map_mesh_error(status); 00544 } 00545 00546 const char *MeshInterfaceNanostack::get_ip_address() 00547 { 00548 nanostack_lock(); 00549 00550 const char *ret = NULL; 00551 if (mesh_api && mesh_api->getOwnIpAddress(ip_addr_str, sizeof ip_addr_str)) { 00552 ret = ip_addr_str; 00553 } 00554 00555 nanostack_unlock(); 00556 00557 return ret; 00558 } 00559 00560 const char *MeshInterfaceNanostack::get_mac_address() 00561 { 00562 return mac_addr_str; 00563 } 00564 00565 int ThreadInterface::connect() 00566 { 00567 // initialize mesh networking resources, memory, timers, etc... 00568 mesh_system_init(); 00569 nanostack_lock(); 00570 00571 mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_THREAD); 00572 if (!mesh_api) { 00573 nanostack_unlock(); 00574 return NSAPI_ERROR_NO_MEMORY ; 00575 } 00576 if (register_rf() < 0) { 00577 nanostack_unlock(); 00578 return NSAPI_ERROR_DEVICE_ERROR ; 00579 } 00580 00581 // After the RF is up, we can seed the random from it. 00582 randLIB_seed_random(); 00583 00584 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); 00585 if (status != MESH_ERROR_NONE) { 00586 nanostack_unlock(); 00587 return map_mesh_error(status); 00588 } 00589 int ret = this->actual_connect(); 00590 00591 nanostack_unlock(); 00592 00593 return ret; 00594 } 00595 00596 int LoWPANNDInterface::connect() 00597 { 00598 // initialize mesh networking resources, memory, timers, etc... 00599 mesh_system_init(); 00600 nanostack_lock(); 00601 00602 mesh_api = MeshInterfaceFactory::createInterface(MESH_TYPE_6LOWPAN_ND); 00603 if (!mesh_api) { 00604 nanostack_unlock(); 00605 return NSAPI_ERROR_NO_MEMORY ; 00606 } 00607 if (register_rf() < 0) { 00608 nanostack_unlock(); 00609 return NSAPI_ERROR_DEVICE_ERROR ; 00610 } 00611 00612 // After the RF is up, we can seed the random from it. 00613 randLIB_seed_random(); 00614 00615 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)); 00616 if (status != MESH_ERROR_NONE) { 00617 nanostack_unlock(); 00618 return map_mesh_error(status); 00619 } 00620 int ret = this->actual_connect(); 00621 00622 nanostack_unlock(); 00623 00624 return ret; 00625 } 00626 00627 NanostackInterface * NanostackInterface::_ns_interface; 00628 00629 NanostackInterface * NanostackInterface::get_stack() 00630 { 00631 nanostack_lock(); 00632 00633 if (NULL == _ns_interface) { 00634 _ns_interface = new NanostackInterface(); 00635 } 00636 00637 nanostack_unlock(); 00638 00639 return _ns_interface; 00640 } 00641 00642 00643 const char * NanostackInterface::get_ip_address() 00644 { 00645 // Unsupported 00646 return NULL; 00647 } 00648 00649 int NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) 00650 { 00651 // Validate parameters 00652 if (NULL == handle) { 00653 MBED_ASSERT(false); 00654 return NSAPI_ERROR_NO_SOCKET ; 00655 } 00656 int8_t ns_proto; 00657 if (NSAPI_UDP == protocol) { 00658 ns_proto = SOCKET_UDP; 00659 } else if (NSAPI_TCP == protocol) { 00660 ns_proto = SOCKET_TCP; 00661 } else { 00662 MBED_ASSERT(false); 00663 return NSAPI_ERROR_UNSUPPORTED ; 00664 } 00665 *handle = (void*)NULL; 00666 00667 nanostack_lock(); 00668 00669 NanostackSocket * socket = new NanostackSocket(ns_proto); 00670 if (NULL == socket) { 00671 nanostack_unlock(); 00672 tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY ); 00673 return NSAPI_ERROR_NO_MEMORY ; 00674 } 00675 if (!socket->open()) { 00676 delete socket; 00677 nanostack_unlock(); 00678 tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR ); 00679 return NSAPI_ERROR_DEVICE_ERROR ; 00680 } 00681 *handle = (void*)socket; 00682 00683 nanostack_unlock(); 00684 00685 tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); 00686 00687 return 0; 00688 } 00689 00690 int NanostackInterface::socket_close(void *handle) 00691 { 00692 // Validate parameters 00693 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00694 if (NULL == handle) { 00695 MBED_ASSERT(false); 00696 return NSAPI_ERROR_NO_SOCKET ; 00697 } 00698 tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); 00699 00700 nanostack_lock(); 00701 00702 delete socket; 00703 00704 nanostack_unlock(); 00705 00706 return 0; 00707 00708 } 00709 00710 int NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned int size) 00711 { 00712 // Validate parameters 00713 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00714 if (NULL == handle) { 00715 MBED_ASSERT(false); 00716 return NSAPI_ERROR_NO_SOCKET ; 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 00809 nanostack_lock(); 00810 00811 ns_address_t ns_address; 00812 ns_address.type = ADDRESS_IPV6; 00813 memset(ns_address.address, 0, sizeof ns_address.address); 00814 ns_address.identifier = address.get_port(); 00815 int ret = NSAPI_ERROR_DEVICE_ERROR ; 00816 if (0 == ::socket_bind(socket->socket_id, &ns_address)) { 00817 socket->set_bound(); 00818 ret = 0; 00819 } 00820 00821 nanostack_unlock(); 00822 00823 tr_debug("socket_bind(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00824 00825 return ret; 00826 } 00827 00828 int NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00829 { 00830 return NSAPI_ERROR_UNSUPPORTED ; 00831 } 00832 00833 int NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00834 { 00835 return NSAPI_ERROR_UNSUPPORTED ; 00836 } 00837 00838 int NanostackInterface::socket_listen(void *handle, int backlog) 00839 { 00840 return NSAPI_ERROR_UNSUPPORTED ; 00841 } 00842 00843 int NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) 00844 { 00845 // Validate parameters 00846 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00847 if (NULL == handle) { 00848 MBED_ASSERT(false); 00849 return NSAPI_ERROR_NO_SOCKET ; 00850 } 00851 00852 nanostack_lock(); 00853 00854 int ret; 00855 ns_address_t ns_addr; 00856 int random_port = socket->is_bound() ? 0 : 1; 00857 convert_mbed_addr_to_ns(&ns_addr, &addr); 00858 if (0 == ::socket_connect(socket->socket_id, &ns_addr, random_port)) { 00859 socket->set_connecting(&ns_addr); 00860 ret = 0; 00861 } else { 00862 ret = NSAPI_ERROR_DEVICE_ERROR ; 00863 } 00864 00865 nanostack_unlock(); 00866 00867 tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00868 00869 return ret; 00870 } 00871 00872 int NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) 00873 { 00874 return NSAPI_ERROR_UNSUPPORTED ; 00875 } 00876 00877 int NanostackInterface::socket_send(void *handle, const void *p, unsigned size) 00878 { 00879 // Validate parameters 00880 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00881 if (NULL == handle) { 00882 MBED_ASSERT(false); 00883 return NSAPI_ERROR_NO_SOCKET ; 00884 } 00885 00886 nanostack_lock(); 00887 00888 int ret; 00889 if (socket->closed()) { 00890 ret = NSAPI_ERROR_NO_CONNECTION ; 00891 } else if (socket->is_connecting()) { 00892 ret = NSAPI_ERROR_WOULD_BLOCK ; 00893 } else { 00894 ret = ::socket_sendto(socket->socket_id, &socket->ns_address, (uint8_t*)p, size); 00895 /* 00896 * \return 0 on success. 00897 * \return -1 invalid socket id. 00898 * \return -2 Socket memory allocation fail. 00899 * \return -3 TCP state not established. 00900 * \return -4 Socket tx process busy. 00901 * \return -5 TLS authentication not ready. 00902 * \return -6 Packet too short. 00903 * */ 00904 if (-4 == ret) { 00905 ret = NSAPI_ERROR_WOULD_BLOCK ; 00906 } else if (ret != 0) { 00907 tr_warning("socket_sendto ret %i, socket_id %i", ret, socket->socket_id); 00908 ret = NSAPI_ERROR_DEVICE_ERROR ; 00909 } else { 00910 ret = size; 00911 } 00912 } 00913 00914 nanostack_unlock(); 00915 00916 tr_debug("socket_send(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00917 00918 return ret; 00919 } 00920 00921 int NanostackInterface::socket_recv(void *handle, void *data, unsigned size) 00922 { 00923 // Validate parameters 00924 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00925 if (NULL == handle) { 00926 MBED_ASSERT(false); 00927 return NSAPI_ERROR_NO_SOCKET ; 00928 } 00929 00930 nanostack_lock(); 00931 00932 int ret; 00933 if (socket->closed()) { 00934 ret = NSAPI_ERROR_NO_CONNECTION ; 00935 } else if (socket->data_available()) { 00936 ret = socket->data_copy_and_free(data, size, NULL, true); 00937 } else { 00938 ret = NSAPI_ERROR_WOULD_BLOCK ; 00939 } 00940 00941 nanostack_unlock(); 00942 00943 tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00944 00945 return ret; 00946 } 00947 00948 void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) 00949 { 00950 // Validate parameters 00951 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00952 if (NULL == handle) { 00953 MBED_ASSERT(false); 00954 return; 00955 } 00956 00957 nanostack_lock(); 00958 00959 socket->callback = callback; 00960 socket->callback_data = id; 00961 00962 nanostack_unlock(); 00963 00964 tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); 00965 }
Generated on Tue Jul 12 2022 17:34:49 by
1.7.2