NimBLE-Arduino
NimBLE-Arduino copied to clipboard
Multiple Characteristics with same UUID
Hi, some devices have multiple characteristics with same UUID under one service. Here is one example of an HID device having multiple characteristics: 2a4d for service 1812
Scanning for 50s...
Discovering profile...
Service: 1800 Generic Access, Handle (0x01)
Characteristic: 2a00 Device Name, Property: 0x02 (R), Handle(0x02), VHandle(0x03)
Value 56522d5041524b | "VR-PARK"
Characteristic: 2a01 Appearance, Property: 0x02 (R), Handle(0x04), VHandle(0x05)
Value c103 | "\xc1\x03"
Characteristic: 2a04 Peripheral Preferred Connection Parameters, Property: 0x02 (R), Handle(0x06), VHandle(0x07)
Value 060009001e005802 | "\x06\x00\t\x00\x1e\x00X\x02"
Service: 1801 Generic Attribute, Handle (0x08)
Characteristic: 2a05 Service Changed, Property: 0x20 (I), Handle(0x09), VHandle(0x0A)
Descriptor: 2902 Client Characteristic Configuration, Handle(0x0b)
Value 0000 | "\x00\x00"
Service: 180a Device Information, Handle (0x0C)
Characteristic: 2a29 Manufacturer Name String, Property: 0x02 (R), Handle(0x0D), VHandle(0x0E)
Value 7a68756861695f6a69656c69 | "zhuhai_jieli"
Characteristic: 2a24 Model Number String, Property: 0x02 (R), Handle(0x0F), VHandle(0x10)
Value 6869645f6d6f757365 | "hid_mouse"
Characteristic: 2a25 Serial Number String, Property: 0x02 (R), Handle(0x11), VHandle(0x12)
Value 303030303030 | "000000"
Characteristic: 2a27 Hardware Revision String, Property: 0x02 (R), Handle(0x13), VHandle(0x14)
Value 302e302e31 | "0.0.1"
Characteristic: 2a26 Firmware Revision String, Property: 0x02 (R), Handle(0x15), VHandle(0x16)
Value 302e302e31 | "0.0.1"
Characteristic: 2a28 Software Revision String, Property: 0x02 (R), Handle(0x17), VHandle(0x18)
Value 302e302e31 | "0.0.1"
Characteristic: 2a23 System ID, Property: 0x02 (R), Handle(0x19), VHandle(0x1A)
Value 0000000000000000 | "\x00\x00\x00\x00\x00\x00\x00\x00"
Characteristic: 2a2a IEEE 11073-20601 Regulatory Certification Data List, Property: 0x02 (R), Handle(0x1B), VHandle(0x1C)
Value | ""
Characteristic: 2a50 PnP ID, Property: 0x02 (R), Handle(0x1D), VHandle(0x1E)
Failed to read characteristic: insufficient authentication
Service: 180f Battery Service, Handle (0x1F)
Characteristic: 2a19 Battery Level, Property: 0x12 (NR), Handle(0x20), VHandle(0x21)
Value 33 | "3"
Descriptor: 2902 Client Characteristic Configuration, Handle(0x22)
Value 0000 | "\x00\x00"
Service: 1812 Human Interface Device, Handle (0x23)
Characteristic: 2a4e Protocol Mode, Property: 0x06 (Rw), Handle(0x24), VHandle(0x25)
Value 01 | "\x01"
Characteristic: 2a4d Report, Property: 0x1A (RWN), Handle(0x26), VHandle(0x27)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x28)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x29)
Value 0101 | "\x01\x01"
Characteristic: 2a4d Report, Property: 0x1A (NRW), Handle(0x2A), VHandle(0x2B)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x2c)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x2d)
Value 0201 | "\x02\x01"
Characteristic: 2a4d Report, Property: 0x0E (RwW), Handle(0x2E), VHandle(0x2F)
Value | ""
Descriptor: 2908 Report Reference, Handle(0x30)
Value 0102 | "\x01\x02"
Characteristic: 2a4d Report, Property: 0x1A (RWN), Handle(0x31), VHandle(0x32)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x33)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x34)
Value 0301 | "\x03\x01"
Characteristic: 2a4d Report, Property: 0x1A (RWN), Handle(0x35), VHandle(0x36)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x37)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x38)
Value 0401 | "\x04\x01"
Characteristic: 2a4d Report, Property: 0x1A (RWN), Handle(0x39), VHandle(0x3A)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x3b)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x3c)
Value 0501 | "\x05\x01"
Characteristic: 2a4d Report, Property: 0x1A (NRW), Handle(0x3D), VHandle(0x3E)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x3f)
Value 0000 | "\x00\x00"
Descriptor: 2908 Report Reference, Handle(0x40)
Value 0601 | "\x06\x01"
Characteristic: 2a4b Report Map, Property: 0x02 (R), Handle(0x41), VHandle(0x42)
Value 05010902a10185020901a10005091901290515002501 | "\x05\x01\t\x02\xa1\x01\x85\x02\t\x01\xa1\x00\x05\t\x19\x01)\x05\x15\x00%\x01"
Characteristic: 2a33 Boot Mouse Input Report, Property: 0x1A (RWN), Handle(0x43), VHandle(0x44)
Value | ""
Descriptor: 2902 Client Characteristic Configuration, Handle(0x45)
Value | ""
Characteristic: 2a4a HID Information, Property: 0x02 (R), Handle(0x46), VHandle(0x47)
Value 01010003 | "\x01\x01\x00\x03"
Characteristic: 2a4c HID Control Point, Property: 0x04 (w), Handle(0x48), VHandle(0x49)
Service: ae40 , Handle (0x4A)
Characteristic: ae41 , Property: 0x04 (w), Handle(0x4B), VHandle(0x4C)
Characteristic: ae42 , Property: 0x10 (N), Handle(0x4D), VHandle(0x4E)
Descriptor: 2902 Client Characteristic Configuration, Handle(0x4f)
Value 0000 | "\x00\x00"
The code for getCharacteristic only returns the first found one.
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) {
NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
for(auto &it: m_characteristicVector) {
if(it->getUUID() == uuid) {
NIMBLE_LOGD(LOG_TAG, "<< getCharacteristic: found the characteristic with uuid: %s", uuid.toString().c_str());
return it;
}
}
Are there any ideas and thoughts about this?
I have started working on a solution for this. It adds an instance number parameter to select from multiple attributes with the same UUID. The branch is here https://github.com/h2zero/NimBLE-Arduino/tree/remote-attr-index if you would like to test it.
I had a look at this. Very nice. I got the idea of having inst as the enumerator on "same uuid" services and characteristics. I will play around with this. Thank you!
@mkohns Were you able to test this? Does it work for you?
I have just run into the same getCharacteristic problem with a HID device -- returning just the "first" characteristic is not enough. Took me ages to figure out :-)
My fix was to instead call getCharacteristics and subscribe to each returned characteristic individually. Incidentally I eventually found somebody else with this problem who documented it well, albeit in Chinese, so you might like to use Google Translate.
PS: I am using master branch because I was getting unexplainable crashes on 1.4. Shrug.
@mkohns Any feedback on this? Did the changes in that branch work for you?