Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android BLE: Identify the Characteristic Type?

I am developing an android application with BLE. The requirement of this application is to update the voltage variation in a specific hardware with various inputs. So I enable BLE notify API in this application. This will notify the application in a period of time with latest hardware voltage.

Implementation

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
BluetoothGattDescriptor des = characteristic.getDescriptors();
des.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);         
//Set the value of the descriptor to enable notification
                    mBluetoothGatt.writeDescriptor(des);

I am getting notification in the notification values in the Gatt CallBack method

      @Override
      public void onCharacteristicChanged(BluetoothGatt Gatt, BluetoothGattCharacteristic characteristic) {
                    Log.w(TAG, "**ACTION_DATA_AVAILABLE**" + characteristic.getUuid());
//Indication or notification was received
                    broadcastUpdate(BLEConstants.ACTION_DATA_AVAILABLE, characteristic);                     
//Go broadcast an intent with the characteristic data
                }

But my problem is, I am getting the normal response also in the same Gatt callback method. I want to update the notification as a specific way in the UI. So I need to separate normal response and notification. Is there any way to do the same? Or any option to identify the particular message is from notify?

like image 338
Nithinjith Avatar asked Aug 24 '16 10:08

Nithinjith


People also ask

What is characteristic in BLE?

A characteristic object represents a characteristic of a Bluetooth® Low Energy peripheral device. If read or write are supported in the object Attributes property, you can read characteristic values using read or you can write characteristic values using write .

How many characteristics can a BLE service have?

A service can have one or more characteristics, and each service distinguishes itself from other services by means of a unique numeric ID called a UUID, which can be either 16-bit (for officially adopted BLE Services) or 128-bit (for custom services).

How do you write Bluetooth characteristics?

write( c , data ) writes the specified data to a characteristic of a Bluetooth® Low Energy peripheral device. The Attributes property of the input characteristic object c must be "Write" and/or "WriteWithoutResponse" . write( c , data , type ) specifies whether the device expects a response back using type .


2 Answers

In general, we create (on the hardware side) one characteristic with both WRITE and NOTIFY properties, so that we can read whenever we want or completely enable notify to get real-time data.

If you have access to the hardware firmware and can add characteristics, it would be nice to separate the voltage characteristic, and the response one. Thus you can test upon the onCharacteristicChanged argument :

int propertiesFlags = characteristic.getUuid();

Another good way to do it, and that's what I do usually, is using one characteristic, but assigning data intervals. Some kind of convention between your app and the hardware :

@Override
public void onCharacteristicChanged(BluetoothGatt Gatt, BluetoothGattCharacteristic characteristic) {
    byte[] data = characteristic.getValue();
    if(data[1] < SOME_PREDIFINDED_VALUE){
        //it's a real-time data update
    }else{
        //it's a response to some data you sent.
    }

}

Otherwise, the response will just be a characteristic change meaning a new value of hardware voltage.

like image 136
Achraf Amil Avatar answered Oct 28 '22 21:10

Achraf Amil


No if you don't have possibility to change the firmware. According to your explanation it seems that NOTIFY characteristic type is triggered no meter if you asked for value or the value is changed.

If so, the only way I can imagine as solution is following.

  1. You have asked for value. You have to set flag and you have to consider that all the values reported while flag is set are values that you have been asking for.
  2. You have not asked for value. Consider it as notifications.

Hope it helps.

Update:

It seems that you are using RN4020 MLDP which doesn't have exposed documentation for private service, according to this

The best I could found was the following:

//    private static final String MLDP_PRIVATE_SERVICE = "00035b03-58e6-07dd-021a-08123a000300"; //Private service for Microchip MLDP
//    private static final String MLDP_DATA_PRIVATE_CHAR = "00035b03-58e6-07dd-021a-08123a000301"; //Characteristic for MLDP Data, properties - notify, write
//    private static final String MLDP_CONTROL_PRIVATE_CHAR = "00035b03-58e6-07dd-021a-08123a0003ff"; //Characteristic for MLDP Control, properties - read, write
//    private static final String CHARACTERISTIC_NOTIFICATION_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";  //Special UUID for descriptor needed to enable notifications

from here

Which means that only way to transfer data is using

//    private static final String MLDP_DATA_PRIVATE_CHAR = "00035b03-58e6-07dd-021a-08123a000301"; //Characteristic for MLDP Data, properties - notify, write

and this characteristic has only NOTIFY, not read. So if you are using it, you can not avoid notification callback on device side.

like image 43
Darko Djuric Avatar answered Oct 28 '22 20:10

Darko Djuric