Mistake on this page?
Report an issue in GitHub or email us
NetworkStack.h
Go to the documentation of this file.
1 
2 /* NetworkStack
3  * Copyright (c) 2015 ARM Limited
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef NETWORK_STACK_H
19 #define NETWORK_STACK_H
20 
21 #include <type_traits>
22 #include "nsapi_types.h"
25 #include "DNS.h"
26 
27 /** @file NetworkStack.h NetworkStack class */
28 /** @addtogroup netsocket
29  * @{ */
30 
31 // Predeclared classes
33 
34 /** NetworkStack class
35  *
36  * Common interface that is shared between hardware that
37  * can connect to a network over IP. By implementing the
38  * NetworkStack, a network stack can be used as a target
39  * for instantiating network sockets.
40  */
41 class NetworkStack : public DNS {
42 public:
43  virtual ~NetworkStack() = default;
44 
45  /** Get the local IP address
46  *
47  * @param address SocketAddress representation of the local IP address
48  * @retval NSAPI_ERROR_OK on success
49  * @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
50  * @retval NSAPI_ERROR_PARAMETER if the provided pointer is invalid
51  * @retval NSAPI_ERROR_NO_ADDRESS if the address cannot be obtained from stack
52  */
53  virtual nsapi_error_t get_ip_address(SocketAddress *address);
54 
55  /** Get the IPv6 link local address
56  *
57  * @param address SocketAddress representation of the link local IPv6 address
58  * @retval NSAPI_ERROR_OK on success
59  * @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
60  * @retval NSAPI_ERROR_PARAMETER if the provided pointer is invalid
61  */
63 
64  /** Get the local IP address on interface name
65  *
66  * @param address SocketAddress representation of the link local IPv6 address
67  * @param interface_name Network interface_name
68  * @retval NSAPI_ERROR_OK on success
69  * @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
70  * @retval NSAPI_ERROR_PARAMETER if the provided pointer is invalid
71  * @retval NSAPI_ERROR_NO_ADDRESS if the address cannot be obtained from stack
72  */
73  virtual nsapi_error_t get_ip_address_if(SocketAddress *address, const char *interface_name);
74 
75  /** Translates a hostname to an IP address with specific version
76  *
77  * The hostname may be either a domain name or an IP address. If the
78  * hostname is an IP address, no network transactions will be performed.
79  *
80  * If no stack-specific DNS resolution is provided, the hostname
81  * will be resolve using a UDP socket on the stack.
82  *
83  * @param host Hostname to resolve
84  * @param address Pointer to a SocketAddress to store the result.
85  * @param version IP version of address to resolve, NSAPI_UNSPEC indicates
86  * version is chosen by the stack (defaults to NSAPI_UNSPEC)
87  * @param interface_name Network interface_name
88  * @retval NSAPI_ERROR_OK on success
89  * @retval NSAPI_ERROR_PARAMETER if invalid (null) name is provided
90  * @retval NSAPI_ERROR_DNS_FAILURE if DNS resolution fails
91  * @retval int other negative errors, see @ref nsapi_dns_query
92  */
93  virtual nsapi_error_t gethostbyname(const char *host,
94  SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL);
95 
96  /** Translate a hostname to the multiple IP addresses with specific version using network interface name.
97  *
98  * The hostname may be either a domain name or an IP address. If the
99  * hostname is an IP address, no network transactions will be performed.
100  *
101  * If no stack-specific DNS resolution is provided, the hostname
102  * will be resolve using a UDP socket on the stack.
103  *
104  * @param hostname Hostname to resolve.
105  * @param hints Pointer to a SocketAddress with query parameters.
106  * @param res Pointer to a SocketAddress array to store the result..
107  * @param interface_name Network interface name
108  * @return number of results on success, negative error code on failure.
109  */
110  virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name = NULL);
111 
112  /** Hostname translation callback (asynchronous)
113  *
114  * Callback will be called after DNS resolution completes or a failure occurs.
115  *
116  * Callback should not take more than 10ms to execute, otherwise it might
117  * prevent underlying thread processing. A portable user of the callback
118  * should not make calls to network operations due to stack size limitations.
119  * The callback should not perform expensive operations such as socket recv/send
120  * calls or blocking operations.
121  *
122  * @param result Negative error code on failure or
123  * value that represents the number of DNS records
124  * @param address On success, destination for the host SocketAddress
125  */
127 
128  /** Translates a hostname to multiple IP addresses (asynchronous)
129  *
130  * The hostname may be either a domain name or an IP address. If the
131  * hostname is an IP address, no network transactions will be performed.
132  *
133  * If no stack-specific DNS resolution is provided, the hostname
134  * will be resolve using a UDP socket on the stack.
135  *
136  * Call is non-blocking. Result of the DNS operation is returned by the callback.
137  * If this function returns failure, callback will not be called. In case result
138  * is success (IP address was found from DNS cache), callback will be called
139  * before function returns.
140  *
141  * @param host Hostname to resolve
142  * @param callback Callback that is called for result
143  * @param version IP version of address to resolve, NSAPI_UNSPEC indicates
144  * version is chosen by the stack (defaults to NSAPI_UNSPEC)
145  * @param interface_name Network interface_name
146  * @return 0 on immediate success,
147  * negative error code on immediate failure or
148  * a positive unique id that represents the hostname translation operation
149  * and can be passed to cancel
150  */
151  virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version = NSAPI_UNSPEC,
152  const char *interface_name = NULL);
153 
154  /** Translates a hostname to the multiple IP addresses (asynchronous)
155  *
156  * The hostname may be either a domain name or an IP address. If the
157  * hostname is an IP address, no network transactions will be performed.
158  *
159  * If no stack-specific DNS resolution is provided, the hostname
160  * will be resolve using a UDP socket on the stack.
161  *
162  * The call is non-blocking. Result of the DNS operation is returned by the callback.
163  * If this function returns failure, callback will not be called. In case that
164  * IP addresses are found from DNS cache, callback will be called before function returns.
165  *
166  * @param hostname Hostname to resolve
167  * @param hints Pointer to a SocketAddress with query parameters.
168  * @param callback Callback that is called for result
169  * @param interface_name Network interface_name
170  * @return 0 on immediate success,
171  * negative error code on immediate failure or
172  * a positive unique id that represents the hostname translation operation
173  * and can be passed to cancel
174  */
175  virtual nsapi_value_or_error_t getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name = NULL);
176 
177  /** Cancels asynchronous hostname translation
178  *
179  * When translation is cancelled, callback will not be called.
180  *
181  * @param id Unique id of the hostname translation operation
182  * @return NSAPI_ERROR_OK on success, negative error code on failure
183  */
185 
186  /** Add a domain name server to list of servers to query
187  *
188  * @param address Destination for the host address
189  * @param interface_name Network interface name
190  * @return NSAPI_ERROR_OK on success, negative error code on failure
191  */
192  virtual nsapi_error_t add_dns_server(const SocketAddress &address, const char *interface_name = NULL);
193 
194  /** Get a domain name server from a list of servers to query
195  *
196  * Returns a DNS server address for a index. If returns error no more
197  * DNS servers to read.
198  *
199  * @param index Index of the DNS server, starts from zero
200  * @param address Destination for the host address
201  * @param interface_name Network interface name
202  * @return NSAPI_ERROR_OK on success, negative error code on failure
203  */
204  virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name = NULL);
205 
206  /* Set stack options
207  *
208  * setstackopt allows an application to pass stack-specific options
209  * to the underlying stack using stack-specific level and option names,
210  * or to request generic options using levels from nsapi_stack_level_t.
211  *
212  * For unsupported options, NSAPI_ERROR_UNSUPPORTED is returned
213  * and the stack is unmodified.
214  *
215  * @param level Stack-specific protocol level or nsapi_stack_level_t
216  * @param optname Level-specific option name
217  * @param optval Option value
218  * @param optlen Length of the option value
219  * @return NSAPI_ERROR_OK on success, negative error code on failure
220  */
221  virtual nsapi_error_t setstackopt(int level, int optname, const void *optval, unsigned optlen);
222 
223  /* Get stack options
224  *
225  * getstackopt allows an application to retrieve stack-specific options
226  * to the underlying stack using stack-specific level and option names,
227  * or to request generic options using levels from nsapi_stack_level_t.
228  *
229  * @param level Stack-specific protocol level or nsapi_stack_level_t
230  * @param optname Level-specific option name
231  * @param optval Destination for option value
232  * @param optlen Length of the option value
233  * @return NSAPI_ERROR_OK on success, negative error code on failure
234  */
235  virtual nsapi_error_t getstackopt(int level, int optname, void *optval, unsigned *optlen);
236 
237  /** Dynamic downcast to a OnboardNetworkStack */
239  {
240  return 0;
241  }
242 
243 protected:
244  friend class InternetSocket;
245  friend class InternetDatagramSocket;
246  friend class TCPSocket;
247 
248  /** Opens a socket
249  *
250  * Creates a network socket and stores it in the specified handle.
251  * The handle must be passed to following calls on the socket.
252  *
253  * A stack may have a finite number of sockets, in this case
254  * NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
255  *
256  * @param handle Destination for the handle to a newly created socket
257  * @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP
258  * @return NSAPI_ERROR_OK on success, negative error code on failure
259  */
260  virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) = 0;
261 
262  /** Close the socket
263  *
264  * Closes any open connection and deallocates any memory associated
265  * with the socket.
266  *
267  * @param handle Socket handle
268  * @return NSAPI_ERROR_OK on success, negative error code on failure
269  */
270  virtual nsapi_error_t socket_close(nsapi_socket_t handle) = 0;
271 
272  /** Bind a specific address to a socket
273  *
274  * Binding a socket specifies the address and port on which to receive
275  * data. If the IP address is zeroed, only the port is bound.
276  *
277  * @param handle Socket handle
278  * @param address Local address to bind
279  * @return NSAPI_ERROR_OK on success, negative error code on failure.
280  */
281  virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address) = 0;
282 
283  /** Listen for connections on a TCP socket
284  *
285  * Marks the socket as a passive socket that can be used to accept
286  * incoming connections.
287  *
288  * @param handle Socket handle
289  * @param backlog Number of pending connections that can be queued
290  * simultaneously
291  * @return NSAPI_ERROR_OK on success, negative error code on failure
292  */
293  virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog) = 0;
294 
295  /** Connects TCP socket to a remote host
296  *
297  * Initiates a connection to a remote server specified by the
298  * indicated address.
299  *
300  * @param handle Socket handle
301  * @param address The SocketAddress of the remote host
302  * @return NSAPI_ERROR_OK on success, negative error code on failure
303  */
304  virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address) = 0;
305 
306  /** Accepts a connection on a TCP socket
307  *
308  * The server socket must be bound and set to listen for connections.
309  * On a new connection, creates a network socket and stores it in the
310  * specified handle. The handle must be passed to following calls on
311  * the socket.
312  *
313  * A stack may have a finite number of sockets, in this case
314  * NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
315  *
316  * This call is non-blocking. If accept would block,
317  * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
318  *
319  * @param server Socket handle to server to accept from
320  * @param handle Destination for a handle to the newly created socket
321  * @param address Destination for the remote address or NULL
322  * @return NSAPI_ERROR_OK on success, negative error code on failure
323  */
325  nsapi_socket_t *handle, SocketAddress *address = 0) = 0;
326 
327  /** Send data over a TCP socket
328  *
329  * The socket must be connected to a remote host. Returns the number of
330  * bytes sent from the buffer.
331  *
332  * This call is non-blocking. If send would block,
333  * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
334  *
335  * @param handle Socket handle
336  * @param data Buffer of data to send to the host
337  * @param size Size of the buffer in bytes
338  * @return Number of sent bytes on success, negative error
339  * code on failure
340  */
342  const void *data, nsapi_size_t size) = 0;
343 
344  /** Receive data over a TCP socket
345  *
346  * The socket must be connected to a remote host. Returns the number of
347  * bytes received into the buffer.
348  *
349  * This call is non-blocking. If recv would block,
350  * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
351  *
352  * @param handle Socket handle
353  * @param data Destination buffer for data received from the host
354  * @param size Size of the buffer in bytes
355  * @return Number of received bytes on success, negative error
356  * code on failure
357  */
359  void *data, nsapi_size_t size) = 0;
360 
361  /** Send a packet over a UDP socket
362  *
363  * Sends data to the specified address. Returns the number of bytes
364  * sent from the buffer.
365  *
366  * This call is non-blocking. If sendto would block,
367  * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
368  *
369  * @param handle Socket handle
370  * @param address The SocketAddress of the remote host
371  * @param data Buffer of data to send to the host
372  * @param size Size of the buffer in bytes
373  * @return Number of sent bytes on success, negative error
374  * code on failure
375  */
376  virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
377  const void *data, nsapi_size_t size) = 0;
378 
379  /** Receive a packet over a UDP socket
380  *
381  * Receives data and stores the source address in address if address
382  * is not NULL. Returns the number of bytes received into the buffer.
383  *
384  * This call is non-blocking. If recvfrom would block,
385  * NSAPI_ERROR_WOULD_BLOCK is returned immediately.
386  *
387  * @param handle Socket handle
388  * @param address Destination for the source address or NULL
389  * @param buffer Destination buffer for data received from the host
390  * @param size Size of the buffer in bytes
391  * @return Number of received bytes on success, negative error
392  * code on failure
393  */
395  void *buffer, nsapi_size_t size) = 0;
396 
397  /** Register a callback on state change of the socket
398  *
399  * The specified callback will be called on state changes such as when
400  * the socket can recv/send/accept successfully and on when an error
401  * occurs. The callback may also be called spuriously without reason.
402  *
403  * The callback may be called in an interrupt context and should not
404  * perform expensive operations such as recv/send calls.
405  *
406  * @param handle Socket handle
407  * @param callback Function to call on state change
408  * @param data Argument to pass to callback
409  */
410  virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) = 0;
411 
412  /** Set stack-specific socket options.
413  *
414  * The setsockopt allow an application to pass stack-specific hints
415  * to the underlying stack. For unsupported options,
416  * NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified.
417  *
418  * @param handle Socket handle.
419  * @param level Stack-specific protocol level.
420  * @param optname Stack-specific option identifier.
421  * @param optval Option value.
422  * @param optlen Length of the option value.
423  * @return NSAPI_ERROR_OK on success, negative error code on failure.
424  */
425  virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
426  int optname, const void *optval, unsigned optlen);
427 
428  /** Get stack-specific socket options.
429  *
430  * The getstackopt allow an application to retrieve stack-specific hints
431  * from the underlying stack. For unsupported options,
432  * NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified.
433  *
434  * @param handle Socket handle.
435  * @param level Stack-specific protocol level.
436  * @param optname Stack-specific option identifier.
437  * @param optval Destination for option value.
438  * @param optlen Length of the option value.
439  * @return NSAPI_ERROR_OK on success, negative error code on failure.
440  */
441  virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
442  int optname, void *optval, unsigned *optlen);
443 
444 private:
445 
446  /** Call in callback
447  *
448  * Callback is used to call the call in method of the network stack.
449  */
451 
452  /** Get a call in callback
453  *
454  * Get a call in callback from the network stack context.
455  *
456  * Callback should not take more than 10ms to execute, otherwise it might
457  * prevent underlying thread processing. A portable user of the callback
458  * should not make calls to network operations due to stack size limitations.
459  * The callback should not perform expensive operations such as socket recv/send
460  * calls or blocking operations.
461  *
462  * @return Call in callback
463  */
464  virtual call_in_callback_cb_t get_call_in_callback();
465 
466  /** Call a callback after a delay
467  *
468  * Call a callback from the network stack context after a delay. If function
469  * returns error callback will not be called.
470  *
471  * @param delay Delay in milliseconds
472  * @param func Callback to be called
473  * @return NSAPI_ERROR_OK on success, negative error code on failure
474  */
475  virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
476 };
477 
478 inline NetworkStack *_nsapi_create_stack(NetworkStack *stack, std::true_type /* convertible to NetworkStack */)
479 {
480  return stack;
481 }
482 
483 inline NetworkStack *_nsapi_create_stack(NetworkInterface *iface, std::false_type /* not convertible to NetworkStack */)
484 {
485  return iface->get_stack();
486 }
487 
488 /** Convert a raw nsapi_stack_t object into a C++ NetworkStack object
489  *
490  * @param stack Pointer to an object that can be converted to a stack
491  * - A raw nsapi_stack_t object
492  * - A pointer to a network stack
493  * - A pointer to a network interface
494  * @return Pointer to the underlying network stack
495  */
497 
498 template <typename IF>
500 {
501  return _nsapi_create_stack(iface, std::is_convertible<IF *, NetworkStack *>());
502 }
503 
504 
505 #endif
506 
507 /** @} */
virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle, const void *data, nsapi_size_t size)=0
Send data over a TCP socket.
Socket implementation that uses IP network stack.
Base class for DNS provider.
Definition: DNS.h:25
SocketAddress class.
nsapi_stack structure
Definition: nsapi_types.h:321
NetworkStack * nsapi_create_stack(nsapi_stack_t *stack)
Convert a raw nsapi_stack_t object into a C++ NetworkStack object.
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address)=0
Connects TCP socket to a remote host.
mbed::Callback< void(nsapi_value_or_error_t result, SocketAddress *address)> hostbyname_cb_t
Hostname translation callback (asynchronous)
Definition: NetworkStack.h:126
virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog)=0
Listen for connections on a TCP socket.
NetworkStack class.
Definition: NetworkStack.h:41
Network Interface base class.
void * nsapi_socket_t
Opaque handle for network sockets.
Definition: nsapi_types.h:207
virtual nsapi_value_or_error_t getaddrinfo_async(const char *hostname, SocketAddress *hints, hostbyname_cb_t callback, const char *interface_name=NULL)
Translates a hostname to the multiple IP addresses (asynchronous)
virtual nsapi_error_t get_ip_address(SocketAddress *address)
Get the local IP address.
virtual nsapi_error_t get_ip_address_if(SocketAddress *address, const char *interface_name)
Get the local IP address on interface name.
signed int nsapi_error_t
Type used to represent error codes.
Definition: nsapi_types.h:95
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address)
Get the IPv6 link local address.
virtual OnboardNetworkStack * onboardNetworkStack()
Dynamic downcast to a OnboardNetworkStack.
Definition: NetworkStack.h:238
virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle, void *data, nsapi_size_t size)=0
Receive data over a TCP socket.
virtual nsapi_error_t socket_close(nsapi_socket_t handle)=0
Close the socket.
virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address)=0
Bind a specific address to a socket.
virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, void *buffer, nsapi_size_t size)=0
Receive a packet over a UDP socket.
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=nullptr) noexcept
Create a callback class with type inferred from the arguments.
Definition: Callback.h:678
signed int nsapi_size_or_error_t
Type used to represent either a size or error passed through sockets.
Definition: nsapi_types.h:106
mbed OS API for onboard IP stack abstraction
virtual nsapi_error_t gethostbyname_async_cancel(int id)
Cancels asynchronous hostname translation.
virtual nsapi_value_or_error_t getaddrinfo(const char *hostname, SocketAddress *hints, SocketAddress **res, const char *interface_name=NULL)
Translate a hostname to the multiple IP addresses with specific version using network interface name...
signed int nsapi_value_or_error_t
Type used to represent either a value or error.
Definition: nsapi_types.h:113
virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address, const void *data, nsapi_size_t size)=0
Send a packet over a UDP socket.
virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)=0
Opens a socket.
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name=NULL)
Get a domain name server from a list of servers to query.
virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen)
Set stack-specific socket options.
SocketAddress class.
Definition: SocketAddress.h:36
TCP socket connection.
Definition: TCPSocket.h:32
Common interface that is shared between network devices.
virtual nsapi_error_t add_dns_server(const SocketAddress &address, const char *interface_name=NULL)
Add a domain name server to list of servers to query.
virtual void socket_attach(nsapi_socket_t handle, void(*callback)(void *), void *data)=0
Register a callback on state change of the socket.
virtual nsapi_error_t gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version=NSAPI_UNSPEC, const char *interface_name=NULL)
Translates a hostname to an IP address with specific version.
unsigned int nsapi_size_t
Type used to represent the size of data passed through sockets.
Definition: nsapi_types.h:99
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, int optname, void *optval, unsigned *optlen)
Get stack-specific socket options.
virtual nsapi_error_t socket_accept(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address=0)=0
Accepts a connection on a TCP socket.
Callback class based on template specialization.
Definition: Callback.h:53
virtual nsapi_value_or_error_t gethostbyname_async(const char *host, hostbyname_cb_t callback, nsapi_version_t version=NSAPI_UNSPEC, const char *interface_name=NULL)
Translates a hostname to multiple IP addresses (asynchronous)
InternetDatagramSocket socket implementation.
Domain Name Service.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.