0

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 BluetoothGattServices 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())
    }
113408
  • 3,364
  • 6
  • 27
  • 54
  • 1
    If you want to write as a GATT client you should look up the characteristic in the service, set a value and then call writeCharacteristic. The "new" and "add" calls should only be used if you want to build a GATT server. – Emil Sep 23 '19 at 18:00
  • @Emil I tried your suggestions but both didn't work. I update the question with the code snippets – 113408 Sep 24 '19 at 09:03

0 Answers0