Pinned to some recent date

Committer:
Simon Cooksey
Date:
Thu Nov 17 16:43:53 2016 +0000
Revision:
0:fb7af294d5d9
Initial commit

Who changed what in which revision?

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