Skip to content

Commit afb85ad

Browse files
author
Amanda Butler
authored
Merge pull request #957 from SeppoTakalo/ONME-4165
Various clarifications for NetworkInterface state and connection
2 parents e328458 + 5c2073a commit afb85ad

File tree

3 files changed

+84
-6
lines changed

3 files changed

+84
-6
lines changed

docs/api/networkinterfaces/NetworkStatus.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This interface informs you about connection state changes asynchronously. Providing a method to register a callback function to a socket accomplishes this. Each time the network interface's state changes, it triggers the callback.
44

5-
<span class="images">![](https://s3-us-west-2.amazonaws.com/mbed-os-docs-images/NetworkinterfaceStates.png)<span>Network states</span></span>
5+
<span class="images">![](../../images/NetworkinterfaceStates.png)<span>Network states</span></span>
66

77
#### Usage
88

@@ -74,11 +74,46 @@ Optionally, the application might want to set the `connect()` method to nonblock
7474

7575
By default, the `connect()` call blocks until `NSAPI_STATUS_GLOBAL_UP` state is reached. Some applications might require only link-local connectivity and therefore do not need to block that long. In those case monitoring the state changes is the preferred behavior.
7676

77+
### Using multiple connection status callbacks
78+
79+
The NetworkInterface API includes two functions that the applications can use to register more than one status callback for each network interface:
80+
81+
```
82+
/** Add event listener for interface.
83+
*
84+
* This API allows multiple callback to be registered for a single interface.
85+
* When first called, an internal list of event handlers is created and registered to
86+
* interface through attach() API.
87+
*
88+
* The application may only use the attach() or add_event_listener() interface. Mixing use
89+
* of both leads to undefined behavior.
90+
*
91+
* @param status_cb The callback for status changes.
92+
*/
93+
void add_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
94+
95+
/** Remove event listener from interface.
96+
*
97+
* Remove previously added callback from the handler list.
98+
*
99+
* @param status_cb The callback to unregister.
100+
*/
101+
void remove_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
102+
```
103+
104+
The callback prototype is the same as that for the `NetworkInterface::attach()`.
105+
106+
The `NetworkInterface::attach()` is still functional, and it is a porting API that each interface should provide. The functions above use `NetworkInterface::attach()` internally, so the application cannot use both at the same time.
107+
108+
You must either refactor the application by replacing `NetworkInterface::attach()` calls with `NetworkInterface::add_event_listener()`, or the application must remain using the `NetworkInterface::attach()`.
109+
110+
This optional and has a small RAM and ROM increase, so applications are not required to use it. Both APIs are still supported, but use is limited to one at a time.
111+
77112
### Example
78113

79114
Registering a status callback that connection state changes trigger depends on whether the network interface provides this functionality.
80115

81-
[![View code](https://www.mbed.com/embed/?url=https://os.mbed.com/teams/mbed_example/code/TCPSocket_ConnStateCb_Example/)](https://os.mbed.com/teams/mbed_example/code/TCPSocket_ConnStateCb_Example/file/8a8191e3d305/main.cpp)
116+
[![View code](https://www.mbed.com/embed/?url=https://os.mbed.com/teams/mbed_example/code/TCPSocket_ConnStateCb_Example/)](https://os.mbed.com/teams/mbed_example/code/TCPSocket_ConnStateCb_Example/file/c66df92cf71b/main.cpp)
82117

83118
### Related content
84119

docs/api/networkinterfaces/networkinterface.md

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ NetworkInterface is also the controlling API that the application uses to specif
1515

1616
When you create a network interface, it starts from the disconnected state. When you call `NetworkInteface::connect()`, the interface stays connected until you call `NetworkInterface::disconnect()`. The following diagram illustrates the state changes:
1717

18-
<span class="images">![](https://s3-us-west-2.amazonaws.com/mbed-os-docs-images/NetworkinterfaceStates.png)<span>Network states</span></span>
18+
<span class="images">![](../../images/NetworkinterfaceStates.png)<span>Network states</span></span>
1919

20-
The interface handles all state changes itself between `Connecting`, `Local connectivity` and `Global route found`. Calling `NetworkInterface::connect()` might return when either local or global connectivity states are reached. This depends on the connectivity. For example, Ethernet and Wi-Fi interfaces return when global connectivity is reached. 6LoWPAN-based mesh networks depend on the standard you're using. 6LoWPAN-ND returns when it connects to a border router that provides global connection. The thread returns when you create a local mesh network and may later get global connection when it finds a border router.
20+
The interface handles all state changes between `Connecting`, `Local connectivity` and `Global route found`. Calling `NetworkInterface::connect()` might return when either local or global connectivity states are reached. This depends on the connectivity. For example, Ethernet and Wi-Fi interfaces return when global connectivity is reached. 6LoWPAN-based mesh networks depend on the standard you're using. The `LoWPANNDInterface` returns from `connect()` call when it connects to a border router that provides a global connection. The `ThreadInterface` returns from `connect()` call when it joins a local mesh network. It may later get a global connection when it finds a border router.
2121

22-
When a network or route is lost or any other cause limits the connectivity, the interface may change its state back to `Connecting`, `Local connectivity` or `Disconnected`. In the `Connecting` and `Local connectivity` states, the interface reconnects until the application chooses to call `NetworkInterface::disconnect()`. Depending on the network, this reconnection might have internal back off periods, and not all interfaces implement the reconnection logic.
22+
When a network or route is lost or any other cause limits the connectivity, the interface may change its state back to `Connecting`, `Local connectivity` or `Disconnected`. In the `Connecting` and `Local connectivity` states, the interface reconnects until the application chooses to call `NetworkInterface::disconnect()`. Depending on the network, this reconnection might have internal backoff periods, and not all interfaces implement the reconnection logic at all. Please refer to table below for information on how different interfaces behave.
2323

2424
An application may check the connection status by calling `nsapi_connection_status_t get_connection_status()` or register a callback to monitoring status changes. The following table lists defined network states with actions that applictions should take on the state change:
2525

@@ -30,11 +30,21 @@ An application may check the connection status by calling `nsapi_connection_stat
3030
| Local connectivity | `NSAPI_STATUS_LOCAL_UP` | You can create sockets and communicate with local devices in the same network. |
3131
| Global route found | `NSAPI_STATUS_GLOBAL_UP` | You can create sockets and communicate with all hosts. |
3232

33-
3433
Use the following API to register status callbacks:
3534

3635
- [Network status](network-status.html): API for monitoring network status changes.
3736

37+
Error handling and reconnection logic depends on the network interface. Please use the following table to determine what actions your application needs to do on each network type.
38+
39+
| `NetworkInterface` subclass | Does it reconnect automatically? | Possible states |
40+
|------------------------------|---------------------------------|-----------------|
41+
| `EthernetInterface` | Yes | 1.`NSAPI_STATUS_DISCONNECTED`<br />2.`NSAPI_STATUS_CONNECTING`<br />3.`NSAPI_STATUS_GLOBAL_UP`|
42+
| `WiFiInterface` | Yes, when onboard network stack is used.<br />For external modules, it depends on the driver.<br />See examples below. | - |
43+
| `OdinWiFiInterface` or<br /> `RTWInterface` | Yes | 1.`NSAPI_STATUS_DISCONNECTED`<br />2.`NSAPI_STATUS_CONNECTING`<br />3.`NSAPI_STATUS_GLOBAL_UP`|
44+
| `ESP8266Interface` | Yes | 1.`NSAPI_STATUS_DISCONNECTED`<br />2.`NSAPI_STATUS_CONNECTING`<br />3.`NSAPI_STATUS_GLOBAL_UP`|
45+
| `CellularInterface` | Mostly no | 1.`NSAPI_STATUS_DISCONNECTED`<br />2.`NSAPI_STATUS_CONNECTING`<br />3.`NSAPI_STATUS_GLOBAL_UP`<br />`CellularInterface` may also send Cellular specific states specified in `CellularCommon.h` |
46+
| `LoWPANNDInterface` or<br />`ThreadInterface` or<br />`WisunInterface` | Yes | 1.`NSAPI_STATUS_DISCONNECTED`<br />2.`NSAPI_STATUS_CONNECTING`<br />4.`NSAPI_STATUS_LOCAL_UP`<br />4.`NSAPI_STATUS_GLOBAL_UP`|
47+
3848
### Default network interface
3949

4050
In Mbed OS, targets that provide network connectivity also provide a default network interface. This can be Ethernet, Wi-Fi, mesh or cellular. Using a default interface allows you to port applications to different targets and connectivity options.
@@ -97,6 +107,39 @@ if (wifi) {
97107
}
98108
```
99109

110+
### Notes on portable applications
111+
112+
When you expect an application to be portable between different network interfaces, please use the following guidelines:
113+
114+
1. Use only `NetworkInterface::get_default_instance()` for getting the interface.
115+
1. Register the network status handler, and implement reconnection logic.
116+
117+
Please see the previous section, [Default network interface](#default-network-interface), on how to use the portable API for the network interface.
118+
119+
For network status changes, the API is specified in [Network status](network-status.html) section. Being portable means that your application only communicates after `NSAPI_STATUS_GLOBAL_UP` is received and tries to reconnect the network if `NSAPI_STATUS_DISCONNECTED` is received without calling `NetworkInterface::disconnect()`.
120+
121+
### Using multiple network interfaces
122+
123+
In Mbed OS, applications usually use one network interface at a time, and most APIs are designed this way. With few limitations, applications are able to operate more than one NetworkInterface. In Mbed OS, there are two built-in IP stacks and many external IP stacks provided by modules. Please refer to the [Architecture:IP networking](reference/ip-networking.html) section for an explanation of how different stacks are integrated into Mbed OS.
124+
125+
When you use two network interfaces and both are operating on different IP stacks, the interfaces can work independently because there is no common data path, for example an application that uses an on-board Ethernet interface and any of the external Wi-Fi modules.
126+
127+
When you use two network interfaces and both use the same IP stacks, there are limitations.
128+
129+
We have modified the LwIP routing core to support multiple active interfaces, but when more than one interface is active in LwIP, only one is the default. All the outgoing traffic flows through it.
130+
131+
If you need to force the traffic to only one of the interfaces, you need to use `Socket::setsockopt(NSAPI_SOCKET, NSAPI_BIND_TO_DEVICE, <interface name>, <interface name length>)` to bind the socket into one interface. You can fetch the interface name from the `NetworkInterface::get_interface_name()` call.
132+
133+
Another, more common, case is where only one of the interface is active at a time. In this case, there is no need for `Socket::setsockopt()` if another interface is brought down because there is only one route option. This works with LwIP but is not verified with Nanostack because it is used only on specific use cases, such as mesh routing.
134+
135+
### Asynchronous operation
136+
137+
`NetworkInterface::connect()` and `NetworkInterface::disconnect()` are blocking by default. When an application prefers asynchronous operation, it can set the interface into nonblocking mode by calling `NetworkInterface::set_blocking(false)`. This has to be done for each interface separately.
138+
139+
When an interface operates in asynchronous mode, the return values of `connect()` and `disconnect()` have slightly different meanings. Calling `connect()` starts the asynchronous operation, which puts the device in the `GLOBAL_UP` state. Calling `disconnect()` puts the target in the `DISCONNECTED` state. Return code in asynchronous mode does not reflect the connection status. The most common return codes in asynchronous mode is `NSAPI_ERROR_OK`, which means that operation just started. Please refer to the Doxygen documentation of [NetworkInterface::connect()](https://os.mbed.com/docs/mbed-os/development/mbed-os-api-doxy/class_network_interface.html#aaf6bf1dfffbe6a5626b7b52eaa542b6e) and [NetworkInterface::disconnect()](https://os.mbed.com/docs/mbed-os/development/mbed-os-api-doxy/class_network_interface.html#afdda3f62c7d73df183ee2d352e8cd146) for return values of these functions.
140+
141+
To check whether the interface is connected, the application needs to register the status callback for the interface. Please refer to the [Network status API](network-status.html) for information on how to do so.
142+
100143
### Related content
101144

102145
- [Configuring the default network interface](../reference/configuration-connectivity.html#selecting-the-default-network-interface).
-6.51 KB
Loading

0 commit comments

Comments
 (0)