简体   繁体   English

Android 的 bluez 和服务/特性缓存问题

[英]bluez and service/characteristics cache issue with Android

I have some trouble to communicate through BLE between an Android mobile application and a custom embedded device.我在 Android 移动应用程序和自定义嵌入式设备之间通过 BLE 进行通信时遇到了一些麻烦。 The embedded device is peripheral and used a custom GATT profile define with Bluez.嵌入式设备是外围设备,并使用 Bluez 定义的自定义 GATT 配置文件。 Everything is working fine.一切正常。 The problem is that sometimes, we deploy new firmware on the embedded device with new services sometimes, but also new characteristics very often.问题是有时,我们有时会在嵌入式设备上部署新固件,提供新服务,但也经常使用新特性。 We are using the last Bluezversion (5.54)我们正在使用最后一个 Bluezversion (5.54)

Everything is working great with IOS. IOS 一切正常。 But with Android, randomly sometimes the mobile app continues to use the old services/characteristics UUID.但是对于 Android,有时移动应用程序会随机继续使用旧的服务/特征 UUID。 So basically the mobile app sends a request on wrong characteristics... We are not able to reproduce the issue in a determinist way of course..所以基本上移动应用程序会发送一个关于错误特征的请求......我们当然无法以确定性的方式重现这个问题......

We find some stuff about cache: silabs我们发现了一些关于缓存的东西: silabs

After looking for some answers on the internet, we find some info relating to bonding.在互联网上寻找一些答案后,我们找到了一些与粘合有关的信息。 So we tried to add this in the mobile App Android side:于是我们尝试在手机App Android端添加这个:

Method m = device.getClass().getMethod(“removeBond”, (Class[]) null);
            m.invoke(device, (Object[]) null);

We also tried to force the refresh the cache from Android side:我们还尝试从 Android 端强制刷新缓存:

final Method refresh = gatt.getClass().getMethod(“refresh”); refresh.invoke(gatt);

But it always no working correctly.. We also check the presence of client supported features and database hash in our characteristics.但它总是无法正常工作。我们还在我们的特征中检查客户端支持的功能和数据库 hash 的存在。 it seems present as expected:它似乎按预期存在:

./btgatt-client -i hci0 -d xxxx
[GATT client]# Service Added - UUID: 00001800-0000-1000-8000-00805f9b34fb start: 0x0001 end: 0x0005
[GATT client]# Service Added - UUID: 00001801-0000-1000-8000-00805f9b34fb start: 0x0006 end: 0x000f
[GATT client]# Service Added - UUID: 0000df00-0000-1000-8000-00805f9b34fb start: 0x0010 end: 0x0012
[GATT client]# Service Added - UUID: 0000d200-0000-1000-8000-00805f9b34fb start: 0x0013 end: 0x0023
[GATT client]# Service Added - UUID: 0000d010-0000-1000-8000-00805f9b34fb start: 0x0024 end: 0x002a
[GATT client]# Service Added - UUID: 0000d100-0000-1000-8000-00805f9b34fb start: 0x002b end: 0x0031
[GATT client]# Service Added - UUID: 0000d700-0000-1000-8000-00805f9b34fb start: 0x0032 end: 0x0045
[GATT client]# Service Added - UUID: 0000d900-0000-1000-8000-00805f9b34fb start: 0x0046 end: 0x0050
[GATT client]# Service Added - UUID: 0000d600-0000-1000-8000-00805f9b34fb start: 0x0051 end: 0x0053
[GATT client]# Service Added - UUID: 0000d500-0000-1000-8000-00805f9b34fb start: 0x0054 end: 0x0072
[GATT client]# Service Added - UUID: 0000d850-0000-1000-8000-00805f9b34fb start: 0x0073 end: 0x0075
[GATT client]# Service Added - UUID: 0000d400-0000-1000-8000-00805f9b34fb start: 0x0076 end: 0x007a
[GATT client]# Service Added - UUID: 0000da00-0000-1000-8000-00805f9b34fb start: 0x007b end: 0x0085
[GATT client]# Service Added - UUID: 0000d300-0000-1000-8000-00805f9b34fb start: 0x0086 end: 0x0099
[GATT client]# Service Added - UUID: 0000d200-0000-1000-8000-00805f9b34fb start: 0x009a end: 0x00b1
[GATT client]# Service Added - UUID: 0000d800-0000-1000-8000-00805f9b34fb start: 0x00b2 end: 0x00ba
[GATT client]# GATT discovery procedures complete

service - start: 0x0001, end: 0x0005, type: primary, uuid: 00001800-0000-1000-8000-00805f9b34fb
      charac - start: 0x0002, value: 0x0003, props: 0x02, ext_props: 0x0000, uuid: 00002a00-0000-1000-8000-00805f9b34fb
      charac - start: 0x0004, value: 0x0005, props: 0x02, ext_props: 0x0000, uuid: 00002a01-0000-1000-8000-00805f9b34fb

service - start: 0x0006, end: 0x000f, type: primary, uuid: 00001801-0000-1000-8000-00805f9b34fb
      charac - start: 0x0007, value: 0x0008, props: 0x20, ext_props: 0x0000, uuid: 00002a05-0000-1000-8000-00805f9b34fb
          descr - handle: 0x0009, uuid: 00002902-0000-1000-8000-00805f9b34fb
      charac - start: 0x000a, value: 0x000b, props: 0x0a, ext_props: 0x0000, uuid: 00002b29-0000-1000-8000-00805f9b34fb
      charac - start: 0x000c, value: 0x000d, props: 0x02, ext_props: 0x0000, uuid: 00002b2a-0000-1000-8000-00805f9b34fb
      charac - start: 0x000e, value: 0x000f, props: 0x02, ext_props: 0x0000, uuid: 00002b3a-0000-1000-8000-00805f9b34fb

service - start: 0x0010, end: 0x0012, type: primary, uuid: 0000df00-0000-1000-8000-00805f9b34fb
      charac - start: 0x0011, value: 0x0012, props: 0x08, ext_props: 0x0000, uuid: 0000df01-0000-1000-8000-00805f9b34fb

service - start: 0x0013, end: 0x0023, type: primary, uuid: 0000d200-0000-1000-8000-00805f9b34fb
      charac - start: 0x0014, value: 0x0015, props: 0x0a, ext_props: 0x0000, uuid: 0000d008-0000-1000-8000-00805f9b34fb
      charac - start: 0x0016, value: 0x0017, props: 0x0a, ext_props: 0x0000, uuid: 0000d007-0000-1000-8000-00805f9b34fb
      charac - start: 0x0018, value: 0x0019, props: 0x08, ext_props: 0x0000, uuid: 0000d006-0000-1000-8000-00805f9b34fb
      charac - start: 0x001a, value: 0x001b, props: 0x08, ext_props: 0x0000, uuid: 0000d005-0000-1000-8000-00805f9b34fb
      charac - start: 0x001c, value: 0x001d, props: 0x08, ext_props: 0x0000, uuid: 0000d004-0000-1000-8000-00805f9b34fb
      charac - start: 0x001e, value: 0x001f, props: 0x02, ext_props: 0x0000, uuid: 0000d003-0000-1000-8000-00805f9b34fb
      charac - start: 0x0020, value: 0x0021, props: 0x08, ext_props: 0x0000, uuid: 0000d002-0000-1000-8000-00805f9b34fb
      charac - start: 0x0022, value: 0x0023, props: 0x08, ext_props: 0x0000, uuid: 0000d001-0000-1000-8000-00805f9b34fb

service - start: 0x0024, end: 0x002a, type: primary, uuid: 0000d010-0000-1000-8000-00805f9b34fb
      charac - start: 0x0025, value: 0x0026, props: 0x02, ext_props: 0x0000, uuid: 0000d013-0000-1000-8000-00805f9b34fb
      charac - start: 0x0027, value: 0x0028, props: 0x08, ext_props: 0x0000, uuid: 0000d012-0000-1000-8000-00805f9b34fb
      charac - start: 0x0029, value: 0x002a, props: 0x08, ext_props: 0x0000, uuid: 0000d011-0000-1000-8000-00805f9b34fb

service - start: 0x002b, end: 0x0031, type: primary, uuid: 0000d100-0000-1000-8000-00805f9b34fb
      charac - start: 0x002c, value: 0x002d, props: 0x02, ext_props: 0x0000, uuid: 0000d103-0000-1000-8000-00805f9b34fb
      charac - start: 0x002e, value: 0x002f, props: 0x0a, ext_props: 0x0000, uuid: 0000d102-0000-1000-8000-00805f9b34fb
      charac - start: 0x0030, value: 0x0031, props: 0x02, ext_props: 0x0000, uuid: 0000d101-0000-1000-8000-00805f9b34fb

service - start: 0x0032, end: 0x0045, type: primary, uuid: 0000d700-0000-1000-8000-00805f9b34fb
      charac - start: 0x0033, value: 0x0034, props: 0x02, ext_props: 0x0000, uuid: 0000d709-0000-1000-8000-00805f9b34fb
      charac - start: 0x0035, value: 0x0036, props: 0x08, ext_props: 0x0000, uuid: 0000d706-0000-1000-8000-00805f9b34fb
      charac - start: 0x0037, value: 0x0038, props: 0x10, ext_props: 0x0000, uuid: 0000d704-0000-1000-8000-00805f9b34fb
          descr - handle: 0x0039, uuid: 00002902-0000-1000-8000-00805f9b34fb
      charac - start: 0x003a, value: 0x003b, props: 0x08, ext_props: 0x0000, uuid: 0000d707-0000-1000-8000-00805f9b34fb
      charac - start: 0x003c, value: 0x003d, props: 0x08, ext_props: 0x0000, uuid: 0000d703-0000-1000-8000-00805f9b34fb
      charac - start: 0x003e, value: 0x003f, props: 0x02, ext_props: 0x0000, uuid: 0000d708-0000-1000-8000-00805f9b34fb
      charac - start: 0x0040, value: 0x0041, props: 0x02, ext_props: 0x0000, uuid: 0000d702-0000-1000-8000-00805f9b34fb
      charac - start: 0x0042, value: 0x0043, props: 0x02, ext_props: 0x0000, uuid: 0000d705-0000-1000-8000-00805f9b34fb
      charac - start: 0x0044, value: 0x0045, props: 0x02, ext_props: 0x0000, uuid: 0000d701-0000-1000-8000-00805f9b34fb

service - start: 0x0046, end: 0x0050, type: primary, uuid: 0000d900-0000-1000-8000-00805f9b34fb
      charac - start: 0x0047, value: 0x0048, props: 0x08, ext_props: 0x0000, uuid: 0000d905-0000-1000-8000-00805f9b34fb
      charac - start: 0x0049, value: 0x004a, props: 0x02, ext_props: 0x0000, uuid: 0000d904-0000-1000-8000-00805f9b34fb
      charac - start: 0x004b, value: 0x004c, props: 0x02, ext_props: 0x0000, uuid: 0000d903-0000-1000-8000-00805f9b34fb
      charac - start: 0x004d, value: 0x004e, props: 0x08, ext_props: 0x0000, uuid: 0000d902-0000-1000-8000-00805f9b34fb
      charac - start: 0x004f, value: 0x0050, props: 0x08, ext_props: 0x0000, uuid: 0000d901-0000-1000-8000-00805f9b34fb

service - start: 0x0051, end: 0x0053, type: primary, uuid: 0000d600-0000-1000-8000-00805f9b34fb
      charac - start: 0x0052, value: 0x0053, props: 0x08, ext_props: 0x0000, uuid: 0000d601-0000-1000-8000-00805f9b34fb

service - start: 0x0054, end: 0x0072, type: primary, uuid: 0000d500-0000-1000-8000-00805f9b34fb
      charac - start: 0x0055, value: 0x0056, props: 0x0a, ext_props: 0x0000, uuid: 0000d516-0000-1000-8000-00805f9b34fb
      charac - start: 0x0057, value: 0x0058, props: 0x0a, ext_props: 0x0000, uuid: 0000d517-0000-1000-8000-00805f9b34fb
      charac - start: 0x0059, value: 0x005a, props: 0x02, ext_props: 0x0000, uuid: 0000d514-0000-1000-8000-00805f9b34fb
      charac - start: 0x005b, value: 0x005c, props: 0x02, ext_props: 0x0000, uuid: 0000d513-0000-1000-8000-00805f9b34fb
      charac - start: 0x005d, value: 0x005e, props: 0x02, ext_props: 0x0000, uuid: 0000d512-0000-1000-8000-00805f9b34fb
      charac - start: 0x005f, value: 0x0060, props: 0x08, ext_props: 0x0000, uuid: 0000d511-0000-1000-8000-00805f9b34fb
      charac - start: 0x0061, value: 0x0062, props: 0x02, ext_props: 0x0000, uuid: 0000d509-0000-1000-8000-00805f9b34fb
      charac - start: 0x0063, value: 0x0064, props: 0x08, ext_props: 0x0000, uuid: 0000d510-0000-1000-8000-00805f9b34fb
      charac - start: 0x0065, value: 0x0066, props: 0x08, ext_props: 0x0000, uuid: 0000d508-0000-1000-8000-00805f9b34fb
      charac - start: 0x0067, value: 0x0068, props: 0x08, ext_props: 0x0000, uuid: 0000d518-0000-1000-8000-00805f9b34fb
      charac - start: 0x0069, value: 0x006a, props: 0x08, ext_props: 0x0000, uuid: 0000d506-0000-1000-8000-00805f9b34fb
      charac - start: 0x006b, value: 0x006c, props: 0x08, ext_props: 0x0000, uuid: 0000d505-0000-1000-8000-00805f9b34fb
      charac - start: 0x006d, value: 0x006e, props: 0x08, ext_props: 0x0000, uuid: 0000d504-0000-1000-8000-00805f9b34fb
      charac - start: 0x006f, value: 0x0070, props: 0x08, ext_props: 0x0000, uuid: 0000d507-0000-1000-8000-00805f9b34fb
      charac - start: 0x0071, value: 0x0072, props: 0x0a, ext_props: 0x0000, uuid: 0000d501-0000-1000-8000-00805f9b34fb

service - start: 0x0073, end: 0x0075, type: primary, uuid: 0000d850-0000-1000-8000-00805f9b34fb
      charac - start: 0x0074, value: 0x0075, props: 0x08, ext_props: 0x0000, uuid: 0000d853-0000-1000-8000-00805f9b34fb

service - start: 0x0076, end: 0x007a, type: primary, uuid: 0000d400-0000-1000-8000-00805f9b34fb
      charac - start: 0x0077, value: 0x0078, props: 0x02, ext_props: 0x0000, uuid: 0000d402-0000-1000-8000-00805f9b34fb
      charac - start: 0x0079, value: 0x007a, props: 0x02, ext_props: 0x0000, uuid: 0000d401-0000-1000-8000-00805f9b34fb

service - start: 0x007b, end: 0x0085, type: primary, uuid: 0000da00-0000-1000-8000-00805f9b34fb
      charac - start: 0x007c, value: 0x007d, props: 0x02, ext_props: 0x0000, uuid: 0000da05-0000-1000-8000-00805f9b34fb
      charac - start: 0x007e, value: 0x007f, props: 0x08, ext_props: 0x0000, uuid: 0000da04-0000-1000-8000-00805f9b34fb
      charac - start: 0x0080, value: 0x0081, props: 0x02, ext_props: 0x0000, uuid: 0000da03-0000-1000-8000-00805f9b34fb
      charac - start: 0x0082, value: 0x0083, props: 0x02, ext_props: 0x0000, uuid: 0000da02-0000-1000-8000-00805f9b34fb
      charac - start: 0x0084, value: 0x0085, props: 0x08, ext_props: 0x0000, uuid: 0000da01-0000-1000-8000-00805f9b34fb

service - start: 0x0086, end: 0x0099, type: primary, uuid: 0000d300-0000-1000-8000-00805f9b34fb
      charac - start: 0x0087, value: 0x0088, props: 0x02, ext_props: 0x0000, uuid: 0000d309-0000-1000-8000-00805f9b34fb
      charac - start: 0x0089, value: 0x008a, props: 0x08, ext_props: 0x0000, uuid: 0000d30a-0000-1000-8000-00805f9b34fb
      charac - start: 0x008b, value: 0x008c, props: 0x02, ext_props: 0x0000, uuid: 0000d308-0000-1000-8000-00805f9b34fb
      charac - start: 0x008d, value: 0x008e, props: 0x0a, ext_props: 0x0000, uuid: 0000d307-0000-1000-8000-00805f9b34fb
      charac - start: 0x008f, value: 0x0090, props: 0x02, ext_props: 0x0000, uuid: 0000d306-0000-1000-8000-00805f9b34fb
      charac - start: 0x0091, value: 0x0092, props: 0x02, ext_props: 0x0000, uuid: 0000d305-0000-1000-8000-00805f9b34fb
      charac - start: 0x0093, value: 0x0094, props: 0x02, ext_props: 0x0000, uuid: 0000d304-0000-1000-8000-00805f9b34fb
      charac - start: 0x0095, value: 0x0096, props: 0x08, ext_props: 0x0000, uuid: 0000d302-0000-1000-8000-00805f9b34fb
      charac - start: 0x0097, value: 0x0098, props: 0x12, ext_props: 0x0000, uuid: 0000d301-0000-1000-8000-00805f9b34fb
          descr - handle: 0x0099, uuid: 00002902-0000-1000-8000-00805f9b34fb

service - start: 0x009a, end: 0x00b1, type: primary, uuid: 0000d200-0000-1000-8000-00805f9b34fb
      charac - start: 0x009b, value: 0x009c, props: 0x02, ext_props: 0x0000, uuid: 0000d211-0000-1000-8000-00805f9b34fb
      charac - start: 0x009d, value: 0x009e, props: 0x08, ext_props: 0x0000, uuid: 0000d210-0000-1000-8000-00805f9b34fb
      charac - start: 0x009f, value: 0x00a0, props: 0x12, ext_props: 0x0000, uuid: 0000d209-0000-1000-8000-00805f9b34fb
          descr - handle: 0x00a1, uuid: 00002902-0000-1000-8000-00805f9b34fb
      charac - start: 0x00a2, value: 0x00a3, props: 0x02, ext_props: 0x0000, uuid: 0000d208-0000-1000-8000-00805f9b34fb
      charac - start: 0x00a4, value: 0x00a5, props: 0x08, ext_props: 0x0000, uuid: 0000d206-0000-1000-8000-00805f9b34fb
      charac - start: 0x00a6, value: 0x00a7, props: 0x08, ext_props: 0x0000, uuid: 0000d207-0000-1000-8000-00805f9b34fb
      charac - start: 0x00a8, value: 0x00a9, props: 0x08, ext_props: 0x0000, uuid: 0000d205-0000-1000-8000-00805f9b34fb
      charac - start: 0x00aa, value: 0x00ab, props: 0x02, ext_props: 0x0000, uuid: 0000d204-0000-1000-8000-00805f9b34fb
      charac - start: 0x00ac, value: 0x00ad, props: 0x02, ext_props: 0x0000, uuid: 0000d203-0000-1000-8000-00805f9b34fb
      charac - start: 0x00ae, value: 0x00af, props: 0x02, ext_props: 0x0000, uuid: 0000d202-0000-1000-8000-00805f9b34fb
      charac - start: 0x00b0, value: 0x00b1, props: 0x02, ext_props: 0x0000, uuid: 0000d201-0000-1000-8000-00805f9b34fb

service - start: 0x00b2, end: 0x00ba, type: primary, uuid: 0000d800-0000-1000-8000-00805f9b34fb
      charac - start: 0x00b3, value: 0x00b4, props: 0x02, ext_props: 0x0000, uuid: 0000d805-0000-1000-8000-00805f9b34fb
      charac - start: 0x00b5, value: 0x00b6, props: 0x08, ext_props: 0x0000, uuid: 0000d804-0000-1000-8000-00805f9b34fb
      charac - start: 0x00b7, value: 0x00b8, props: 0x02, ext_props: 0x0000, uuid: 0000d803-0000-1000-8000-00805f9b34fb
      charac - start: 0x00b9, value: 0x00ba, props: 0x08, ext_props: 0x0000, uuid: 0000d801-0000-1000-8000-00805f9b34fb

uuid 2B29 and 2B2A are present in the service discovery... uuid 2B29 和 2B2A 存在于服务发现中...

it is funny also because the demon bluetoothd is crashing when I am using btgatt-client from 5.54.这也很有趣,因为当我从 5.54 使用 btgatt-client 时,恶魔蓝牙正在崩溃。 I have to run the test with 5.50 gatt client...我必须使用 5.50 gatt 客户端运行测试...

EDIT1:编辑1:

I was able to reproduce the issue on a customer device.我能够在客户设备上重现该问题。 I tried to disable the cache by putting in the bluetoothd conf under /etc/bluetooth/main.conf :我试图通过在/etc/bluetooth/main.conf下放入 bluetoothd conf 来禁用缓存:

[GATT]
Cache = no

The issue is always present after this change.此更改后问题始终存在。 By the way I was trying to remove the cache by deleting the directory in /var/lib/bluetooth .顺便说一句,我试图通过删除/var/lib/bluetooth中的目录来删除缓存。 But in fact I have not this directory in my case.但实际上我没有这个目录。 Indeed all our main rootfs is read only on our device.事实上,我们所有的主要 rootfs 在我们的设备上都是只读的。 So bluetoothd is not able to create the directory.. So perhaps that this is not a real cache issue?所以蓝牙无法创建目录。所以也许这不是一个真正的缓存问题?

Explanation解释

There's an issue with some versions of Android when the bonding (with LE) operation occurs.发生绑定(使用 LE)操作时,某些版本的 Android 存在问题。 In Nordic's source code, there's indeed a comment ( source ) that confirms it:在 Nordic 的源代码中,确实有一条注释( source )证实了这一点:

// 1. On devices running Android 4.3-5.x, 8.x and 9.0 the Service Changed
//    characteristic needs to be enabled by the app (for bonded devices).
//    The request will be ignored if there is no Service Changed characteristic.
// This "fix" broke this in Android 8:
// https://android-review.googlesource.com/c/platform/system/bt/+/239970
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
    || Build.VERSION.SDK_INT == Build.VERSION_CODES.O
    || Build.VERSION.SDK_INT == Build.VERSION_CODES.O_MR1
    || Build.VERSION.SDK_INT == Build.VERSION_CODES.P)
        initQueue.addFirst(Request.newEnableServiceChangedIndicationsRequest());

Basically, there's a characteristic in charge of indicating whether or not the cached attributes should be updated when there's been a change in services.基本上,有一个特性负责指示当服务发生变化时是否应该更新缓存的属性。 And it's been broken at some point.它在某个时候被打破了。

Solution解决方案

The comment from Nordic is quite self-explanatory: you need to enable the Service Changed manually. Nordic 的评论非常不言自明:您需要手动启用 Service Changed。 Here's how they do it: part 1 and part 2 .他们是这样做的: 第 1 部分和第 2 部分 And here's a concise Kotlin version:这是一个简洁的 Kotlin 版本:

private val GENERIC_ATTRIBUTE_SERVICE =
    UUID.fromString("00001801-0000-1000-8000-00805f9b34fb")
private val SERVICE_CHANGED_CHARACTERISTIC =
    UUID.fromString("00002a05-0000-1000-8000-00805f9b34fb")
private val CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID =
    UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")

private fun enableServiceChanged(gatt: BluetoothGatt) {
    val service = gatt.getService(GENERIC_ATTRIBUTE_SERVICE) ?: return
    val characteristic = service.getCharacteristic(SERVICE_CHANGED_CHARACTERISTIC)
        ?: return
    
    val properties = characteristic.properties
    if (properties and BluetoothGattCharacteristic.PROPERTY_INDICATE === 0)
        return
    
    gatt.setCharacteristicNotification(characteristic, true)
    characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID)?.apply {
        value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
        internalWriteDescriptorWorkaround(gatt, this)
    }
}

private fun internalWriteDescriptorWorkaround(
        gatt: BluetoothGatt,
        descriptor: BluetoothGattDescriptor
) {
        with (descriptor.characteristic) {
            val originalWriteType = writeType
            writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
            gatt.writeDescriptor(descriptor)
            writeType = originalWriteType
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM