Android Bluetooth status 133 in onCharacteristicwrite

Quarter2Twelve picture Quarter2Twelve · Sep 17, 2014 · Viewed 12.3k times · Source

I'm new to Android and now doing a simple app that requires writing some data into a peripheral device.

Actually nothing goes wrong in a Samsung GT-S7272C device. But when I switch to Sony LT29i, there will always be a status 133 when I'm trying to write into a certain characteristic. I will give out some brief code.

BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_TIME_INPUT_CHAR);
if (tChar == null) throw new AssertionError("characteristic null when sync time!");

int diff = /*a int*/;
tChar.setValue(diff, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
gatt.writeCharacteristic(tChar);

and the onCharacteristicWrite function:

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.d(TAG, String.format("Sync: onCharWrite, status = %d", status));
    try {
        if (status != BluetoothGatt.GATT_SUCCESS) throw new AssertionError("Error on char write");
        super.onCharacteristicWrite(gatt, characteristic, status);
        if (characteristic.getUuid().equals(SYNC_TIME_INPUT_CHAR)) {
            BluetoothGattService syncService = gatt.getService(SYNC_DATA_SERVICE);
            BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_HEIGHT_INPUT_CHAR);
            if (tChar == null) throw new AssertionError("characteristic null when sync time!");
            tChar.setValue(/*another int*/, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
            gatt.writeCharacteristic(tChar);
        }
        else if {
            ...
        }
    } catch (AssertionError e) {
        ...
    }

Writing into first characteristic has nothing wrong and control will reach the onCharacteristicWrite and enter the first if statement with status 0, which means success. Problem is the second writing action in the if statement, which will also trigger onCharacteristicWrite function but yield a status 133, which cannot be found in the official site. Then the device disconnect automatically.

I've confirmed that the data type and the offset are all correct. And because in another device it works really nice, I think there might be some tiny differences of the bluetooth stack implementation between different device that I should do something more tricky to solve this problem.

I've search for result for a long time. Some results lead me to the C source code(Sorry, I will post the link below because I don't have enough reputation to post more than 2 links), but I can only find that 133 means GATT_ERROR there, which is not more helpful than just a 133. I've also found a issue in google group, discussing some familiar questions, but I failed to find a solution here.

I'm a little bit sad because, if it is something wrong with the C code, even if I can locate what's wrong, I still have no way to make it right in my own code, right?

I hope that someone has the familiar experience before and may give me some suggestions. Thanks a lot!

links:

  • C source code: https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.4.2_r1/stack/include/gatt_api.h

  • Issue: https://code.google.com/p/android/issues/detail?id=58381

Answer

benka picture benka · Sep 17, 2014

I had a similar issue when I tried to write to some characteristic I can't remember though if i got the same error code or not. (And it worked on some devices while it didn't on others).

What turned out to be the problem is the property of the characteristics and the writeType.

Because characteristics can have values set:

  • write without response OR
  • write with response

In reference to this property you have to set the writeType before writing the actual data to the characteristic.

You can set the type once you get the Characteristic but before writing to it.

BluetoothGattCharacteristic tChar = syncService.getCharacteristic(SYNC_HEIGHT_INPUT_CHAR);
        if (tChar == null) throw new AssertionError("characteristic null when sync time!");

        // use one of them in regards of the Characteristic's property
        tChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
        //tChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);


        tChar.setValue(/*another int*/, BluetoothGattCharacteristic.FORMAT_SINT32, 0);
        gatt.writeCharacteristic(tChar);