无法维持BLE连接 - BlueZ Linux <-> iOS

3

安装:

我在一个嵌入式Linux平台上运行BlueZ 5.48,使用Python的example-gatt-server作为外围设备。 我使用hciconfig hci0 leadv 0启用广告。

我正在尝试使用iPhone(iOS v12.1.4)上的nRF Connect连接设备。

这些设备都在我的桌子上,RSSI约为-40dBm,信号水平应该很好。

问题:

我意识到有几个问题,并按优先级顺序列出它们(最重要的在前)。

a) 在iPhone上的nRF Connect中,我可以看到设备并进行连接,但在30-60秒后,某些原因导致断开连接。 它从未要求我授权配对或输入PIN码。

b) 在Linux中,只要iPhone连接,我就会看到Bluetooth: SMP security requested but not available不断打印。

c) 在iPhone上,我永远无法在普通蓝牙设备列表中看到我的外围设备...即使可能这种方式没办法匹配,但这也是一个较小的问题。

我尝试过的方法:

1)我从example-gatt-server Python代码中删除了具有安全/加密特性的TestService,因此剩下的都是HeartrateBattery服务。 iPhone的nRF Connect应用程序仍在连接30-60秒后断开连接。

2)为了确定断开连接的原因,我查看了Linux中bluetooth.service的日志:

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()

这似乎是说发生了超时(原因1)。

3) 我在Linux sysfs中修改了默认的conn_min_interval=24conn_max_interval=40supervision_timeout=42值以匹配苹果兼容性指南。(值被显式地更改为1224200。)重启并重新启动蓝牙后,没有任何改变。

4) 我尝试在hciconfig hci0 leadv 0之前输入btmgmt bredr offbtmgmt bondable off,但没有变化。

5) 我运行了nRF Sniffer,但似乎没有捕获到断开事件。我可以通过过滤其BD地址来告诉我的周边正在广播,如下所示:

Sniffer

6) 我彻底禁用了example-gatt-server。虽然nRF Connect仍然能够连接,但在30-60秒后断开连接。这似乎将问题隔离在iOS应用程序、BlueZ堆栈或较低级别的Linux驱动程序层/配置内。

7) 使用nRF Connect连接Android没有问题,可以保持稳定的连接。

问题

有没有人有关于接下来该尝试什么的建议?

编辑1:

根据评论,我在iPhone连接时在Linux主机上运行了btmon。我启用了iPhone上的Heartrate特征的notify。日志显示由于超时而断开连接。

< 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)                           

请在Linux机器上运行“btmon”,而不是使用nrf sniffer。这样您可以查看所有数据包,可能会发现断开连接的原因以及谁断开了连接。无论是GATT还是SMP,如果没有收到先前请求的响应,则都有30秒的超时时间。 - Emil
2个回答

1
我注意到你的btmon日志有:

    Error: Insufficient Authentication (0x05)

根据Bluez与iOS配对问题,在使用新参数修复后,这仍然是可能的情况吗?
(顺便提一下,iOS只会在设备列表中显示已发现或先前配对的BREDR启用设备)

很遗憾,“NoInputNoOutput” 对我仍然不起作用。在 iOS 上点击配对后,它立即抛出“身份验证失败(0x05)”,然后一遍又一遍地重新提示。我的唯一解决方法是使用自定义代理,使用“KeyboardDisplay”自动提交“yes”(顺便说一下,我正在使用 BLE 而不是 BREDR)。 - Austin

1

我相信按照苹果设计指南中的价值观解决了我的问题。我编辑并重新构建了内核,因此默认的蓝牙参数如下:

$ 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

这似乎可以在Linux和iPhone之间保持BLE连接,时间长度由我决定。
注意:之前尝试通过sysfs编辑这些参数时,我认为设置在重新启动后丢失了...或者没有像我想象的那样应用。我还使用了略有不同的值(conn_max_interval = 24与现在的12)。

显然,蓝牙芯片无法使用先前的连接参数相互通信,导致超时。无论是其中一个收音机出了问题还是时钟出了问题(用于保持同步)。如果您启动并运行嗅探器,您可能可以看到哪个设备有问题。 - Emil
2
值得一提的是,min/max时间间隔以1.25毫秒为单位,因此12的实际间隔为15毫秒。同样,监督超时单位为10毫秒,因此500表示5000毫秒。 - Carsten Hansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接