... | @@ -258,42 +258,49 @@ As previously mentioned, Bluetooth Low Energy offers two different ways of actua |
... | @@ -258,42 +258,49 @@ As previously mentioned, Bluetooth Low Energy offers two different ways of actua |
|
|
|
|
|
##### GATT
|
|
##### GATT
|
|
|
|
|
|
Using BLESSED's `PeripheralManager` class, you can easily create and add characteristics:
|
|
Using BLESSED's `PeripheralManager` class, you can easily create services and characteristics:
|
|
|
|
|
|
BluetoothGattCharacteristic allocatorChar = new BluetoothGattCharacteristic(ALLOCATOR_UUID, PROPERTY_READ, PERMISSION_READ);
|
|
```Java
|
|
gattService.addCharacteristic(allocatorChar);
|
|
BluetoothGattService gattService = new BluetoothGattService(SERVICE_UUID, SERVICE_TYPE_PRIMARY);
|
|
|
|
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, PROPERTY_READ, PERMISSION_READ);
|
|
|
|
gattService.addCharacteristic(characteristic);
|
|
peripheralManager.add(gattService);
|
|
peripheralManager.add(gattService);
|
|
|
|
```
|
|
|
|
|
|
And start advertising the GATT service:
|
|
And start advertising the GATT service by its UUID:
|
|
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, scanResponse);
|
|
|
|
|
|
|
|
See this file for more information on how the `blessed-gatt` branch creates and advertises its GATT service:
|
|
```Java
|
|
|
|
AdvertiseSettings adSettings = new AdvertiseSettings.Builder()
|
|
|
|
.setConnectable(true)
|
|
|
|
.setTimeout(0)
|
|
|
|
.build();
|
|
|
|
AdvertiseData adData = new AdvertiseData.Builder().addServiceUuid(SERVICE_UUID).build();
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, adData);
|
|
|
|
```
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L261>
|
|
When a central device discovers a peripheral that's advertising the app's service UUID, it connects to the `BluetoothPeripheral` object by using the `centralManager.connectPeripheral()` method.
|
|
|
|
|
|
When a central device discovers a peripheral that's advertising the app's service UUID, it connects to the `BluetoothPeripheral` object by using the `centralManager.connectPeripheral()` method. See the following file for the full implementation of peer connections on the `blessed-gatt` branch:
|
|
See the following file for the full implementation of advertising, discovery and peer connections on the `blessed-gatt` branch:
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L320>
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java>
|
|
|
|
|
|
##### L2CAP CoC
|
|
##### L2CAP CoC
|
|
|
|
|
|
With L2CAP CoC, there is less of a conceptual divide between "central" and "peripheral" devices than there is with GATT. Instead of advertising a set of services consisting of characteristics, a peripheral using L2CAP CoC can just advertise a "PSM" value, which is similar to a port number, and open a Bluetooth server socket running on that PSM value. On our `blessed-gatt` branch, we advertise the PSM if the device supports L2CAP CoC:
|
|
With L2CAP CoC, there is less of a conceptual divide between "central" and "peripheral" devices than there is with GATT. Instead of advertising a set of services consisting of characteristics, a peripheral using L2CAP CoC can just advertise a "PSM" value, which is similar to a port number, and open a Bluetooth server socket running on that PSM value. On our `blessed-gatt` branch, we advertise the PSM if the device supports L2CAP CoC:
|
|
|
|
|
|
```Java
|
|
```Java
|
|
if (USE_L2CAP && SDK_INT >= 29 && serverSocket == null) openServerSocket();
|
|
|
|
AdvertiseSettings adSettings = new AdvertiseSettings.Builder()
|
|
|
|
.setConnectable(true)
|
|
|
|
.setTimeout(0)
|
|
|
|
.build();
|
|
|
|
AdvertiseData adData = new AdvertiseData.Builder().addServiceUuid(PARCEL_UUID).build();
|
|
AdvertiseData adData = new AdvertiseData.Builder().addServiceUuid(PARCEL_UUID).build();
|
|
AdvertiseData scanResponse;
|
|
AdvertiseData scanResponse;
|
|
if (USE_L2CAP && SDK_INT >= 29) {
|
|
if (USE_L2CAP && SDK_INT >= 29) {
|
|
byte[] serviceData = new byte[4];
|
|
byte[] serviceData = new byte[4];
|
|
writeUint32(psm, serviceData, 0);
|
|
writeUint32(psm, serviceData, 0);
|
|
scanResponse = new AdvertiseData.Builder()
|
|
scanResponse = new AdvertiseData.Builder()
|
|
.addServiceData(PARCEL_UUID, serviceData).build();
|
|
.addServiceData(PARCEL_UUID, serviceData)
|
|
|
|
.build();
|
|
|
|
} else {
|
|
|
|
scanResponse = adData;
|
|
}
|
|
}
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, scanResponse);
|
|
```
|
|
```
|
|
|
|
|
|
Then, whenever we discover an L2CAP-compatible device, we can connect to it using a method like the `connectViaSocket()` method on the `blessed-gatt` branch:
|
|
Then, whenever we discover an L2CAP-compatible device, we can connect to it using a method like the `connectViaSocket()` method on the `blessed-gatt` branch:
|
... | @@ -302,14 +309,14 @@ Then, whenever we discover an L2CAP-compatible device, we can connect to it usin |
... | @@ -302,14 +309,14 @@ Then, whenever we discover an L2CAP-compatible device, we can connect to it usin |
|
|
|
|
|
#### Notes
|
|
#### Notes
|
|
|
|
|
|
- BLESSED doesn't provide a wrapper for the new advertising set API (added in API level 26), which supports Bluetooth 5 advertising features such as periodic advertising, extended advertising and coded PHY, so if we want to use those features we'll need to use the Android API directly, rather than going through BLESSED
|
|
- BLESSED doesn't provide a wrapper for the new advertising set API (added in API level 26), which supports Bluetooth 5 advertising features such as periodic advertising, extended advertising and coded PHY. If we want to use those features we'll need to use the Android API directly, rather than going through BLESSED.
|
|
- If we use any Bluetooth 5 advertising features then we also need to use the Android API directly for scanning (or submit a pull request upstream for BLESSED to allow legacy mode to be turned off for scanning)
|
|
- If we use any Bluetooth 5 advertising features then we also need to use the Android API directly for scanning (or submit a pull request upstream for BLESSED to allow legacy mode to be turned off for scanning).
|
|
- We can, however, use BLESSED to request coded PHY for GATT connections
|
|
- We can, however, use BLESSED to request coded PHY for GATT connections.
|
|
- The Moto G 4G never receives the result of starting advertising (no callback to `onAdvertisingStarted()` or `onAdvertiseFailure()`)
|
|
- The Moto G 4G never receives the result of starting advertising (no callback to `onAdvertisingStarted()` or `onAdvertiseFailure()`).
|
|
- The Moto G 4G and Huawei P8 Lite 2015 can discover the Samsung Galaxy J5 2016, but it can't discover them and they can't discover each other
|
|
- The Moto G 4G and Huawei P8 Lite 2015 can discover the Samsung Galaxy J5 2016, but it can't discover them and they can't discover each other.
|
|
- The P8 Lite can connect to the J5 via GATT and exchange pings and pongs
|
|
- The P8 Lite can connect to the J5 via GATT and exchange pings and pongs.
|
|
- The Moto G can't connect to the J5 via GATT: it receives a callback to `onConnectingPeripheral()`, never receives `onConnectedPeripheral()`, and eventually receives `onDisconnectedPeripheral()` with status `LMP_OR_LL_RESPONSE_TIMEOUT`. The J5 receives onCentralConnected() and onCentralDisconnected() as expected. The J5 can subsequently connect back to the Moto G, using the address it learned from the unsuccessful connection, and exchange pings and pongs
|
|
- The Moto G can't connect to the J5 via GATT: it receives a callback to `onConnectingPeripheral()`, never receives `onConnectedPeripheral()`, and eventually receives `onDisconnectedPeripheral()` with status `LMP_OR_LL_RESPONSE_TIMEOUT`. The J5 receives `onCentralConnected()` and `onCentralDisconnected()` as expected. The J5 can subsequently connect back to the Moto G, using the address it learned from the unsuccessful connection, and exchange pings and pongs.
|
|
- When the J5 receives a connection from the Moto G or P8 Lite, the J5 sees the same address that the Moto G/P8 Lite gets from its own BluetoothAdapter, ie the BT classic address
|
|
- When the J5 receives a connection from the Moto G or P8 Lite, the J5 sees the same address that the Moto G/P8 Lite gets from its own `BluetoothAdapter`, ie the BT classic address.
|
|
|
|
|
|
### Socket-Like Communication via GATT
|
|
### Socket-Like Communication via GATT
|
|
|
|
|
... | @@ -361,32 +368,23 @@ The full handshake as implemented in the `blessed-gatt-allocator-vuln` and `bles |
... | @@ -361,32 +368,23 @@ The full handshake as implemented in the `blessed-gatt-allocator-vuln` and `bles |
|
|
|
|
|
#### Notes
|
|
#### Notes
|
|
|
|
|
|
The allocator characteristic works as an active list of nearby peers, so higher level protocols could possibly utilize this as a way to further increase peer discovery and data propagation.
|
|
* The allocator characteristic works as an active list of nearby peers, so higher level protocols could possibly utilize this as a way to further increase peer discovery and data propagation.
|
|
|
|
* Because each peripheral has a limited number of read characteristics, protocols built on top of this strategy should prioritize quicker, more frequent connections rather than long lasting data transfers.
|
|
Because each peripheral has a limited number of read characteristics, protocols built on top of this strategy should prioritize quicker, more frequent connections rather than long lasting data transfers.
|
|
* The allocator system allows a socket-like abstraction to be made on top of regular GATT reads and writes.
|
|
|
|
|
|
The allocator system allows a socket-like abstraction to be made on top of regular GATT reads and writes.
|
|
|
|
This is useful because GATT has much greater support than L2CAP CoC among Android devices, especially older devices.
|
|
This is useful because GATT has much greater support than L2CAP CoC among Android devices, especially older devices.
|
|
The allocator characteristic system can be used in parallel with L2CAP CoC, by advertising the PSM of the peripheral's L2CAP server socket along with the UUID of the mesh service.
|
|
The allocator characteristic system can be used in parallel with L2CAP CoC, by advertising the PSM of the peripheral's L2CAP server socket along with the UUID of the mesh service.
|
|
This allows L2CAP CoC to be used between centrals and peripherals that support it, with the allocator characteristic system providing a fallback for older devices.
|
|
This allows L2CAP CoC to be used between centrals and peripherals that support it, with the allocator characteristic system providing a fallback for older devices.
|
|
|
|
* The GATT protocol allows a central to read from any read characteristic, not only the one that has been allocated to it.
|
|
The GATT protocol allows a central to read from any read characteristic, not only the one that has been allocated to it.
|
|
|
|
If the communication between a peripheral and a central needs to be confidential then higher-layer protocols must ensure that this remains the case even when the data sent from the peripheral to the central can easily be observed by other devices nearby.
|
|
If the communication between a peripheral and a central needs to be confidential then higher-layer protocols must ensure that this remains the case even when the data sent from the peripheral to the central can easily be observed by other devices nearby.
|
|
In practice this is unlikely to make a big difference to the design of higher-layer protocols, which must already be designed around the assumption that any data sent over a wireless medium can easily be received by unintended recipients.
|
|
In practice this is unlikely to make a big difference to the design of higher-layer protocols, which must already be designed around the assumption that any data sent over a wireless medium can easily be received by unintended recipients.
|
|
|
|
|
|
### BluetoothCommunicator
|
|
### BluetoothCommunicator
|
|
|
|
|
|
BluetoothCommunicator is a BLE library built upon the core Android `BluetoothGATT` objects similar to BLESSED. However, unlike BLESSED, BluetoothCommunicator is geared more towards async messaging, and not a general-use library. Because of the added flexibility working with BLESSED gives us, future development of BLE mesh networking tools will likely focus on our allocator characteristic framework. However it is useful to research the BluetoothCommunicator library because it gives us insight into how a higher-level messaging framework might be built upon the allocator characteristic system.
|
|
BluetoothCommunicator is a BLE library built upon the core Android `BluetoothGATT` objects similar to BLESSED. However, unlike BLESSED, BluetoothCommunicator is geared more towards async messaging, and not a general-use library.
|
|
|
|
|
|
#### Peer Advertisement
|
|
<https://github.com/niedev/BluetoothCommunicator>
|
|
|
|
|
|
TODO find code snippets from blechat impl
|
|
Because of the added flexibility working with BLESSED gives us, future development of BLE mesh networking tools will likely focus on our allocator characteristic framework. However it is useful to research the BluetoothCommunicator library because it gives us insight into how a higher-level messaging framework might be built upon the allocator characteristic system.
|
|
|
|
|
|
#### Peer Discovery
|
|
|
|
|
|
|
|
#### Peer Connectivity
|
|
|
|
|
|
|
|
#### Notes
|
|
|
|
|
|
|
|
While the library has methods built to enable auto-peering, our attempt to enable auto-peering with this framework proved unsuccessful.
|
|
While the library has methods built to enable auto-peering, our attempt to enable auto-peering with this framework proved unsuccessful.
|
|
|
|
|
... | | ... | |