BLE Descriptor UUID - android

I'm new in the world of BLE, I am currently able to connect to the BLE module and I can communicate with it/receive Data by pressing a Button.
Now I want to use the Descriptor, but I don't exactly know how to define the required UUID. I only discovered that it is 0x2902.
I want to use the following Code:
BluetoothGattCharacteristic init_gatt=mConnectedGatt.getService(STATE_REQUEST_SERVICE_UUID).getCharacteristic(STATE_CHAR_UUID);
mConnectedGatt.setCharacteristicNotification(init_gatt,true);
BluetoothGattDescriptor descriptor=characteristic.getDescriptor(STATE_CHAR_UUID);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mConnectedGatt.writeDescriptor(descriptor);
Can anyone tell me how I can create the UUID which is necessary for this line?
BluetoothGattDescriptor descriptor=characteristic.getDescriptor(STATE_CHAR_UUID);

If you're looking for creating a random UUID, you can do that like this:
if(uniqueId == null) {
uniqueId = UUID.randomUUID().toString();
}
You can actually log the list of device supported using:
for (BluetoothGattDescriptor descriptor:characteristic.getDescriptors()){
Log.e(TAG, "BluetoothGattDescriptor: "+descriptor.getUuid().toString());
}

BluetoothGattCharacteristic init_gatt=mConnectedGatt.getService(STATE_REQUEST_SERVICE_UUID).getCharacteristic(STATE_CHAR_UUID);
for (BluetoothGattDescriptor descriptor:characteristic.getDescriptors()){
Log.e(TAG, "BluetoothGattDescriptor: "+descriptor.getUuid().toString());
}
That's all I'm testing atm.
For the other Characteristic I'm Using, I got the hex Values which I have to write to the Characteristic by a collegue. In this case not

Related

writeable characteristic for android custom ble service always returns write permission zero when discovered

I'm creating a custom BLE service on Android with a single characteristic that can be read/written. The code looks like this:
public static UUID MY_SERVICE = UUID.fromString("e0ec8d9c-5e4d-470a-b87f-64f433685301");
public static UUID MY_CHARACTERISTIC = UUID.fromString("e0ec8d9c-5e4d-470a-b87f-64f433685302");
/**
* Return a configured {#link BluetoothGattService} instance for the
* Custom Service.
*/
public static BluetoothGattService createCustomBleService() {
BluetoothGattService service = new BluetoothGattService(MY_SERVICE,
BluetoothGattService.SERVICE_TYPE_PRIMARY);
// Current Configuration characteristic
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(MY_CHARACTERISTIC,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PERMISSION_READ |BluetoothGattCharacteristic.PERMISSION_WRITE);
boolean serviceAdded = service.addCharacteristic(characteristic);
Log.i(TAG, "Building BLE service addCharacteristic returned "+serviceAdded);
return service;
}
The call to addCharacteristic(...) returns true. The service itself is created, can be advertised, and the service and its characteristic are discoverable by clients. Somewhere else in client side code, subsequent to a BLE scan that locates said service, the discovery code that runs looks like this:
for (BluetoothGattService service : gatt.getServices()) {
serviceUuid = service.getUuid().toString();
if( MY_SERVICE.toString().equals(serviceUuid) ) {
List<BluetoothGattCharacteristic> gattCharacteristics = service.getCharacteristics();
for( BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics ) {
characteristicUuid = gattCharacteristic.getUuid().toString();
Log.d(TAG, "onServicesDiscovered() - found characteristic uuid="+characteristicUuid);
int cProps = gattCharacteristic.getProperties();
Log.d(TAG, "onServicesDiscovered() - found characteristic properties "+cProps);
if ((( MY_CHARACTERISTIC.toString().equals(characteristicUuid) ))&&((cProps & BluetoothGattCharacteristic.PROPERTY_WRITE)>0)) {
writeCharacteristic(gatt,gattCharacteristic,"configStringLiteral");
}
}
}
}
When this service discovery code runs, as I mentioned, it finds the custom service and the characteristic that were defined. Any values I set for characteristic properties show up properly at the time of discovery on client side. The characteristic shows as writeable.
The problem is that characteristic write fails always even though the properties say its writable.
Has anyone seen this?... or perhaps I'm doing something dumb and have been looking at it too long.
(BTW the device hosting the custom service at runtime is a Samsung Galaxy 7 and the client is a Galaxy 6 ...or vice versa, same behavior)
Permission info is not sent over BLE when the services are discovered. Therfore the permission property should not be used for remote characteristics.
A client should inspect the characteristic property only to decide what can be done. If it receives an error saying for example encryption needed, the Bluetooth stack shall start encryption and then retry the request.
So, characteristic properties are the correct way to declare to a client what can be done with it. Characteristic permissions only tell the local GATT Server implementation how it should react to incoming GATT requests.

Android - Getting null descriptors from a Characteristic

I am trying to interface with an Red Bear Labs nRF8001 Arduino Shield via Android Studio. I am succesfully able to send a command via Android and recieve it on my Arduino.
However I wish to read the response from my Arduino, using "OnCharacteristicChange" - however research showed a descriptor is required.
This is my code sample:
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if(status != BluetoothGatt.GATT_SUCCESS){
Log.i("BtServiceCallback","OnServicesDiscovered Failed!");
}
BluetoothGattService service = gatt.getService(RBLService.UUID_BLE_SHIELD_SERVICE);
BluetoothGattCharacteristic characteristic = service.getCharacteristic(RBLService.UUID_BLE_SHIELD_TX);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(RBLGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
byte[] val = readSetPoint.getBytes();
characteristic.setValue(val);
gatt.setCharacteristicNotification(characteristic,true);
gatt.writeCharacteristic(characteristic);
Log.i("Sent = ", characteristic.getStringValue(0));
}
Whenever I try to create a descriptor from the characteristic, I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference
at uk.ac.as988brighton.bluecontroller.MainActivity$1.onServicesDiscovered(MainActivity.java:160)
at android.bluetooth.BluetoothGatt$1.onSearchComplete(BluetoothGatt.java:286)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:103)
at android.os.Binder.execTransact(Binder.java:573)
I am using the UUIDs from RBL's Github:
public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
public static String BLE_SHIELD_TX = "713d0003-503e-4c75-ba94-3148f18d941e";
public static String BLE_SHIELD_RX = "713d0002-503e-4c75-ba94-3148f18d941e";
public static String BLE_SHIELD_SERVICE = "713d0000-503e-4c75-ba94-3148f18d941e";
I am unsure as to what is causing the null descriptor.
Edit
I have used different combinations for the descriptor - such as using
BluetoothGattDescriptor characteristic.getDescriptor(RBLService.UUID_BLE_SHIELD_TX);
But still receiving the same error.
It looks like you need to make sure you're naming things the same. Both your service and characteristic uuid are declared as BLE_SHIELD_SERVICE and BLE_SHIELD_TX but you're trying to access them with UUID_BLE_SHIELD_SERVICE and UUID_BLE_SHIELD_TX.
So change
BluetoothGattService service = gatt.getService(RBLService.UUID_BLE_SHIELD_SERVICE); to
BluetoothGattService service = gatt.getService(RBLService.BLE_SHIELD_SERVICE);
and
BluetoothGattCharacteristic characteristic = service.getCharacteristic(RBLService.UUID_BLE_SHIELD_TX); to
BluetoothGattCharacteristic characteristic = service.getCharacteristic(RBLService.BLE_SHIELD_TX);
and I believe it should work. Also make sure you are broadcasting those exact service and characteristic uuid's from your peripheral.
Good luck!

Decode BLE GattServices data

I am implementing BLE in Android Studio. I have connected with the peripheral device ok. In my onServicesDiscovered method I want to analyze the services (and characteristics) and I get something like the following when I print out:
android.bluetooth.BluetoothGattService#41b6dd18
There is 4 services in the list and they all look similar except for the numbers at the end. How can I convert this to useful information. I have seen no reference to this format.
Thanks.
Try to read the uuid from the BluetoothGattService object.
You can find uuid of standard services on Bluetooth SIG website. If the uuid is not there (i.e. custom services), you should read the manual of the peripheral or reach out the peripheral maker.
That depends on what you consider "useful" information.
BLE works mostly like dictionary where you look up long numbers (characteristics) and get binary data, so without prior information about the device you're working on, there is not much you can see when you discover services.
That said, in the BLE docs, there is a method displayGattServices() which puts the discovered services info in an ExpandableListView, and here I changed it to print the UUIDs of services and characteristics to logcat instead.
Besides the UUIDs, you can use getProperties() to find out other characteristic properties such as the format of the characteristic data, or getPermissions() to see whether you can read or write the characteristic.
// Demonstrates how to iterate through the supported GATT
// Services/Characteristics.
private void displayGattServices(List<BluetoothGattService> gattServices) {
final String TAG = "BleServiceInfo";
if (gattServices == null) return;
String uuid;
String unknownServiceString = "Unknown service"
String unknownCharaString = "Unknown characteristic"
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
Log.d(TAG, "Service: " + gattService.getUuid().toString());
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
Log.d(TAG, "\tCharacteristic: " + gattCharacteristic.getUuid().toString());
}
}
}
Call this method from onServicesDisccovered() like this:
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
....
displayGattServices(gatt.getServices());
}

Failing to establish a connection with a custom service

I currently own a LilyPad Simblee BLE Board - RFD77101, with which I'm trying to establish a connection with a custom service that I am defining in arduino 1.6.5 IDE with the Simblee.customUUID command.
I later tried to get the service and the characteristic in Android Studio with the BluetoothleGatt sample code using the UUID I established previously.
The problem is when I connect to the Simblee the app fails to recognize the service and logs me the following error.
Custom BLE Service not found
The code is kinda long hence I am not posting all of it directly. If anyone has an idea as to a solution to my problem and need and part of code I am obviously more than glad to post it.
Thanks to anyone in advance.
This is the public void where I attempt to obtain the characteristic:
public void readCustomCharacteristic() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("fe84-0000-1000-8000-00805f9b34fb"));
if(mCustomService == null) {
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
BluetoothGattCharacteristic mReadCharacteristic = mCustomService.getCharacteristic(UUID.fromString("2d30c083-f39f-4ce6-923f-3484ea480596"));
if(!mBluetoothGatt.readCharacteristic(mReadCharacteristic)) {
Log.w(TAG, "Failed to read characteristic");
}
}
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("fe84-0000-1000-8000-00805f9b34fb"));
The UUID you provided is not in correct format. According to the documentation, the part before first hyphen should consist of 4 hex octets (See the one you provided for characteristics) but you only got 2 here. You should add padding 0 in front like
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("0000fe84-0000-1000-8000-00805f9b34fb"));
Edit : Missing a point here. Have you called mBluetoothGatt.discoverServices()?

Android bluetooth get the heart rate measurement

I want to get the value of the HRM of an "A&D UA-651BLE" device.
this is what's written in the datasheet of this device to get the HRM value:
Set the application to pairing mode to start scanning.
Start pairing of A&D BLE device following each instruction manual.
At pairing mode, the application should set time and date and any other device settings
to A&D BLE device. After successful pairing, A&D BLE device shows “End” on the screen.
Take a measurement and finish the measurement, then A&D BLE device start BLE
connection with advertising. The application starts scanning with suitable interval so that
the application catches the advertising of A&D BLE device as soon as it can.
At initial connection or pairing, the Application set “2” to CCCD (Client Characteristic
Configuration Descriptor) so that A&D BLE device sends a measurement data with
Indication.
After A&D device recognizes to be set “2” to CCCD and to be synchronized time and date
within 5 seconds after connected, send the data with Indication.
If the timeout set CCCD and time and date is expired, A&D BLE device will not send data
and store the data in memory. The stored data in A&D BLE device can send next
successful connection.
this is my service 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);
}
}
and this is the method that read data:
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
Log.e("HRM value",stringBuilder.toString());
dataComposition.put(characteristic.getUuid().toString(),stringBuilder.toString());
intent.putExtra(EXTRA_DATA,dataComposition);
}
the problem is that this code doesn't return any data !!
There's an Android Open Source Project example that does precisely this, easiest option would be to clone the android-BluetoothLeGatt code, build and compare it to your own. If you can't spot the difference / issue simply deploy both app's and step through both sets of code. Having some known working code will also help to rule out the possibility that the HRM is not functioning properly.
Do you have and example , i try this with equal device and i cant obtain the information y try with
public String response() {
if (mConnected) {
mBluetoothLeService.readCharacteristic(characteristica);
byte response[] = characteristica.getValue();
String respuesta = ReadBytes(response);
mBluetoothLeService.disconnect();
return respuesta;
} else {
return null;
}
}

Categories

Resources