Android 6.0 Marshmallow BLE:连接参数

33

Android 6中,蓝牙低功耗连接参数管理方式似乎已经发生了变化。

我有一个需要使用一些特定连接参数的BLE外设设备(特别是连接间隔),我想使用BLE规范允许的最小连接间隔(即7.5毫秒)。

Android SDK不允许从BLE GAP Central(智能手机)端选择它,因此正确的方法是在GAP Peripheral设备发送L2CAP Connection Parameter Update请求后进行设置。

我请求的参数是:

  • conn interval min : 7.5ms
  • conn interval max : 7.5ms
  • slave latency : 0
  • supervision timeout : 2000ms

这个方法在我测试过的所有Android设备上都可以正常工作,从4.3到5.x。发送L2CAP Connection Parameter Update请求后,我的设备收到了一个L2CAP Connection Parameter Update响应,其中包含0x0000(被接受),接着又接收到一个LE Connection Update Complete event,在这里我可以看到所请求的连接参数已经被成功地采用了。

但是,在Nexus 9平板电脑或两台不同的Nexus 5设备上测试时,它们都运行Android 6.0.1,我发现L2CAP Connection Parameter Update Request始终会被拒绝(我收到了一个L2CAP Connection Parameter Update Response,其中包含0x0001(被拒绝))。然后我收到了一个LE Connection Update Complete event,在这里我可以看到请求的连接参数没有被采用。

我已经尝试了两个不同的Peripheral端实现(一个是ST Microelectronics的BlueNRG,另一个是Nordic Semiconductor的nRF52),但结果完全一样。

在更多测试之后:我尝试使用不同的参数集,改变conn interval max(保持其他参数不变)。以下是我的发现:

  • 使用最大连接间隔为18.75ms时,接受更新请求并将间隔设置为18.75ms。
  • 使用最大连接间隔为17.50ms时,接受更新请求并将间隔设置为15.00ms。
  • 使用最大连接间隔为15.00ms时,接受更新请求并将间隔设置为15.00ms。
  • 使用最大连接间隔为13.75ms时,接受更新请求并将间隔设置为11.25ms。
  • 使用最大连接间隔为11.25ms时,接受更新请求并将间隔设置为11.25ms。
  • 对于任何小于11.25ms的其他最大连接间隔值,我都会被拒绝。
  • 因此,观察到Android 6的BLE堆栈处理连接参数的方式明显发生了变化。但似乎没有任何信息或文档来证实这一点。

    我的观察结论是,现在允许的最小连接间隔为11.25ms(实际上符合我的需求),而之前的Android版本中是7.5ms。但是找到经验性的结果后,我想确定我是否漏掉了其他约束/规则,或者该最小值是否不会是动态的,例如依赖于当前电池电量......

    最好的情况是拥有类似于苹果蓝牙设计指南(第3.6节)的东西,以澄清LE外围设备应如何处理此主题。

    是否有人遇到同样的问题或知道谷歌提供更多有用信息?

4个回答

11
比较AOSP 6.0.1_r17与AOSP 5.1.1_r14中GattService.java中的connectionParameterUpdate()方法。在两种情况下,调用都会使用相同的参数一直到bta_dm_api.c中的BTA_DmBleUpdateConnectionParams()函数中,并且经过Buedroid处理。
    switch (connectionPriority)
    {
        case BluetoothGatt.CONNECTION_PRIORITY_HIGH:
            minInterval = 9; // 11.25ms
            maxInterval = 12; // 15ms
            break;

        case BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER:
            minInterval = 80; // 100ms
            maxInterval = 100; // 125ms
            latency = 2;
            break;
    }

5.1:

    switch (connectionPriority)
    {
        case BluetoothGatt.CONNECTION_PRIORITY_HIGH:
            minInterval = 6; // 7.5ms
            maxInterval = 8; // 10ms
            break;

        case BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER:
            minInterval = 80; // 100ms
            maxInterval = 100; // 125ms
            latency = 2;
            break;
    }

这可能是你问题的一部分答案。虽然BLE支持最低7.5ms的CI,但我不知道为什么链路层不会在外设请求下降CI时切换到更低的CI。我不知道Android代码的任何部分是否控制与外围设备的协商结果。


我想补充一下,在btm_ble_api.h中,BTM_BLE_CONN_INT_MIN [0x0006]和BTM_BLE_CONN_INT_MAX [0x0C80]的值没有改变。因此,这个拒绝可能不是在l2c_ble.c中发生的。 - GPS

5
谷歌没有提供任何有关蓝牙LE堆栈更改连接参数的文档,即使在Android 6中明显有一些更改。
我的经验与你相同,也就是说,在Android 6+中,11.25ms现在是最快的连接间隔。
我猜想他们不发布文档的原因是许多制造商将自己的BLE堆栈放入手机中(三星和HTC上的BLE行为与原始的Android不同)。
我还发现引起许多问题的另一个观察是,在确认请求的参数之前,Android 6+会更改连接参数2到6次。
我观察到,在请求800ms至1100ms的连接参数更新间隔后,我看到初始间隔返回7.5ms,然后跳到48.75ms,然后跳到我请求的1098.75ms。然后,我订阅了我的服务的通知,连接间隔再次跳回到7.5ms,然后再次回到1098.75ms。此后,它在连接期间稳定在1098.75ms。
这些测试是在安卓6.0.1上的Nexus 6上运行的。
很明显,在Android 6 BLE堆栈上发生了一些奇怪的事情。

1
嘿,我发现连接参数被多次更改,而且通常是在协商后10秒以上。这导致我们的实现出现了很多问题。你有没有找到解决这个问题或阻止它发生的方法? - horsejockey

1

Google的工程师在Bluedroid的最近一个提交中犯了一个错误,他们将BTM_BLE_CONN_INT_MIN_LIMIT定义为0x0009,这意味着连接间隔是1.25ms x 9 = 11.25ms。为了符合标准,它应该被定义为0x0006


有没有办法修复这个问题? - Josu Goñi

1

11.25毫秒是新的最小连接间隔。他们不再允许7.5毫秒是因为如果同时在蓝牙上流式传输音频,音频可能会变得卡顿。


具有讽刺意味的是,在我正在处理的项目中,当我们尝试从外围设备传输音频时,如果连接间隔大于10毫秒,音频会变得混乱不清。这很大程度上是因为(可能)链路层一次只能处理有限数量的数据包。 - GPS

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