... | @@ -85,7 +85,7 @@ Testing mesh networking software is often challenging from a developer's perspec |
... | @@ -85,7 +85,7 @@ Testing mesh networking software is often challenging from a developer's perspec |
|
|
|
|
|
Bluetooth is a short-range radio technology that comes bundled with most modern day mobile devices.
|
|
Bluetooth is a short-range radio technology that comes bundled with most modern day mobile devices.
|
|
It allows devices to discover each other and transfer data over a range of up to 10 metres.
|
|
It allows devices to discover each other and transfer data over a range of up to 10 metres.
|
|
The accessibility of Bluetooth API's on most modern day smartphones makes Bluetooth an attractive transport for infrastructure-free data transfers, like those needed for a public mesh system.
|
|
The availability of Bluetooth APIs on most modern day smartphones makes Bluetooth an attractive transport for infrastructure-free data transfers, like those needed for a public mesh system.
|
|
|
|
|
|
### Resources
|
|
### Resources
|
|
|
|
|
... | @@ -240,7 +240,7 @@ If advertising is started while the app is in the foreground then it can continu |
... | @@ -240,7 +240,7 @@ If advertising is started while the app is in the foreground then it can continu |
|
A BLE advertisement may be "connectable" or "scannable" (or neither).
|
|
A BLE advertisement may be "connectable" or "scannable" (or neither).
|
|
Connectable means that a device receiving the advertisement can connect to the device that sent it.
|
|
Connectable means that a device receiving the advertisement can connect to the device that sent it.
|
|
Scannable means that a device receiving the advertisement can request additional data - the "scan record" - from the device that sent the advertisement.
|
|
Scannable means that a device receiving the advertisement can request additional data - the "scan record" - from the device that sent the advertisement.
|
|
However, we found that some devices (eg Samsung J5 2016) receive the advertisement packet but not the scan record, so any information an app makes available via scan records also needs to be made available by other means.
|
|
However, we found that some devices (eg Samsung Galaxy J5 2016) receive the advertisement packet but not the scan record, so any information an app makes available via scan records also needs to be made available by other means.
|
|
|
|
|
|
A connectable or scannable advertisement can include up to 31 bytes of data. To save energy, it's useful to include a UUID to identify the service being advertised. This allows devices listening for advertisements to filter out irrelevant advertisements without waking the CPU, as filtering can be done by the Bluetooth chipset. Self-assigned service UUIDs are 128 bits long, so including a service UUID in the advertisement uses 18 of the 31 available bytes (vendors who obtain UUIDs from the Bluetooth standards body can use shorter representations).
|
|
A connectable or scannable advertisement can include up to 31 bytes of data. To save energy, it's useful to include a UUID to identify the service being advertised. This allows devices listening for advertisements to filter out irrelevant advertisements without waking the CPU, as filtering can be done by the Bluetooth chipset. Self-assigned service UUIDs are 128 bits long, so including a service UUID in the advertisement uses 18 of the 31 available bytes (vendors who obtain UUIDs from the Bluetooth standards body can use shorter representations).
|
|
|
|
|
... | @@ -455,7 +455,7 @@ NSD is also a special case for Android apps running on ChromeOS: apps can't gene |
... | @@ -455,7 +455,7 @@ NSD is also a special case for Android apps running on ChromeOS: apps can't gene |
|
The following comment suggests that NSD service resolution will fail for network interfaces that don't have an associated Network instance:
|
|
The following comment suggests that NSD service resolution will fail for network interfaces that don't have an associated Network instance:
|
|
<https://cs.android.com/android/platform/superproject/+/master:packages/modules/Connectivity/service-t/src/com/android/server/NsdService.java;drc=b45a2ea782074944f79fc388df20b06e01f265f7;l=576>
|
|
<https://cs.android.com/android/platform/superproject/+/master:packages/modules/Connectivity/service-t/src/com/android/server/NsdService.java;drc=b45a2ea782074944f79fc388df20b06e01f265f7;l=576>
|
|
|
|
|
|
On at least some devices, NSD works when the LAN is a Wi-Fi Direct legacy mode access point. Tested with Samsung A21s as access point, Nokia 1.3 as client and vice versa. Tested with the `wifi-direct-and-nsd` branch.
|
|
On at least some devices, NSD works when the LAN is a Wi-Fi Direct legacy mode access point. Tested with Samsung Galaxy A21s as access point, Nokia 1.3 as client and vice versa. Tested with the `wifi-direct-and-nsd` branch.
|
|
|
|
|
|
Some devices (Huawei P8 Lite 2015, Moto G 4G, Moto E3) don't receive the attributes map in the NSD advertisement. This appears to be an Android bug that was fixed in Android 7 (API level 24):
|
|
Some devices (Huawei P8 Lite 2015, Moto G 4G, Moto E3) don't receive the attributes map in the NSD advertisement. This appears to be an Android bug that was fixed in Android 7 (API level 24):
|
|
|
|
|
... | @@ -511,21 +511,108 @@ https://invent.kde.org/network/kdeconnect-android/-/blob/master/src/org/kde/kdec |
... | @@ -511,21 +511,108 @@ https://invent.kde.org/network/kdeconnect-android/-/blob/master/src/org/kde/kdec |
|
|
|
|
|
## Wi-Fi
|
|
## Wi-Fi
|
|
|
|
|
|
|
|
Wi-Fi is widely supported by smartphones and other mobile devices, and allows for easy interoperation between platforms.
|
|
|
|
Wi-Fi access points are available worldwide and may be usable (without internet access) even during internet shutdowns.
|
|
|
|
|
|
|
|
Some Android devices can also act as access points.
|
|
|
|
The system UI allows the user to enable an access point and configure its network name and password.
|
|
|
|
Clients connected to the access point can access the internet via the device providing the access point.
|
|
|
|
Some devices require a SIM card to be inserted before this feature can be used.
|
|
|
|
|
|
|
|
On Android versions 5.1 and earlier (API level 22), applications can use reflection to access a hidden API for enabling an access point, including specifying the network name and password.
|
|
|
|
|
|
|
|
Android versions 8 and later (API level 26) have an API for creating a "local-only hotspot", which is an access point that doesn't share the device's internet connection with connected clients, but allows them to communicate with each other and with the device providing the access point.
|
|
|
|
|
|
|
|
<https://developer.android.com/reference/android/net/wifi/WifiManager#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)>
|
|
|
|
|
|
|
|
This is similar to a Wi-Fi Direct legacy mode access point, which is described in the Wi-Fi Direct section.
|
|
|
|
|
|
### Wi-Fi Client
|
|
### Wi-Fi Client
|
|
|
|
|
|
#### Peer Advertisement
|
|
On Android, connections to Wi-Fi access points are managed through the `WifiManager` API.
|
|
|
|
|
|
#### Peer Discovery
|
|
<https://developer.android.com/reference/android/net/wifi/WifiManager>
|
|
|
|
|
|
#### Peer Connectivity
|
|
A device connected to an access point can use TCP and UDP to communicate with other clients on the same network, if the access point allows it.
|
|
|
|
|
|
#### Notes
|
|
To use Wi-Fi when the device's screen is turned off, it can be helpful to hold a `WifiLock` with the lock mode `WIFI_MODE_FULL_HIGH_PERF` to keep the Wi-Fi radio awake:
|
|
|
|
|
|
|
|
* <https://developer.android.com/reference/android/net/wifi/WifiManager.WifiLock>
|
|
|
|
* <https://developer.android.com/reference/android/net/wifi/WifiManager#WIFI_MODE_FULL_HIGH_PERF>
|
|
|
|
|
|
|
|
#### Scanning for Available Networks
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
#### Connecting to a Specific Network
|
|
|
|
|
|
|
|
It might be useful for mesh peers to be able to connect to specific Wi-Fi access points without user interaction - particularly access points provided by other mesh peers (eg local-only hotspots or Wi-Fi Direct legacy mode access points).
|
|
|
|
|
|
|
|
The network names and passwords of these access points could be distributed via other transports, such as BLE advertising or Wi-Fi Direct service discovery.
|
|
|
|
|
|
|
|
The `wifi-client-request-network` branch uses three different techniques for requesting a connection to a specific Wi-Fi network:
|
|
|
|
|
|
|
|
##### 1. `WifiNetworkSpecifier`
|
|
|
|
|
|
|
|
<https://developer.android.com/guide/topics/connectivity/wifi-bootstrap>
|
|
|
|
|
|
|
|
This method is available on Android versions 10 and later (API level 29) and was tested on the Samsung Galaxy A21s and Nokia 1.3.
|
|
|
|
|
|
|
|
When the app requests the network, the system shows a progress indicator and searches for the network nearby. If the network isn't found, the system shows a dialog with options to try again or cancel. If the network is found, the system shows a dialog asking the user whether to connect or cancel. The app receives a callback with the user's response. If the device is already connected to a Wi-Fi network with internet access, it disconnects and connects to the requested network instead.
|
|
|
|
|
|
|
|
The requested network does not appear in the device's list of saved networks.
|
|
|
|
|
|
|
|
As expected, there is no warning about lack of internet access and the device stays connected to the network.
|
|
|
|
|
|
|
|
The app can disconnect from the requested network by unregistering the `NetworkCallback`. After doing this, reconnecting to the requested network requires confirmation from the user again.
|
|
|
|
|
|
|
|
The docs [seem to suggest](https://developer.android.com/guide/topics/connectivity/wifi-bootstrap#bypass-approval) that the app can reconnect to the requested network in future without needing user approval again, but we couldn't confirm this behaviour (tested with the Samsung Galaxy A21s as client and the Nokia 1.3 providing a Wi-Fi Direct legacy mode access point).
|
|
|
|
|
|
|
|
There doesn't seem to be a way to disconnect from the requested network without calling `ConnectionManager#unregisterNetworkCallback()`, which (per the docs and confirmed by testing) disconnects and forgets the network, thus requiring user confirmation for reconnection. `WifiManager#disconnect()` returns false, while `WifiManager#getConnectionInfo()` returns a `WifiInfo` with its network ID set to -1, so `WifiManager#disableNetwork()` (which requires a valid network ID) can't be used either.
|
|
|
|
|
|
|
|
If the access point is stopped and restarted, thus forcing the client to disconnect, the client asks for user confirmation again when reconnecting, even if the same NetworkRequest and NetworkCallback instances are used. The client asks for user confirmation even if it's currently connected to the requested network.
|
|
|
|
|
|
|
|
##### 2. `WifiManager#enableNetwork()`
|
|
|
|
|
|
|
|
This method is available on Android versions 9 and earlier (API level 28) and was tested on the LGE Nexus 5X, Moto G 4G and Honor 8A.
|
|
|
|
|
|
|
|
The app creates a `WifiConfiguration` with a high priority value, adds the configuration via `WifiManager#addNetwork()`, and enables the configuration via `WifiManager#enableNetwork()`. This doesn't require user approval and connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network doesn't have internet access. The Honor 8A sometimes reconnects to the network with internet access instead of connecting to the requested network.
|
|
|
|
|
|
|
|
A few seconds after connecting to the requested network, the Honor 8A shows a dialog that warns about lack of internet access. Regardless of whether "Cancel" or "Connect" is chosen, the device stays connected to the requested network.
|
|
|
|
|
|
|
|
The requested network is added to the device's list of saved networks.
|
|
|
|
|
|
|
|
There is no warning about lack of internet access and the device stays connected to the network.
|
|
|
|
|
|
|
|
The app can disconnect from the requested network and remove the saved configuration by calling `WifiManager#removeNetwork()`.
|
|
|
|
|
|
|
|
##### 3. `WifiManager#connect()`
|
|
|
|
|
|
|
|
This method is available on Android versions 9 and earlier (API level 28) and was tested on the LGE Nexus 5X, Moto G 4G and Honor 8A.
|
|
|
|
|
|
|
|
As in the previous method, the app creates a `WifiConfiguration` with a high priority value and adds the configuration via `WifiManager#addNetwork()`. The app then uses reflection to call `WifiManager#connect()`. Like the previous method, this connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network does not have internet access. The Honor 8A sometimes reconnects to the network with internet access instead of connecting to the requested network.
|
|
|
|
|
|
|
|
A few seconds after connecting to the requested network, the Honor 8A shows a dialog that warns about lack of internet access. Regardless of whether "Cancel" or "Connect" is chosen, the device stays connected to the requested network.
|
|
|
|
|
|
|
|
The requested network is added to the device's list of saved networks.
|
|
|
|
|
|
|
|
There is no warning about lack of internet access and the device stays connected to the network.
|
|
|
|
|
|
|
|
The app can disconnect from the requested network and remove the saved configuration by calling `WifiManager#removeNetwork()`.
|
|
|
|
|
|
|
|
TCP connection attempts from the client devices to the device providing the access point (Nokia 1.3) can take several seconds to connect, which is surprising on a LAN.
|
|
|
|
|
|
|
|
##### Summary
|
|
|
|
|
|
|
|
Connecting to a specific network is possible on any API level, but on Android 10 and later (API level 29) it requires user interaction.
|
|
|
|
If the network doesn't have internet access, some devices show a warning dialog or notification.
|
|
|
|
If the device is currently connected to a network with internet access, the device may reconnect to that network instead of connecting to the requested network.
|
|
|
|
|
|
|
|
##### Security Concerns
|
|
|
|
|
|
- The `wifi-client-request-network` branch uses three different techniques for requesting a connection to a specific Wi-fi network:
|
|
The authors of [Nearby Threats: Reversing, Analyzing, and Attacking Google’s ‘Nearby Connections’ on Android](https://francozappa.github.io/publication/rearby/) noted that when a device connects to a Wi-Fi access point, all of the device's traffic is routed through the access point, even if the app that requested the connection didn't expect the access point to provide internet access.
|
|
|
|
|
|
1. API >= 29 (tested on Samsung A21s and Nokia 1.3): The app uses `WifiNetworkSpecifier`, as recommended here. When the app requests the network, the system shows a progress indicator and searches for the network nearby. If the network isn't found, the system shows a dialog with options to try again or cancel. If the network is found, the system shows a dialog asking the user whether to connect or cancel. The app receives a callback with the user's response. The requested network does not appear in the device's list of saved networks. If the device is already connected to a Wi-fi network with internet access, it disconnects and connects to the requested network instead. As expected, there is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network by unregistering the `NetworkCallback`. After doing this, reconnecting to the requested network requires confirmation from the user again. The docs seem to suggest that if the app doesn't unregister the callback then the app can reconnect to the requested network in future without needing user approval again, but I haven't tested this yet.
|
|
This security concern is relevant for mesh applications that connect to access points without user interaction, even if they don't use Google Nearby.
|
|
2. API < 29 (tested on Nexus 5X): The app creates a `WifiConfiguration` with a high priority value, adds the configuration via `WifiManager#addNetwork()`, and enables the configuration via `WifiManager#enableNetwork()`. This doesn't require user approval and connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network doesn't have internet access. The requested network is added to the device's list of saved networks. There is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network and remove the saved configuration by calling `WifiManager#removeNetwork()`.
|
|
|
|
3. API < 29 (tested on Nexus 5X): As in the previous method, the app creates a `WifiConfiguration` with a high priority value and adds the configuration via `WifiManager#addNetwork()`. The app then uses reflection to call `WifiManager#connect()`. Like the previous method, this connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network does not have internet access. The requested network is added to the device's list of saved networks. There is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network and remove the saved configuration by calling `WifiManager#removeNetwork()`.
|
|
|
|
|
|
|
|
### Wi-Fi Direct
|
|
### Wi-Fi Direct
|
|
|
|
|
... | @@ -567,7 +654,7 @@ We tested several devices to see whether the Wi-Fi Aware API was supported: |
... | @@ -567,7 +654,7 @@ We tested several devices to see whether the Wi-Fi Aware API was supported: |
|
| OnePlus 5T (A5010) | 10 | 29 | No |
|
|
| OnePlus 5T (A5010) | 10 | 29 | No |
|
|
| Redmi Note 7 | 10 (MIUI 12.5.1) | 29 | No |
|
|
| Redmi Note 7 | 10 (MIUI 12.5.1) | 29 | No |
|
|
| Redmi Note 10 5G | 11 (MIUI 12) | 30 | No |
|
|
| Redmi Note 10 5G | 11 (MIUI 12) | 30 | No |
|
|
| Samsung A10s (SM-A107F/DS) | 11 (One UI Core 3.1) | 30 | No |
|
|
| Samsung Galaxy A10s (SM-A107F/DS) | 11 (One UI Core 3.1) | 30 | No |
|
|
| Sony XZ2 (H8216) | 10 | 29 | No |
|
|
| Sony XZ2 (H8216) | 10 | 29 | No |
|
|
|
|
|
|
These results suggest that Wi-Fi Aware is not useful for creating smartphone-based mesh networks at present, due to the small number of devices implementing the standard. It may become suitable in future if widely implemented in smartphones.
|
|
These results suggest that Wi-Fi Aware is not useful for creating smartphone-based mesh networks at present, due to the small number of devices implementing the standard. It may become suitable in future if widely implemented in smartphones.
|
... | | ... | |