我试图在我的应用中使用基本的蓝牙LE连接,但我遇到了问题。我有几个传感器可以连接到这个应用程序的iOS版本,但我无法使用Android版本连接到它们。我似乎唯一可以连接到的是我已设置为配置模式的信标。
再次检查我的ADB日志后,我注意到无论何时无法连接到设备,总是有四次拨打bt_osi_alarm
和bta_gattc_conn_cback
。我想知道如何解释这个。
连接尝试失败:
D/BluetoothGatt(17824): connect() - device: 00:17:E9:C0:86:14, auto: false
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
W/bt_btif (14357): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0002
D/BtGatt.GattService(14357): onConnected() - clientIf=6, connId=0, address=00:17:E9:C0:86:14
D/BluetoothGatt(17824): onClientConnectionState() - status=133 clientIf=6 device=00:17:E9:C0:86:14
I/mono-stdout(17824): BLEAdapter.OnConnectionStateChange()
I/mono-stdout(17824): Gatt disconnected!
对其中一个信标的成功连接尝试没有这四组bt_osi_alarm
和bta_gattc_conn_cback
错误。最好是有人知道Android源代码,希望他们可以告诉我发生了什么。我知道这是一个很长的镜头,但我有点选择。感谢。
答案 0 :(得分:0)
一些其他信息可能有助于社区为您调试此问题。请在原始问题中添加以下内容:
BluetoothDevice
connectGatt()
根据我的经验,对于posix定时器来说,警报到期时间过于接近,切换到枪支,并不像其错误级别所暗示的那样严重。在我的nexus 7 / marshmallow设备上,当连接到蓝牙设备(串行配置文件,而不是BLE)时,我看到此消息不断,所以我不认为这是一个错误。
我建议您检查BLE设备制造商,看看是否有任何固件升级。
正在发生的事情是android bt代码的某些部分是设置一个非常短的计时器。如此之短,它会在应用程序测量之前到期。
在提交081e4b67b44a5fd397c2d79a5566e11ae52d4aca
中将错误,警报到期时间过于接近posix计时器,切换到枪支,已添加到android源代码中提交消息为我们提供了有关正在发生的事情的更多背景信息。
确保警报在过去过期时被回叫
原来我们处理的posix计时器表现不佳。
如果计时器是TIMER_ABSTIME,则以下情况应为真: "如果已经过了指定的时间,则该功能将成功 并且应该提交到期通知。"
但唉,情况并非如此。如果到期时间恰好是 在过去(例如非常短的计时器,它被上下文击中 在可以设置定时器之前切换)定时器决定撤防 本身。这意味着不再发生回调,也不再发生警报 处理过。
悲伤。
但幸运的是,我们可以使用timer_gettime来检查状态 timer_settime后的计时器。如果timer_gettime告诉我们计时器是 在我们武装之后解除武装,我们想要发出警报 回调自己。
将所有计时器回调放在同一个线程上(如果是这样的话) 已经基本的计时器实现)并使用了sempahore 当警报在正常的posix定时器回调中到期时发出信号 也在计时器中没有设置案例。
该代码还包括以下注释
如果过去是下一次过期(例如获得上下文的短暂计时器) 然后计时器可能已经自己解决了。检测这种情况 并通过手动发信号通知| alarm_expired |来解决它 信号量。
计时器实际上可能超短(少数 毫秒)和计时器在我们调用之前正常到期 | timer_gettime |。最坏的情况,| alarm_expired |两次发出信号 那个警报。在那种情况下,没有什么不好的事情会发生 回调调度功能检查以确保计时器在头部 列表实际上已过期。