Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does setCharacteristicNotification() not actually enable notifications?

Tags:

The BluetoothLeGatt Android BLE example contains the following code:

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,                                           boolean enabled) {     if (mBluetoothAdapter == null || mBluetoothGatt == null) {         Log.w(TAG, "BluetoothAdapter not initialized");         return;     }     mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);      // This is specific to Heart Rate Measurement.     if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {         BluetoothGattDescriptor descriptor = characteristic.getDescriptor(                 UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));         descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);         mBluetoothGatt.writeDescriptor(descriptor);     } } 

My question is basically, why is the marked code specific to Heart Rate Measurement? It seems like having a Client Characteristic Config Descriptor (CCCD) characteristic is the standard way to control characteristic notification, so why doesn't setCharacteristicNotification() take care of writing to it? And since it doesn't do that, what does setCharacteristicNotification() actually do?

I'm pretty new to BLE and there aren't any explanations of it on the internet that don't assume that you already understand it all! So don't assume I know what a CCCD or whatever is! It was difficult enough finding out what CCCD even stands for!

Edit: See also this answer which supports my understanding of CCCDs (and makes me continue to wonder why you have to write to them manually in Android when there is a function that looks like it should do that for you): https://devzone.nordicsemi.com/index.php/what-does-cccd-mean

like image 592
Timmmm Avatar asked Apr 02 '14 16:04

Timmmm


2 Answers

I think is a litte bit late for give an answer but today I had the same doubt and I found a clear answer. Using setCharacteristicNotification() you enable notification localy (on android device) and setting CCC descriptor to ENABLE_NOTIFICATION_VALUE you enable notification on ble peripheral. In fact for enabling CCC notification you have to use setValue() and writeDescriptor() that are methods used for writing characteristics (in this case characteristics descriptors) to remote device. I found this on: http://processors.wiki.ti.com/index.php/SensorTag_User_Guide

like image 92
Davide Giovanelli Avatar answered Sep 20 '22 17:09

Davide Giovanelli


Here is an excerpt from the O'Reilly book "Getting Started With Bluetooth Low Energy":

To enable notifications on Android, you normally have to locally enable the notification for the particular characteristic you are interested in.

Once that’s done, you also have to enable notifications on the peer device by writing to the device’s client characteristic configuration descriptor (CCCD)

I believe this answers your question.

So

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);  

refers to the first part

and

mBluetoothGatt.writeDescriptor(descriptor);  

refers to the 2nd.

like image 43
Tomi Avatar answered Sep 20 '22 17:09

Tomi