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

Method "Connect" with signature "" doesn't exist -> cannot pair device #150

Closed
BlackHawk1912 opened this issue Jan 17, 2020 · 13 comments
Closed
Assignees
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend bug Something isn't working
Milestone

Comments

@BlackHawk1912
Copy link

  • bleak version: 0.5.1
  • Python version: 3.7.6
  • Operating System: Raspbian with Linux kernel 4.19.75
  • Hardware: Raspberry Pi 4B
  • BlueZ version (bluetoothctl -v) in case of Linux: 5.50

Description

When trying to connect a custom BLE Device, I get the same error as in #55
org.freedesktop.DBus.Error.UnknownObject: Method "Connect" with signature "" on interface "org.bluez.Device1" doesn't exist

I use the discover beforehand but still get the error.
With the gatttool itself the connection is also not working. EXCEPT when I use the gatttool and set the addresstype to random (sudo gatttool -t random -b D8:80:05:21:2F:99 -I). Then it works.

My idea was to use the BlueZ adapter-api call for ConnectDevice which can receive an AddressType of "random". But further investigation showed me, that you didn't implement this methode. And because I am trying to pair a device, I searched for the "Pair"-methode of the BlueZ device-api which is also not called from Bleak.

Can you please explain why that is and you online use the "Connect"-methode, and what can cause the Connect-signature problem?

@hbldh hbldh self-assigned this Jan 23, 2020
@hbldh hbldh added the Backend: BlueZ Issues and PRs relating to the BlueZ backend label Jan 23, 2020
@hbldh
Copy link
Owner

hbldh commented Jan 23, 2020

I have been under the impression that pairing should not be required, and I have personally never needed it for my own usecases. When you say "custom BLE Device" what do you mean by that?

The random or public address type is not a settable parameter in the BlueZ DBus API, but a read-only attribute on a device. If you run discover you should be able to access that parameter like this:

import asyncio
from bleak import discover


async def run():
    devices = await discover()
    for d in devices:
        print("{0}: Address type: {1}".format(d, self.details["props"].get("AddressType", "Not Available")))


loop = asyncio.get_event_loop()
loop.run_until_complete(run())

I have been pondering adding a pair method to the BleakClient, but I have not got the time to do the actual work...

@BlackHawk1912
Copy link
Author

BlackHawk1912 commented Jan 23, 2020

I work for a company and we are currently developing a new BLE smart home device. My task at the moment is to write a python script which connects the device to Windows and Linux machines. The device itself has an nrf52 Bluetooth controller.

This device needs to be paired to the machine to actually read the characteristics. Under Windows, I managed to pair the device not via Bleak but rather with the UWP Bluetooth Samples (Scenario 8 to be precise). Which is not ideal but a story another issue :P

And as I said, on Linux the pairing work via gatttool but only when SPECIFICALLY setting the address type to random. Otherwise it will not even connect.

(Quick fix of your code in case someone else needs it:)

import asyncio
from bleak import discover


async def run():
    devices = await discover()
    for d in devices:
        print("{0}: Address type: {1}".format(d, d.details["props"].get("AddressType", "Not Available")))


loop = asyncio.get_event_loop()
loop.run_until_complete(run())

It seems like the address type is INDEED set to random. Which makes me curious why I needed to SPECIFICALLY set it in the gatttool. But anyway...

We tried to implement the pairing into bluezdbus/client.py, which looks like this:

async def pair(self, **kwargs) -> bool:

    if await self.is_paired():
        logger.debug("Device is already paired")
        return True

    logger.debug(
        "Pairing with BLE device @ {0} with {1}".format(self.address, self.device)
    )
    try:
        await self._bus.callRemote(
            self._device_path,
            "Pair",
            interface="org.bluez.Device1",
            destination="org.bluez",
        ).asFuture(self.loop)
    except RemoteError as e:
        raise BleakError(str(e))

    if await self.is_paired():
        logger.debug("Pairing successful.")
    else:
        raise BleakError(
            "Pairing to {0} was not successful!".format(self.address)
        )

    return True

That seemed to work but after the pairing we were not able to read the characteristics anymore. And some of our test devices wont be found at all anywhere in the hci0 adapter after that. Others work fine until trying to read a characteristic, then they are instantly disconnected.

So I fear we ran into a problem where we are set on our own and you cannot help us any further in the paring process, am I right :/ ?

@5frank
Copy link

5frank commented Jan 24, 2020

@BlackHawk1912 have you tried to reproduce your issue with btmon running? It might show more details on what is happening.

@BlackHawk1912
Copy link
Author

@5frank I just checked btmon and unfortunatly noticed the same behavior. The pairing SEEMS to work but as soon as I try to read something, the pairing AND the conenction are no more.
In my bluetooth sniffer I also see no action after the connection. The connection is there but the pairing process doesn't seem to be happening at all on the physical layer.

I am now certain that I am facing a problem with the BlueZ stack or the DBus, rather than bleak themself.
In the next few days I will try a different linux machine, rather then the Pi and I also plan on trying a bluetooth dongle for the Pi. Maybe there is a problem with the internal handeling of the bluetooth chip and LE.

@hbldh
Copy link
Owner

hbldh commented Feb 3, 2020

I have been experiencing the same problems with a new device I have obtained. It only occurs in the BlueZ backend, unpaired. I can connect just fine to it from Windows without pairing, so it should not be needed. I will keep investigating, but I have no idea as to a solution right now...

@hbldh hbldh added the bug Something isn't working label Feb 3, 2020
@BlackHawk1912
Copy link
Author

Wow okay. Meanwhile we assumed it is a problem with the firmware on our device (which is currently in development to but works on all other devices) but we keep investigating the next days. I'll keep you updated if we find something.

@BlackHawk1912
Copy link
Author

Okay, we seem to found the issue on our side. It was something with the firmware on our device not sending the right connection parameter i think. Unfortunately I can't point out what exactly was going on because I am not working on the firmware.

@hbldh I have another question regarding how to get the alias name of the device I connected to. Should I open a new issue? Or can you give me a quick tip on how to get it without using the discovery?

@5frank
Copy link

5frank commented Feb 12, 2020

@BlackHawk1912 Curios if your issue was because bluez rejected a "Update connection parameter request" from the BLE device/server? In that case I would gladly discuss it in more details.

@niecore
Copy link

niecore commented Feb 17, 2020

@5frank Yes, it was an issue with the exchange of the connection parameter. It seems like bluez and the ble stack nrf_sd where not able to find a common interval.

If you want to start discussing, get in contact with me via mail.

@wompydomp
Copy link

wompydomp commented Mar 8, 2020

Hi, I am trying to connect a Huawaei Band 4 similar to the honor band 3 mentioned by @zyv using his script. I fail with the same error messages when using the bleak example code. Using bleak (0.5.1), bluez (5.50-1+b1) on debian.

python3 bleak_connect.py 
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/bleak/backends/bluezdbus/client.py", line 124, in connect
    ).asFuture(self.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 "bleak_connect.py", line 14, in <module>
    loop.run_until_complete(run(address, loop))
  File "/usr/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
    return future.result()
  File "bleak_connect.py", line 8, in run
    async with BleakClient(address, loop=loop) as client:
  File "/usr/local/lib/python3.7/dist-packages/bleak/backends/client.py", line 43, in __aenter__
    await self.connect()
  File "/usr/local/lib/python3.7/dist-packages/bleak/backends/bluezdbus/client.py", line 126, in connect
    raise BleakError(str(e))
bleak.exc.BleakError: org.freedesktop.DBus.Error.UnknownObject: Method "Connect" with signature "" on interface "org.bluez.Device1" doesn't exist

with adjusted examples from: https://bleak.readthedocs.io/en/latest/usage.html
I can connect to the device via gatttool as shown here https://medium.com/@arunmag/my-journey-towards-reverse-engineering-a-smart-band-bluetooth-le-re-d1dea00e4de2

Any ideas in which direction i should look for solutions?

@hbldh
Copy link
Owner

hbldh commented Mar 27, 2020

I will not look at this in the foreseeable future I am afraid. I am swamped with other (paid) work and cannot guarantee doing anything with this project for quite some time. I will still address PRs to develop branch occasionally, so if you desire these changes you have to do the legwork yourselves.

@ghost
Copy link

ghost commented Apr 7, 2020

@wompydomp I was having the same issue, in my case, reversing the order of bytes in the mac address fixes the issue. The MAC of the device is AA:01:01:E1:80:02 but the Dbus object path is "/org/bluez/hci0/dev_02_80_E1_01_01_AA"

@hbldh
Copy link
Owner

hbldh commented Apr 21, 2020

@Illule Is that so. If you send in an address AA:01:01:E1:80:02 bleak constructs the DBus object path here, called from the connect method, since it seemed that the path was constructed that way and that woudl avoid waiting for discovery of the path before connecting. It seems I have to revisit that decision...

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 bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants