我正在开发一个 BluetoothLE 传感器设备,为此我需要形成一对多的数据广播。根据规范,外围设备可能只有一个主设备,并且由于我正在设计的芯片和堆栈的限制,一个主设备只能有三个从设备。据我了解,Android 无论如何都不能成为 BLE 从属设备,因此不能让我的设备作为主设备。
BT4 规范和制造商文档都谈到了另一种操作模式,称为广播模式。在广播模式下,永远不会建立连接,并且应用程序数据作为广告数据包的一部分进行传输。这完全符合我的需求,因为许多 Android/iOS 手机可以同时扫描每个数据包。一个广告包以突发方式多次传输,所以我怀疑数据的接收大部分是可靠的。如果一个数据包在这里和那里丢失,它是可以容忍的。
有趣的是,我希望这些数据包能够携带实时传感器数据,这些数据以 10-20Hz 的速率更新。从我在网上找到的示例来看,这种模式下的 BLE 主要用于“iBeacon”类型的实现,它们在其中广播静态数据。我找不到有关如何在 Android 堆栈中过滤广告数据包的任何信息。它们可能是每个蓝牙硬件地址返回一个结果,也可能是地址和数据的唯一组合。第二个选项适用于此应用程序。如果开始和停止扫描会重置过滤器,我也可以做一些工作。
Android 文档没有提到扫描方法中的设备过滤是如何工作的。我已经能够在网上找到一篇试图解决同样问题的帖子,但回复未解决:BLE: Multiple discovery of the same peripheral during scan。在 iOS 中,我的同事告诉我,有一个参数可以传递给 scan 函数,使这成为可能。
我试图从 Android 源代码中的 startLeScan() 调用中追溯代码,但代码非常复杂,并且抽象的使用使得很难识别包含它的对象的实现。我得到的最远的是从 BluetoothManagerService 类方法 getBluetoothGatt() 返回的 IBluetoothGatt 对象。该对象接收开始扫描的请求。它在 github 上的当前修订版的 BluetoothManagerService.java 的第 790 行附近被实例化。该对象是从消息的结果中投射出来的,所以我怀疑结果可能是电话/驱动程序特定的。能够进一步追踪它超出了我的专业知识。
我想解决的另一个问题是打开和关闭扫描的速度有多快。扫描是一项耗电量大的操作,但数据的广播将在相当精确的实时计时器上定期发生。因此,如果可以打开和关闭扫描,这将是一个很好的优化,这样广播和扫描是同步的,而扫描仪在其他 90% 以上的时间里会关闭。这可能需要进行实验测试。
我还在做可行性研究,看看我们的 Android 配件是否可行。我现在的手机还不能运行 4.3 版,所以我无法通过实验测试/破解它。