4

I have a one Android Phone acting as Central Device and another Android Phone acting as Peripheral.

From Central, I'm making a request to read characteristic of Peripheral, using mBluetoothGatt.readCharacteristic ( characteristic )

Onto the peripheral, the method

void onCharacteristicReadRequest ( // Bluetooth GATT Server Callback Method
            BluetoothDevice device,
            int requestId,
            int offset,
            BluetoothGattCharacteristic characteristic
)

invokes, and there I'm doing two things: 1. Initializing a byte [] value to store String in byte form. 2. Sending response to the Client using method mGattServer.sendResponse().

@Override public void onCharacteristicReadRequest (
        BluetoothDevice device, int requestId, int offset,
        BluetoothGattCharacteristic characteristic ) {
    super.onCharacteristicReadRequest ( device, requestId, offset, characteristic );
    String string = "This is a data to be transferred";
    byte[] value = string.getBytes ( Charset.forName ( "UTF-8" ) );
    mGattServer.sendResponse ( device, requestId, BluetoothGatt.GATT_SUCCESS, 0, value );
}

My problem here is that above method gets called multiple times when I have made a read request once from the Central device.

Due to this, I'm getting the data on the Central device as something like

This is a data to be transferredThis is a data to be transferredThis is a...

I have also tried with other characteristics. But for those, callback method gets called once.

Can you point me where I am doing wrong?

EDIT: From Peripheral, I have debugged that I am sending 32-bytes of data. When I change string value from This is a data to be transferred to DATA, the method onCharacteristicReadRequest() calls one time only.

Further experiments with the field string have led me to the conclusion that maximum amount of bytes to be sent in the response is 21-bytes. If this is the case, then how should I send the response from the GATT Server, so that Central Device can obtain exact data only?

Ritwik Jamuar
  • 351
  • 1
  • 4
  • 17
  • the answer is here https://stackoverflow.com/questions/33274009/how-to-prevent-bluetoothgattcallback-from-being-executed-multiple-times-at-a-tim – Vladimir Tsykunov Nov 17 '17 at 07:40
  • I am also seeing the same issue with max length of 21-byte on Android 8.1.0, not sure it's the protocol limitation or bug. Do you find a solution already? – Dino Tw Jun 08 '18 at 18:04

3 Answers3

3

In android how you do for big text

    private String data = "123456789123456789123xx";

Let above being your text

Then following will be implementation of onCharacteristicReadRequest()

@Override
public void onCharacteristicReadRequest(BluetoothDevice device, 
                  int requestId, int offset,
                  BluetoothGattCharacteristic characteristic) {

    super.onCharacteristicReadRequest(device, requestId, offset, characteristic);

    byte value[] = data.getBytes();
    value = Arrays.copyOfRange(value,offset,value.length);
    gattServer.sendResponse ( device, requestId, 
                              BluetoothGatt.GATT_SUCCESS, offset, value );
}

So basically in every call offset amount of data is transferred so in next calls to this method you should send only offset, to length of data

this is same as what @Вадзім Жукоўскі said, but for C#

Thanks @Вадзім Жукоўскі for pointing this out

Ankur
  • 429
  • 4
  • 10
1

This from C#, but I think it can help. When you transfer a large array of bytes, you need to use offset. Otherwise, as in your case, you constantly start transferring your array from the beginning. Offset changes automatically. You just need to use it to offset the array when reading the next piece of data.

byte[] result = DataBytes.Skip(offset).ToArray();
mGattServer.SendResponse(device, requestId, GattStatus.Success, offset, result);
0

when onCharacteristicReadRequest be invoked, You should judge whether the characteristic you are about to read is you want:

   void onCharacteristicReadRequest ( // Bluetooth GATT Server Callback Method
                BluetoothDevice device,
                int requestId,
                int offset,
                BluetoothGattCharacteristic characteristic
    )