mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 /*
elessair 0:f269e3021894 2 * Copyright (c) 2016 ARM Limited. All rights reserved.
elessair 0:f269e3021894 3 */
elessair 0:f269e3021894 4
elessair 0:f269e3021894 5 #ifndef NANOSTACK_INTERFACE_H_
elessair 0:f269e3021894 6 #define NANOSTACK_INTERFACE_H_
elessair 0:f269e3021894 7
elessair 0:f269e3021894 8 #include "NetworkStack.h"
elessair 0:f269e3021894 9 #include "MeshInterface.h"
elessair 0:f269e3021894 10 #include "NanostackRfPhy.h"
elessair 0:f269e3021894 11
elessair 0:f269e3021894 12 #include "mbed-mesh-api/Mesh6LoWPAN_ND.h"
elessair 0:f269e3021894 13 #include "mbed-mesh-api/MeshThread.h"
elessair 0:f269e3021894 14
elessair 0:f269e3021894 15 class NanostackInterface : public NetworkStack {
elessair 0:f269e3021894 16 public:
elessair 0:f269e3021894 17 static NanostackInterface *get_stack();
elessair 0:f269e3021894 18
elessair 0:f269e3021894 19 protected:
elessair 0:f269e3021894 20
elessair 0:f269e3021894 21 /** Get the local IP address
elessair 0:f269e3021894 22 *
elessair 0:f269e3021894 23 * @return Null-terminated representation of the local IP address
elessair 0:f269e3021894 24 * or null if not yet connected
elessair 0:f269e3021894 25 */
elessair 0:f269e3021894 26 virtual const char *get_ip_address();
elessair 0:f269e3021894 27
elessair 0:f269e3021894 28 /** Opens a socket
elessair 0:f269e3021894 29 *
elessair 0:f269e3021894 30 * Creates a network socket and stores it in the specified handle.
elessair 0:f269e3021894 31 * The handle must be passed to following calls on the socket.
elessair 0:f269e3021894 32 *
elessair 0:f269e3021894 33 * A stack may have a finite number of sockets, in this case
elessair 0:f269e3021894 34 * NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
elessair 0:f269e3021894 35 *
elessair 0:f269e3021894 36 * @param handle Destination for the handle to a newly created socket
elessair 0:f269e3021894 37 * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP
elessair 0:f269e3021894 38 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 39 */
elessair 0:f269e3021894 40 virtual int socket_open(void **handle, nsapi_protocol_t proto);
elessair 0:f269e3021894 41
elessair 0:f269e3021894 42 /** Close the socket
elessair 0:f269e3021894 43 *
elessair 0:f269e3021894 44 * Closes any open connection and deallocates any memory associated
elessair 0:f269e3021894 45 * with the socket.
elessair 0:f269e3021894 46 *
elessair 0:f269e3021894 47 * @param handle Socket handle
elessair 0:f269e3021894 48 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 49 */
elessair 0:f269e3021894 50 virtual int socket_close(void *handle);
elessair 0:f269e3021894 51
elessair 0:f269e3021894 52 /** Bind a specific address to a socket
elessair 0:f269e3021894 53 *
elessair 0:f269e3021894 54 * Binding a socket specifies the address and port on which to recieve
elessair 0:f269e3021894 55 * data. If the IP address is zeroed, only the port is bound.
elessair 0:f269e3021894 56 *
elessair 0:f269e3021894 57 * @param handle Socket handle
elessair 0:f269e3021894 58 * @param address Local address to bind
elessair 0:f269e3021894 59 * @return 0 on success, negative error code on failure.
elessair 0:f269e3021894 60 */
elessair 0:f269e3021894 61 virtual int socket_bind(void *handle, const SocketAddress &address);
elessair 0:f269e3021894 62
elessair 0:f269e3021894 63 /** Listen for connections on a TCP socket
elessair 0:f269e3021894 64 *
elessair 0:f269e3021894 65 * Marks the socket as a passive socket that can be used to accept
elessair 0:f269e3021894 66 * incoming connections.
elessair 0:f269e3021894 67 *
elessair 0:f269e3021894 68 * @param handle Socket handle
elessair 0:f269e3021894 69 * @param backlog Number of pending connections that can be queued
elessair 0:f269e3021894 70 * simultaneously
elessair 0:f269e3021894 71 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 72 */
elessair 0:f269e3021894 73 virtual int socket_listen(void *handle, int backlog);
elessair 0:f269e3021894 74
elessair 0:f269e3021894 75 /** Connects TCP socket to a remote host
elessair 0:f269e3021894 76 *
elessair 0:f269e3021894 77 * Initiates a connection to a remote server specified by the
elessair 0:f269e3021894 78 * indicated address.
elessair 0:f269e3021894 79 *
elessair 0:f269e3021894 80 * @param handle Socket handle
elessair 0:f269e3021894 81 * @param address The SocketAddress of the remote host
elessair 0:f269e3021894 82 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 83 */
elessair 0:f269e3021894 84 virtual int socket_connect(void *handle, const SocketAddress &address);
elessair 0:f269e3021894 85
elessair 0:f269e3021894 86 /** Accepts a connection on a TCP socket
elessair 0:f269e3021894 87 *
elessair 0:f269e3021894 88 * The server socket must be bound and set to listen for connections.
elessair 0:f269e3021894 89 * On a new connection, creates a network socket and stores it in the
elessair 0:f269e3021894 90 * specified handle. The handle must be passed to following calls on
elessair 0:f269e3021894 91 * the socket.
elessair 0:f269e3021894 92 *
elessair 0:f269e3021894 93 * A stack may have a finite number of sockets, in this case
elessair 0:f269e3021894 94 * NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
elessair 0:f269e3021894 95 *
elessair 0:f269e3021894 96 * This call is non-blocking. If accept would block,
elessair 0:f269e3021894 97 * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
elessair 0:f269e3021894 98 *
elessair 0:f269e3021894 99 * @param server Socket handle to server to accept from
elessair 0:f269e3021894 100 * @param handle Destination for a handle to the newly created socket
elessair 0:f269e3021894 101 * @param address Destination for the remote address or NULL
elessair 0:f269e3021894 102 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 103 */
elessair 0:f269e3021894 104 virtual int socket_accept(void *handle, void **server, SocketAddress *address);
elessair 0:f269e3021894 105
elessair 0:f269e3021894 106 /** Send data over a TCP socket
elessair 0:f269e3021894 107 *
elessair 0:f269e3021894 108 * The socket must be connected to a remote host. Returns the number of
elessair 0:f269e3021894 109 * bytes sent from the buffer.
elessair 0:f269e3021894 110 *
elessair 0:f269e3021894 111 * This call is non-blocking. If send would block,
elessair 0:f269e3021894 112 * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
elessair 0:f269e3021894 113 *
elessair 0:f269e3021894 114 * @param handle Socket handle
elessair 0:f269e3021894 115 * @param data Buffer of data to send to the host
elessair 0:f269e3021894 116 * @param size Size of the buffer in bytes
elessair 0:f269e3021894 117 * @return Number of sent bytes on success, negative error
elessair 0:f269e3021894 118 * code on failure
elessair 0:f269e3021894 119 */
elessair 0:f269e3021894 120 virtual int socket_send(void *handle, const void *data, unsigned size);
elessair 0:f269e3021894 121
elessair 0:f269e3021894 122 /** Receive data over a TCP socket
elessair 0:f269e3021894 123 *
elessair 0:f269e3021894 124 * The socket must be connected to a remote host. Returns the number of
elessair 0:f269e3021894 125 * bytes received into the buffer.
elessair 0:f269e3021894 126 *
elessair 0:f269e3021894 127 * This call is non-blocking. If recv would block,
elessair 0:f269e3021894 128 * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
elessair 0:f269e3021894 129 *
elessair 0:f269e3021894 130 * @param handle Socket handle
elessair 0:f269e3021894 131 * @param data Destination buffer for data received from the host
elessair 0:f269e3021894 132 * @param size Size of the buffer in bytes
elessair 0:f269e3021894 133 * @return Number of received bytes on success, negative error
elessair 0:f269e3021894 134 * code on failure
elessair 0:f269e3021894 135 */
elessair 0:f269e3021894 136 virtual int socket_recv(void *handle, void *data, unsigned size);
elessair 0:f269e3021894 137
elessair 0:f269e3021894 138 /** Send a packet over a UDP socket
elessair 0:f269e3021894 139 *
elessair 0:f269e3021894 140 * Sends data to the specified address. Returns the number of bytes
elessair 0:f269e3021894 141 * sent from the buffer.
elessair 0:f269e3021894 142 *
elessair 0:f269e3021894 143 * This call is non-blocking. If sendto would block,
elessair 0:f269e3021894 144 * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
elessair 0:f269e3021894 145 *
elessair 0:f269e3021894 146 * @param handle Socket handle
elessair 0:f269e3021894 147 * @param address The SocketAddress of the remote host
elessair 0:f269e3021894 148 * @param data Buffer of data to send to the host
elessair 0:f269e3021894 149 * @param size Size of the buffer in bytes
elessair 0:f269e3021894 150 * @return Number of sent bytes on success, negative error
elessair 0:f269e3021894 151 * code on failure
elessair 0:f269e3021894 152 */
elessair 0:f269e3021894 153 virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
elessair 0:f269e3021894 154
elessair 0:f269e3021894 155 /** Receive a packet over a UDP socket
elessair 0:f269e3021894 156 *
elessair 0:f269e3021894 157 * Receives data and stores the source address in address if address
elessair 0:f269e3021894 158 * is not NULL. Returns the number of bytes received into the buffer.
elessair 0:f269e3021894 159 *
elessair 0:f269e3021894 160 * This call is non-blocking. If recvfrom would block,
elessair 0:f269e3021894 161 * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
elessair 0:f269e3021894 162 *
elessair 0:f269e3021894 163 * @param handle Socket handle
elessair 0:f269e3021894 164 * @param address Destination for the source address or NULL
elessair 0:f269e3021894 165 * @param data Destination buffer for data received from the host
elessair 0:f269e3021894 166 * @param size Size of the buffer in bytes
elessair 0:f269e3021894 167 * @return Number of received bytes on success, negative error
elessair 0:f269e3021894 168 * code on failure
elessair 0:f269e3021894 169 */
elessair 0:f269e3021894 170 virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
elessair 0:f269e3021894 171
elessair 0:f269e3021894 172 /** Register a callback on state change of the socket
elessair 0:f269e3021894 173 *
elessair 0:f269e3021894 174 * The specified callback will be called on state changes such as when
elessair 0:f269e3021894 175 * the socket can recv/send/accept successfully and on when an error
elessair 0:f269e3021894 176 * occurs. The callback may also be called spuriously without reason.
elessair 0:f269e3021894 177 *
elessair 0:f269e3021894 178 * The callback may be called in an interrupt context and should not
elessair 0:f269e3021894 179 * perform expensive operations such as recv/send calls.
elessair 0:f269e3021894 180 *
elessair 0:f269e3021894 181 * @param handle Socket handle
elessair 0:f269e3021894 182 * @param callback Function to call on state change
elessair 0:f269e3021894 183 * @param data Argument to pass to callback
elessair 0:f269e3021894 184 */
elessair 0:f269e3021894 185 virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
elessair 0:f269e3021894 186
elessair 0:f269e3021894 187 /* Set stack-specific socket options
elessair 0:f269e3021894 188 *
elessair 0:f269e3021894 189 * The setsockopt allow an application to pass stack-specific hints
elessair 0:f269e3021894 190 * to the underlying stack. For unsupported options,
elessair 0:f269e3021894 191 * NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified.
elessair 0:f269e3021894 192 *
elessair 0:f269e3021894 193 * @param handle Socket handle
elessair 0:f269e3021894 194 * @param level Stack-specific protocol level
elessair 0:f269e3021894 195 * @param optname Stack-specific option identifier
elessair 0:f269e3021894 196 * @param optval Option value
elessair 0:f269e3021894 197 * @param optlen Length of the option value
elessair 0:f269e3021894 198 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 199 */
elessair 0:f269e3021894 200 virtual int setsockopt(void *handle, int level, int optname, const void *optval, unsigned optlen);
elessair 0:f269e3021894 201
elessair 0:f269e3021894 202 /* Get stack-specific socket options
elessair 0:f269e3021894 203 *
elessair 0:f269e3021894 204 * The getstackopt allow an application to retrieve stack-specific hints
elessair 0:f269e3021894 205 * from the underlying stack. For unsupported options,
elessair 0:f269e3021894 206 * NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified.
elessair 0:f269e3021894 207 *
elessair 0:f269e3021894 208 * @param handle Socket handle
elessair 0:f269e3021894 209 * @param level Stack-specific protocol level
elessair 0:f269e3021894 210 * @param optname Stack-specific option identifier
elessair 0:f269e3021894 211 * @param optval Destination for option value
elessair 0:f269e3021894 212 * @param optlen Length of the option value
elessair 0:f269e3021894 213 * @return 0 on success, negative error code on failure
elessair 0:f269e3021894 214 */
elessair 0:f269e3021894 215 virtual int getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
elessair 0:f269e3021894 216
elessair 0:f269e3021894 217 private:
elessair 0:f269e3021894 218 static NanostackInterface * _ns_interface;
elessair 0:f269e3021894 219 };
elessair 0:f269e3021894 220
elessair 0:f269e3021894 221 class MeshInterfaceNanostack : public MeshInterface {
elessair 0:f269e3021894 222 public:
elessair 0:f269e3021894 223
elessair 0:f269e3021894 224 /** Attach phy and initialize the mesh
elessair 0:f269e3021894 225 *
elessair 0:f269e3021894 226 * Initializes a mesh interface on the given phy. Not needed if
elessair 0:f269e3021894 227 * the phy is passed to the mesh's constructor.
elessair 0:f269e3021894 228 *
elessair 0:f269e3021894 229 * @return 0 on success, negative on failure
elessair 0:f269e3021894 230 */
elessair 0:f269e3021894 231 virtual int initialize(NanostackRfPhy *phy);
elessair 0:f269e3021894 232
elessair 0:f269e3021894 233 /** Start the interface
elessair 0:f269e3021894 234 *
elessair 0:f269e3021894 235 * @return 0 on success, negative on failure
elessair 0:f269e3021894 236 */
elessair 0:f269e3021894 237 virtual int connect() = 0;
elessair 0:f269e3021894 238
elessair 0:f269e3021894 239 /** Stop the interface
elessair 0:f269e3021894 240 *
elessair 0:f269e3021894 241 * @return 0 on success, negative on failure
elessair 0:f269e3021894 242 */
elessair 0:f269e3021894 243 virtual int disconnect();
elessair 0:f269e3021894 244
elessair 0:f269e3021894 245 /** Get the internally stored IP address
elessair 0:f269e3021894 246 /return IP address of the interface or null if not yet connected
elessair 0:f269e3021894 247 */
elessair 0:f269e3021894 248 virtual const char *get_ip_address();
elessair 0:f269e3021894 249
elessair 0:f269e3021894 250 /** Get the internally stored MAC address
elessair 0:f269e3021894 251 /return MAC address of the interface
elessair 0:f269e3021894 252 */
elessair 0:f269e3021894 253 virtual const char *get_mac_address();
elessair 0:f269e3021894 254
elessair 0:f269e3021894 255 protected:
elessair 0:f269e3021894 256 MeshInterfaceNanostack();
elessair 0:f269e3021894 257 MeshInterfaceNanostack(NanostackRfPhy *phy);
elessair 0:f269e3021894 258 int register_rf();
elessair 0:f269e3021894 259 int actual_connect();
elessair 0:f269e3021894 260 virtual NetworkStack * get_stack(void);
elessair 0:f269e3021894 261
elessair 0:f269e3021894 262 void mesh_network_handler(mesh_connection_status_t status);
elessair 0:f269e3021894 263 NanostackRfPhy *phy;
elessair 0:f269e3021894 264 AbstractMesh *mesh_api;
elessair 0:f269e3021894 265 int8_t rf_device_id;
elessair 0:f269e3021894 266 uint8_t eui64[8];
elessair 0:f269e3021894 267 char ip_addr_str[40];
elessair 0:f269e3021894 268 char mac_addr_str[24];
elessair 0:f269e3021894 269 Semaphore connect_semaphore;
elessair 0:f269e3021894 270 };
elessair 0:f269e3021894 271
elessair 0:f269e3021894 272 class LoWPANNDInterface : public MeshInterfaceNanostack {
elessair 0:f269e3021894 273 public:
elessair 0:f269e3021894 274
elessair 0:f269e3021894 275 /** Create an uninitialized LoWPANNDInterface
elessair 0:f269e3021894 276 *
elessair 0:f269e3021894 277 * Must initialize to initialize the mesh on a phy.
elessair 0:f269e3021894 278 */
elessair 0:f269e3021894 279 LoWPANNDInterface() : MeshInterfaceNanostack() {
elessair 0:f269e3021894 280
elessair 0:f269e3021894 281 }
elessair 0:f269e3021894 282
elessair 0:f269e3021894 283 /** Create an initialized MeshInterface
elessair 0:f269e3021894 284 *
elessair 0:f269e3021894 285 */
elessair 0:f269e3021894 286 LoWPANNDInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy) {
elessair 0:f269e3021894 287
elessair 0:f269e3021894 288 }
elessair 0:f269e3021894 289
elessair 0:f269e3021894 290 int connect();
elessair 0:f269e3021894 291 protected:
elessair 0:f269e3021894 292 Mesh6LoWPAN_ND *get_mesh_api() const { return static_cast<Mesh6LoWPAN_ND *>(mesh_api); }
elessair 0:f269e3021894 293 private:
elessair 0:f269e3021894 294
elessair 0:f269e3021894 295 };
elessair 0:f269e3021894 296
elessair 0:f269e3021894 297 class ThreadInterface : public MeshInterfaceNanostack {
elessair 0:f269e3021894 298 public:
elessair 0:f269e3021894 299
elessair 0:f269e3021894 300 /** Create an uninitialized LoWPANNDInterface
elessair 0:f269e3021894 301 *
elessair 0:f269e3021894 302 * Must initialize to initialize the mesh on a phy.
elessair 0:f269e3021894 303 */
elessair 0:f269e3021894 304 ThreadInterface() : MeshInterfaceNanostack() {
elessair 0:f269e3021894 305
elessair 0:f269e3021894 306 }
elessair 0:f269e3021894 307
elessair 0:f269e3021894 308 /** Create an initialized MeshInterface
elessair 0:f269e3021894 309 *
elessair 0:f269e3021894 310 */
elessair 0:f269e3021894 311 ThreadInterface(NanostackRfPhy *phy) : MeshInterfaceNanostack(phy) {
elessair 0:f269e3021894 312
elessair 0:f269e3021894 313 }
elessair 0:f269e3021894 314
elessair 0:f269e3021894 315 int connect();
elessair 0:f269e3021894 316 protected:
elessair 0:f269e3021894 317 MeshThread *get_mesh_api() const { return static_cast<MeshThread *>(mesh_api); }
elessair 0:f269e3021894 318 private:
elessair 0:f269e3021894 319
elessair 0:f269e3021894 320 };
elessair 0:f269e3021894 321
elessair 0:f269e3021894 322
elessair 0:f269e3021894 323 #endif /* NANOSTACK_INTERFACE_H_ */