Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connecting to Private Random Non-Resolvable address #363

Closed
5frank opened this issue Nov 20, 2020 · 8 comments
Closed

Connecting to Private Random Non-Resolvable address #363

5frank opened this issue Nov 20, 2020 · 8 comments
Assignees
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend

Comments

@5frank
Copy link

5frank commented Nov 20, 2020

  • bleak version: 0.9.1
  • Python version: 3.7.3
  • Operating System: Linux-4.19.0-12-amd64-x86_64-with-debian-10.6
  • BlueZ version (bluetoothctl -v) in case of Linux: 5.50

Description

I believe there is a issue connecting to devices with Private Random Non-Resolvable address. I have not yet excluded
other explanations, so if this address scheme is supposed to work, please close the issue. However, it seems to work with https://github.com/go-ble/ble (uses hci sockets) so looks like a bleak or bluez/dbus issue.

What I Did

The device is discovered but when trying to connect the device was "not found".

Log and traceback:

[...]
DEBUG:bleak.backends.bluezdbus.scanner:303: hwt_lmin-0000, 29:43:C6:23:4C:D1 (-69 dBm), Object Path: /org/bluez/hci0/dev_29_43_C6_23_4C_D1
DEBUG:bleak.backends.bluezdbus.scanner:297: InterfacesRemoved, org.freedesktop.DBus.ObjectManager (/): ['/org/bluez/hci0/dev_29_43_C6_23_4C_D1', ['org.freedesktop.DBus.Properties', 'org.freedesktop.DBus.Introspectable', 'org.bluez.Device1']]
DEBUG:bleak.backends.bluezdbus.scanner:303: None, None (None dBm), Object Path: None
[...]
DEBUG:bleak.backends.bluezdbus.scanner:303: None, None (None dBm), Object Path: None
DEBUG:main:48: address=29:43:C6:23:4C:D1. details={'path': '/org/bluez/hci0/dev_29_43_C6_23_4C_D1', 'props': {'Address': '29:43:C6:23:4C:D1', 'AddressType': 'random', 'Name': 'hwt_lmin-0000', 'Alias': 'hwt_lmin-0000', 'Paired': False, 'Trusted': False, 'Blocked': False, 'LegacyPairing': False, 'RSSI': -69, 'Connected': False, 'UUIDs': ['00001811-0000-1000-8000-00805f9b34fb'], 'Adapter': '/org/bluez/hci0', 'ServicesResolved': False}}, metadata={'uuids': ['00001811-0000-1000-8000-00805f9b34fb'], 'manufacturer_data': {}}
DEBUG:bleak.backends.bluezdbus.client:126: Connecting to BLE device @ 29:43:C6:23:4C:D1 with hci0
Traceback (most recent call last):
  File "/home/sfrank/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 135, in connect
    ).asFuture(loop)
txdbus.error.RemoteError: org.freedesktop.DBus.Error.UnknownObject: Method "Connect" with signature "" on interface "org.bluez.Device1" doesn't exist


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 81, in <module>
    main()
  File "main.py", line 77, in main
    loop.run_until_complete(run(address))
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "main.py", line 36, in run
    async with BleakClient(d) as clnt:
  File "/home/sfrank/.local/lib/python3.7/site-packages/bleak/backends/client.py", line 60, in __aenter__
    await self.connect()
  File "/home/sfrank/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 142, in connect
    self.address
bleak.exc.BleakError: Device with address 29:43:C6:23:4C:D1 could not be found. Try increasing `timeout` value or moving the device closer.

btmon (address differs from above as it is not static. it is the same device):

[...]
> HCI Event: LE Meta Event (0x3e) plen 31                             #7 [hci0] 6.803599
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Connectable undirected - ADV_IND (0x00)
        Address type: Random (0x01)
        Address: 27:52:05:AA:A5:C5 (Non-Resolvable)
        Data length: 19
        16-bit Service UUIDs (complete): 1 entry
          Alert Notification Service (0x1811)
        Name (complete): hwt_lmin-0000
        RSSI: -79 dBm (0xb1)

> HCI Event: LE Meta Event (0x3e) plen 12                             #8 [hci0] 6.804412
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Scan response - SCAN_RSP (0x04)
        Address type: Random (0x01)
        Address: 27:52:05:AA:A5:C5 (Non-Resolvable)
        Data length: 0
        RSSI: -78 dBm (0xb2)
@ MGMT Event: Device Found (0x0012) plen 33                           {0x0002} [hci0] 6.804432
        LE Address: 27:52:05:AA:A5:C5 (Non-Resolvable)
        RSSI: -78 dBm (0xb2)
        Flags: 0x00000000
        Data length: 19
        16-bit Service UUIDs (complete): 1 entry
          Alert Notification Service (0x1811)
        Name (complete): hwt_lmin-0000
@ MGMT Event: Device Found (0x0012) plen 33                           {0x0001} [hci0] 6.804432
        LE Address: 27:52:05:AA:A5:C5 (Non-Resolvable)
        RSSI: -78 dBm (0xb2)
        Flags: 0x00000000
        Data length: 19
        16-bit Service UUIDs (complete): 1 entry
          Alert Notification Service (0x1811)
        Name (complete): hwt_lmin-0000
@ MGMT Command: Stop Discovery (0x0024) plen 1                        {0x0001} [hci0] 6.809591
        Address type: 0x06
          LE Public
          LE Random
@hbldh
Copy link
Owner

hbldh commented Nov 20, 2020

I have no idea what “Private Random Non-Resolvable address” means and entails.

Can you at least detect the device with discover or find_device_by_address? The BlueZ DBus API does not provide any public/private address distinction, so I have no idea how to solve this.

@hbldh hbldh self-assigned this Nov 20, 2020
@5frank
Copy link
Author

5frank commented Nov 20, 2020

Yes I can detect it with discover and even read the name.

@5frank
Copy link
Author

5frank commented Nov 23, 2020

Perhaps I was wrong attributing it to the odd address scheme. Same problem after changing the device firmware to use "Private Random Resolvable address".
Have anyone successfully connected to device with random BLE address on Linux?

@5frank
Copy link
Author

5frank commented Nov 23, 2020

Works after:

$ bluetoothctl 
Agent registered
[bluetooth]# devices
...
[bluetooth]# trust 5B:6E:6A:3F:53:59
[CHG] Device 5B:6E:6A:3F:53:59 Trusted: yes
Changing 5B:6E:6A:3F:53:59 trust succeeded
[bluetooth]# pair 5B:6E:6A:3F:53:59
Attempting to pair with 5B:6E:6A:3F:53:59

I also needed to power cycle the device.
Perhaps this is expected behavior when address is random!? Is it the same on other backends or is the trust/paring handled automagically when connecting?

@5frank
Copy link
Author

5frank commented Nov 23, 2020

This dirty workaround solves it for now:

from subprocess import Popen, run, PIPE
import time

def bluetoothctl(dev):
    props = dev.details['props']
    if not props:
        loger.warning("No props")
        return

    logger.debug(str(props))

    p = Popen("bluetoothctl", stdin=PIPE, stdout=PIPE, stderr=PIPE)

    trusted = props.get("Trusted", False)
    if not trusted:
        cmd = "trust {}\n".format(dev.address)
        p.stdin.write(cmd.encode())
        time.sleep(1)

    paired = props.get("Paired", False)
    if not paired:
        cmd = "pair {}\n".format(dev.address)
        p.stdin.write(cmd.encode())
        time.sleep(1)

    if 1:
        cmd = "quit\n"
        p.stdin.write(cmd.encode())
        time.sleep(1)

    p.communicate()
    logger.debug("bluethoothctl stdout:'%s', stderr:'%s'", str(p.stdout), str(p.stderr))


async def main():
    dev = await discover(...)[0]
    bluetoothctl(dev) 
    async with BleakClient(dev) as clnt:
        ...

I suspect same thing could be done with the dbus interface. Still not sure if this counts as a bug or not?

@5frank
Copy link
Author

5frank commented Nov 25, 2020

No problems connecting to same device in MacOS.
Same problem with bluetoothctl: 5.53 (D-BUS API considered stable >= 5.52)
Not sure my workaround is reliable, problem seem to have disappeared on one machine after applying it once.

@hbldh
Copy link
Owner

hbldh commented Nov 25, 2020

You can pair in Bleak now as well (since 0.9.0): https://github.com/hbldh/bleak/blob/develop/bleak/backends/bluezdbus/client.py#L255-L315

First, it does a Trust call and then a Pair call to the DBus API. Try it out and see if it changes anything.

@hbldh hbldh added the Backend: BlueZ Issues and PRs relating to the BlueZ backend label Nov 25, 2020
@5frank
Copy link
Author

5frank commented Nov 26, 2020

embarrassing - pairing was needed. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend
Projects
None yet
Development

No branches or pull requests

2 participants