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: TYBLE16_simple_data_logger TYBLE16_MP3_Air
NetworkStack.cpp
00001 /* Socket 00002 * Copyright (c) 2015 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 "NetworkStack.h" 00018 #include "nsapi_dns.h" 00019 #include "stddef.h" 00020 #include <new> 00021 #include "events/EventQueue.h" 00022 #include "mbed_shared_queues.h" 00023 #include "platform/mbed_error.h" 00024 00025 // Default NetworkStack operations 00026 00027 nsapi_error_t NetworkStack::get_ip_address(SocketAddress *address) 00028 { 00029 return NSAPI_ERROR_UNSUPPORTED ; 00030 } 00031 00032 const char *NetworkStack::get_ip_address() 00033 { 00034 return nullptr; 00035 } 00036 00037 nsapi_error_t NetworkStack::get_ipv6_link_local_address(SocketAddress *address) 00038 { 00039 return NSAPI_ERROR_UNSUPPORTED ; 00040 } 00041 00042 nsapi_error_t NetworkStack::get_ip_address_if(SocketAddress *address, const char *interface_name) 00043 { 00044 return NSAPI_ERROR_UNSUPPORTED ; 00045 } 00046 00047 const char *NetworkStack::get_ip_address_if(const char *interface_name) 00048 { 00049 return nullptr; 00050 } 00051 00052 nsapi_error_t NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name) 00053 { 00054 if (name[0] == '\0') { 00055 return NSAPI_ERROR_PARAMETER ; 00056 } 00057 00058 // check for simple ip addresses 00059 if (address->set_ip_address(name)) { 00060 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { 00061 return NSAPI_ERROR_DNS_FAILURE ; 00062 } 00063 00064 return NSAPI_ERROR_OK ; 00065 } 00066 00067 // if the version is unspecified, try to guess the version from the 00068 // ip address of the underlying stack 00069 if (version == NSAPI_UNSPEC ) { 00070 SocketAddress testaddress; 00071 if (this->get_ip_address(&testaddress) == NSAPI_ERROR_OK ) { 00072 version = testaddress.get_ip_version(); 00073 } 00074 } 00075 00076 return nsapi_dns_query(this, name, address, interface_name, version); 00077 } 00078 00079 nsapi_value_or_error_t NetworkStack::gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name) 00080 { 00081 SocketAddress address; 00082 00083 if (name[0] == '\0') { 00084 return NSAPI_ERROR_PARAMETER ; 00085 } 00086 00087 // check for simple ip addresses 00088 if (address.set_ip_address(name)) { 00089 if (version != NSAPI_UNSPEC && address.get_ip_version() != version) { 00090 return NSAPI_ERROR_DNS_FAILURE ; 00091 } 00092 00093 callback(NSAPI_ERROR_OK , &address); 00094 return NSAPI_ERROR_OK ; 00095 } 00096 00097 // if the version is unspecified, try to guess the version from the 00098 // ip address of the underlying stack 00099 if (version == NSAPI_UNSPEC ) { 00100 SocketAddress testaddress; 00101 if (this->get_ip_address(&testaddress) == NSAPI_ERROR_OK ) { 00102 version = testaddress.get_ip_version(); 00103 } 00104 } 00105 00106 call_in_callback_cb_t call_in_cb = get_call_in_callback(); 00107 00108 return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version); 00109 } 00110 00111 nsapi_error_t NetworkStack::gethostbyname_async_cancel(int id) 00112 { 00113 return nsapi_dns_query_async_cancel(id); 00114 } 00115 00116 nsapi_error_t NetworkStack::add_dns_server(const SocketAddress &address, const char *interface_name) 00117 { 00118 return nsapi_dns_add_server(address, interface_name); 00119 } 00120 00121 nsapi_error_t NetworkStack::get_dns_server(int index, SocketAddress *address, const char *interface_name) 00122 { 00123 return NSAPI_ERROR_UNSUPPORTED ; 00124 } 00125 00126 nsapi_error_t NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen) 00127 { 00128 return NSAPI_ERROR_UNSUPPORTED ; 00129 } 00130 00131 nsapi_error_t NetworkStack::getstackopt(int level, int optname, void *optval, unsigned *optlen) 00132 { 00133 return NSAPI_ERROR_UNSUPPORTED ; 00134 } 00135 00136 nsapi_error_t NetworkStack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) 00137 { 00138 return NSAPI_ERROR_UNSUPPORTED ; 00139 } 00140 00141 nsapi_error_t NetworkStack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) 00142 { 00143 return NSAPI_ERROR_UNSUPPORTED ; 00144 } 00145 00146 nsapi_error_t NetworkStack::call_in(int delay, mbed::Callback<void()> func) 00147 { 00148 static events::EventQueue *event_queue = mbed::mbed_event_queue(); 00149 00150 if (!event_queue) { 00151 goto NO_MEM; 00152 } 00153 00154 if (delay > 0) { 00155 if (event_queue->call_in(delay, func) == 0) { 00156 goto NO_MEM; 00157 } 00158 } else { 00159 if (event_queue->call(func) == 0) { 00160 goto NO_MEM; 00161 } 00162 } 00163 00164 return NSAPI_ERROR_OK ; 00165 00166 NO_MEM: 00167 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \ 00168 "NetworkStack::call_in() unable to add event to queue. Increase \"events.shared-eventsize\"\n"); 00169 } 00170 00171 call_in_callback_cb_t NetworkStack::get_call_in_callback() 00172 { 00173 call_in_callback_cb_t cb(this, &NetworkStack::call_in); 00174 return cb; 00175 } 00176 00177 // NetworkStackWrapper class for encapsulating the raw nsapi_stack structure 00178 class NetworkStackWrapper : public NetworkStack { 00179 private: 00180 inline nsapi_stack_t *_stack() 00181 { 00182 return reinterpret_cast<nsapi_stack_t *>( 00183 reinterpret_cast<uint8_t *>(this) 00184 - offsetof(nsapi_stack_t, _stack_buffer)); 00185 } 00186 00187 inline const nsapi_stack_api_t *_stack_api() 00188 { 00189 return _stack()->stack_api; 00190 } 00191 00192 public: 00193 using NetworkStack::get_ip_address; 00194 using NetworkStack::gethostbyname; 00195 virtual const char *get_ip_address() 00196 { 00197 if (!_stack_api()->get_ip_address) { 00198 return 0; 00199 } 00200 00201 static uint8_t buffer[sizeof(SocketAddress)]; 00202 SocketAddress *address = new (buffer) SocketAddress(_stack_api()->get_ip_address(_stack())); 00203 return address->get_ip_address(); 00204 } 00205 00206 virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name) 00207 { 00208 if (!_stack_api()->gethostbyname) { 00209 return NetworkStack::gethostbyname(name, address, version, interface_name); 00210 } 00211 00212 nsapi_addr_t addr = {NSAPI_UNSPEC , 0}; 00213 nsapi_error_t err = _stack_api()->gethostbyname(_stack(), name, &addr, version); 00214 address->set_addr(addr); 00215 return err; 00216 } 00217 00218 virtual nsapi_error_t add_dns_server(const SocketAddress &address, const char *interface_name) 00219 { 00220 if (!_stack_api()->add_dns_server) { 00221 return NetworkStack::add_dns_server(address, interface_name); 00222 } 00223 00224 return _stack_api()->add_dns_server(_stack(), address.get_addr()); 00225 } 00226 00227 virtual nsapi_error_t setstackopt(int level, int optname, const void *optval, unsigned optlen) 00228 { 00229 if (!_stack_api()->setstackopt) { 00230 return NSAPI_ERROR_UNSUPPORTED ; 00231 } 00232 00233 return _stack_api()->setstackopt(_stack(), level, optname, optval, optlen); 00234 } 00235 00236 virtual nsapi_error_t getstackopt(int level, int optname, void *optval, unsigned *optlen) 00237 { 00238 if (!_stack_api()->getstackopt) { 00239 return NSAPI_ERROR_UNSUPPORTED ; 00240 } 00241 00242 return _stack_api()->getstackopt(_stack(), level, optname, optval, optlen); 00243 } 00244 00245 protected: 00246 virtual nsapi_error_t socket_open(nsapi_socket_t *socket, nsapi_protocol_t proto) 00247 { 00248 if (!_stack_api()->socket_open) { 00249 return NSAPI_ERROR_UNSUPPORTED ; 00250 } 00251 00252 return _stack_api()->socket_open(_stack(), socket, proto); 00253 } 00254 00255 virtual nsapi_error_t socket_close(nsapi_socket_t socket) 00256 { 00257 if (!_stack_api()->socket_close) { 00258 return NSAPI_ERROR_UNSUPPORTED ; 00259 } 00260 00261 return _stack_api()->socket_close(_stack(), socket); 00262 } 00263 00264 virtual nsapi_error_t socket_bind(nsapi_socket_t socket, const SocketAddress &address) 00265 { 00266 if (!_stack_api()->socket_bind) { 00267 return NSAPI_ERROR_UNSUPPORTED ; 00268 } 00269 00270 return _stack_api()->socket_bind(_stack(), socket, address.get_addr(), address.get_port()); 00271 } 00272 00273 virtual nsapi_error_t socket_listen(nsapi_socket_t socket, int backlog) 00274 { 00275 if (!_stack_api()->socket_listen) { 00276 return NSAPI_ERROR_UNSUPPORTED ; 00277 } 00278 00279 return _stack_api()->socket_listen(_stack(), socket, backlog); 00280 } 00281 00282 virtual nsapi_error_t socket_connect(nsapi_socket_t socket, const SocketAddress &address) 00283 { 00284 if (!_stack_api()->socket_connect) { 00285 return NSAPI_ERROR_UNSUPPORTED ; 00286 } 00287 00288 return _stack_api()->socket_connect(_stack(), socket, address.get_addr(), address.get_port()); 00289 } 00290 00291 virtual nsapi_error_t socket_accept(nsapi_socket_t server, nsapi_socket_t *socket, SocketAddress *address) 00292 { 00293 if (!_stack_api()->socket_accept) { 00294 return NSAPI_ERROR_UNSUPPORTED ; 00295 } 00296 00297 nsapi_addr_t addr = {NSAPI_IPv4 , 0}; 00298 uint16_t port = 0; 00299 00300 nsapi_error_t err = _stack_api()->socket_accept(_stack(), server, socket, &addr, &port); 00301 00302 if (address) { 00303 address->set_addr(addr); 00304 address->set_port(port); 00305 } 00306 00307 return err; 00308 } 00309 00310 virtual nsapi_size_or_error_t socket_send(nsapi_socket_t socket, const void *data, nsapi_size_t size) 00311 { 00312 if (!_stack_api()->socket_send) { 00313 return NSAPI_ERROR_UNSUPPORTED ; 00314 } 00315 00316 return _stack_api()->socket_send(_stack(), socket, data, size); 00317 } 00318 00319 virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t socket, void *data, nsapi_size_t size) 00320 { 00321 if (!_stack_api()->socket_recv) { 00322 return NSAPI_ERROR_UNSUPPORTED ; 00323 } 00324 00325 return _stack_api()->socket_recv(_stack(), socket, data, size); 00326 } 00327 00328 virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t socket, const SocketAddress &address, const void *data, nsapi_size_t size) 00329 { 00330 if (!_stack_api()->socket_sendto) { 00331 return NSAPI_ERROR_UNSUPPORTED ; 00332 } 00333 00334 return _stack_api()->socket_sendto(_stack(), socket, address.get_addr(), address.get_port(), data, size); 00335 } 00336 00337 virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t socket, SocketAddress *address, void *data, nsapi_size_t size) 00338 { 00339 if (!_stack_api()->socket_recvfrom) { 00340 return NSAPI_ERROR_UNSUPPORTED ; 00341 } 00342 00343 nsapi_addr_t addr = {NSAPI_IPv4 , 0}; 00344 uint16_t port = 0; 00345 00346 nsapi_size_or_error_t err = _stack_api()->socket_recvfrom(_stack(), socket, &addr, &port, data, size); 00347 00348 if (address) { 00349 address->set_addr(addr); 00350 address->set_port(port); 00351 } 00352 00353 return err; 00354 } 00355 00356 virtual void socket_attach(nsapi_socket_t socket, void (*callback)(void *), void *data) 00357 { 00358 if (!_stack_api()->socket_attach) { 00359 return; 00360 } 00361 00362 return _stack_api()->socket_attach(_stack(), socket, callback, data); 00363 } 00364 00365 virtual nsapi_error_t setsockopt(nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen) 00366 { 00367 if (!_stack_api()->setsockopt) { 00368 return NSAPI_ERROR_UNSUPPORTED ; 00369 } 00370 00371 return _stack_api()->setsockopt(_stack(), socket, level, optname, optval, optlen); 00372 } 00373 00374 virtual nsapi_error_t getsockopt(nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen) 00375 { 00376 if (!_stack_api()->getsockopt) { 00377 return NSAPI_ERROR_UNSUPPORTED ; 00378 } 00379 00380 return _stack_api()->getsockopt(_stack(), socket, level, optname, optval, optlen); 00381 } 00382 }; 00383 00384 00385 // Conversion function for network stacks 00386 NetworkStack *nsapi_create_stack(nsapi_stack_t *stack) 00387 { 00388 MBED_STATIC_ASSERT(sizeof stack->_stack_buffer >= sizeof(NetworkStackWrapper), 00389 "The nsapi_stack_t stack buffer must fit a NetworkStackWrapper"); 00390 return new (stack->_stack_buffer) NetworkStackWrapper; 00391 } 00392 00393 NetworkStack *nsapi_create_stack(NetworkStack *stack) 00394 { 00395 return stack; 00396 } 00397
Generated on Tue Jul 12 2022 13:54:37 by
