BLE GATT 设计 - 隐蔽或通用特性

BLE GATT Design - Discreet or generic characteristics

我正在为设备设计自定义 GATT 服务,我正在考虑为我们的 services/characteristics 使用更通用的方法,而不是每个数据点的标准谨慎服务和特征。

在我们的场景中,该设备不需要与其他设备一起使用 servers/vendors 因此我们只是需要与该设备交互的公司。因此,似乎抽象出每个离散数据点的价值较小。

通用方法需要具有三个特征的单一服务:

谨慎的方法(我所知道的最佳实践)意味着多个服务具有按逻辑分组的特征:

在设备 BLE 服务器和客户端上使用通用方法似乎更容易实现。

Thoughts/feedback来自真实经历?

您正在考虑的基本上是 Att/GATT 之上的另一个 Att 协议,但除非您考虑所有极端情况和可扩展性,否则您将获得更少的功能,而更多的开发成本。

优点:

  • 无需了解 BLE GATT 的理念,
  • 不需要拥抱Att/GATT协议,这只是一个透明传输协议。

缺点:

  • 需要重新发明自定义多路复用协议,
  • 需要在自定义协议中分配ID,维护分配,
  • 将减少 MTU(并且它在 BLE 中已经不是那么大),因为您将需要几个字节用于 muxing 协议,
  • 丢失所有通用基础设施(协议分析器、客户端代码、通用客户端 API(想想 iOS/Android 代码)、通用客户端应用程序(许多用于 PC 的通用客户端应用程序,phone)),
  • 关贸总协定的自我描述性丧失,
  • 版本控制实现起来更乏味(想想未来的固件版本会公开更多数据,或者以另一种形式公开数据,想想功能集略有不同的未来产品)。

总的来说,我认为没有充分的理由这样做。

GATT 是一种使 Att 具有自描述性的方法。您可以创建具有通用或自定义特征的自定义服务,它们中的每一个都应该公开一个值。这有一些不错的功能。对于每个特征,您有:

  • 类型标识符(实际上是 UUID,标准或自定义),
  • 标准访问方法(读取、写入、通知、指示),
  • 标准访问权限(例如,仅在配对后访问),
  • 可选描述符(您可以以标准方式指定数据的实际编码,添加名称)。

您可以创建一个或多个自定义服务,将所有“数据点”作为其中的不同特征。只有一项包含所有自定义特征的自定义服务是非常好的。这主要取决于应用程序。

您可能拥有通用标准服务,例如电池服务、设备信息服务或软件更新。

有关 ID 分配方案,请参阅

使用尽可能少的 services/characteristics 的一个好处是,服务发现时间将比使用大型 GATT 数据库时短得多。服务发现协议是一种非常低效的协议,会导致大量的往返。这将直接影响建立连接所需的时间。如果您的设备已绑定,幸运的是可以跳过服务发现。

如果您只有一个简单的设备,例如心率监测器、骑行速度传感器或类似的设备,其中 GATT 理念是有意义的并且不会产生那么多特性,那么您通常可以采用这种方法。

但是,如果您打算使用更高级的通信,包括大量功能,这些功能可能会在固件升级时发生变化,那么您自己拥有 TX/RX 特性和 encode/decode 数据可能会更容易使用一些自定义协议(例如第一个字节表示操作码,其余数据是参数)。否则,如果您使用 GATT 结构并添加特性或服务并假设您正在使用绑定以便 GATT 数据库将缓存在客户端中,您很可能需要正确使用和实施服务更改指示功能,跟踪您已将此指示发送给哪些客户端,并希望 Android 或客户端上运行的任何蓝牙堆栈没有错误,并正确刷新 GATT 缓存并在 GATT 数据库更新时通知您的应用程序(Android 在 Android 12).

之前并没有真正做到这一点

只有 TX/RX 个特征也可以更容易地处理错误。如果缺少一个或几个预期特征,但存在其他特征,您的应用会发生什么情况? (我曾经在廉价的联想平板电脑上发现过这个错误)如果您有很多 characteristics/services.

,您的 onServicesDiscovered 方法可能必须更高级才能在继续之前验证所有特征是否正确

另请注意,如果您只想 send/receive 数据,也可以使用 L2CAP CoC,它在 Android >= 10 和 iOS 中实现。