Search code examples
javaandroidbluetooth-lowenergyandroid-bluetoothrxandroidble

Why setMaxBatchSize() is not useful for larger MTU in RxAndroidBle?


I want to transmit data to device through BLE. The num of bytes is 64 per transmission.

Now the problem is that, When I modify the MTU through setMaxBatchSize(ex 64), mRxBleConnection.getMtu() returns the default MTU (23).

    private void connect(RxBleDevice rxBleDevice){

         connectionObservable = rxBleDevice.establishConnection(false)
                .subscribe(rxBleConnection -> {

                    mRxBleConnection = rxBleConnection;
                    rxBleConnection.setupNotification(MainActivity.MY_UUID);
                    longWrite();

                });


    }
    private void longWrite(){
           mRxBleConnection.setupNotification(MainActivity.MY_UUID)
                .flatMap(ob -> ob.merge(
                        mRxBleConnection.createNewLongWriteBuilder()
                                .setCharacteristicUuid(MainActivity.MY_UUID)
                                .setBytes(HexString.hexToBytes(writeData))
                                .setMaxBatchSize(64)
                                .build(),ob)
                )

        .subscribe(bytes -> {
            Log.i(TAG,mRxBleConnection.getMtu());

            doResponse(HexString.bytesToHex(bytes));

        },throwable -> {

        });
    }
  1. Try another way RxBleConnection.requestMtu(int)
Disposable writeSubscription = mRxBleConnection.requestMtu(176)
                .subscribe(
                        integer -> {
                            Log.i(TAG, "longWrite: "+integer);
                        },
                        throwable ->{

                        }

                );

the log

04-22 16:30:58.895 9435-9494/com.example.write D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
04-22 16:30:59.642 9435-9494/com.example.write D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=50:8C:B1:6A:F9:34
04-22 16:30:59.671 9435-9532/com.example.write D/BluetoothGatt: configureMTU() - device: 50:8C:B1:6A:F9:34 mtu: 176
04-22 16:31:00.035 9435-9494/com.example.write D/BluetoothGatt: onConnectionUpdated() - Device=50:8C:B1:6A:F9:34 interval=6 latency=0 timeout=500 status=0
04-22 16:31:00.347 9435-9494/com.example.write D/BluetoothGatt: onConfigureMTU() - Device=50:8C:B1:6A:F9:34 mtu=23 status=0

The mtu always be 23.

SLOVED----------CLOSED

I found BLE version of bluetooth device is 4.0, which is too low to support settings MTU. Even if the phone supports it,the device that communicates with the phone does not support it. Setting MTU Requires mobile phone and device support at the same time.


Solution

  • Answering the question from the topic — see below

    LongWriteOperationBuilder.setMaxBatchSize() Javadoc:

    /**
    * Setter for a maximum size of a byte array that may be write at once
    * If this is not specified - the default value of the connection's MTU is used
    *
    * @param maxBatchSize the maximum size of a byte array to write at once
    * @return the LongWriteOperationBuilder
    */
    

    If .setMaxBatchSize() is not specified the value derived from MTU is used. It is one way implication. It does not say that setting this property changes MTU.

    Additionally as you tried to set different MTU you could see in the logs that the new value was not accepted — the peripheral you want to communicate does not allow it.