noble icon indicating copy to clipboard operation
noble copied to clipboard

Help - Subscribe to a Characteristic with indicate properties

Open mathbozzi opened this issue 4 years ago • 3 comments

I'm trying to read from my Blood Pressure monitor. The service is 1810 and the characteristic is 2a35, but the buffer is empty. The properties is: [ 'indicate' ].

My code:

const noble = require('@abandonware/noble')

 noble.on('stateChange', async (state) => {
    if (state === 'poweredOn') {
        await noble.startScanningAsync([], false);
    }else {
        noble.stopScanningAsync();
    }
 });


noble.on('discover', async (peripheral) => {
    console.log(peripheral.id)
    if (peripheral.id === "ec21e54394ca") peripheral.connectAsync(() => {


        peripheral.discoverServices(['1810'],(e, services) => {
            const bp = services[0];
            console.log({ bp })
            bp.discoverCharacteristics(['2a35'], (e, characteristics) => {   
                const chara = characteristics[0]
                // chara.notify(true,async function(error){});
                chara.subscribeAsync();
                // chara.subscribe();
                console.log("here");
                console.log(chara);

                // chara.once('read', (data) => {
                //     console.log(data);
                // })
                chara.once('data', async function(data,isNotification){
                    console.log('hello',data, isNotification);
                })

                chara.readAsync(async (error,data)=>{
                    console.log(data);
                })

            })
        })

    })
})


out:

ec21e54394ca    
{
  bp: Service {
    _noble: Noble {
      initialized: true,
      address: '00:1a:7d:da:71:13',
      _state: 'poweredOn',
      _bindings: [NobleBindings],
      _peripherals: [Object],
      _services: [Object],
      _characteristics: [Object],
      _descriptors: [Object],
      _discoveredPeripheralUUids: [Array],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _allowDuplicates: false
    },
    _peripheralId: 'ec21e54394ca',
    uuid: '1810',
    name: 'Blood Pressure',
    type: 'org.bluetooth.service.blood_pressuer',
    includedServiceUuids: null,
    characteristics: null
  }
}
here
Characteristic {
  _noble: Noble {
    initialized: true,
    address: '00:1a:7d:da:71:13',
    _state: 'poweredOn',
    _bindings: NobleBindings {
      _state: 'poweredOn',
      _addresses: [Object],
      _addresseTypes: [Object],
      _connectable: [Object],
      _pendingConnectionUuid: null,
      _connectionQueue: [],
      _handles: [Object],
      _gatts: [Object],
      _aclStreams: [Object],
      _signalings: [Object],
      _hci: [Hci],
      _gap: [Gap],
      _events: [Object: null prototype],
      _eventsCount: 24,
      onSigIntBinded: [Function: bound ],
      _scanServiceUuids: []
    },
    _peripherals: { ec21e54394ca: [Peripheral] },
    _services: { ec21e54394ca: [Object] },
    _characteristics: { ec21e54394ca: [Object] },
    _descriptors: { ec21e54394ca: [Object] },
    _discoveredPeripheralUUids: [ 'ec21e54394ca' ],
    _events: [Object: null prototype] {
      warning: [Function (anonymous)],
      newListener: [Function (anonymous)],
      stateChange: [AsyncFunction (anonymous)],
      discover: [AsyncFunction (anonymous)]
    },
    _eventsCount: 4,
    _allowDuplicates: false
  },
  _peripheralId: 'ec21e54394ca',
  _serviceUuid: '1810',
  uuid: '2a35',
  name: 'Blood Pressure Measurement',
  type: 'org.bluetooth.characteristic.blood_pressure_measurement',
  properties: [ 'indicate' ],                 /////////// INDICATE
  descriptors: null,
  _events: [Object: null prototype] {
    notify: [Function: bound onceWrapper] { listener: [Function (anonymous)] }
  },
  _eventsCount: 1
}
hello <Buffer > false                       /////////////BUFFER EMPTY
<Buffer >                                        //////////// BUFFER EMPTY

Buffer is empty,it means that i'm not subscribed? ..

mathbozzi avatar Feb 18 '21 15:02 mathbozzi

You can print out the descriptor value. Usually when you subscribe the value changes from 0 to 1 or something else. Notification won't work if the descriptor value stays 0 after subscription.

Btw I have been trying on Similar device since last week without any luck. I having the same issue and checked everything possible. The device which I am using requires pairing and this is the first time I use indicate which could be the issue. I am going to test indicate on an ESP32 and let you know.

You can try to test your device using node-ble module which uses dbus.

Let me know if you are able to figure it out.

Thanks, R

rabee05 avatar Feb 20 '21 07:02 rabee05

You can print out the descriptor value. Usually when you subscribe the value changes from 0 to 1 or something else. Notification won't work if the descriptor value stays 0 after subscription.

Btw I have been trying on Similar device since last week without any luck. I having the same issue and checked everything possible. The device which I am using requires pairing and this is the first time I use indicate which could be the issue. I am going to test indicate on an ESP32 and let you know.

You can try to test your device using node-ble module which uses dbus.

Let me know if you are able to figure it out.

Thanks, R

New code add descriptor


1. const noble = require('@abandonware/noble')
2. 
3. noble.on('stateChange', async (state) => {
4.     if (state === 'poweredOn') {
5.         await noble.startScanningAsync([], false);
6.     } else {
7.         noble.stopScanningAsync();
8.     }
9. });
10. 
11. 
12. noble.on('discover', async (peripheral) => {
13.     console.log(peripheral.id)
14.     if (peripheral.id === "ec21e54394ca") peripheral.connectAsync(() => {
15. 
16. 
17.         peripheral.discoverServices(['1810'], async (e, services) => {
18.             const bp = services[0];
19.             console.log({ bp })
20.             bp.discoverCharacteristics(['2a35'], async (e, characteristics) => {
21.                 const chara = characteristics[0]
22.                 // chara.notify(true,async function(error){});
23.                 // chara.subscribeAsync();                              **// i have commented to work**
24.                 // chara.subscribe();
25.                 console.log("here");
26.                 console.log(chara);
27. 
28.                //**added descriptors service**
29.                 const descriptors = await chara.discoverDescriptorsAsync();
30.                 const userDescriptionDescriptor = descriptors.find((descriptor) => descriptor.uuid === '2902');
31.                 console.log(userDescriptionDescriptor)         
32. 
33.                 if (userDescriptionDescriptor) {
34. 
35.                     userDescriptionDescriptor.once('valueRead', async (data) => {
36.                         console.log('helloo2', data)             //**BUFFER**
37.                     })
38. 
39.                     await userDescriptionDescriptor.readValueAsync();
40.                 }
41.                 //**finish descriptors**
42. 
43.                 // chara.once('read', (data) => {
44.                 //     console.log(data);
45.                 // })
46.                 chara.once('data', async function (data, isNotification) {
47.                     console.log('hello', data, isNotification);
48.                 })
49. 
50.                 chara.readAsync(async (error, data) => {
51.                     console.log(data);
52.                 })
53. 
54.             })
55.         })
56. 
57.     })
58. })


out:

Descriptor {
  _noble: Noble {
    initialized: true,
    address: '00:1a:7d:da:71:13',
    _state: 'poweredOn',
    _bindings: NobleBindings {
      _state: 'poweredOn',
      _addresses: [Object],
      _addresseTypes: [Object],
      _connectable: [Object],
      _pendingConnectionUuid: null,
      _connectionQueue: [],
      _handles: [Object],
      _gatts: [Object],
      _aclStreams: [Object],
      _signalings: [Object],
      _hci: [Hci],
      _gap: [Gap],
      _events: [Object: null prototype],
      _eventsCount: 24,
      onSigIntBinded: [Function: bound ],
      _scanServiceUuids: []
    },
    _peripherals: { ec21e54394ca: [Peripheral] },
    _services: { ec21e54394ca: [Object] },
    _characteristics: { ec21e54394ca: [Object] },
    _descriptors: { ec21e54394ca: [Object] },
    _discoveredPeripheralUUids: [ 'ec21e54394ca' ],
    _events: [Object: null prototype] {
      warning: [Function (anonymous)],
      newListener: [Function (anonymous)],
      stateChange: [AsyncFunction (anonymous)],
      discover: [AsyncFunction (anonymous)]
    },
    _eventsCount: 4,
    _allowDuplicates: false
  },
  _peripheralId: 'ec21e54394ca',
  _serviceUuid: '1810',
  _characteristicUuid: '2a35',
  uuid: '2902',
  name: 'Client Characteristic Configuration',
  type: 'org.bluetooth.descriptor.gatt.client_characteristic_configuration'
}
helloo2 <Buffer 00 00>              //descriptor buffer 
hello <Buffer > false                  //characteristc buffer (empty)
<Buffer >                                  //characteristc buffer (empty)

If i uncomment the line 23, i don't get descriptors values. How will i know if descriptor value change after i subscribe to characteristc? Then, the code with the line 23 commented works and descriptor buffer is 00 00. It means that if i don't subscribe to charac, is the initial descriptor value 00? On positive case, how i change the descriptor value to 01?
tks

mathbozzi avatar Feb 20 '21 14:02 mathbozzi

Did you find out a fix?

rabee05 avatar Jul 04 '21 14:07 rabee05