BLE plugin: "Read failed"


#1

Hi,
I want to read glucose measurements from a BLE-enabled glucose meter with Ionic2. For this purpose, I use the official BLE Plugin.
Scanning and connecting to a device works pretty good. The problem kicks in on reading a characteristic. I always get the following output: ## ERROR READ ##Read failed
This is my code:

// assuming there is only one device in range
BLE.scan([], 30).subscribe(
            device => {

                console.log("## DEVICE ##" + JSON.stringify(device));

                BLE.connect(device.id).subscribe(
                    data => {

                        console.log("## CONNECT ##" + JSON.stringify(data));
// service und characteristic UUID: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.glucose.xml
                        BLE.read(device.id, '1808', '2A18').then(function (data) {
                            console.log("## READ ##" + JSON.stringify(data));
                        }, function (error) {
                            console.log("## ERROR READ ##" + error);
                        });

                    },
                    error => console.log("## ERROR CONNECTING ##" + JSON.stringify(error))
                );

            },
            error => console.log("## ERROR SCANNING ##" + JSON.stringify(error))
        );

As the glucose service is pretty complex compared to the battery service, I tried to read this first. Unfortunately, my glucose meter device does not have a battery service.
Is there any bug in my code or why do I get this nothing saying error?

What I know from the source code of the BLE plugin:
The error message is set in readCharacteristic(CallbackContext callbackContext, UUID serviceUUID, UUID characteristicUUID) in Periperhal.java. This is a consequence of a failing initialization of BluetoothGatt#readCharacteristic. But this only returns true or false, so no more information there.

Another thing I noticed while using this plugin:
I always have to scan for devices first. Only after doing so I can connect (again, looking at the source code of the plugin, it is obvious as peripherals are cached and only added while scanning). To my knowledge, a huge benefit of BLE is that a peripheral does not always have to advertise but you can connect to it. So in my eyes, it would be much better to get all bonded devices at initialization time of the plugin.

I hope you can help me with this error.
Thanks in advance.


#2

ok this was my fault. I implemented the GATT in a wrong way. Now, it works.


#3

Hi,
I’d like to do something very similar. I want to read the data from a HRM service. My BLE.read does not fail but the result object doesn’t contain the expected data.

This is my code:

    connect(device) {
      BLE.connect(device).subscribe(
        peripheralData => {
          console.log("Connect:" + JSON.stringify(peripheralData));
            BLE.startNotification(device, '180D', '2A37').subscribe(function (notificationData){
              console.log("Notification:"+ String.fromCharCode.apply(null, new Uint8Array(notificationData)));
              BLE.read(device, '180D', '2A37').then(function (data){
                //console.log("READ:" + String.fromCharCode.apply(null, new Uint8Array(data)));
                console.log ("Read" + JSON.stringify(data));
              }, function(error) {
                console.log("Error Read" + JSON.stringify(error));
              });
            }, function(error){
              console.log("Error Notification" + JSON.stringify(error));
            });
          },
      error => console.log("Error Connecting" + JSON.stringify(error))
      );
    }

This is the result form the Chrome developer console:

    DEVICE READY FIRED AFTER 48 ms index.js:248
Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode. lang.js:360
Scanning Started home.ts:41
Scanning has stopped home.ts:50
[{"advertising":{},"id":"D0:1A:29:4B:5D:47","rssi":-59,"name":"HRM1"}] home.ts:51
Connect To Device home.ts:59
{"advertising":{},"id":"D0:1A:29:4B:5D:47","rssi":-59,"name":"HRM1"} home.ts:60
Connect:{"characteristics":[{"characteristic":"2a00","service":"1800","properties":["Read","Write"]},{"characteristic":"2a01","service":"1800","properties":["Read"]},{"characteristic":"2a04","service":"1800","properties":["Read"]},{"descriptors":[{"uuid":"2902"}],"characteristic":"2a05","service":"1801","properties":["Indicate"]},{"descriptors":[{"uuid":"2902"}],"characteristic":"2a37","service":"180d","properties":["Read","Notify"]},{"characteristic":"2a38","service":"180d","properties":["Read"]},{"characteristic":"2a39","service":"180d","properties":["Write"]},{"characteristic":"2a29","service":"180a","properties":["Read"]},{"characteristic":"2a24","service":"180a","properties":["Read"]},{"characteristic":"2a25","service":"180a","properties":["Read"]},{"characteristic":"2a27","service":"180a","properties":["Read"]},{"characteristic":"2a26","service":"180a","properties":["Read"]},{"characteristic":"2a28","service":"180a","properties":["Read"]}],"advertising":{},"id":"D0:1A:29:4B:5D:47","services":["1800","1801","180d","180a"],"rssi":-59,"name":"HRM1"} devices.ts:37
Notification:™ devices.ts:39
Read{} devices.ts:42
Notification:š devices.ts:39
Read{} devices.ts:42
Notification:› devices.ts:39
Read{} devices.ts:42
Notification:œ devices.ts:39
Read{} devices.ts:42
Notification: devices.ts:39
Read{} devices.ts:42
Notification:ž devices.ts:39
Read{} devices.ts:42
Notification:Ÿ devices.ts:39
Read{} devices.ts:42
Notification:  devices.ts:39
Read{} devices.ts:42
Notification:¡ devices.ts:39
Read{} devices.ts:42
Notification:¢ devices.ts:39
Read{} devices.ts:42
Notification:£ devices.ts:39
Read{} devices.ts:42
Notification:¤ 

Would you share the solution to your problem? Perhaps it’ll useful to fix my issue too.

Thanks!


#4

Did you ever figure this out? I’m also having a problem with the read not returning anything.


#5

Turned out it was reading the data, but because it’s a Uint8Array it wasn’t printing in the output. The solution is to convert the buffer to a string like so:

BLE.read(deviceid, "180a", "2a24").then(function(buffer){
var data = new Uint8Array(buffer);
console.log(String.fromCharCode.apply(null,data));
});

#6

I need to read BLE characteristic.

Can you share a working sample?

Thank you very much.


#7

Hi! I don’t know what I have to do to implement the GATT in my glucose meter. Could you post how yo did it? Thanks.