sblendid icon indicating copy to clipboard operation
sblendid copied to clipboard

Force Subscribe to Indication

Open progerzua opened this issue 4 years ago • 7 comments

Description

I'm working with BLE device, which have Notification and Indication on the same characteristic. By default, noble/other frameworks subscribes on Notification, and thus I`m getting always only the first packet, and never got others.

Is it possible to force use Indication instead of Notification in this library? Havent tried it yet, but I see you active developer there, so it would be great if youll explain this for me.

I`m porting Android app to Linux, and on Android you can choose between Indication and Notification.

progerzua avatar Sep 19 '19 13:09 progerzua

Hey @progerzua

Do I understand you correctly that you want to automatically subscribe to notifications for all characteristics on a peripheral / service that allow notifications once you connect to it?

If so, right now that is not possible, you would have to do it more explicitly. The way I thought people would do it is that they would know the service uuids and characteristic uuids they want to subscribe to:

import Sblendid from "@sblendid/sblendid";

(async () => {
  const peripheral = await Sblendid.connect("My Peripheral");
  const service = await peripheral.getService("service-uuid");

  service.on("characteristic-uuid-a", value => {
    console.log("Got notification on uuid a", value)
  });

  service.on("characteristic-uuid-b", value => {
    console.log("Got notification on uuid b", value)
  });
})();

If you automatically want to subscribe to all notifications on all services you would have to do this:

import Sblendid from "@sblendid/sblendid";

function onNotification(uuid, value) {
  console.log("Got notification on", uuid, value);
}

(async () => {
  const peripheral = await Sblendid.connect("My Peripheral");
  const services = await peripheral.getServices();

  for (const service of services) {
    const characteristics = await service.getCharacteristics();

    for(const characteristic of characteristics) {
      if (characteristic.properties.notify) {
        await characteristic.on("notify", value => onNotification(characteristic.uuid, value))
      }
    }
  }
})();

LukasBombach avatar Sep 19 '19 15:09 LukasBombach

I want to highlight, that I didn`t used your library yet.

I know service uuid, and I want to subscribe to it as for Indication, not as for Notification.

Notification - is when you receive information, without confirmation. Indication - when you send confirmation, when you got packet. If you haven`t sent confirmation(ACK) packet, it will not send other packets.

My device on one characteristic have both Indication and Notification. In noble/bleak libraries I have only 'subscribe method', and it automatically subscribes for Notification only, while my device expects Indication.

That leads to problem, that device always resends first packet, because thinks that I didn`t got this.

Does your library have low-level control, which will allow me to use Indication strategy while subscribing? Its specific and problem only this certain device and probably not usual situation.

In android you have special flag to do this https://stackoverflow.com/questions/31030718/handling-indications-instead-of-notifications-in-android-ble

progerzua avatar Sep 19 '19 15:09 progerzua

@progerzua I am doing some research right now, but I cannot be absolutely sure.

For macOS support, I am using a compiled binary of this library: https://github.com/Timeular/noble-mac

This library is a native node addon that provides node js bindings for Apple's CoreBluetooth API, i.e., whenever I am using a Bluetooth function in my library I am actually calling Apple's CoreBluetooth API.

So when I notify for a characteristic, I am actually calling CBPeripheral.setNotifyValue and I am not entirely sure if that handles indications. I could not find much yet on indications.

The same goes for Windows, I am using this: https://github.com/Timeular/noble-winrt which uses Microsoft's WinRT / UWP Api, I would also have to dig into the source code to give you an answer.

For Linux — I am not there yet, I still need to find or write an adapter for that, but I will probably end up using Bluez via DBUS.

So to make a long story short—I don't know yet. I will have to check when I am done with the basic implementation. I will keep this issue open to at least give you an answer (or you can try it out then) and maybe it would be possible to make sure my adapters send indications.

LukasBombach avatar Sep 19 '19 18:09 LukasBombach

@LukasBombach thank you very much for the answer!

I`m interested mostly in Linux, and I know, that almost everything is possible in Linux =).

Indications work okay in case if you have ONLY Indication. But one of my devices has one characteristic, that has both Indication and Notification and its a problem. Probably most of the devices don`t act like that.

Sorry for confusing you, probably I'm solving a very rare problem) Just I want to know, is it possible at all, because there is a chance, that it's impossible. I`m not very competent in js and ble things, and trying to figure out things on my own.

I dig up a little bit and looks like there is no such control if you`ll use Bluez via DBUS(there are just 'startNotify' method). Noble uses hci via socket-connection, so I hope its more hackable.

I`ll try to play with variables useNotify, useIndicate in deep sources of noble and debug all this thing https://github.com/noble/noble/blob/c4cd18a7a429bb832f6c4ca793be3faf9af884e9/lib/hci-socket/gatt.js#L617 . (honestly have no idea how this emitters work and how this code works in deep)

progerzua avatar Sep 19 '19 19:09 progerzua

Ok, I will still keep this open as I aim to make this library somewhat complete. Unfortunately this won't have the highes priority (as I need to get things to work completely and also bug-free first).

LukasBombach avatar Sep 19 '19 20:09 LukasBombach

For anyone, who will come here from Google: its definitely possible in noble. Maybe I`ll write some workaround, but to check idea - you can just add little changes in this snippet. If replace all 'useNotify' with 'false' in all if statements, it will use Indications and work properly.

Its possible, because noble works with bluetooth on level of sockets, which is low-level and allows to make this dirty hack.

@LukasBombach you can close this issue.

progerzua avatar Sep 23 '19 08:09 progerzua

@progerzua not gonna close it though because it needs to work in sblendid too :)

Thanks for the update

LukasBombach avatar Sep 23 '19 08:09 LukasBombach