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.
Fork of mbed-os by
features/netsocket/NetworkStack.cpp@1:3deb71413561, 2017-07-20 (annotated)
- Committer:
- xuaner
- Date:
- Thu Jul 20 14:26:57 2017 +0000
- Revision:
- 1:3deb71413561
- Parent:
- 0:f269e3021894
mbed_os
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elessair | 0:f269e3021894 | 1 | /* Socket |
elessair | 0:f269e3021894 | 2 | * Copyright (c) 2015 ARM Limited |
elessair | 0:f269e3021894 | 3 | * |
elessair | 0:f269e3021894 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
elessair | 0:f269e3021894 | 5 | * you may not use this file except in compliance with the License. |
elessair | 0:f269e3021894 | 6 | * You may obtain a copy of the License at |
elessair | 0:f269e3021894 | 7 | * |
elessair | 0:f269e3021894 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
elessair | 0:f269e3021894 | 9 | * |
elessair | 0:f269e3021894 | 10 | * Unless required by applicable law or agreed to in writing, software |
elessair | 0:f269e3021894 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
elessair | 0:f269e3021894 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
elessair | 0:f269e3021894 | 13 | * See the License for the specific language governing permissions and |
elessair | 0:f269e3021894 | 14 | * limitations under the License. |
elessair | 0:f269e3021894 | 15 | */ |
elessair | 0:f269e3021894 | 16 | |
elessair | 0:f269e3021894 | 17 | #include "NetworkStack.h" |
elessair | 0:f269e3021894 | 18 | #include "nsapi_dns.h" |
elessair | 0:f269e3021894 | 19 | #include "mbed.h" |
elessair | 0:f269e3021894 | 20 | #include "stddef.h" |
elessair | 0:f269e3021894 | 21 | #include <new> |
elessair | 0:f269e3021894 | 22 | |
elessair | 0:f269e3021894 | 23 | |
elessair | 0:f269e3021894 | 24 | // Default NetworkStack operations |
elessair | 0:f269e3021894 | 25 | int NetworkStack::gethostbyname(const char *name, SocketAddress *address) |
elessair | 0:f269e3021894 | 26 | { |
elessair | 0:f269e3021894 | 27 | // check for simple ip addresses |
elessair | 0:f269e3021894 | 28 | if (address->set_ip_address(name)) { |
elessair | 0:f269e3021894 | 29 | return 0; |
elessair | 0:f269e3021894 | 30 | } |
elessair | 0:f269e3021894 | 31 | |
elessair | 0:f269e3021894 | 32 | return nsapi_dns_query(this, name, address); |
elessair | 0:f269e3021894 | 33 | } |
elessair | 0:f269e3021894 | 34 | |
elessair | 0:f269e3021894 | 35 | int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) |
elessair | 0:f269e3021894 | 36 | { |
elessair | 0:f269e3021894 | 37 | // check for simple ip addresses |
elessair | 0:f269e3021894 | 38 | if (address->set_ip_address(name)) { |
elessair | 0:f269e3021894 | 39 | if (address->get_ip_version() != version) { |
elessair | 0:f269e3021894 | 40 | return NSAPI_ERROR_DNS_FAILURE; |
elessair | 0:f269e3021894 | 41 | } |
elessair | 0:f269e3021894 | 42 | |
elessair | 0:f269e3021894 | 43 | return 0; |
elessair | 0:f269e3021894 | 44 | } |
elessair | 0:f269e3021894 | 45 | |
elessair | 0:f269e3021894 | 46 | return nsapi_dns_query(this, name, address, version); |
elessair | 0:f269e3021894 | 47 | } |
elessair | 0:f269e3021894 | 48 | |
elessair | 0:f269e3021894 | 49 | int NetworkStack::add_dns_server(const SocketAddress &address) |
elessair | 0:f269e3021894 | 50 | { |
elessair | 0:f269e3021894 | 51 | return nsapi_dns_add_server(address); |
elessair | 0:f269e3021894 | 52 | } |
elessair | 0:f269e3021894 | 53 | |
elessair | 0:f269e3021894 | 54 | int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen) |
elessair | 0:f269e3021894 | 55 | { |
elessair | 0:f269e3021894 | 56 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 57 | } |
elessair | 0:f269e3021894 | 58 | |
elessair | 0:f269e3021894 | 59 | int NetworkStack::getstackopt(int level, int optname, void *optval, unsigned *optlen) |
elessair | 0:f269e3021894 | 60 | { |
elessair | 0:f269e3021894 | 61 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 62 | } |
elessair | 0:f269e3021894 | 63 | |
elessair | 0:f269e3021894 | 64 | int NetworkStack::setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen) |
elessair | 0:f269e3021894 | 65 | { |
elessair | 0:f269e3021894 | 66 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 67 | } |
elessair | 0:f269e3021894 | 68 | |
elessair | 0:f269e3021894 | 69 | int NetworkStack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) |
elessair | 0:f269e3021894 | 70 | { |
elessair | 0:f269e3021894 | 71 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 72 | } |
elessair | 0:f269e3021894 | 73 | |
elessair | 0:f269e3021894 | 74 | |
elessair | 0:f269e3021894 | 75 | // NetworkStackWrapper class for encapsulating the raw nsapi_stack structure |
elessair | 0:f269e3021894 | 76 | class NetworkStackWrapper : public NetworkStack |
elessair | 0:f269e3021894 | 77 | { |
elessair | 0:f269e3021894 | 78 | private: |
elessair | 0:f269e3021894 | 79 | inline nsapi_stack_t *_stack() |
elessair | 0:f269e3021894 | 80 | { |
elessair | 0:f269e3021894 | 81 | return reinterpret_cast<nsapi_stack_t *>( |
elessair | 0:f269e3021894 | 82 | reinterpret_cast<uint8_t *>(this) |
elessair | 0:f269e3021894 | 83 | - offsetof(nsapi_stack_t, _stack_buffer)); |
elessair | 0:f269e3021894 | 84 | } |
elessair | 0:f269e3021894 | 85 | |
elessair | 0:f269e3021894 | 86 | inline const nsapi_stack_api_t *_stack_api() |
elessair | 0:f269e3021894 | 87 | { |
elessair | 0:f269e3021894 | 88 | return _stack()->stack_api; |
elessair | 0:f269e3021894 | 89 | } |
elessair | 0:f269e3021894 | 90 | |
elessair | 0:f269e3021894 | 91 | public: |
elessair | 0:f269e3021894 | 92 | virtual const char *get_ip_address() |
elessair | 0:f269e3021894 | 93 | { |
elessair | 0:f269e3021894 | 94 | if (!_stack_api()->get_ip_address) { |
elessair | 0:f269e3021894 | 95 | return 0; |
elessair | 0:f269e3021894 | 96 | } |
elessair | 0:f269e3021894 | 97 | |
elessair | 0:f269e3021894 | 98 | static uint8_t buffer[sizeof(SocketAddress)]; |
elessair | 0:f269e3021894 | 99 | SocketAddress *address = new (buffer) SocketAddress(_stack_api()->get_ip_address(_stack())); |
elessair | 0:f269e3021894 | 100 | return address->get_ip_address(); |
elessair | 0:f269e3021894 | 101 | } |
elessair | 0:f269e3021894 | 102 | |
elessair | 0:f269e3021894 | 103 | virtual int gethostbyname(const char *name, SocketAddress *address) |
elessair | 0:f269e3021894 | 104 | { |
elessair | 0:f269e3021894 | 105 | if (!_stack_api()->gethostbyname) { |
elessair | 0:f269e3021894 | 106 | return NetworkStack::gethostbyname(name, address); |
elessair | 0:f269e3021894 | 107 | } |
elessair | 0:f269e3021894 | 108 | |
elessair | 0:f269e3021894 | 109 | nsapi_addr_t addr = {NSAPI_IPv4, 0}; |
elessair | 0:f269e3021894 | 110 | int err = _stack_api()->gethostbyname(_stack(), name, &addr, NSAPI_UNSPEC); |
elessair | 0:f269e3021894 | 111 | address->set_addr(addr); |
elessair | 0:f269e3021894 | 112 | return err; |
elessair | 0:f269e3021894 | 113 | } |
elessair | 0:f269e3021894 | 114 | |
elessair | 0:f269e3021894 | 115 | virtual int gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) |
elessair | 0:f269e3021894 | 116 | { |
elessair | 0:f269e3021894 | 117 | if (!_stack_api()->gethostbyname) { |
elessair | 0:f269e3021894 | 118 | return NetworkStack::gethostbyname(name, address, version); |
elessair | 0:f269e3021894 | 119 | } |
elessair | 0:f269e3021894 | 120 | |
elessair | 0:f269e3021894 | 121 | nsapi_addr_t addr = {NSAPI_IPv4, 0}; |
elessair | 0:f269e3021894 | 122 | int err = _stack_api()->gethostbyname(_stack(), name, &addr, version); |
elessair | 0:f269e3021894 | 123 | address->set_addr(addr); |
elessair | 0:f269e3021894 | 124 | return err; |
elessair | 0:f269e3021894 | 125 | } |
elessair | 0:f269e3021894 | 126 | |
elessair | 0:f269e3021894 | 127 | virtual int add_dns_server(const SocketAddress &address) |
elessair | 0:f269e3021894 | 128 | { |
elessair | 0:f269e3021894 | 129 | if (!_stack_api()->add_dns_server) { |
elessair | 0:f269e3021894 | 130 | return NetworkStack::add_dns_server(address); |
elessair | 0:f269e3021894 | 131 | } |
elessair | 0:f269e3021894 | 132 | |
elessair | 0:f269e3021894 | 133 | return _stack_api()->add_dns_server(_stack(), address.get_addr()); |
elessair | 0:f269e3021894 | 134 | } |
elessair | 0:f269e3021894 | 135 | |
elessair | 0:f269e3021894 | 136 | virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen) |
elessair | 0:f269e3021894 | 137 | { |
elessair | 0:f269e3021894 | 138 | if (!_stack_api()->setstackopt) { |
elessair | 0:f269e3021894 | 139 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 140 | } |
elessair | 0:f269e3021894 | 141 | |
elessair | 0:f269e3021894 | 142 | return _stack_api()->setstackopt(_stack(), level, optname, optval, optlen); |
elessair | 0:f269e3021894 | 143 | } |
elessair | 0:f269e3021894 | 144 | |
elessair | 0:f269e3021894 | 145 | virtual int getstackopt(int level, int optname, void *optval, unsigned *optlen) |
elessair | 0:f269e3021894 | 146 | { |
elessair | 0:f269e3021894 | 147 | if (!_stack_api()->getstackopt) { |
elessair | 0:f269e3021894 | 148 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 149 | } |
elessair | 0:f269e3021894 | 150 | |
elessair | 0:f269e3021894 | 151 | return _stack_api()->getstackopt(_stack(), level, optname, optval, optlen); |
elessair | 0:f269e3021894 | 152 | } |
elessair | 0:f269e3021894 | 153 | |
elessair | 0:f269e3021894 | 154 | protected: |
elessair | 0:f269e3021894 | 155 | virtual int socket_open(nsapi_socket_t *socket, nsapi_protocol_t proto) |
elessair | 0:f269e3021894 | 156 | { |
elessair | 0:f269e3021894 | 157 | if (!_stack_api()->socket_open) { |
elessair | 0:f269e3021894 | 158 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 159 | } |
elessair | 0:f269e3021894 | 160 | |
elessair | 0:f269e3021894 | 161 | return _stack_api()->socket_open(_stack(), socket, proto); |
elessair | 0:f269e3021894 | 162 | } |
elessair | 0:f269e3021894 | 163 | |
elessair | 0:f269e3021894 | 164 | virtual int socket_close(nsapi_socket_t socket) |
elessair | 0:f269e3021894 | 165 | { |
elessair | 0:f269e3021894 | 166 | if (!_stack_api()->socket_close) { |
elessair | 0:f269e3021894 | 167 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 168 | } |
elessair | 0:f269e3021894 | 169 | |
elessair | 0:f269e3021894 | 170 | return _stack_api()->socket_close(_stack(), socket); |
elessair | 0:f269e3021894 | 171 | } |
elessair | 0:f269e3021894 | 172 | |
elessair | 0:f269e3021894 | 173 | virtual int socket_bind(nsapi_socket_t socket, const SocketAddress &address) |
elessair | 0:f269e3021894 | 174 | { |
elessair | 0:f269e3021894 | 175 | if (!_stack_api()->socket_bind) { |
elessair | 0:f269e3021894 | 176 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 177 | } |
elessair | 0:f269e3021894 | 178 | |
elessair | 0:f269e3021894 | 179 | return _stack_api()->socket_bind(_stack(), socket, address.get_addr(), address.get_port()); |
elessair | 0:f269e3021894 | 180 | } |
elessair | 0:f269e3021894 | 181 | |
elessair | 0:f269e3021894 | 182 | virtual int socket_listen(nsapi_socket_t socket, int backlog) |
elessair | 0:f269e3021894 | 183 | { |
elessair | 0:f269e3021894 | 184 | if (!_stack_api()->socket_listen) { |
elessair | 0:f269e3021894 | 185 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 186 | } |
elessair | 0:f269e3021894 | 187 | |
elessair | 0:f269e3021894 | 188 | return _stack_api()->socket_listen(_stack(), socket, backlog); |
elessair | 0:f269e3021894 | 189 | } |
elessair | 0:f269e3021894 | 190 | |
elessair | 0:f269e3021894 | 191 | virtual int socket_connect(nsapi_socket_t socket, const SocketAddress &address) |
elessair | 0:f269e3021894 | 192 | { |
elessair | 0:f269e3021894 | 193 | if (!_stack_api()->socket_connect) { |
elessair | 0:f269e3021894 | 194 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 195 | } |
elessair | 0:f269e3021894 | 196 | |
elessair | 0:f269e3021894 | 197 | return _stack_api()->socket_connect(_stack(), socket, address.get_addr(), address.get_port()); |
elessair | 0:f269e3021894 | 198 | } |
elessair | 0:f269e3021894 | 199 | |
elessair | 0:f269e3021894 | 200 | virtual int socket_accept(nsapi_socket_t server, nsapi_socket_t *socket, SocketAddress *address) |
elessair | 0:f269e3021894 | 201 | { |
elessair | 0:f269e3021894 | 202 | if (!_stack_api()->socket_accept) { |
elessair | 0:f269e3021894 | 203 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 204 | } |
elessair | 0:f269e3021894 | 205 | |
elessair | 0:f269e3021894 | 206 | nsapi_addr_t addr = {NSAPI_IPv4, 0}; |
elessair | 0:f269e3021894 | 207 | uint16_t port = 0; |
elessair | 0:f269e3021894 | 208 | |
elessair | 0:f269e3021894 | 209 | int err = _stack_api()->socket_accept(_stack(), server, socket, &addr, &port); |
elessair | 0:f269e3021894 | 210 | |
elessair | 0:f269e3021894 | 211 | if (address) { |
elessair | 0:f269e3021894 | 212 | address->set_addr(addr); |
elessair | 0:f269e3021894 | 213 | address->set_port(port); |
elessair | 0:f269e3021894 | 214 | } |
elessair | 0:f269e3021894 | 215 | |
elessair | 0:f269e3021894 | 216 | return err; |
elessair | 0:f269e3021894 | 217 | } |
elessair | 0:f269e3021894 | 218 | |
elessair | 0:f269e3021894 | 219 | virtual int socket_send(nsapi_socket_t socket, const void *data, unsigned size) |
elessair | 0:f269e3021894 | 220 | { |
elessair | 0:f269e3021894 | 221 | if (!_stack_api()->socket_send) { |
elessair | 0:f269e3021894 | 222 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 223 | } |
elessair | 0:f269e3021894 | 224 | |
elessair | 0:f269e3021894 | 225 | return _stack_api()->socket_send(_stack(), socket, data, size); |
elessair | 0:f269e3021894 | 226 | } |
elessair | 0:f269e3021894 | 227 | |
elessair | 0:f269e3021894 | 228 | virtual int socket_recv(nsapi_socket_t socket, void *data, unsigned size) |
elessair | 0:f269e3021894 | 229 | { |
elessair | 0:f269e3021894 | 230 | if (!_stack_api()->socket_recv) { |
elessair | 0:f269e3021894 | 231 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 232 | } |
elessair | 0:f269e3021894 | 233 | |
elessair | 0:f269e3021894 | 234 | return _stack_api()->socket_recv(_stack(), socket, data, size); |
elessair | 0:f269e3021894 | 235 | } |
elessair | 0:f269e3021894 | 236 | |
elessair | 0:f269e3021894 | 237 | virtual int socket_sendto(nsapi_socket_t socket, const SocketAddress &address, const void *data, unsigned size) |
elessair | 0:f269e3021894 | 238 | { |
elessair | 0:f269e3021894 | 239 | if (!_stack_api()->socket_sendto) { |
elessair | 0:f269e3021894 | 240 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 241 | } |
elessair | 0:f269e3021894 | 242 | |
elessair | 0:f269e3021894 | 243 | return _stack_api()->socket_sendto(_stack(), socket, address.get_addr(), address.get_port(), data, size); |
elessair | 0:f269e3021894 | 244 | } |
elessair | 0:f269e3021894 | 245 | |
elessair | 0:f269e3021894 | 246 | virtual int socket_recvfrom(nsapi_socket_t socket, SocketAddress *address, void *data, unsigned size) |
elessair | 0:f269e3021894 | 247 | { |
elessair | 0:f269e3021894 | 248 | if (!_stack_api()->socket_recvfrom) { |
elessair | 0:f269e3021894 | 249 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 250 | } |
elessair | 0:f269e3021894 | 251 | |
elessair | 0:f269e3021894 | 252 | nsapi_addr_t addr = {NSAPI_IPv4, 0}; |
elessair | 0:f269e3021894 | 253 | uint16_t port = 0; |
elessair | 0:f269e3021894 | 254 | |
elessair | 0:f269e3021894 | 255 | int err = _stack_api()->socket_recvfrom(_stack(), socket, &addr, &port, data, size); |
elessair | 0:f269e3021894 | 256 | |
elessair | 0:f269e3021894 | 257 | if (address) { |
elessair | 0:f269e3021894 | 258 | address->set_addr(addr); |
elessair | 0:f269e3021894 | 259 | address->set_port(port); |
elessair | 0:f269e3021894 | 260 | } |
elessair | 0:f269e3021894 | 261 | |
elessair | 0:f269e3021894 | 262 | return err; |
elessair | 0:f269e3021894 | 263 | } |
elessair | 0:f269e3021894 | 264 | |
elessair | 0:f269e3021894 | 265 | virtual void socket_attach(nsapi_socket_t socket, void (*callback)(void *), void *data) |
elessair | 0:f269e3021894 | 266 | { |
elessair | 0:f269e3021894 | 267 | if (!_stack_api()->socket_attach) { |
elessair | 0:f269e3021894 | 268 | return; |
elessair | 0:f269e3021894 | 269 | } |
elessair | 0:f269e3021894 | 270 | |
elessair | 0:f269e3021894 | 271 | return _stack_api()->socket_attach(_stack(), socket, callback, data); |
elessair | 0:f269e3021894 | 272 | } |
elessair | 0:f269e3021894 | 273 | |
elessair | 0:f269e3021894 | 274 | virtual int setsockopt(nsapi_socket_t socket, int level, int optname, const void *optval, unsigned optlen) |
elessair | 0:f269e3021894 | 275 | { |
elessair | 0:f269e3021894 | 276 | if (!_stack_api()->setsockopt) { |
elessair | 0:f269e3021894 | 277 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 278 | } |
elessair | 0:f269e3021894 | 279 | |
elessair | 0:f269e3021894 | 280 | return _stack_api()->setsockopt(_stack(), socket, level, optname, optval, optlen); |
elessair | 0:f269e3021894 | 281 | } |
elessair | 0:f269e3021894 | 282 | |
elessair | 0:f269e3021894 | 283 | virtual int getsockopt(nsapi_socket_t socket, int level, int optname, void *optval, unsigned *optlen) |
elessair | 0:f269e3021894 | 284 | { |
elessair | 0:f269e3021894 | 285 | if (!_stack_api()->getsockopt) { |
elessair | 0:f269e3021894 | 286 | return NSAPI_ERROR_UNSUPPORTED; |
elessair | 0:f269e3021894 | 287 | } |
elessair | 0:f269e3021894 | 288 | |
elessair | 0:f269e3021894 | 289 | return _stack_api()->getsockopt(_stack(), socket, level, optname, optval, optlen); |
elessair | 0:f269e3021894 | 290 | } |
elessair | 0:f269e3021894 | 291 | }; |
elessair | 0:f269e3021894 | 292 | |
elessair | 0:f269e3021894 | 293 | |
elessair | 0:f269e3021894 | 294 | // Conversion function for network stacks |
elessair | 0:f269e3021894 | 295 | NetworkStack *nsapi_create_stack(nsapi_stack_t *stack) |
elessair | 0:f269e3021894 | 296 | { |
elessair | 0:f269e3021894 | 297 | MBED_ASSERT(sizeof stack->_stack_buffer >= sizeof(NetworkStackWrapper)); |
elessair | 0:f269e3021894 | 298 | return new (stack->_stack_buffer) NetworkStackWrapper; |
elessair | 0:f269e3021894 | 299 | } |
elessair | 0:f269e3021894 | 300 | |
elessair | 0:f269e3021894 | 301 | NetworkStack *nsapi_create_stack(NetworkStack *stack) |
elessair | 0:f269e3021894 | 302 | { |
elessair | 0:f269e3021894 | 303 | return stack; |
elessair | 0:f269e3021894 | 304 | } |
elessair | 0:f269e3021894 | 305 |