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

Use random Bluetooth address #600

Closed
dlech opened this issue Jan 16, 2022 · 16 comments · Fixed by pybricks/pybricks-code#1262
Closed

Use random Bluetooth address #600

dlech opened this issue Jan 16, 2022 · 16 comments · Fixed by pybricks/pybricks-code#1262
Assignees
Labels
enhancement New feature or request software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) topic: bluetooth Issues involving bluetooth

Comments

@dlech
Copy link
Member

dlech commented Jan 16, 2022

Is your feature request related to a problem? Please describe.
We are currently using the same Bluetooth address as LEGO for all hubs but we have a different GATT database. This causes problems when the OS that connects to the hub caches GATT info. This results in errors about missing GATT services/characteristics and such. BlueZ is the worst about this and usually requires manually removing the device and manually deleting a cache file.

I was also just chatting with someone who had to reboot their iPhone in order to get the official LEGO apps to work again because connecting to the hub after restoring LEGO firmware was not working. Not sure if this is related, but sounds similar.

Describe the solution you'd like
If we use a random Bluetooth address on every connection, then the OS will see the hub as a new device every time and we can avoid issues with wrong cached values.

Describe alternatives you've considered
Keep things the way they are.

@dlech dlech added enhancement New feature or request topic: bluetooth Issues involving bluetooth software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) labels Jan 16, 2022
@SpudGunMan
Copy link

do you need a new one each time? why wouldn't you just make a new one for pybricks just offset the original? makes for more of an identification standard for multiple devices

@dlech
Copy link
Member Author

dlech commented Jan 19, 2022

do you need a new one each time?

This would avoid many issues with caching on Linux (and possibly other OSes, but that has yet to be proven).

why wouldn't you just make a new one for pybricks just offset the original?

Apple doesn't allow access to the Bluetooth address for security/privacy reasons. So having a fixed address is not useful on all platforms. Instead, we prefer using the device name as the unique identifier. It works on all platforms and is more memorable and meaningful than a Bluetooth address.

@Novakasa
Copy link

This would impact a usecase of mine in which I automatically keep track of different hubs to store information about them on PC. I understand that I can use names for this, but then this would require the users of my project to set unique names for each of the hubs. It would be nice if we had a way to uniquely identify hubs regardless of the names. I think even just providing unique default names for the hubs could be helpful.

@dlech
Copy link
Member Author

dlech commented Jan 21, 2022

Does the unique identifier need to be in the advertising data (before connecting) or is reading it after connecting good enough? https://github.com/pybricks/pybricks-micropython/issues/50 has some more ideas on this.

@Novakasa
Copy link

Novakasa commented Jan 21, 2022

It would be ideal if it were in the advertising data, since otherwise when connecting a specific one I would need to trial-connect each hub.

@Novakasa
Copy link

Novakasa commented May 11, 2022

After rethinking the requirements for my project, I think the name as implemented now should suffice for me after all.

dlech added a commit to pybricks/pybricks-micropython that referenced this issue Sep 19, 2022
This changes the driver to use a random Bluetooth address when
advertising/accepting connections. This will help prevent issues with
Bluetooth stacks caching the attribute database of the official LEGO
firmware and trying to use it for the Pybricks firmware or vice versa.

The Bluetooth chip appears to use the same random address after each
reset, so we don't get the full benefit avoiding caching issues when
the Pybricks firmware GATT database changes.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Sep 19, 2022
The BlueNRG-MS chip always uses the same random address. We would like
to use a new random address on each reset to work around BlueZ bugs
like Chrome causing duplicate notifications after a device disconnects.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
This changes the driver to use a random Bluetooth address when
advertising/accepting connections. This will help prevent issues with
Bluetooth stacks caching the attribute database of the official LEGO
firmware and trying to use it for the Pybricks firmware or vice versa.

The Bluetooth chip appears to use the same random address after each
reset, so we don't get the full benefit avoiding caching issues when
the Pybricks firmware GATT database changes.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
The BlueNRG-MS chip always uses the same random address. We would like
to use a new random address on each reset to work around BlueZ bugs
like Chrome causing duplicate notifications after a device disconnects.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
This gives the Bluetooth chip a new random address each time it resets.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
This changes the bluetooth driver to give the device a new random
address each time the bluetooth chip resets.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
This changes the bluetooth driver to give the device a new random
address each time the bluetooth chip resets.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 20, 2022
This updates all Bluetooth drivers to use a nonresolvable private
address instead of a public address. This means that each time the
Bluetooth chip is reset, we get a new random address (or more often
on a properly implemented stack like btstack). This should help avoid
issues caused by OS Bluetooth stacks caching the device attribute
database which can change when firmware is updated.

Issue: pybricks/support#600
dlech added a commit to pybricks/pybricks-micropython that referenced this issue Oct 21, 2022
This updates all Bluetooth drivers to use a nonresolvable private
address instead of a public address. This means that each time the
Bluetooth chip is reset, we get a new random address (or more often
on a properly implemented stack like btstack). This should help avoid
issues caused by OS Bluetooth stacks caching the device attribute
database which can change when firmware is updated.

Issue: pybricks/support#600
@dlech
Copy link
Member Author

dlech commented Oct 21, 2022

Implemented via nonresolvable private addresses in pybricks/pybricks-micropython@1815b8e.

@laurensvalk
Copy link
Member

When disconnecting and connecting, the previously used hub lingers for a while.

Screenshot from 2022-10-21 09-55-45

Attempting to connect can fail in one of two ways. Either you get an infinite loop in Pybricks Code:

Screencast.from.21-10-22.09.59.09.webm

Or you get this error:

image

@laurensvalk laurensvalk reopened this Oct 21, 2022
@laurensvalk
Copy link
Member

laurensvalk commented Oct 21, 2022

It sticks around for just a few seconds (on Ubuntu 22.04 + Chrome), so it isn't terrible.

I know we can't change how the Web BLE UI works (although... perhaps can we hide paired hubs?), but perhaps we could make a more informative error message if the newly selected hub has an identical address, and tell them to try again.

By the time they try again, the old hub will be gone anyway.

@laurensvalk
Copy link
Member

Side note: it fixes switching between pybricksdev and pybricks code as expected. Nice!

@dlech
Copy link
Member Author

dlech commented Oct 21, 2022

It sticks around for just a few seconds (on Ubuntu 22.04 + Chrome), so it isn't terrible.

This behavior is only seen on Linux and would need to be fixed in BlueZ and/or Chromium, so I think we can call it good and close this issue.

@laurensvalk
Copy link
Member

Getting out of the infinite loop in Pybricks Code might be worth doing though?

@dlech
Copy link
Member Author

dlech commented Oct 21, 2022

Hmm... I missed that one. Will look into it.

dlech added a commit to pybricks/pybricks-code that referenced this issue Oct 26, 2022
The 'gattserverdisconnected' event is called before the device is
actually disconnected, so if the user tries to connect again
immediately, the web browser will show a still "paired" device, but
selecting this devices results in an infinite wait. This is a bug in
Chromium, but we can work around it by adding a delay to give BlueZ
time to actually disconnect the device.

Closes: pybricks/support#600
dlech added a commit to pybricks/pybricks-code that referenced this issue Oct 26, 2022
The 'gattserverdisconnected' event is called before the device is
actually disconnected, so if the user tries to connect again
immediately, the web browser will show a still "paired" device, but
selecting this devices results in an infinite wait. This is a bug in
Chromium, but we can work around it by adding a delay to give BlueZ
time to actually disconnect the device.

Closes: pybricks/support#600
@laurensvalk
Copy link
Member

On Move Hub and Technic Hub, I always see the same Bluetooth address in the connection dialog. Even after rebooting the hub. Is this expected?

To reproduce, have both Technic Hub and Move Hub and a Prime Hub for comparison, all named "Pybricks Hub" so Chrome will show the addresses.

Only the address for Prime Hub changes after rebooting the hub and re-opening the dialog.

@dlech
Copy link
Member Author

dlech commented Nov 26, 2022

I get a new address after reboot (removing battery) on both hubs using Bleak, so maybe a Chrome bug? Or something to do with the way it is rebooted?

(bleak-py3.10) david@freyr:~/work/pybricks/bleak$ python examples/discover.py 
scanning for 5 seconds, please wait...

18:10:6A:CB:8D:8E: technic_hub
---------------------------
AdvertisementData(local_name='technic_hub', service_data={'00002a50-0000-1000-8000-00805f9b34fb': b'\x01\x97\x03\x80\x00\x00\x00'}, service_uuids=['c5f50001-8280-46da-89f4-6d8051e4aeef'], tx_power=0, rssi=-57)

0C:95:4D:80:FA:6D: move_hub
---------------------------
AdvertisementData(local_name='move_hub', service_data={'00002a50-0000-1000-8000-00805f9b34fb': b'\x01\x97\x03@\x00\x00\x00'}, service_uuids=['c5f50001-8280-46da-89f4-6d8051e4aeef'], tx_power=1, rssi=-47)
(bleak-py3.10) david@freyr:~/work/pybricks/bleak$ python examples/discover.py 
scanning for 5 seconds, please wait...

19:7F:18:36:15:49: move_hub
---------------------------
AdvertisementData(local_name='move_hub', service_data={'00002a50-0000-1000-8000-00805f9b34fb': b'\x01\x97\x03@\x00\x00\x00'}, service_uuids=['c5f50001-8280-46da-89f4-6d8051e4aeef'], tx_power=1, rssi=-56)

30:17:F7:3C:06:20: technic_hub
---------------------------
AdvertisementData(local_name='technic_hub', service_data={'00002a50-0000-1000-8000-00805f9b34fb': b'\x01\x97\x03\x80\x00\x00\x00'}, service_uuids=['c5f50001-8280-46da-89f4-6d8051e4aeef'], tx_power=0, rssi=-65)

@laurensvalk
Copy link
Member

laurensvalk commented Nov 26, 2022

I think I'm only able to reproduce it when my PC (workstation) and Laptop are both scanning in Pybricks Code at the same time.

Maybe I'm on to something --- it seems I can finally reproduce some problems I saw at WRO last week (presumably with a lot of laptops around), which looks very similar when giving Pybricks at other people's places. (More than 1 laptop but not that many).

  • Hub not finding remote
  • Technic hub stuck in the power off blink loop

To be followed up in separate issue.

dlech added a commit to pybricks/pybricks-code that referenced this issue Apr 1, 2023
If the user did not request disconnection, then we know this is a true
disconnect event and not an early one so we don't need the delay hack
in that case.

Issue: pybricks/support#600
Issue: pybricks/support#1021
dlech added a commit to pybricks/pybricks-code that referenced this issue Apr 1, 2023
If the user did not request disconnection, then we know this is a true
disconnect event and not an early one so we don't need the delay hack
in that case.

Issue: pybricks/support#600
Issue: pybricks/support#1021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) topic: bluetooth Issues involving bluetooth
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants