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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
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:28:44 by
