-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to save service discovery during bonding makes it impossible to get data from some bonded devices on reconnect #903
Comments
Ah, yeah that's a tricky issue. I haven't had to deal with a device that assumes everything is cached and sends notifications / events immediately after connection like that! I'm thinking there will be more needed at the C level to support this, in particular the exposing CCCD for caching will certainly be needed to maintain the subscriptions to characteristics. I started work on that a few years ago but didn't have the resources to finalise and test it. Oh wait, CCCD is more about the device / server end isn't it, you're referring more to the client / central side wanting to cache the characteristics. I'm really not as familar with that side, I've only developed devices myself. I'm not sure if the central side stack needs to be informed about the characterisics to set up buffers or anything? Maybe if it's just characteristic identifiers then exposing them to be saved / resored in the json file would be enough; certainly that makes sense to start with to see if it works? |
I can't logon to github from this device so I have to respond this way.
Yes I am thinking about bonded reconnects. A client needs to be able to read/write/enable/disable characteristics/descriptors without having to do service discovery (which is painfully slow). A server that has bonded to a client that has enabled the 0x2902 descriptor shall not have to re-enable the descriptor in order to receive notifications/indications on a reconnect. So this code
# Write to the Client Characteristic Configuration to subscribe to
# notify/indications for this characteristic.
async def subscribe(self, notify: bool=True, indicate: bool=False):
# Ensure that the generated notifications are dispatched in case the app
# hasn't awaited on notified/indicated yet.
self._register_with_connection()
if cccd := await self.descriptor(bluetooth.UUID(_CCCD_UUID)):
await cccd.write(struct.pack("<H", _CCCD_NOTIFY * notify + _CCCD_INDICATE * indicate))
else:
raise ValueError("CCCD not found")
would only need to register for the notifications/indications on a bonded reconnect.
If one can create the ClientService, ClientCharacteristic, and ClientDescriptor objects from the saved handles and properties would this be sufficient to
write and read a characteristic/descriptor and to receive indications/notifications ... without doing any service discovery process. I think that if one can do this
re-creation, the rest of the objects can be completed ... but I do not know, especially objects like the ClientDiscovery (only necessary for service discovery?).
I am actually having a lot of difficulty with bonded health devices on reconnects because of the necessity of redoing service discovery and its slowness.
Some thermometers allow you to keep taking measurements but you will lose the first as they have evented before one can subscribe. This is NOT
very user friendly to an elderly clientelle!
Looking at the btstack C code, this is the information I need to get and cache
typedef struct {
uint16_t start_group_handle;
uint16_t end_group_handle;
uint16_t uuid16;
uint8_t uuid128[16];
} gatt_client_service_t;
typedef struct {
uint16_t start_handle;
uint16_t value_handle;
uint16_t end_handle;
uint16_t properties;
uint16_t uuid16;
uint8_t uuid128[16];
} gatt_client_characteristic_t;
typedef struct {
uint16_t handle;
uint16_t uuid16;
uint8_t uuid128[16];
} gatt_client_characteristic_descriptor_t;
Brian
…________________________________
From: Andrew Leech ***@***.***>
Sent: Monday, July 22, 2024 7:50 PM
To: micropython/micropython-lib ***@***.***>
Cc: Brian Reinhold ***@***.***>; Author ***@***.***>
Subject: Re: [micropython/micropython-lib] Unable to save service discovery during bonding makes it impossible to get data from some bonded devices on reconnect (Issue #903)
Ah, yeah that's a tricky issue. I haven't had to deal with a device that assumes everything is cached and sends notifications / events immediately after connection like that!
I'm thinking there will be more needed at the C level to support this, in particular the exposing CCCD for caching will certainly be needed to maintain the subscriptions to characteristics. I started work on that a few years ago but didn't have the resources to finalise and test it.
Oh wait, CCCD is more about the device / server end isn't it, you're referring more to the client / central side wanting to cache the characteristics. I'm really not as familar with that side, I've only developed devices myself.
I'm not sure if the central side stack needs to be informed about the characterisics to set up buffers or anything? Maybe if it's just characteristic identifiers then exposing them to be saved / resored in the json file would be enough; certainly that makes sense to start with to see if it works?
—
Reply to this email directly, view it on GitHub<#903 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AJMDO647W45W6ZCKHQBALXTZNWLF3AVCNFSM6AAAAABLJH4YBGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBTHE4TQNBXGI>.
You are receiving this because you authored the thread.
|
Here is what I get from service discovery (pulse oximeter) printing out the handles. Descriptor discovery is not done so I dont have those values. I suppose I could catch them when I subscribe. I find that enabling descriptors every connection is not an issue as some devices misbehave and do not persist their enabled states even when bonded (which is a violation), but discovering the descriptor each time before enabling is a hinder and can be an issue.
2024-07-23 11:52:49 INFO bt_async_central: LNI: ================ Service discovery results:
2024-07-23 11:52:49 INFO bt_async_central: LNI: Service: UUID('46a970e0-0d5f-11e2-8b5e-0002a5d5c51b') start handle: 31 end handle: 43
2024-07-23 11:52:49 INFO bt_async_central: LNI: Characteristic: UUID('0aad7ea0-0d60-11e2-8e3c-0002a5d5c51b') value handle: 33 end handle: 34
2024-07-23 11:52:49 INFO bt_async_central: LNI: Characteristic: UUID('34e27863-76ff-4f8e-96f1-9e3993aa6199') value handle: 36 end handle: 37
2024-07-23 11:52:49 INFO bt_async_central: LNI: Characteristic: UUID('1447af80-0d60-11e2-88b6-0002a5d5c51b') value handle: 39 end handle: 40
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID('ec0a8f24-4d24-11e7-b114-b2f933d5fe66') value handle: 42 end handle: 43
2024-07-23 11:52:50 INFO bt_async_central: LNI: Service: UUID(0x180a) start handle: 6 end handle: 30
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a24) value handle: 11 end handle: 12
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a29) value handle: 8 end handle: 9
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a26) value handle: 20 end handle: 21
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a28) value handle: 17 end handle: 18
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a25) value handle: 14 end handle: 15
2024-07-23 11:52:50 INFO bt_async_central: LNI: Characteristic: UUID(0x2a23) value handle: 26 end handle: 27
2024-07-23 11:52:51 INFO bt_async_central: LNI: Characteristic: UUID(0x2a27) value handle: 23 end handle: 24
2024-07-23 11:52:51 INFO bt_async_central: LNI: Characteristic: UUID(0x2a2a) value handle: 29 end handle: 30
2024-07-23 11:52:51 INFO bt_async_central: LNI: Service: UUID(0x1800) start handle: 1 end handle: 5
2024-07-23 11:52:51 INFO bt_async_central: LNI: Characteristic: UUID(0x2a01) value handle: 5 end handle: 7
2024-07-23 11:52:51 INFO bt_async_central: LNI: Characteristic: UUID(0x2a00) value handle: 3 end handle: 5
2024-07-23 11:52:51 INFO bt_async_central: LNI: Service: UUID(0x180f) start handle: 68 end handle: 65535
2024-07-23 11:52:51 INFO bt_async_central: LNI: Characteristic: UUID(0x2a19) value handle: 70 end handle: 65535
2024-07-23 11:52:51 INFO bt_async_central: LNI: Service: UUID(0x1805) start handle: 60 end handle: 67
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a2b) value handle: 62 end handle: 64
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a14) value handle: 66 end handle: 67
2024-07-23 11:52:52 INFO bt_async_central: LNI: Service: UUID(0x1822) start handle: 44 end handle: 59
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a5f) value handle: 50 end handle: 52
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a5e) value handle: 46 end handle: 48
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a60) value handle: 54 end handle: 55
2024-07-23 11:52:52 INFO bt_async_central: LNI: Characteristic: UUID(0x2a52) value handle: 57 end handle: 59
Brian
…________________________________
From: Andrew Leech ***@***.***>
Sent: Monday, July 22, 2024 7:50 PM
To: micropython/micropython-lib ***@***.***>
Cc: Brian Reinhold ***@***.***>; Author ***@***.***>
Subject: Re: [micropython/micropython-lib] Unable to save service discovery during bonding makes it impossible to get data from some bonded devices on reconnect (Issue #903)
Ah, yeah that's a tricky issue. I haven't had to deal with a device that assumes everything is cached and sends notifications / events immediately after connection like that!
I'm thinking there will be more needed at the C level to support this, in particular the exposing CCCD for caching will certainly be needed to maintain the subscriptions to characteristics. I started work on that a few years ago but didn't have the resources to finalise and test it.
Oh wait, CCCD is more about the device / server end isn't it, you're referring more to the client / central side wanting to cache the characteristics. I'm really not as familar with that side, I've only developed devices myself.
I'm not sure if the central side stack needs to be informed about the characterisics to set up buffers or anything? Maybe if it's just characteristic identifiers then exposing them to be saved / resored in the json file would be enough; certainly that makes sense to start with to see if it works?
—
Reply to this email directly, view it on GitHub<#903 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AJMDO647W45W6ZCKHQBALXTZNWLF3AVCNFSM6AAAAABLJH4YBGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBTHE4TQNBXGI>.
You are receiving this because you authored the thread.
|
A BLE peripheral that bonds also assumes that the services and characteristics and descriptors discovered during the bonding connection are saved by the client such that on a reconnect, after encryption, service discovery is unnecessary and the peripheral can notify and/or indicate it's data. There are several health devices that do this.
With the aioble library, one is forced to do service discovery every connection in order to subscribe to notifications/indications. However, service discovery is painfully slow, and long before it is done the health device has already indicated/notified its data and by the time one has subscribed (if the device does not disconnect) the data has already been evented and nothing is received.
How to work around this?
Is this a possible work-a-round?
Edit the code so that the start, end, and value handles are made public instead of private
Save these handles and UUID for each service, characteristic, and descriptor discovered
Recreate the ClientService, ClientCharacteristic, and ClientDescriptor for each of the saved items (of interest)
Change the subscribe method such that it uses the saved ClientDescriptor instead of doing further discovery operations to get the Descriptor.
I do not know if that is possible as the devil is always in the details. But to those who are familiar with the inner workings of aioble, is this something one could do, or is it far more complicated that that?
The text was updated successfully, but these errors were encountered: