Simon Cooksey / mbed-os
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 "mbed.h"
00020 #include "stddef.h"
00021 #include <new>
00022 
00023 
00024 // Default NetworkStack operations
00025 int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
00026 {
00027     // check for simple ip addresses
00028     if (address->set_ip_address(name)) {
00029         if (address->get_ip_version() != version) {
00030             return NSAPI_ERROR_DNS_FAILURE ;
00031         }
00032 
00033         return 0;
00034     }
00035 
00036     return nsapi_dns_query(this, name, address, version);
00037 }
00038 
00039 int NetworkStack::add_dns_server(const SocketAddress &address)
00040 {
00041     return nsapi_dns_add_server(address);
00042 }
00043 
00044 int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen)
00045 {
00046     return NSAPI_ERROR_UNSUPPORTED ;
00047 }
00048 
00049 int NetworkStack::getstackopt(int level, int optname, void *optval, unsigned *optlen)
00050 {
00051     return NSAPI_ERROR_UNSUPPORTED ;
00052 }
00053 
00054 int NetworkStack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen)
00055 {
00056     return NSAPI_ERROR_UNSUPPORTED ;
00057 }
00058 
00059 int NetworkStack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
00060 {
00061     return NSAPI_ERROR_UNSUPPORTED ;
00062 }
00063 
00064 
00065 // NetworkStackWrapper class for encapsulating the raw nsapi_stack structure
00066 class NetworkStackWrapper : public NetworkStack
00067 {
00068 private:
00069     inline nsapi_stack_t *_stack()
00070     {
00071         return reinterpret_cast<nsapi_stack_t *>(
00072                 reinterpret_cast<uint8_t *>(this)
00073                 - offsetof(nsapi_stack_t, _stack_buffer));
00074     }
00075 
00076     inline const nsapi_stack_api_t *_stack_api()
00077     {
00078         return _stack()->stack_api;
00079     }
00080 
00081 public:
00082     virtual const char *get_ip_address()
00083     {
00084         if (!_stack_api()->get_ip_address) {
00085             return 0;
00086         }
00087 
00088         static uint8_t buffer[sizeof(SocketAddress)];
00089         SocketAddress *address = new (buffer) SocketAddress(_stack_api()->get_ip_address(_stack()));
00090         return address->get_ip_address();
00091     }
00092 
00093     virtual int gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
00094     {
00095         if (!_stack_api()->gethostbyname) {
00096             return NetworkStack::gethostbyname(name, address, version);
00097         }
00098 
00099         nsapi_addr_t addr = {NSAPI_UNSPEC , 0};
00100         int err = _stack_api()->gethostbyname(_stack(), name, &addr, version);
00101         address->set_addr(addr);
00102         return err;
00103     }
00104 
00105     virtual int add_dns_server(const SocketAddress &address)
00106     {
00107         if (!_stack_api()->add_dns_server) {
00108             return NetworkStack::add_dns_server(address);
00109         }
00110 
00111         return _stack_api()->add_dns_server(_stack(), address.get_addr());
00112     }
00113 
00114     virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen)
00115     {
00116         if (!_stack_api()->setstackopt) {
00117             return NSAPI_ERROR_UNSUPPORTED ;
00118         }
00119 
00120         return _stack_api()->setstackopt(_stack(), level, optname, optval, optlen);
00121     }
00122 
00123     virtual int getstackopt(int level, int optname, void *optval, unsigned *optlen)
00124     {
00125         if (!_stack_api()->getstackopt) {
00126             return NSAPI_ERROR_UNSUPPORTED ;
00127         }
00128 
00129         return _stack_api()->getstackopt(_stack(), level, optname, optval, optlen);
00130     }
00131 
00132 protected:
00133     virtual int socket_open(nsapi_socket_t *socket, nsapi_protocol_t proto)
00134     {
00135         if (!_stack_api()->socket_open) {
00136             return NSAPI_ERROR_UNSUPPORTED ;
00137         }
00138 
00139         return _stack_api()->socket_open(_stack(), socket, proto);
00140     }
00141 
00142     virtual int socket_close(nsapi_socket_t socket)
00143     {
00144         if (!_stack_api()->socket_close) {
00145             return NSAPI_ERROR_UNSUPPORTED ;
00146         }
00147 
00148         return _stack_api()->socket_close(_stack(), socket);
00149     }
00150 
00151     virtual int socket_bind(nsapi_socket_t socket, const SocketAddress &address)
00152     {
00153         if (!_stack_api()->socket_bind) {
00154             return NSAPI_ERROR_UNSUPPORTED ;
00155         }
00156 
00157         return _stack_api()->socket_bind(_stack(), socket, address.get_addr(), address.get_port());
00158     }
00159 
00160     virtual int socket_listen(nsapi_socket_t socket, int backlog)
00161     {
00162         if (!_stack_api()->socket_listen) {
00163             return NSAPI_ERROR_UNSUPPORTED ;
00164         }
00165 
00166         return _stack_api()->socket_listen(_stack(), socket, backlog);
00167     }
00168 
00169     virtual int socket_connect(nsapi_socket_t socket, const SocketAddress &address)
00170     {
00171         if (!_stack_api()->socket_connect) {
00172             return NSAPI_ERROR_UNSUPPORTED ;
00173         }
00174 
00175         return _stack_api()->socket_connect(_stack(), socket, address.get_addr(), address.get_port());
00176     }
00177 
00178     virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *socket, SocketAddress *address)
00179     {
00180         if (!_stack_api()->socket_accept) {
00181             return NSAPI_ERROR_UNSUPPORTED ;
00182         }
00183 
00184         nsapi_addr_t addr = {NSAPI_IPv4 , 0};
00185         uint16_t port = 0;
00186 
00187         int err = _stack_api()->socket_accept(_stack(), server, socket, &addr, &port);
00188 
00189         if (address) {
00190             address->set_addr(addr);
00191             address->set_port(port);
00192         }
00193 
00194         return err;
00195     }
00196 
00197     virtual int socket_send(nsapi_socket_t socket, const void *data, unsigned size)
00198     {
00199         if (!_stack_api()->socket_send) {
00200             return NSAPI_ERROR_UNSUPPORTED ;
00201         }
00202 
00203         return _stack_api()->socket_send(_stack(), socket, data, size);
00204     }
00205 
00206     virtual int socket_recv(nsapi_socket_t socket, void *data, unsigned size)
00207     {
00208         if (!_stack_api()->socket_recv) {
00209             return NSAPI_ERROR_UNSUPPORTED ;
00210         }
00211 
00212         return _stack_api()->socket_recv(_stack(), socket, data, size);
00213     }
00214 
00215     virtual int socket_sendto(nsapi_socket_t socket, const SocketAddress &address, const void *data, unsigned size)
00216     {
00217         if (!_stack_api()->socket_sendto) {
00218             return NSAPI_ERROR_UNSUPPORTED ;
00219         }
00220 
00221         return _stack_api()->socket_sendto(_stack(), socket, address.get_addr(), address.get_port(), data, size);
00222     }
00223 
00224     virtual int socket_recvfrom(nsapi_socket_t socket, SocketAddress *address, void *data, unsigned size)
00225     {
00226         if (!_stack_api()->socket_recvfrom) {
00227             return NSAPI_ERROR_UNSUPPORTED ;
00228         }
00229 
00230         nsapi_addr_t addr = {NSAPI_IPv4 , 0};
00231         uint16_t port = 0;
00232 
00233         int err = _stack_api()->socket_recvfrom(_stack(), socket, &addr, &port, data, size);
00234 
00235         if (address) {
00236             address->set_addr(addr);
00237             address->set_port(port);
00238         }
00239 
00240         return err;
00241     }
00242 
00243     virtual void socket_attach(nsapi_socket_t socket, void (*callback)(void *), void *data)
00244     {
00245         if (!_stack_api()->socket_attach) {
00246             return;
00247         }
00248 
00249         return _stack_api()->socket_attach(_stack(), socket, callback, data);
00250     }
00251 
00252     virtual int setsockopt(nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen)
00253     {
00254         if (!_stack_api()->setsockopt) {
00255             return NSAPI_ERROR_UNSUPPORTED ;
00256         }
00257 
00258         return _stack_api()->setsockopt(_stack(), socket, level, optname, optval, optlen);
00259     }
00260 
00261     virtual int getsockopt(nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen)
00262     {
00263         if (!_stack_api()->getsockopt) {
00264             return NSAPI_ERROR_UNSUPPORTED ;
00265         }
00266 
00267         return _stack_api()->getsockopt(_stack(), socket, level, optname, optval, optlen);
00268     }
00269 };
00270 
00271 
00272 // Conversion function for network stacks
00273 NetworkStack *nsapi_create_stack(nsapi_stack_t *stack)
00274 {
00275     MBED_ASSERT(sizeof stack->_stack_buffer >= sizeof(NetworkStackWrapper));
00276     return new (stack->_stack_buffer) NetworkStackWrapper;
00277 }
00278 
00279 NetworkStack *nsapi_create_stack(NetworkStack *stack)
00280 {
00281     return stack;
00282 }
00283