I'm trying to write a custom characteristic to a BLE Device using Google's example project .
On the DeviceControlActivity
and while I'm looping through the fetched BluetoothGattService
s I try to set a characteristic for one of them. At this point I'm just picking one randomly to test.
private void displayGattServices(List<BluetoothGattService> gattServices) {
...
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
uuid = gattService.getUuid().toString();
if(uuid.equals("00001800-0000-1000-8000-00805f9b34fb") && !firstTime){
firstTime = true;
BluetoothGattCharacteristic customChar = new BluetoothGattCharacteristic(MY_CHARACTERISTIC,
BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PERMISSION_READ |BluetoothGattCharacteristic.PERMISSION_WRITE);
byte[] val = new byte[20];
val[0] = 71;
val[1] = 97;
val[2] = 108;
val[3] = 97;
val[4] = 120;
val[5] = 121;
val[6] = 32;
val[7] = 70;
val[8] = 105;
val[9] = 116;
val[10] = -30;
val[11] = -109;
val[12] = -108;
val[13] = 32;
val[14] = 40;
val[15] = 70;
val[16] = 57;
val[17] = 66;
val[18] = 57;
val[19] = 41;
customChar.setValue(val);
boolean isAdded = gattService.addCharacteristic(customChar);
Log.d(TAG,"CARAC ADDED? "+isAdded);
}
...
}
This call to addCharacteristic
returns true which according to the docs means the writing operation was successful, however when I rescan the services (without executing the code above) I cannot find the BluetoothGattCharacteristic
also when I try to read the value of said characteristic I get a status 135. According to this post means GATT_ILLEGAL_PARAMETER
Please note that the byte array is literally copied from another characteristic so normally it should do the trick.
Is it possible that the device I'm trying to write to doesn't support writing ? or the service itself ?
EDIT:
Following the suggestion on the comment, I have tried to modify an existing characteristic using the code below without success (I think the characteristic was created using READ only flag?)
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
...
uuid = gattCharacteristic.getUuid().toString();
// UUID for device name
if(uuid.equals("00002a00-0000-1000-8000-00805f9b34fb") && !firstTime){
firstTime = true;
gattCharacteristic.setValue("Hello");
boolean isAdded = mBluetoothLeService.writeCharacteristic(gattCharacteristic);
Log.d(TAG,"CARAC ADDED? "+isAdded); // returns false
}
I also tried to setup a GattServer
and creating a new service with new characteristic but also without any success. Here is the code (this partuses Kotlin):
mBluetoothGattServer = mBluetoothManager?.openGattServer(this@MainActivity,gattCallback)
mBluetoothGattServer?.connect(result.device,false)
val gattCallback = object: BluetoothGattServerCallback() {
override fun onConnectionStateChange(device: BluetoothDevice?, status: Int, newState: Int) {
super.onConnectionStateChange(device, status, newState)
if (newState == BluetoothProfile.STATE_CONNECTED) {
val service = BluetoothGattService(UUID.fromString("f000aa01-0451-4000-b000-000000000000"), BluetoothGattService.SERVICE_TYPE_PRIMARY)
val characteristic = BluetoothGattCharacteristic(UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb"),
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ or BluetoothGattCharacteristic.PERMISSION_WRITE)
characteristic.addDescriptor(BluetoothGattDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"), BluetoothGattCharacteristic.PERMISSION_WRITE))
service.addCharacteristic(characteristic)
mBluetoothGattServer?.addService(service)
}
}
// Not sure if this is needed but it never triggers.
override fun onCharacteristicWriteRequest(device: BluetoothDevice?, requestId: Int, characteristic: BluetoothGattCharacteristic?, preparedWrite: Boolean, responseNeeded: Boolean, offset: Int, value: ByteArray?) {
super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value)
mBluetoothGattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, "Hello".toByteArray())
}