Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NetworkStack.cpp Source File

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