Bluetooth
Lager makes it simple to connect to and test BLE devices using Bleak. First, find the address of the device to which you wish to connect:
~ lager ble scan
Name Address rssi
Nordic_UART E4:B6:8E:F3:A0:2E -31
Then, you can enumerate the services, characteristics, and descriptors with the following program.
ble.py
import asyncio
import sys
from bleak import BleakClient
async def run(address):
async with BleakClient(address) as client:
print(f"Connected: {client.is_connected}")
for service in client.services:
print(f"[Service] {service}")
for char in service.characteristics:
if "read" in char.properties:
try:
value = bytes(await client.read_gatt_char(char.uuid))
print(
f"\t[Characteristic] {char} ({','.join(char.properties)}), Value: {value}"
)
except Exception as e:
print(
f"\t[Characteristic] {char} ({','.join(char.properties)}), Value: {e}"
)
else:
value = None
print(
f"\t[Characteristic] {char} ({','.join(char.properties)}), Value: {value}"
)
for descriptor in char.descriptors:
try:
value = bytes(
await client.read_gatt_descriptor(descriptor.handle)
)
print(f"\t\t[Descriptor] {descriptor}) | Value: {value}")
except Exception as e:
print(f"\t\t[Descriptor] {descriptor}) | Value: {e}")
def main():
if len(sys.argv) != 2:
print('Usage: lager python connect.py BLE_ADDRESS', file=sys.stderr)
raise SystemExit(1)
ble_address = sys.argv[1]
loop = asyncio.get_event_loop()
loop.run_until_complete(run(ble_address))
if __name__ == '__main__':
main()
Run it with the address of the device you'd like to enumerate:
~ lager python ble.py E4:B6:8E:F3:A0:2E
Connected: True
[Service] 6e400001-b5a3-f393-e0a9-e50e24dcca9e (Handle: 11): Nordic UART Service
[Characteristic] 6e400003-b5a3-f393-e0a9-e50e24dcca9e (Handle: 14): Nordic UART TX (notify), Value: None
[Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 16): Client Characteristic Configuration) | Value: b'\x00\x00'
[Characteristic] 6e400002-b5a3-f393-e0a9-e50e24dcca9e (Handle: 12): Nordic UART RX (write-without-response,write), Value: None
[Service] 00001801-0000-1000-8000-00805f9b34fb (Handle: 10): Generic Attribute Profile