don/cordova-plugin-ble-central

startNotification sometimes throws Peripheral not connected or code 133

fudom opened this issue · 4 comments

We use startNotification after BLE connect (incl. scan before) on app start. It works. But sometimes it fails with error:

Peripheral {id} is not connected.

or

Write descriptor failed: 133

Tested on Android 8.1 and other versions.

Error 133 (0x85) is GATT_ERROR. But the reason or source is not clear. Any experience with that?

@fudom perhaps see if the summary from here has any hints. Specifically, I'd recommend either:

  1. Use autoConnect and don't explicitly scan (i.e., let the OS schedule this itself)
  2. Explicitly scan and then use connect
  3. (Maybe) for a non-bonded device, it's safe to just use connect without an explicit scan (to be confirmed)

Thanks for the advice. We always need to scan before connect. Otherwise, some information are missing (e.g. name) or connection will fail. I love Bluetooth/BLE on Android and its quirks. ;-) Anyway...

Btw. another error I get is Failed to set client characteristic notification for {uuid}...

It would be great if we got a success callback upon successful subscription to the notification.

I return Promise<Observable> which sould be only resolved, when the notification is actually started. But currently there is no way to find out, if a notification started successfully, if I see it correctly in the docs. The success callback is used for received data instead. Maybe a limitation of Cordova plugins to only have two callbacks?

A workaround on my side could be to wait a certain amount of time for an error. And continue (resolve/return) if timed out as "ok". One idea could be, that the first success callback is for successfully started. But other ideas are welcome.

I only want return on a working notification. I would retry the startNotification on error. Maybe with reconnect. Just to avoid an invalid state.

Btw. I use the awesome-cordova-plugins wrapper for Ionic/Angular.

It would be great if we got a success callback upon successful subscription to the notification.

This is possible, by using await ble.withPromises.startNotification(device_id, success, failure) instead. I can't change the existing callback for fear of breaking backward compatibility, but the promise-returning version instead does exactly what you're requesting.

Ok thanks, I'll give this a try and will bypass the outdated plugin wrapper for TypeScript. I wish all Cordova plugins would provide strong types for TypeScript and use modern methods like Promises (async/await) and Observable. Then we wouldn't need wrappers. Anyway... Btw. I see some related issues:

#635 > #95 > #903

This includes the option { emitOnRegistered: true }. I haven't checked the code yet, but If it works (I think I try the promise solution), I can try again to start the notification if it fails. Maybe with reconnect. I would prefer a better solution than trial and error. Maybe with a ready state. Anway, I think it's better to do this automatically in background than to fail in front of users.

I'm closing the issue for now, although I can't reproduce the error and so can't say for sure if it works. But it looks like it's exactly what I wanted. Getting the status of startNotification. Thanks again.