1
votes

I am working on a BLE app. I am through to establishing communication between Mobile app (CENTRAL - BluetoothGattClient) and PERIPHERAL (GATT SERVER) albeit not neatly.

PERIPHERAL has one service which in turn has single characteristic on which CENTRAL has enabled notification. Read/Write from both sides happen through this characteristic

Here is the complete flow of communication from CENTRAL (Mobile) side

enter image description here

Problem 1

Sometime while receiving multiple packets from PERIPHERAL, I receive read notification - 'onCharcteristicChanged()' before I finish writing ACK (STEP 9) i.e. onCharcteristicChanged() is called before onCharctristicWrite().

In this scenario though I issue bleGatt.readCharacteristic(charac) but onCharactristicRead() never gets called. CENTRAL gets stuck. It is unable to read while waiting.

Problem 2

Sometime, while sending ACK, after issuing bleGatt.writeCharactristic(charac), onChactristicWrite() is not called hence ACK is not received by PERIPHERAL and communication stops.

Problem 3

Overall communication is very slow. It takes > 400ms to write one chunk (<=20 bytes) of data.

Is there any better strategy to sync Read/Write properly? I tried to do it by using BluetoothGattCallbacks but as explained it is not working properly.

What can be done to increase the speed of communication?

Both READ and WRITE is happening in same thread.

I have tested this on Moto E (Marshmallow), Moto G5 (Nougat) and Samsung S6 (Lollipop). The behaviour is consistent across devices.

My PERIPHERAL device is nRF52840.

Thanks

1

1 Answers

2
votes

The easiest way to make sure your GATT communication works correctly is to use a queue for the BluetoothGatt object, since only one GATT operation can run at a time. That's why it doesn't work when you for example call readCharacteristic before the onCharacteristicWrite is called by the system.

The reason you get the notification before the write response is because the peripheral sends the notification before the write response.

What you can do to speed up the communication is to use Write Without Response instead of Write With Response. That way multiple packets can be sent in one round trip. The onCharacteristicWrite will then be called immediately (as long as the internal buffers are not filled up). Just be aware of https://issuetracker.google.com/issues/37121017.