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: blinky_max32630fthr
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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t ret = this->actual_connect(); 00586 00587 nanostack_unlock(); 00588 00589 return ret; 00590 } 00591 00592 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t 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 nsapi_size_or_error_t 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 nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t 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 nsapi_size_or_error_t 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 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00840 { 00841 return NSAPI_ERROR_UNSUPPORTED ; 00842 } 00843 00844 nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00845 { 00846 return NSAPI_ERROR_UNSUPPORTED ; 00847 } 00848 00849 nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog) 00850 { 00851 return NSAPI_ERROR_UNSUPPORTED ; 00852 } 00853 00854 nsapi_error_t 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 nsapi_error_t 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 nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) 00888 { 00889 return NSAPI_ERROR_UNSUPPORTED ; 00890 } 00891 00892 nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *p, nsapi_size_t 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 nsapi_size_or_error_t 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 nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t 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 nsapi_size_or_error_t 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 14:21:16 by
1.7.2
