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?