0

I'm trying to write data to a BLE-characteristic, but I got the status 130 in my callback what means GATT_WRONG_STATE. Unfortunately, I have no idea, what state is wrong and how I can change this.

I'm using the BLE-App from the Android-connectivity samples (https://github.com/android/connectivity-samples/tree/master/BluetoothLeGatt) with minor changes so far.

Here's my DeviceControlActivity:

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            mConnected = true;
            updateConnectionState(R.string.connected);
            invalidateOptionsMenu();
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            mConnected = false;
            updateConnectionState(R.string.disconnected);
            invalidateOptionsMenu();
            clearUI();
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the user interface.
            displayGattServices(mBluetoothLeService.getSupportedGattServices());
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
            testWriteToCharacteristic();
        }
    }
};

private void testWriteToCharacteristic() {
        Log.d(TAG, "testWriteToCharacteristic");
        if (mNameService == null) {
            for (BluetoothGattService gattService: mBluetoothLeService.getSupportedGattServices()) {
                if (gattService.getUuid().equals(SampleGattAttributes.UUID_NAME_SERVICE)) {
                    mNameService = gattService;
                    Log.d(TAG, "rename service found");
                    break;
                }
            }
            mNameCharacteristic = mNameService.getCharacteristic(SampleGattAttributes.UUID_NAME_CHANNEL_CHARACTERISTICS);
        }
        mBluetoothLeService.writeCharacteristic(mNameCharacteristic);
    }
    [..]

..so I'm trying to write data right after I received the current value for that characteristic. (doing so right after ACTION_GATT_SERVICES_DISCOVERED hasn't worked either)

and here my changes to BluetoothLeService:

 private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
     [..]
     @Override
     public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
         Log.d(TAG, "onCharacteristicWrite, Status: " + status + ", " + characteristic.getUuid().toString());
         super.onCharacteristicWrite(gatt, characteristic, status);
         //Log.d(TAG, "onCharacteristicWrite value:"+characteristic.getStringValue(0)+" ");
     }

     @Override
     public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
         Log.d(TAG, "onReliableWriteCompleted");
         super.onReliableWriteCompleted(gatt, status);
     }
 };

 public void writeCharacteristic(BluetoothGattCharacteristic ch) {
     if (mBluetoothGatt == null) return;
     ch.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
     mBluetoothGatt.beginReliableWrite();
     String value = "TestValue" + new Random().nextInt(1000) + "\0";
     ch.setValue(value);
     mBluetoothGatt.writeCharacteristic(ch);
     mBluetoothGatt.executeReliableWrite();
 }

the callbackMethod "onCharacteristicWrite" is called with the status 130 GATT_WRONG_STATE. "onReliableWriteCompleted" is never called. I tried all 3 write type settings to no avail.

Heres the log output:

2020-04-08 15:03:25.540 4290-4315/com.example.android.bluetoothlegatt I/BluetoothLeService: Connected to GATT server.
2020-04-08 15:03:25.540 4290-4315/com.example.android.bluetoothlegatt D/BluetoothGatt: discoverServices() - device: E1:4B:30:8B:ED:AD
2020-04-08 15:03:25.541 4290-4315/com.example.android.bluetoothlegatt I/BluetoothLeService: Attempting to start service discovery:true
2020-04-08 15:03:26.484 4290-4307/com.example.android.bluetoothlegatt D/BluetoothGatt: onConnectionUpdated() - Device=E1:4B:30:8B:ED:AD interval=6 latency=0 timeout=500 status=0
2020-04-08 15:03:27.178 4290-4307/com.example.android.bluetoothlegatt D/BluetoothGatt: onSearchComplete() = Device=E1:4B:30:8B:ED:AD Status=0
2020-04-08 15:03:27.291 4290-4315/com.example.android.bluetoothlegatt D/BluetoothGatt: onConnectionUpdated() - Device=E1:4B:30:8B:ED:AD interval=171 latency=6 timeout=600 status=0
2020-04-08 15:03:27.340 4290-4298/com.example.android.bluetoothlegatt I/bluetoothlegat: Compiler allocated 4MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
2020-04-08 15:03:28.742 4290-4290/com.example.android.bluetoothlegatt D/BluetoothAdapter: isLeEnabled(): ON
2020-04-08 15:03:28.742 4290-4290/com.example.android.bluetoothlegatt D/BluetoothLeScanner: could not find callback wrapper
2020-04-08 15:03:31.711 4290-4290/com.example.android.bluetoothlegatt D/BluetoothGatt: setCharacteristicNotification() - uuid: 33b5376e-0942-1f91-379b-ac5af36b9efa enable: true
2020-04-08 15:03:33.704 4290-4315/com.example.android.bluetoothlegatt D/BluetoothLeService: broadcast Update
2020-04-08 15:03:33.728 4290-4290/com.example.android.bluetoothlegatt D/DeviceControlActivity: testWriteToCharacteristic
2020-04-08 15:03:33.728 4290-4290/com.example.android.bluetoothlegatt D/DeviceControlActivity: rename service found
2020-04-08 15:03:34.130 4290-4307/com.example.android.bluetoothlegatt D/BluetoothLeService: onCharacteristicWrite, Status: 130, 33b5376e-0942-1f91-379b-ac5af36b9efa

Reading all characteristics value is no problem.

Any suggestions on how to solve this issue?

Best regards, Michael

EDIT - PROBLEM SOLVED:

It was the ReliableWrite causing the problem. Removed it and now it works. Thank you Emil for the hint!

ElKamero
  • 3
  • 3
  • What are the characteristic's properties? Are you really sure you want to use Reliable Writes? I have never seen anyone actually use Reliable Writes before. The feature is quite stupid and Android's implementation for it is broken anyway. – Emil Apr 08 '20 at 15:59
  • ch.getProperties() returns 10, what means READ (2) and WRITE (8), right? The characteristic is writable - tested with the Xamarin-BLE-Scanner-Example-App, where I can write a string value without any problems. – ElKamero Apr 09 '20 at 06:21
  • Problem was the ReliableWrite! Intention was to make shure that the data is written as I have to initialize a device with 512bytes in several chunks and this feature looked like made for this.. still stupid not to try without before, but yeah.. happens ;) Thanks for the hint @Emil ! – ElKamero Apr 09 '20 at 06:39

1 Answers1

0

To use reliable writes, the characteristic properties must include the reliable writes bit. Your characteristic doesn't, so simply use "normal" writes instead.

Emil
  • 16,784
  • 2
  • 41
  • 52