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