Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to maintain BLE connection - BlueZ Linux <-> iOS

Setup:

I'm running BlueZ 5.48 on an embedded Linux platform, with the Python example-gatt-server as a peripheral. I enable advertising with hciconfig hci0 leadv 0.

I am trying to connect using nRF Connect from an iPhone (iOS v12.1.4).

The devices are both on my desk, measuring about -40dBm RSSI, so signal levels should be good.

Issue(s):

I'm aware of several issues, and will list them in priority order (highest first).

a) In nRF Connect on the iPhone, I can see the device and connect, but after 30-60 seconds something causes a disconnect. It never asks me for permission to pair or enter a PIN.

b) In Linux, I see Bluetooth: SMP security requested but not available printed repeatedly as long as the iPhone is connected.

c) On the iPhone, I cannot see my peripheral device in the regular Bluetooth Devices list...ever. (This is a lesser issue...although I'd like to try pairing this way if possible.)

What I've tried:

1) I removed the TestService with secure / encrypted characteristics from the example-gatt-server Python code, so all that remain are Heartrate and Battery services. The iPhone nRF Connect app still disconnects after 30-60 seconds.

2) To determine the cause of disconnect, I looked at the journal for bluetooth.service in Linux:

Mar 15 18:44:57 sn0010 bluetoothd[775]: src/gatt-database.c:send_notification_to_device() GATT server sending notification
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/adapter.c:dev_disconnected() Device MAC_ADDR_HERE disconnected, reason 1
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/adapter.c:adapter_remove_connection()
Mar 15 18:44:58 sn0010 bluetoothd[775]: plugins/policy.c:disconnect_cb() reason 1
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/adapter.c:bonding_attempt_complete() hci0 bdaddr MAC_ADDR_HERE type 1 status 0xe
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/device.c:device_bonding_complete() bonding (nil) status 0x0e
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/device.c:device_bonding_failed() status 14
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/adapter.c:resume_discovery()
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/device.c:att_disconnected_cb()
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/device.c:att_disconnected_cb() Connection timed out (110)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20d080: device MAC_ADDR_HERE profile batt-profile state changed: connected -> disconnecting (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20d080: device MAC_ADDR_HERE profile batt-profile state changed: disconnecting -> disconnected (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20d638: device MAC_ADDR_HERE profile deviceinfo state changed: connected -> disconnecting (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20d638: device MAC_ADDR_HERE profile deviceinfo state changed: disconnecting -> disconnected (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20ca00: device MAC_ADDR_HERE profile gap-profile state changed: connected -> disconnecting (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/service.c:change_state() 0x20ca00: device MAC_ADDR_HERE profile gap-profile state changed: disconnecting -> disconnected (0)
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/gatt-client.c:btd_gatt_client_disconnected() Device disconnected. Cleaning up.
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/device.c:att_disconnected_cb() Automatic connection disabled
Mar 15 18:44:58 sn0010 bluetoothd[775]: attrib/gattrib.c:g_attrib_unref() 0x21e968: g_attrib_unref=0
Mar 15 18:44:58 sn0010 bluetoothd[775]: src/gatt-database.c:att_disconnected()

This seems to say a timeout occurred (reason 1).

3) I altered the default conn_min_interval=24, conn_max_interval=40, supervision_timeout=42 values in Linux sysfs to match the Apple compatibility guidelines. (Values were changed to 12, 24, and 200 explicitly.) Rebooting and restarting Bluetooth with this didn't make any difference.

4) I tried issuing btmgmt bredr off and btmgmt bondable off before hciconfig hci0 leadv 0, but no change.

5) I ran nRF Sniffer but it didn't seem to capture disconnect events. I can tell my peripheral is advertising by filtering on its BD addr as shown below:

Sniffer

6) I disabled the example-gatt-server altogether. nRF Connect is still able to connect, but disconnects after 30-60 seconds again. This seems to isolate the issue within the iOS app, the BlueZ stack, or lower Linux driver layers/configuration.

7) Connecting using nRF Connect for Android works fine and maintains a steady connection as long as I wish.

Question

Does anyone have advice for what to try next?

EDIT 1:

Per comment, I have run btmon on the Linux host while the iPhone is connected. I enabled notify for Heartrate characteristic on the iPhone. The log shows a disconnect due to timeout.

< ACL Data TX: Handle 128 flags 0x00 dlen 7             #4792 [hci0] 105.414362 
      ATT: Read Request (0x0a) len 2                                            
        Handle: 0x0016                                                          
> ACL Data RX: Handle 128 flags 0x02 dlen 9             #4793 [hci0] 105.466957 
      ATT: Error Response (0x01) len 4                                          
        Read Request (0x0a)                                                     
        Handle: 0x0016                                                          
        Error: Insufficient Authentication (0x05)                               
> HCI Event: Number of Completed Packets (0x13) plen 5  #4794 [hci0] 105.467019 
        Num handles: 1                                                          
        Handle: 128                                                             
        Count: 1                                                                
< ACL Data TX: Handle 128 flags 0x00 dlen 7             #4795 [hci0] 105.474721 
      ATT: Read Request (0x0a) len 2                                            
        Handle: 0x0016                                                          
< ACL Data TX: Handle 128 flags 0x00 dlen 11            #4796 [hci0] 105.564168 
      ATT: Handle Value Notification (0x1b) len 6                               
        Handle: 0x000c                                                          
          Data: 0e7d6400                                                        
< ACL Data TX: Handle 128 flags 0x00 dlen 9             #4797 [hci0] 106.558967 
      ATT: Handle Value Notification (0x1b) len 4                               
        Handle: 0x000c                                                          
          Data: 0665                                                            
> HCI Event: Number of Completed Packets (0x13) plen 5  #4798 [hci0] 106.877481 
        Num handles: 1                                                          
        Handle: 128                                                             
        Count: 3                                                                
> HCI Event: Disconnect Complete (0x05) plen 4          #4799 [hci0] 106.877698 
        Status: Success (0x00)                                                  
        Handle: 128                                                             
        Reason: Connection Timeout (0x08)                                       
@ MGMT Event: Device Disconnected (0x000c) plen 8    {0x0001} [hci0] 106.877764 
        LE Address: 71:68:0B:72:0F:E9 (Resolvable)                              
        Reason: Connection timeout (0x01)                                       
@ MGMT Event: Device Disconnected (0x000c) plen 8    {0x0002} [hci0] 106.877764 
        LE Address: 71:68:0B:72:0F:E9 (Resolvable)                              
        Reason: Connection timeout (0x01)                           
like image 347
bjornruffians Avatar asked Oct 17 '25 01:10

bjornruffians


1 Answers

I believe my issue is solved by using values in accordance with the Apple design guidelines. I edited and rebuilt the kernel so default Bluetooth params are as follows:

$ cat /sys/kernel/debug/bluetooth/hci0/conn_min_interval 
12
$ cat /sys/kernel/debug/bluetooth/hci0/conn_max_interval 
12
$ cat /sys/kernel/debug/bluetooth/hci0/supervision_timeout 
500

This appears to maintain a BLE connection between Linux and the iPhone for as long as I wish.

Note: In attempting to edit these parameters via sysfs before, I believe the settings were lost upon reboot...or otherwise did not get applied like I thought. I had also used slightly different values (conn_max_interval = 24 vs 12 now).

like image 194
bjornruffians Avatar answered Oct 19 '25 15:10

bjornruffians



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!