Closed DsapPH closed 2 years ago
The fact that you are unable to connect with bluetoothctl
suggests it is an issue with the underlying BlueZ. You shouldn't need to a scan every time. If the device is in the devices
list then you shouldn't need to scan again.
What puts it into a state where you can't connect? Is it after you have run your script previously? Could it be the peripheral is not being disconnected from correctly?
You can reset the Bluetooth adapter on the RPi with sudo service bluetooth restart
Does service bluetooth status
show errors?
To get Bluetooth debug information on Linux when running your script have separate terminals open with the following running to get more debug information:
bluetoothctl
(Shows status changes e.g. connection)journalctl -f -u bluetooth
(Shows kernel messages)sudo busctl monitor org.bluez
(Shows D-Bus messages related to the org.bluez bus)sudo btmon
(Shows low-level Bluetooth commands. btmon
log can also be written to a file and read with tools like wiresharkDoing service restart and service status I get 1 error.
pi@raspberrypi:~/BaseStationFW $ service bluetooth status
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2022-04-20 09:47:42 EDT; 4s ago
Docs: man:bluetoothd(8)
Main PID: 211948 (bluetoothd)
Status: "Running"
Tasks: 1 (limit: 4165)
CPU: 82ms
CGroup: /system.slice/bluetooth.service
└─211948 /usr/local/libexec/bluetooth/bluetoothd --experimental
Apr 20 09:47:41 raspberrypi systemd[1]: Starting Bluetooth service...
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Bluetooth daemon 5.64
Apr 20 09:47:42 raspberrypi systemd[1]: Started Bluetooth service.
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Starting SDP server
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Bluetooth management interface 1.18 initialized
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Battery Provider Manager created
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Failed to set privacy: Rejected (0x0b)
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Adv Monitor Manager created with supported features:0x00000000, enabled features:0x00000000, max number of supported>
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Endpoint registered: sender=:1.34 path=/MediaEndpoint/A2DPSink/sbc
Apr 20 09:47:42 raspberrypi bluetoothd[211948]: Endpoint registered: sender=:1.34 path=/MediaEndpoint/A2DPSource/sbc
The error being the Failed to set privacy: Rejected (0x0b)
Restarting the service then doing a scan on
, scan off
, connect
shows the same Failed to connect
.
I dont believe it is a disconnect issue. If I do get a successful connection and then use disconnect
then another connect
I can get the same issue.
Using journalctl -f -u bluetooth
I don't get any new logging when a connection error occurs.
running sudo busctl monitor org.bluez
and then doing the steps to connect I can see it set the connection to True which i assume it means it will connect. Then I see the error shows up but it doesn't give much of a clearly understanding.
‣ Type=error Endian=l Flags=1 Version=1 Cookie=254 ReplyCookie=140
Sender=:1.103 Destination=:1.105
ErrorName=org.bluez.Error.Failed ErrorMessage="le-connection-abort-by-local"
UniqueName=:1.103
MESSAGE "s" {
STRING "le-connection-abort-by-local";
};
Then it sets the connection back to false.
Is any of this information helpful? I haven't used a tool like wireshark before so I want to check that more debugging needs to happen before I try using it. Would an uninstall of BlueZ and reinstall of BlueZ on my raspberry pi be helpful in fixing this? I have no problem wiping and setting it up again before cloning my project back on it.
The Failed to set privacy: Rejected (0x0b)
is a known issue and I don't believe is the source of your issue.
You don't need to use wireshark to read the results from btmon
; although it can just help to make it slightly easier to read the log.
You can try a fresh install if you think you have messed around with things and would benefit from returning to a known state. Although you need to make sure you do all the updates as the BT firmware is often moving on.
One other thing to try if the peripheral you are connecting to is Bluetooth Low Energy (BLE) only, and that is to configure the RPi to be BLE only. This is done in the /etc/bluetooth/main.conf
file by changing ControllerMode
to the following:
ControllerMode = le
These are all just general pointers as this is an issue with BlueZ and not BLE_GATT
.
If you search LE connection abort by local
in https://lore.kernel.org/all/20210930153703.BlueZ.v7.3.Idd761b9b9f4620480db8889e7885a17952c2c13a@changeid/T/ it appears that error message is part of a drive to improve error reporting. However, there doesn't seem to be enough to pin this down. Hopefully btmon
will give us more.
If you wanted to report it on the BlueZ Slack then you will need to have some details from btmon
.
Understood, I'll look into btmon
as well as using wireshark on it.
Having done the fresh install it seems to have fixed this error. I do now run into a new one.
GDBus.Error:org.bluez.Error.Failed: Software caused connection abort (36)
I haven't updated BlueZ yet, could this be what has caused this. Are there other ways to update BlueZ other than building from source?
Makes sense I can start posting about these in BlueZ forums and not on this repository as its BlueZ issues. Feel free to close this since the le-connection-abort-by-local is also not showing up anymore.
I do have one other question that may be related to this repository. Which is why I consistently run into an issue where BLE_GATT.Central(MAC) tells me that it doesn't see the device and the way to fix it is doing a manual bluetoothctl scan. Is this something I can call it to do in python to avoid this issue?
Can you say a little bit more about "consistently"?
There needs to be a step that puts the remote device in to the list of devices BlueZ knows about. This should be a one-time provisioning step for a new remote device. By your use of "consistently" I'm understanding that it is not a one-time provisioning step for you. E.g. you have done the bluetoothctl
scan
and connect
. You then use your script and it works initially until it suddenly stops working and the only fix is to do the provisioning again. Is my reading of what you've written correct?
To do the all the options in Python for provisioning a new device adds a lot of complexity. As this should only be a one-time provisioning step when a new device is added, I took the decision not to add that complexity to the library so it would be good to understand why you are seeing this is not a one-time provisioning step.
Are there other ways to update BlueZ other than building from source?
The short answer to this is no.
I would also ask why you are upgrading and running with --experimental
? If you are on the latest version of your Linux OS the version of BlueZ should be absolutely fine for what BLE_GATT needs. BlueZ is split between user space and kernel space. The above steps you describe are updating the user space only. Unless you have a strong driver for the upgrade, you are best to use the version that ships in your OS install.
Are there other ways to update BlueZ other than building from source?
The short answer to this is no.
I would also ask why you are upgrading and running with
--experimental
? If you are on the latest version of your Linux OS the version of BlueZ should be absolutely fine for what BLE_GATT needs. BlueZ is split between user space and kernel space. The above steps you describe are updating the user space only. Unless you have a strong driver for the upgrade, you are best to use the version that ships in your OS install.
Gotcha I thought you needed the experimental flag, not that it was base in BlueZ. I'm running this off the newest Raspbian so if thats good then I won't upgrade.
Yes thats the issue with provisioning. The moment I disconnect from a connection I wont be able to find the device till I scan again.
When I do scan
I see it find new devices
[bluetooth]# scan on
Discovery started
[CHG] Controller E4:5F:01:70:F2:18 Discovering: yes
[NEW] Device 67:9C:15:DF:68:F7 name
[NEW] Device F3:13:9A:79:71:D0 name
[NEW] Device E3:5E:CC:72:64:4C name
[NEW] Device E8:70:2A:E4:9A:8C name
[NEW] Device 46:C7:F2:CA:C9:E2 name
[NEW] Device 6A:80:40:C0:16:E9 name
[NEW] Device 7F:C1:65:59:A1:20 name
Doing scan off
I see it change devices.
[bluetooth]# scan off
Discovery stopped
[CHG] Device F4:F8:D6:99:3B:9E name is nil
[CHG] Device 57:BD:21:2C:3C:09 name is nil
[CHG] Device 57:BD:21:2C:3C:09 name is nil
[CHG] Device E8:72:90:1E:33:36 name is nil
[CHG] Device E8:72:90:1E:33:36 name is nil
[CHG] Device 6C:4A:85:00:7B:5B name is nil
[CHG] Controller E4:5F:01:70:F2:18 Discovering: no
Shortly after doing that I see it delete devices. No input from me triggers this.
[DEL] Device 7F:C1:65:59:A1:20 name
[DEL] Device EA:6F:79:9A:FC:3F name
[DEL] Device F3:13:9A:79:71:D0 name
[DEL] Device E3:5E:CC:72:64:4C name
[DEL] Device 67:9C:15:DF:68:F7 name
When it comes to the device I am trying to connect too it won't be in that delete list. However If i wait longer and do nothing I then see it get deleted. If I connect to the device then disconnect, and wait it will also delete it. So I'm curious what I can do about this?
The latest version of Raspberry Pi OS/Raspbian should be fine for BLE_GATT. No need for the --experimental
flag either.
Shortly after doing that I see it delete devices. No input from me triggers this.
If you do a connect
inside of bluetoothctl
then that should stop BlueZ from deleting it automatically. After connecting once it should not be deleted.
When BlueZ does a scan it can possibly find a lot of devices over time. To manage this list of devices, BlueZ will delete any device it thinks is not of interest. If you connect
to a device, it will understand that it is a device of interest and should not delete it.
So to be clear the steps inside bluetoothctl
are:
scan on
scan off
connect xx:xx:xx:xx:xx:xx
disconnect
That device should then stay in the devices
list until you delete it. If that is not happening then let me know, but that sounds like a bug in BlueZ.
Yes those are the steps I am taking and shortly after the disconnect it deletes the device like everything else.
OK, I'll try to reproduce over the weekend. This is with BlueZ 5.53?
I'm not confident on the BlueZ version. Is there a command I can run in order to see this?
Also for system I am running a Rasberry PI with Raspbian.
pi@raspberrypi:~/BaseStationFW $ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
You can find the version of Bluez with either bluetoothd -v
or bluetoothctl -v
Perfect and I am on BlueZ 5.55
For BLE we made both the client and the peripheral. They are gonna be hard coded as pairs. Is it possible to manually add the mac of the device to the device_list file? This would be useful since I could run that bash command in python before creating the device and trying to connection.
I've wiped a Raspberry Pi and started from scratch with a clean install of the latest Raspbery Pi OS. This uses BlueZ 5.55 and demonstrates the issue you are describing of deleting the device even if it has been connected to. Reading through the commits for the BlueZ repo I've found various mentions to "since the introduction of the new 30 seconds timeout when setting a device as temporary", but I can't find the actual commit where it was introduced so I don't know exactly what the new rules are.
Anyway, after a little experimentation the following procedure seemed to stop my device being deleted/removed
scan on
scan off
connect xx:xx:xx:xx:xx:xx
trust
disconnect
Can you try this on your system and see if it resolves the issue for you also.
Great find. This solved the issue of needing to scan between each connect. The devices is staying known, including during reboots.
I think that was everything in this ticket besides the Software Abort issue which is something for BlueZ forums. If that was everything feel free to close the ticket. Appreciate all the help with this.
Great! Glad we found a solution.
And I've learnt something new also :-)
When connecting to a BLE peripheral it does not always connect 100% of the time.
Error:
Steps taken. bluetoothctl scan on scan off devices # check if the devices is there connect MAC
I have also tried using other commands I've seen online such as
trust
orpair
before connect however it does not help. The same issue arise in python. Where usingdevice = BLE_GATT.Central(MAC)
and then doingdevice.connect
. My assumption is something may be wrong with my BlueZ. I can take BLE phone apps such as nRF connection and connect to the device without issue. Are there steps I can take towards better debugging this.