... | @@ -197,7 +197,10 @@ The early generations of the Bluetooth standard, which are now sometimes called |
... | @@ -197,7 +197,10 @@ The early generations of the Bluetooth standard, which are now sometimes called |
|
|
|
|
|
At any given time, a Bluetooth classic device may be connectable and/or discoverable. A connectable device can receive incoming connections from other devices. A discoverable device can be discovered by other devices that are performing discovery.
|
|
At any given time, a Bluetooth classic device may be connectable and/or discoverable. A connectable device can receive incoming connections from other devices. A discoverable device can be discovered by other devices that are performing discovery.
|
|
|
|
|
|
An Android device is connectable whenever Bluetooth is turned on. There is an API for making the device discoverable, which requires confirmation from the user. If confirmation is given, the device remains discoverable for up to 120 seconds. On versions of Android up to 8.1 (API level 27), some devices allow making the device discoverable for an unlimited amount of time, but we could not find any devices running versions later than 8.1 that allowed this.
|
|
An Android device is connectable whenever Bluetooth is turned on.
|
|
|
|
There is an API for making the device discoverable, which requires confirmation from the user.
|
|
|
|
If confirmation is given, the device remains discoverable for up to 120 seconds.
|
|
|
|
On Android versions 8.1 and earlier (API level <= 27), some devices allow making the device discoverable for an unlimited amount of time, but we could not find any devices running versions later than 8.1 that allowed this.
|
|
|
|
|
|
Android also provides an API for performing discovery, which does not require confirmation from the user. Discovery runs for about 10 to 30 seconds. Receiving discovery results requires Bluetooth and/or location permissions, depending on the API level.
|
|
Android also provides an API for performing discovery, which does not require confirmation from the user. Discovery runs for about 10 to 30 seconds. Receiving discovery results requires Bluetooth and/or location permissions, depending on the API level.
|
|
|
|
|
... | @@ -217,7 +220,8 @@ If encryption and/or authentication is needed at the Bluetooth layer then the de |
... | @@ -217,7 +220,8 @@ If encryption and/or authentication is needed at the Bluetooth layer then the de |
|
|
|
|
|
If an application can find out the device's own Bluetooth classic address and share it with another device out-of-band then an RFCOMM connection can be made between the devices without needing user confirmation at any stage.
|
|
If an application can find out the device's own Bluetooth classic address and share it with another device out-of-band then an RFCOMM connection can be made between the devices without needing user confirmation at any stage.
|
|
|
|
|
|
On Android versions 6 and later (API level 23), applications do not have access to the device's own Bluetooth classic address. There are workarounds for accessing the address up to Android 8 (API level 26).
|
|
On Android versions 6 and later (API level >= 23), applications do not have access to the device's own Bluetooth classic address.
|
|
|
|
There are workarounds for accessing the address up to Android 8 (API level <= 26).
|
|
|
|
|
|
Beyond that point, an application receiving an RFCOMM connection can still access the address of the remote device, and can send this information back to the remote device (via the RFCOMM connection or out-of-band) to enable the remote device to learn its own address. The developers of Thali who invented this technique called it "help a brother out" or "bro mode".
|
|
Beyond that point, an application receiving an RFCOMM connection can still access the address of the remote device, and can send this information back to the remote device (via the RFCOMM connection or out-of-band) to enable the remote device to learn its own address. The developers of Thali who invented this technique called it "help a brother out" or "bro mode".
|
|
|
|
|
... | @@ -612,7 +616,7 @@ On Android, connections to Wi-Fi access points are managed through the `WifiMana |
... | @@ -612,7 +616,7 @@ On Android, connections to Wi-Fi access points are managed through the `WifiMana |
|
A device connected to an access point can use TCP and UDP to communicate with other clients on the same network, if the network allows clients to communicate with each other.
|
|
A device connected to an access point can use TCP and UDP to communicate with other clients on the same network, if the network allows clients to communicate with each other.
|
|
This is typically allowed on networks with a single access point, but may not be supported on larger networks.
|
|
This is typically allowed on networks with a single access point, but may not be supported on larger networks.
|
|
|
|
|
|
To use Wi-Fi when the device's screen is turned off, it can be helpful to hold a `WifiLock` with lock mode `WIFI_MODE_FULL_HIGH_PERF` to keep the Wi-Fi radio awake:
|
|
To use Wi-Fi when the device's screen is turned off, it can be helpful to hold a `WifiLock` using 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.WifiLock>
|
|
* <https://developer.android.com/reference/android/net/wifi/WifiManager#WIFI_MODE_FULL_HIGH_PERF>
|
|
* <https://developer.android.com/reference/android/net/wifi/WifiManager#WIFI_MODE_FULL_HIGH_PERF>
|
... | @@ -633,7 +637,7 @@ The `wifi-client-request-network` branch uses three different techniques for req |
... | @@ -633,7 +637,7 @@ The `wifi-client-request-network` branch uses three different techniques for req |
|
|
|
|
|
<https://developer.android.com/guide/topics/connectivity/wifi-bootstrap>
|
|
<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.
|
|
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 a connection to a specific network, the system shows a progress indicator and searches for the network nearby.
|
|
When the app requests a connection to a specific 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 isn't found, the system shows a dialog with options to try again or cancel.
|
... | @@ -659,7 +663,7 @@ The system asks for user confirmation even if it's currently connected to the re |
... | @@ -659,7 +663,7 @@ The system asks for user confirmation even if it's currently connected to the re |
|
|
|
|
|
##### 2. `WifiManager#enableNetwork()`
|
|
##### 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.
|
|
This method is available on Android versions 9 and earlier (API level <= 28) and was tested on the LGE Nexus 5X, Moto G 4G, Honor 8A, Huawei P8 Lite 2015, Alcatel A3 XL and Moto Play E6.
|
|
|
|
|
|
The app creates a `WifiConfiguration` with a high priority value, adds the configuration via `WifiManager#addNetwork()`, and enables the configuration via `WifiManager#enableNetwork()`.
|
|
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 confirmation 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.
|
|
This doesn't require user confirmation 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.
|
... | @@ -677,7 +681,7 @@ TCP connection attempts from the client devices to the device providing the acce |
... | @@ -677,7 +681,7 @@ TCP connection attempts from the client devices to the device providing the acce |
|
|
|
|
|
##### 3. `WifiManager#connect()`
|
|
##### 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.
|
|
This method is available on Android versions 9 and earlier (API level <= 28) and was tested on the LGE Nexus 5X, Moto G 4G, Honor 8A, Huawei P8 Lite 2015, Alcatel A3 XL and Moto Play E6.
|
|
|
|
|
|
As in the previous method, the app creates a `WifiConfiguration` with a high priority value and adds the configuration via `WifiManager#addNetwork()`.
|
|
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()`.
|
|
The app then uses reflection to call `WifiManager#connect()`.
|
... | @@ -686,11 +690,11 @@ This method appears to behave identically to the previous method. |
... | @@ -686,11 +690,11 @@ This method appears to behave identically to the previous method. |
|
|
|
|
|
##### Summary
|
|
##### 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.
|
|
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 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.
|
|
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
|
|
#### Security Concerns
|
|
|
|
|
|
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.
|
|
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.
|
|
|
|
|
... | @@ -703,9 +707,9 @@ Android's system UI allows the user to enable an access point and configure its |
... | @@ -703,9 +707,9 @@ Android's system UI allows the user to enable an access point and configure its |
|
Connected clients can access the internet via the access point.
|
|
Connected clients can access the internet via the access point.
|
|
Some devices require a SIM card to be inserted before this feature can be used.
|
|
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.
|
|
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 provide internet access to connected clients.
|
|
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 provide internet access to connected clients.
|
|
|
|
|
|
<https://developer.android.com/reference/android/net/wifi/WifiManager#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)>
|
|
<https://developer.android.com/reference/android/net/wifi/WifiManager#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)>
|
|
|
|
|
... | @@ -720,6 +724,9 @@ Some devices can provide an access point while simultaneously being a client of |
... | @@ -720,6 +724,9 @@ Some devices can provide an access point while simultaneously being a client of |
|
|
|
|
|
### Wi-Fi Direct
|
|
### Wi-Fi Direct
|
|
|
|
|
|
|
|
Wi-Fi Direct is a Wi-Fi standard that enables devices to discover and connect to each other without the need for an access point.
|
|
|
|
The standard includes a "legacy mode" that allows interoperability with ordinary Wi-Fi clients that don't implement the Wi-Fi Direct standard.
|
|
|
|
|
|
#### Peer Advertisement
|
|
#### Peer Advertisement
|
|
|
|
|
|
#### Peer Discovery
|
|
#### Peer Discovery
|
... | @@ -770,11 +777,54 @@ The following list of Wi-Fi Aware certified devices may be useful for determinin |
... | @@ -770,11 +777,54 @@ The following list of Wi-Fi Aware certified devices may be useful for determinin |
|
|
|
|
|
<https://www.wi-fi.org/product-finder-results?sort_by=certified&sort_order=desc&certifications=757>
|
|
<https://www.wi-fi.org/product-finder-results?sort_by=certified&sort_order=desc&certifications=757>
|
|
|
|
|
|
|
|
### Predefined Access Point Credentials
|
|
|
|
|
|
|
|
Given that apps have a limited ability to scan for available Wi-Fi networks, it may be useful for a mesh application to predefine a network and password for access points that are part of the mesh, so that client devices can opportunistically try to connect to any mesh access point that may be nearby, without first needing to scan for available networks.
|
|
|
|
|
|
|
|
In this scenario the password would be considered public knowledge, and would not be relied on for any kind of security.
|
|
|
|
The password would only exist to meet the transport layer's requirement that a password should be specified.
|
|
|
|
|
|
|
|
To test whether this idea was feasible, we investigated the following questions:
|
|
|
|
|
|
|
|
##### 1. Can we request a connection to a network that's not currently in range? If so, do we connect automatically when the network comes into range?
|
|
|
|
|
|
|
|
On Android versions 9 and earlier (API level <= 28), an app can use the `WifiManager` API to request a connection to a network that's not currently in range.
|
|
|
|
If the network later comes into range, the device will connect to it even if the screen is off at the time (tested on the Moto E6 Play and Honor 8A).
|
|
|
|
If the requested network doesn't have internet access, some devices will show a warning dialog after connecting, and some will prefer a network with internet access (tested on the Moto G 4G, Huawei P8 Lite 2015, Alcatel A3 XL, Moto Play E6 and Honor 8A).
|
|
|
|
|
|
|
|
On Android versions 10 and later (API level >= 29), the `WifiNetworkSpecifier` API requires user interaction and doesn't work for a network that's not currently in range - the system shows a retry/cancel dialog if the requested network isn't found.
|
|
|
|
|
|
|
|
However, on Android versions 10 and later we can use the `WifiP2pManager` (Wi-Fi Direct) API to request a connection to a Wi-Fi Direct legacy mode access point with a specified network name and password.
|
|
|
|
This does not require user interaction.
|
|
|
|
If the requested network doesn't come into range within a few seconds, the attempt seems to time out and must be retried (tested with the Samsung A21s as client and the Nokia 1.3 as access point, and vice versa).
|
|
|
|
|
|
|
|
On both devices, the connection attempt receives an immediate success callback regardless of whether the network is in range.
|
|
|
|
If the network comes into range quickly enough then the group info is received.
|
|
|
|
If not, there's a `CONNECTION_STATE_CHANGE` broadcast about 10 to 15 seconds after the connection attempt that may indicate that the attempt has timed out.
|
|
|
|
|
|
|
|
##### 2. If two or more devices are providing access points with the same network name and password, can a client roam from one to the other?
|
|
|
|
|
|
|
|
On Android versions 9 and earlier (API level <= 28) the behaviour depends on whether another network with internet access is available.
|
|
|
|
|
|
|
|
When a network with internet access is available, some devices may connect to it automatically when the first access point of the requested network goes out of range, and may remain connected to it when the second access point of the requested network comes into range.
|
|
|
|
On the Moto G 4G it appears to be a matter of policy not to reconnect automatically to networks without internet access (the network is marked in the system UI as "No internet access detected, won't automatically reconnect").
|
|
|
|
On other devices (eg Huawei P8 Lite 2015), it may depend on whether the client has dropped its connection to the network with internet access during sleep, giving the requested network a chance to be chosen when the device wakes up.
|
|
|
|
|
|
|
|
When no network with internet access is available, some devices may connect automatically to the second access point of the requested network when it comes into range.
|
|
|
|
The Moto G 4G won't do this as a matter of policy.
|
|
|
|
On other devices (eg Honor 8A, Moto E3), it may not happen until a scan for available Wi-Fi networks is triggered.
|
|
|
|
The rate at which apps can trigger these scans is throttled on later API levels.
|
|
|
|
The system may trigger a scan when the screen is turned on.
|
|
|
|
|
|
|
|
On Android versions 10 and later (API level >= 29), we did not manage to trigger automatic reconnection to a network requested via the `WifiNetworkSpecifier` API, regardless of whether the client was reconnecting to the same access point or a second access point with the same network name and password.
|
|
|
|
|
|
|
|
We have not yet tested whether the `WifiP2pManager` (Wi-Fi Direct) API can be used to roam between legacy mode access points with the same network name and password on Android versions 10 and later.
|
|
|
|
|
|
## Other Android APIs
|
|
## Other Android APIs
|
|
|
|
|
|
### Companion Device Pairing
|
|
### Companion Device Pairing
|
|
|
|
|
|
Android versions 8 and later (API level 26) provides a high-level API for discovering nearby Bluetooth and Wi-Fi devices without the application needing to hold the various permissions that are required for using the Bluetooth and Wi-Fi APIs directly.
|
|
Android versions 8 and later (API level >= 26) provides a high-level API for discovering nearby Bluetooth and Wi-Fi devices without the application needing to hold the various permissions that are required for using the Bluetooth and Wi-Fi APIs directly.
|
|
|
|
|
|
https://developer.android.com/guide/topics/connectivity/companion-device-pairing
|
|
https://developer.android.com/guide/topics/connectivity/companion-device-pairing
|
|
|
|
|
... | @@ -801,7 +851,8 @@ The advertiser may then tell the discoverer to switch from Bluetooth to Wi-Fi. W |
... | @@ -801,7 +851,8 @@ The advertiser may then tell the discoverer to switch from Bluetooth to Wi-Fi. W |
|
|
|
|
|
The researchers identified several attacks against Nearby, including the "soft AP attack", in which a malicious advertiser instructs the discoverer to switch to an access point that has internet access. This unexpectedly causes the discoverer's device to route all its traffic through that access point.
|
|
The researchers identified several attacks against Nearby, including the "soft AP attack", in which a malicious advertiser instructs the discoverer to switch to an access point that has internet access. This unexpectedly causes the discoverer's device to route all its traffic through that access point.
|
|
|
|
|
|
Due to this attack, it is not safe to use the Wi-Fi client (WifiManager) API for connecting to a Wi-Fi Direct legacy mode access point provided by another device. However, it appears to be safe to use the Wi-Fi Direct (WifiP2pManager) API for connecting to a legacy mode access point, as in this case the client will not route all its traffic through the access point even if the access point unexpectedly provides internet access.
|
|
Due to this attack, it is not safe to use the Wi-Fi client (`WifiManager`) API for connecting to a Wi-Fi Direct legacy mode access point provided by another device.
|
|
|
|
However, it appears to be safe to use the Wi-Fi Direct (`WifiP2pManager`) API for connecting to a legacy mode access point, as in this case the client will not route all its traffic through the access point even if the access point unexpectedly provides internet access.
|
|
|
|
|
|
## Alternative Transports
|
|
## Alternative Transports
|
|
|
|
|
... | | ... | |