Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 #include "NanostackLockGuard.h" 00021 00022 #include "ns_address.h" 00023 #include "nsdynmemLIB.h" 00024 #include "eventOS_scheduler.h" 00025 #include "randLIB.h" 00026 #include "ip6string.h" 00027 00028 #include "mesh_system.h" // from inside mbed-mesh-api 00029 #include "socket_api.h" 00030 #include "net_interface.h" 00031 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 00039 #define MALLOC ns_dyn_mem_alloc 00040 #define FREE ns_dyn_mem_free 00041 00042 // Socket state progressions: 00043 // UDP: UNOPENED -> DATAGRAM 00044 // TCP client: UNOPENED -> OPENED -> CONNECTING -> STREAM -> CLOSED 00045 // TCP server: UNOPENED -> OPENED -> LISTENING 00046 // TCP accept: UNOPENED -> STREAM -> CLOSED 00047 enum socket_mode_t { 00048 SOCKET_MODE_UNOPENED, // No socket ID 00049 SOCKET_MODE_DATAGRAM, // Socket is datagram type 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_STREAM, // Socket has an open stream 00053 SOCKET_MODE_CLOSED, // Socket is closed and resources are freed 00054 SOCKET_MODE_LISTENING, // Socket is listening for connections 00055 }; 00056 00057 00058 class NanostackSocket { 00059 public: 00060 static void socket_callback(void *cb); 00061 static void* operator new(std::size_t sz); 00062 static void operator delete(void* ptr); 00063 00064 NanostackSocket(int8_t protocol); 00065 ~NanostackSocket(void); 00066 bool open(void); 00067 int accept(NanostackSocket *accepted_socket, ns_address_t *addr); 00068 void close(void); 00069 bool closed(void) {return SOCKET_MODE_CLOSED == mode;} 00070 bool is_connecting(void); 00071 void set_connecting(ns_address_t *addr); 00072 bool is_connected(void); 00073 void set_connected(void); 00074 bool is_listening(void); 00075 void set_listening(void); 00076 00077 // Socket events from nanostack 00078 void event_data(socket_callback_t *sock_cb); 00079 void event_connect_done(socket_callback_t *sock_cb); 00080 void event_connect_fail(socket_callback_t *sock_cb); 00081 void event_connect_closed(socket_callback_t *sock_cb); 00082 void event_connection_reset(socket_callback_t *sock_cb); 00083 void event_tx_done(socket_callback_t *sock_cb); 00084 void event_tx_fail(socket_callback_t *sock_cb); 00085 void event_incoming_connection(socket_callback_t *sock_cb); 00086 00087 // Run callback to signal the next layer of the NSAPI 00088 void signal_event(void); 00089 00090 void (*callback)(void *); 00091 void *callback_data; 00092 int8_t socket_id; /*!< allocated socket ID */ 00093 int8_t proto; /*!< UDP or TCP */ 00094 bool addr_valid; 00095 ns_address_t ns_address; 00096 private: 00097 bool attach(int8_t socket_id); 00098 socket_mode_t mode; 00099 }; 00100 00101 static NanostackSocket * socket_tbl[NS_INTERFACE_SOCKETS_MAX]; 00102 00103 nsapi_error_t map_mesh_error(mesh_error_t err) 00104 { 00105 switch (err) { 00106 case MESH_ERROR_NONE: return 0; 00107 case MESH_ERROR_MEMORY: return NSAPI_ERROR_NO_MEMORY ; 00108 case MESH_ERROR_PARAM: return NSAPI_ERROR_UNSUPPORTED ; 00109 case MESH_ERROR_STATE: return NSAPI_ERROR_DEVICE_ERROR ; 00110 default: return NSAPI_ERROR_DEVICE_ERROR ; 00111 } 00112 } 00113 00114 static void convert_mbed_addr_to_ns(ns_address_t *ns_addr, 00115 const SocketAddress *s_addr) 00116 { 00117 ns_addr->type = ADDRESS_IPV6; 00118 ns_addr->identifier = s_addr->get_port(); 00119 memcpy(ns_addr->address, s_addr->get_ip_bytes(), 16); 00120 } 00121 00122 static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *ns_addr) 00123 { 00124 s_addr->set_port(ns_addr->identifier); 00125 s_addr->set_ip_bytes(ns_addr->address, NSAPI_IPv6 ); 00126 } 00127 00128 void* NanostackSocket::operator new(std::size_t sz) { 00129 return MALLOC(sz); 00130 } 00131 void NanostackSocket::operator delete(void* ptr) { 00132 FREE(ptr); 00133 } 00134 00135 NanostackSocket::NanostackSocket(int8_t protocol) 00136 { 00137 nanostack_assert_locked(); 00138 00139 callback = NULL; 00140 callback_data = NULL; 00141 socket_id = -1; 00142 proto = protocol; 00143 addr_valid = false; 00144 memset(&ns_address, 0, sizeof(ns_address)); 00145 mode = SOCKET_MODE_UNOPENED; 00146 } 00147 00148 NanostackSocket::~NanostackSocket() 00149 { 00150 nanostack_assert_locked(); 00151 00152 if (mode != SOCKET_MODE_CLOSED) { 00153 close(); 00154 } 00155 } 00156 00157 bool NanostackSocket::open(void) 00158 { 00159 nanostack_assert_locked(); 00160 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00161 00162 int temp_socket = socket_open(proto, 0, socket_callback); 00163 00164 if (temp_socket < 0) { 00165 tr_error("NanostackSocket::open() failed"); 00166 return false; 00167 } 00168 00169 if (proto == SOCKET_TCP) { 00170 /* Receive and send buffers enabled by default */ 00171 mode = SOCKET_MODE_OPENED; 00172 } else { 00173 static const int32_t rcvbuf_size = 2048; 00174 socket_setsockopt(temp_socket, SOCKET_SOL_SOCKET, SOCKET_SO_RCVBUF, &rcvbuf_size, sizeof rcvbuf_size); 00175 mode = SOCKET_MODE_DATAGRAM; 00176 } 00177 00178 return attach(temp_socket); 00179 } 00180 00181 int NanostackSocket::accept(NanostackSocket *accepted_socket, ns_address_t *addr) 00182 { 00183 nanostack_assert_locked(); 00184 MBED_ASSERT(SOCKET_MODE_LISTENING == mode && SOCKET_MODE_UNOPENED == accepted_socket->mode); 00185 00186 int temp_socket = socket_accept(socket_id, addr, socket_callback); 00187 if (temp_socket < 0) { 00188 tr_error("NanostackSocket::accept() failed"); 00189 return temp_socket; 00190 } 00191 if (!accepted_socket->attach(temp_socket)) { 00192 return -1; 00193 } 00194 accepted_socket->mode = SOCKET_MODE_STREAM; 00195 return temp_socket; 00196 } 00197 00198 bool NanostackSocket::attach(int8_t temp_socket) 00199 { 00200 nanostack_assert_locked(); 00201 if (temp_socket >= NS_INTERFACE_SOCKETS_MAX) { 00202 MBED_ASSERT(false); 00203 return false; 00204 } 00205 if (socket_tbl[temp_socket] != NULL) { 00206 MBED_ASSERT(false); 00207 return false; 00208 } 00209 socket_id = temp_socket; 00210 socket_tbl[socket_id] = this; 00211 return true; 00212 } 00213 00214 void NanostackSocket::close() 00215 { 00216 nanostack_assert_locked(); 00217 MBED_ASSERT(mode != SOCKET_MODE_CLOSED); 00218 00219 if (socket_id >= 0) { 00220 nsapi_error_t ret = socket_close(socket_id); 00221 MBED_ASSERT(0 == ret); 00222 MBED_ASSERT(socket_tbl[socket_id] == this); 00223 socket_tbl[socket_id] = NULL; 00224 socket_id = -1; 00225 } else { 00226 MBED_ASSERT(SOCKET_MODE_UNOPENED == mode); 00227 } 00228 00229 mode = SOCKET_MODE_CLOSED; 00230 signal_event(); 00231 } 00232 00233 bool NanostackSocket::is_connecting() 00234 { 00235 return SOCKET_MODE_CONNECTING == mode; 00236 } 00237 00238 void NanostackSocket::set_connecting(ns_address_t *addr) 00239 { 00240 nanostack_assert_locked(); 00241 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00242 00243 memcpy(&ns_address, addr, sizeof(ns_address_t)); 00244 mode = SOCKET_MODE_CONNECTING; 00245 } 00246 00247 bool NanostackSocket::is_connected() 00248 { 00249 return SOCKET_MODE_STREAM == mode; 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 bool NanostackSocket::is_listening() 00261 { 00262 return SOCKET_MODE_LISTENING == mode; 00263 } 00264 00265 void NanostackSocket::set_listening() 00266 { 00267 nanostack_assert_locked(); 00268 MBED_ASSERT(SOCKET_MODE_OPENED == mode); 00269 00270 mode = SOCKET_MODE_LISTENING; 00271 } 00272 00273 void NanostackSocket::signal_event() 00274 { 00275 nanostack_assert_locked(); 00276 00277 if (callback != NULL) { 00278 callback(callback_data); 00279 } 00280 } 00281 00282 void NanostackSocket::socket_callback(void *cb) { 00283 nanostack_assert_locked(); 00284 00285 socket_callback_t *sock_cb = (socket_callback_t *) cb; 00286 NanostackSocket *socket = socket_tbl[sock_cb->socket_id]; 00287 MBED_ASSERT(socket != NULL); 00288 00289 tr_debug("socket_callback() sock=%d, event=%d, interface=%d, data len=%d", 00290 sock_cb->socket_id, sock_cb->event_type, sock_cb->interface_id, sock_cb->d_len); 00291 00292 switch (sock_cb->event_type) { 00293 case SOCKET_DATA: 00294 tr_debug("SOCKET_DATA, sock=%d, bytes=%d", sock_cb->socket_id, sock_cb->d_len); 00295 socket->event_data(sock_cb); 00296 break; 00297 case SOCKET_CONNECT_DONE: 00298 tr_debug("SOCKET_CONNECT_DONE"); 00299 socket->event_connect_done(sock_cb); 00300 break; 00301 case SOCKET_CONNECT_FAIL: 00302 tr_debug("SOCKET_CONNECT_FAIL"); 00303 socket->event_connect_fail(sock_cb); 00304 break; 00305 case SOCKET_CONNECT_AUTH_FAIL: 00306 tr_debug("SOCKET_CONNECT_AUTH_FAIL"); 00307 break; 00308 case SOCKET_INCOMING_CONNECTION: 00309 tr_debug("SOCKET_INCOMING_CONNECTION"); 00310 socket->event_incoming_connection(sock_cb); 00311 break; 00312 case SOCKET_TX_FAIL: 00313 tr_debug("SOCKET_TX_FAIL"); 00314 socket->event_tx_fail(sock_cb); 00315 break; 00316 case SOCKET_CONNECT_CLOSED: 00317 tr_debug("SOCKET_CONNECT_CLOSED"); 00318 socket->event_connect_closed(sock_cb); 00319 break; 00320 case SOCKET_CONNECTION_RESET: 00321 tr_debug("SOCKET_CONNECTION_RESET"); 00322 socket->event_connection_reset(sock_cb); 00323 break; 00324 case SOCKET_NO_ROUTE: 00325 tr_debug("SOCKET_NO_ROUTE"); 00326 socket->event_tx_fail(sock_cb); 00327 break; 00328 case SOCKET_TX_DONE: 00329 socket->event_tx_done(sock_cb); 00330 break; 00331 case SOCKET_NO_RAM: 00332 tr_debug("SOCKET_NO_RAM"); 00333 socket->event_tx_fail(sock_cb); 00334 break; 00335 case SOCKET_CONNECTION_PROBLEM: 00336 tr_debug("SOCKET_CONNECTION_PROBLEM"); 00337 break; 00338 default: 00339 break; 00340 } 00341 } 00342 00343 00344 void NanostackSocket::event_data(socket_callback_t *sock_cb) 00345 { 00346 nanostack_assert_locked(); 00347 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00348 (SOCKET_MODE_DATAGRAM == mode)); 00349 00350 signal_event(); 00351 } 00352 00353 void NanostackSocket::event_tx_done(socket_callback_t *sock_cb) 00354 { 00355 nanostack_assert_locked(); 00356 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00357 (SOCKET_MODE_DATAGRAM == mode)); 00358 00359 if (mode == SOCKET_MODE_DATAGRAM) { 00360 tr_debug("SOCKET_TX_DONE, %d bytes sent", sock_cb->d_len); 00361 } else if (mode == SOCKET_MODE_STREAM) { 00362 tr_debug("SOCKET_TX_DONE, %d bytes remaining", sock_cb->d_len); 00363 } 00364 00365 signal_event(); 00366 } 00367 00368 void NanostackSocket::event_connect_done(socket_callback_t *sock_cb) 00369 { 00370 nanostack_assert_locked(); 00371 MBED_ASSERT(SOCKET_MODE_CONNECTING == mode); 00372 00373 set_connected(); 00374 signal_event(); 00375 } 00376 00377 void NanostackSocket::event_connect_fail(socket_callback_t *sock_cb) 00378 { 00379 nanostack_assert_locked(); 00380 MBED_ASSERT(mode == SOCKET_MODE_CONNECTING); 00381 close(); 00382 } 00383 00384 void NanostackSocket::event_incoming_connection(socket_callback_t *sock_cb) 00385 { 00386 nanostack_assert_locked(); 00387 MBED_ASSERT(mode == SOCKET_MODE_LISTENING); 00388 signal_event(); 00389 } 00390 00391 void NanostackSocket::event_connect_closed(socket_callback_t *sock_cb) 00392 { 00393 nanostack_assert_locked(); 00394 00395 // Can happen if we have an orderly close() 00396 // Might never happen as we have not implemented shutdown() in abstraction layer. 00397 MBED_ASSERT(mode == SOCKET_MODE_STREAM); 00398 close(); 00399 } 00400 00401 void NanostackSocket::event_tx_fail(socket_callback_t *sock_cb) 00402 { 00403 nanostack_assert_locked(); 00404 00405 switch (mode) { 00406 case SOCKET_MODE_CONNECTING: 00407 case SOCKET_MODE_STREAM: 00408 // TX_FAIL is fatal for stream sockets 00409 close(); 00410 break; 00411 case SOCKET_MODE_DATAGRAM: 00412 // TX_FAIL is non-fatal for datagram sockets 00413 break; 00414 default: 00415 MBED_ASSERT(false); 00416 break; 00417 } 00418 } 00419 00420 void NanostackSocket::event_connection_reset(socket_callback_t *sock_cb) 00421 { 00422 nanostack_assert_locked(); 00423 00424 // Only TCP sockets can be closed by the remote end 00425 MBED_ASSERT((SOCKET_MODE_STREAM == mode) || 00426 (SOCKET_MODE_CONNECTING == mode)); 00427 close(); 00428 } 00429 00430 NanostackInterface *NanostackInterface::_ns_interface; 00431 00432 NanostackInterface *NanostackInterface::get_stack() 00433 { 00434 NanostackLockGuard lock; 00435 00436 if (NULL == _ns_interface) { 00437 _ns_interface = new NanostackInterface(); 00438 } 00439 00440 return _ns_interface; 00441 } 00442 00443 const char * NanostackInterface::get_ip_address() 00444 { 00445 NanostackLockGuard lock; 00446 00447 for (int if_id = 1; if_id <= 127; if_id++) { 00448 uint8_t address[16]; 00449 int ret = arm_net_address_get(if_id, ADDR_IPV6_GP, address); 00450 if (ret == 0) { 00451 ip6tos(address, text_ip_address); 00452 return text_ip_address; 00453 } 00454 } 00455 // Must result a valid IPv6 address 00456 // For gethostbyname() to detect IP version. 00457 return "::"; 00458 } 00459 00460 nsapi_error_t NanostackInterface::socket_open(void **handle, nsapi_protocol_t protocol) 00461 { 00462 // Validate parameters 00463 if (NULL == handle) { 00464 MBED_ASSERT(false); 00465 return NSAPI_ERROR_NO_SOCKET ; 00466 } 00467 int8_t ns_proto; 00468 if (NSAPI_UDP == protocol) { 00469 ns_proto = SOCKET_UDP; 00470 } else if (NSAPI_TCP == protocol) { 00471 ns_proto = SOCKET_TCP; 00472 } else { 00473 MBED_ASSERT(false); 00474 return NSAPI_ERROR_UNSUPPORTED ; 00475 } 00476 *handle = (void*)NULL; 00477 00478 NanostackLockGuard lock; 00479 00480 NanostackSocket * socket = new NanostackSocket(ns_proto); 00481 if (socket == NULL) { 00482 tr_debug("socket_open() ret=%i", NSAPI_ERROR_NO_MEMORY ); 00483 return NSAPI_ERROR_NO_MEMORY ; 00484 } 00485 if (!socket->open()) { 00486 delete socket; 00487 tr_debug("socket_open() ret=%i", NSAPI_ERROR_DEVICE_ERROR ); 00488 return NSAPI_ERROR_DEVICE_ERROR ; 00489 } 00490 *handle = (void*)socket; 00491 00492 tr_debug("socket_open() socket=%p, sock_id=%d, ret=0", socket, socket->socket_id); 00493 00494 return NSAPI_ERROR_OK ; 00495 } 00496 00497 nsapi_error_t NanostackInterface::socket_close(void *handle) 00498 { 00499 NanostackLockGuard lock; 00500 // Validate parameters 00501 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00502 if (NULL == handle) { 00503 MBED_ASSERT(false); 00504 return NSAPI_ERROR_NO_SOCKET ; 00505 } 00506 tr_debug("socket_close(socket=%p) sock_id=%d", socket, socket->socket_id); 00507 00508 delete socket; 00509 00510 return 0; 00511 00512 } 00513 00514 nsapi_size_or_error_t NanostackInterface::do_sendto(void *handle, const ns_address_t *address, const void *data, nsapi_size_t size) 00515 { 00516 // Validate parameters 00517 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00518 if (handle == NULL) { 00519 MBED_ASSERT(false); 00520 return NSAPI_ERROR_NO_SOCKET ; 00521 } 00522 00523 nsapi_size_or_error_t ret; 00524 00525 NanostackLockGuard lock; 00526 00527 if (socket->closed() || (!address && !socket->is_connected())) { 00528 ret = NSAPI_ERROR_NO_CONNECTION ; 00529 goto out; 00530 } 00531 00532 if (address && socket->proto == SOCKET_TCP) { 00533 tr_error("socket_sendto() not supported with TCP!"); 00534 ret = NSAPI_ERROR_IS_CONNECTED ; 00535 goto out; 00536 } 00537 00538 int retcode; 00539 #if 0 00540 retcode = ::socket_sendto(socket->socket_id, address, 00541 data, size); 00542 #else 00543 // Use sendmsg purely to get the new return style 00544 // of returning data written rather than 0 on success, 00545 // which means TCP can do partial writes. (Sadly, 00546 // it's the only call which takes flags so we can 00547 // leave the NS_MSG_LEGACY0 flag clear). 00548 ns_msghdr_t msg; 00549 ns_iovec_t iov; 00550 iov.iov_base = const_cast<void *>(data); 00551 iov.iov_len = size; 00552 msg.msg_name = const_cast<ns_address_t *>(address); 00553 msg.msg_namelen = address ? sizeof *address : 0; 00554 msg.msg_iov = &iov; 00555 msg.msg_iovlen = 1; 00556 msg.msg_control = NULL; 00557 msg.msg_controllen = 0; 00558 retcode = ::socket_sendmsg(socket->socket_id, &msg, 0); 00559 #endif 00560 00561 /* 00562 * \return length if entire amount written (which could be 0) 00563 * \return value >0 and <length if partial amount written (stream only) 00564 * \return NS_EWOULDBLOCK if nothing written due to lack of queue space. 00565 * \return -1 Invalid socket ID or message structure. 00566 * \return -2 Socket memory allocation fail. 00567 * \return -3 TCP state not established or address scope not defined . 00568 * \return -4 Socket TX process busy or unknown interface. 00569 * \return -5 Socket not connected 00570 * \return -6 Packet too short (ICMP raw socket error). 00571 * */ 00572 if (retcode == NS_EWOULDBLOCK) { 00573 ret = NSAPI_ERROR_WOULD_BLOCK ; 00574 } else if (retcode < 0) { 00575 tr_error("socket_sendmsg: error=%d", retcode); 00576 ret = NSAPI_ERROR_DEVICE_ERROR ; 00577 } else { 00578 ret = retcode; 00579 } 00580 00581 out: 00582 tr_debug("socket_sendto(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00583 00584 return ret; 00585 } 00586 00587 nsapi_size_or_error_t NanostackInterface::socket_sendto(void *handle, const SocketAddress &address, const void *data, nsapi_size_t size) 00588 { 00589 if (address.get_ip_version() != NSAPI_IPv6 ) { 00590 return NSAPI_ERROR_UNSUPPORTED ; 00591 } 00592 00593 ns_address_t ns_address; 00594 convert_mbed_addr_to_ns(&ns_address, &address); 00595 /*No lock gaurd needed here as do_sendto() will handle locks.*/ 00596 return do_sendto(handle, &ns_address, data, size); 00597 } 00598 00599 nsapi_size_or_error_t NanostackInterface::socket_recvfrom(void *handle, SocketAddress *address, void *buffer, nsapi_size_t size) 00600 { 00601 // Validate parameters 00602 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00603 if (handle == NULL) { 00604 MBED_ASSERT(false); 00605 return NSAPI_ERROR_NO_SOCKET ; 00606 } 00607 00608 nsapi_size_or_error_t ret; 00609 00610 NanostackLockGuard lock; 00611 00612 if (socket->closed()) { 00613 ret = NSAPI_ERROR_NO_CONNECTION ; 00614 goto out; 00615 } 00616 00617 ns_address_t ns_address; 00618 00619 int retcode; 00620 retcode = ::socket_recvfrom(socket->socket_id, buffer, size, 0, &ns_address); 00621 00622 if (retcode == NS_EWOULDBLOCK) { 00623 ret = NSAPI_ERROR_WOULD_BLOCK ; 00624 } else if (retcode < 0) { 00625 ret = NSAPI_ERROR_PARAMETER ; 00626 } else { 00627 ret = retcode; 00628 if (address != NULL) { 00629 convert_ns_addr_to_mbed(address, &ns_address); 00630 } 00631 } 00632 00633 out: 00634 if (address) { 00635 tr_debug("socket_recvfrom(socket=%p) sock_id=%d, ret=%i, addr=[%s]:%i", socket, socket->socket_id, ret, 00636 trace_ipv6(address->get_ip_bytes()), address->get_port()); 00637 } else { 00638 tr_debug("socket_recv(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00639 } 00640 00641 return ret; 00642 } 00643 00644 nsapi_error_t NanostackInterface::socket_bind(void *handle, const SocketAddress &address) 00645 { 00646 // Validate parameters 00647 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00648 if (handle == NULL) { 00649 MBED_ASSERT(false); 00650 return NSAPI_ERROR_NO_SOCKET ; 00651 } 00652 00653 const void *addr_field; 00654 switch (address.get_ip_version()) { 00655 case NSAPI_IPv6 : 00656 addr_field = address.get_ip_bytes(); 00657 break; 00658 case NSAPI_UNSPEC : 00659 addr_field = &ns_in6addr_any; 00660 break; 00661 default: 00662 return NSAPI_ERROR_UNSUPPORTED ; 00663 } 00664 00665 NanostackLockGuard lock; 00666 00667 ns_address_t ns_address; 00668 ns_address.type = ADDRESS_IPV6; 00669 memcpy(ns_address.address, addr_field, sizeof ns_address.address); 00670 ns_address.identifier = address.get_port(); 00671 nsapi_error_t ret; 00672 int retcode = ::socket_bind(socket->socket_id, &ns_address); 00673 00674 if (retcode == 0) { 00675 ret = NSAPI_ERROR_OK ; 00676 } else { 00677 ret = NSAPI_ERROR_PARAMETER ; 00678 } 00679 00680 tr_debug("socket_bind(socket=%p) sock_id=%d, retcode=%i, ret=%i", socket, socket->socket_id, retcode, ret); 00681 00682 return ret; 00683 } 00684 00685 nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00686 { 00687 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00688 if (handle == NULL) { 00689 MBED_ASSERT(false); 00690 return NSAPI_ERROR_NO_SOCKET ; 00691 } 00692 00693 nsapi_error_t ret; 00694 00695 NanostackLockGuard lock; 00696 00697 if (::socket_setsockopt(socket->socket_id, level, optname, optval, optlen) == 0) { 00698 ret = NSAPI_ERROR_OK ; 00699 } else { 00700 ret = NSAPI_ERROR_PARAMETER ; 00701 } 00702 00703 return ret; 00704 } 00705 00706 nsapi_error_t NanostackInterface::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00707 { 00708 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00709 if (handle == NULL) { 00710 MBED_ASSERT(false); 00711 return NSAPI_ERROR_NO_SOCKET ; 00712 } 00713 00714 nsapi_error_t ret; 00715 00716 NanostackLockGuard lock; 00717 00718 uint16_t optlen16 = *optlen; 00719 if (::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16) == 0) { 00720 ret = NSAPI_ERROR_OK ; 00721 *optlen = optlen16; 00722 } else { 00723 ret = NSAPI_ERROR_PARAMETER ; 00724 } 00725 00726 return ret; 00727 } 00728 00729 nsapi_error_t NanostackInterface::socket_listen(void *handle, int backlog) 00730 { 00731 //Check if socket exists 00732 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00733 if (handle == NULL) { 00734 MBED_ASSERT(false); 00735 return NSAPI_ERROR_NO_SOCKET ; 00736 } 00737 00738 nsapi_error_t ret = NSAPI_ERROR_OK ; 00739 00740 NanostackLockGuard lock; 00741 00742 if(::socket_listen(socket->socket_id, backlog) < 0) { 00743 ret = NSAPI_ERROR_PARAMETER ; 00744 } else { 00745 socket->set_listening(); 00746 } 00747 00748 return ret; 00749 } 00750 00751 nsapi_error_t NanostackInterface::socket_connect(void *handle, const SocketAddress &addr) 00752 { 00753 // Validate parameters 00754 NanostackSocket *socket = static_cast<NanostackSocket *>(handle); 00755 nsapi_error_t ret; 00756 if (handle == NULL) { 00757 MBED_ASSERT(false); 00758 return NSAPI_ERROR_NO_SOCKET ; 00759 } 00760 00761 NanostackLockGuard lock; 00762 00763 if (addr.get_ip_version() != NSAPI_IPv6 ) { 00764 ret = NSAPI_ERROR_UNSUPPORTED ; 00765 goto out; 00766 } 00767 00768 if (socket->closed()) { 00769 ret = NSAPI_ERROR_NO_CONNECTION ; 00770 goto out; 00771 } 00772 00773 if (socket->is_connecting()) { 00774 ret = NSAPI_ERROR_ALREADY ; 00775 goto out; 00776 } 00777 00778 if (socket->is_connected()) { 00779 ret = NSAPI_ERROR_IS_CONNECTED ; 00780 goto out; 00781 } 00782 00783 ns_address_t ns_addr; 00784 00785 convert_mbed_addr_to_ns(&ns_addr, &addr); 00786 if (::socket_connect(socket->socket_id, &ns_addr, 0) == 0) { 00787 if (socket->proto == SOCKET_TCP) { 00788 socket->set_connecting(&ns_addr); 00789 ret = NSAPI_ERROR_IN_PROGRESS ; 00790 } else { 00791 ret = NSAPI_ERROR_OK ; 00792 } 00793 } else { 00794 ret = NSAPI_ERROR_DEVICE_ERROR ; 00795 } 00796 00797 out: 00798 tr_debug("socket_connect(socket=%p) sock_id=%d, ret=%i", socket, socket->socket_id, ret); 00799 00800 return ret; 00801 } 00802 00803 nsapi_error_t NanostackInterface::socket_accept(void *server, void **handle, SocketAddress *address) 00804 { 00805 NanostackSocket * socket = static_cast<NanostackSocket *>(server); 00806 NanostackSocket *accepted_sock = NULL; 00807 nsapi_error_t ret; 00808 00809 if (handle == NULL) { 00810 MBED_ASSERT(false); 00811 return NSAPI_ERROR_NO_SOCKET ; 00812 } 00813 00814 NanostackLockGuard lock; 00815 00816 if (!socket->is_listening()) { 00817 ret = NSAPI_ERROR_PARAMETER ; 00818 goto out; 00819 } 00820 00821 accepted_sock = new NanostackSocket(socket->proto); 00822 if (accepted_sock == NULL) { 00823 ret = NSAPI_ERROR_NO_MEMORY ; 00824 goto out; 00825 } 00826 00827 ns_address_t ns_addr; 00828 int retcode; 00829 retcode = socket->accept(accepted_sock, &ns_addr); 00830 if (retcode < 0) { 00831 delete accepted_sock; 00832 if (retcode == NS_EWOULDBLOCK) { 00833 ret = NSAPI_ERROR_WOULD_BLOCK ; 00834 } else { 00835 ret = NSAPI_ERROR_DEVICE_ERROR ; 00836 } 00837 goto out; 00838 } 00839 ret = NSAPI_ERROR_OK ; 00840 00841 if (address) { 00842 convert_ns_addr_to_mbed(address, &ns_addr); 00843 } 00844 00845 *handle = accepted_sock; 00846 00847 out: 00848 tr_debug("socket_accept() socket=%p, sock_id=%d, ret=%i", accepted_sock, accepted_sock ? accepted_sock->socket_id : -1, ret); 00849 00850 return ret; 00851 } 00852 00853 nsapi_size_or_error_t NanostackInterface::socket_send(void *handle, const void *data, nsapi_size_t size) 00854 { 00855 return do_sendto(handle, NULL, data, size); 00856 } 00857 00858 nsapi_size_or_error_t NanostackInterface::socket_recv(void *handle, void *data, nsapi_size_t size) 00859 { 00860 return socket_recvfrom(handle, NULL, data, size); 00861 } 00862 00863 void NanostackInterface::socket_attach(void *handle, void (*callback)(void *), void *id) 00864 { 00865 // Validate parameters 00866 NanostackSocket * socket = static_cast<NanostackSocket *>(handle); 00867 if (handle == NULL) { 00868 MBED_ASSERT(false); 00869 return; 00870 } 00871 00872 NanostackLockGuard lock; 00873 00874 socket->callback = callback; 00875 socket->callback_data = id; 00876 00877 tr_debug("socket_attach(socket=%p) sock_id=%d", socket, socket->socket_id); 00878 }
Generated on Sun Jul 17 2022 08:25:28 by 1.7.2