bleak icon indicating copy to clipboard operation
bleak copied to clipboard

Not reliable connection to BLE device on RPI4: different command being used LE Create Connection vs LE Extended Create Connection

Open jimenaCabrejas opened this issue 10 months ago • 4 comments

Hi everyone I have been trying to use this library on a RPI4 to connect to a BLE device, but the connection is not reliable, as a lot of other issues have mentioned, it needs a lot of attempts to connect.

The thing is that when I use bluetoothctl command prompt and use the connect {MAC} command it always connects in the first attempt. So this lead me to believe that it is not a problem with the hardware but with the implementation.

I have captured with btmon the logs of the different ways a connection is stablished using this library and when a connection is stablished with bluetoothctl and I have seen that the commands used are different:

Connection with BLEAK it uses the LE Create Connection command. It fails and the device disconnects

< HCI Command: LE Create Connection (0x08|0x000d) plen 25                                                                  
        Scan interval: 60.000 msec (0x0060)
        Scan window: 60.000 msec (0x0060)
        Filter policy: Accept list is not used (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Own address type: Public (0x00)
        Min connection interval: 30.00 msec (0x0018)
        Max connection interval: 50.00 msec (0x0028)
        Connection latency: 0 (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Min connection length: 0.000 msec (0x0000)
        Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                                                                 
      LE Create Connection (0x08|0x000d) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 19                                                                                 
      LE Connection Complete (0x01)
        Status: Success (0x00)
        Handle: 64
        Role: Central (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Connection interval: 48.75 msec (0x0027)
        Connection latency: 0 (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Central clock accuracy: 0x00
@ MGMT Event: Device Connected (0x000b) plen 44                                                                        
        LE Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Flags: 0x00000008
          Connection Locally Initiated
        Data length: 31
        Flags: 0x06
          LE General Discoverable Mode
          BR/EDR Not Supported
        16-bit Service UUIDs (partial): 1 entry
          Health Thermometer (0x1809)
        Service Data: Unknown (0xc1c4)
          Data: fe97800024646c08bc05106c000003504607000a
@ RAW Open: btmon (privileged) version 2.22                                                                                  
@ RAW Close: btmon                                                                                                            
< HCI Command: LE Read Remote Used Features (0x08|0x0016) plen 2                                                           
        Handle: 64 Address: FE:97:80:00:24:64 (OUI FE-97-80)
> HCI Event: Command Status (0x0f) plen 4                                                                               
      LE Read Remote Used Features (0x08|0x0016) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 12                                                                                  
      LE Read Remote Used Features (0x04)
        Status: Connection Failed to be Established (0x3e)
        Handle: 64 Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Features: 0x3f 0x00 0x00 0x08 0x00 0x00 0x00 0x00
          LE Encryption
          Connection Parameter Request Procedure
          Extended Reject Indication
          Peripheral-initiated Features Exchange
          LE Ping
          LE Data Packet Length Extension
          Remote Public Key Validation
> HCI Event: Disconnect Complete (0x05) plen 4                                                                          
        Status: Success (0x00)
        Handle: 64 Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Reason: Connection Failed to be Established (0x3e)
@ MGMT Event: Device Disconnected (0x000c) plen 8                                                                    
        LE Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Reason: Unspecified (0x00)

Connection with bluetoothctl connect command it uses the LE Extended Create Connection command and it connects

< HCI Command: LE Extended Create Connection (0x08|0x0043) plen 58                
        Filter policy: Accept list is not used (0x00)
        Own address type: Public (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Initiating PHYs: 0x07
        Entry 0: LE 1M
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
        Entry 1: LE 2M
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
        Entry 2: LE Coded
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                          
      LE Extended Create Connection (0x08|0x0043) ncmd 2
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 31                                      
      LE Enhanced Connection Complete (0x0a)
        Status: Success (0x00)
        Handle: 16
        Role: Central (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Local resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Peer resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Connection interval: 10.00 msec (0x0008)
        Connection latency: 0 (0x0000)
        Supervision timeout: 4000 msec (0x0190)
        Central clock accuracy: 0x00
@ MGMT Event: Device Connected (0x000b) plen 44                              
        LE Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Flags: 0x00000008
          Connection Locally Initiated
        Data length: 31
        Flags: 0x06
          LE General Discoverable Mode
          BR/EDR Not Supported
        16-bit Service UUIDs (partial): 1 entry
          Health Thermometer (0x1809)
        Service Data: Unknown (0xc1c4)
          Data: fe97800024646c08bc05146c000003505f07000a
@ RAW Open: btmon (privileged) version 2.22                                         
@ RAW Close: btmon                                                                   
> HCI Event: LE Meta Event (0x3e) plen 4                                           
      LE Channel Selection Algorithm (0x14)
        Handle: 16 Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Algorithm: #1 (0x00)
< HCI Command: LE Read Remote Used Features (0x08|0x0016) plen 2                  
        Handle: 16 Address: FE:97:80:00:24:64 (OUI FE-97-80)
> HCI Event: Command Status (0x0f) plen 4                                       
      LE Read Remote Used Features (0x08|0x0016) ncmd 2
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 12                                         
      LE Read Remote Used Features (0x04)
        Status: Success (0x00)
        Handle: 16 Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Features: 0x3d 0x00 0x00 0x00 0x00 0x00 0x00 0x00
          LE Encryption
          Extended Reject Indication
          Peripheral-initiated Features Exchange
          LE Ping
          LE Data Packet Length Extension

Do you think this might be causing the connection fail issues?

Best regards

jimenaCabrejas avatar Mar 12 '25 10:03 jimenaCabrejas

Interesting finding. Will have to look into it more. A quick web search comes up with some similar cases:

  • https://github.com/bluez/bluez/issues/179
  • https://stackoverflow.com/questions/71250571/how-to-send-le-extended-create-connection-in-ble-with-raspberry-pi

What commands do you use in bluetoothctl to initiate the connection?

dlech avatar Mar 12 '25 14:03 dlech

In bluetoothctl console I do: [bluetooth]# scan on [bluetooth]# scan off (when I see my device) [bluetooth]# connect FE:97:80:00:24:64 (my MAC address)

jimenaCabrejas avatar Mar 12 '25 14:03 jimenaCabrejas

Thanks. The difference in Bleak is that it does the equivalent of:

[bluetooth]# menu scan 
[bluetooth]# transport le
[bluetooth]# back

before scan on. Does this also trigger the issue for you?

dlech avatar Mar 12 '25 14:03 dlech

Apologies for the delayed response. I have been running more tests to reliably reproduce the issue, and I believe the problem was with my setup.

I have two Bluetooth interfaces, hci0 and hci1. In the bluetoothctl console, I set hci1 as the default interface, and all tests were conducted using that interface.

Image

I thought the Bleak library used the default controller, but I believe I was mistaken and it was actually using the hci0 interface. If I set up the BleakScanner like this:

devices = await BleakScanner.discover(timeout=5, adapter='hci1')

and monitor the output it does use the LE Extended Create Connection command:

HCI Command: LE Extended Create Connection (0x08|0x0043) plen 58              
        Filter policy: Accept list is not used (0x00)
        Own address type: Public (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Initiating PHYs: 0x07
        Entry 0: LE 1M
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
        Entry 1: LE 2M
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
        Entry 2: LE Coded
          Scan interval: 60.000 msec (0x0060)
          Scan window: 60.000 msec (0x0060)
          Min connection interval: 10.00 msec (0x0008)
          Max connection interval: 10.00 msec (0x0008)
          Connection latency: 0 (0x0000)
          Supervision timeout: 4000 msec (0x0190)
          Min connection length: 0.000 msec (0x0000)
          Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                        
      LE Extended Create Connection (0x08|0x0043) ncmd 2
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 31                                        
      LE Enhanced Connection Complete (0x0a)
        Status: Success (0x00)
        Handle: 16
        Role: Central (0x00)
        Peer address type: Public (0x00)
        Peer address: FE:97:80:00:24:64 (OUI FE-97-80)
        Local resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Peer resolvable private address: 00:00:00:00:00:00 (Non-Resolvable)
        Connection interval: 10.00 msec (0x0008)
        Connection latency: 0 (0x0000)
        Supervision timeout: 4000 msec (0x0190)
        Central clock accuracy: 0x00
@ MGMT Event: Device Connected (0x000b) plen 44                              
        LE Address: FE:97:80:00:24:64 (OUI FE-97-80)
        Flags: 0x00000008
          Connection Locally Initiated
        Data length: 31
        Flags: 0x06
          LE General Discoverable Mode
          BR/EDR Not Supported
        16-bit Service UUIDs (partial): 1 entry
          Health Thermometer (0x1809)
        Service Data: Unknown (0xc1c4)
          Data: fe97800024646c08bc054f6c000003507807000a
@ RAW Open: btmon (privileged) version 2.22                                        
@ RAW Close: btmon                                                                  

It seems that BlueZ selects the command based on the characteristics of the controller. I'll continue testing to see if I can find anything else! Thank you for taking some time to look into this

jimenaCabrejas avatar Mar 12 '25 16:03 jimenaCabrejas