I'm writing a program to do the following BLE communication between 2 android devices which support android peripheral communication (in this case MOTOROLA MOTO E generation 2) to a series of: connection -> communicate -> disconnection and see if they can do it with good stability. Problem found in the test is also discussed.
The program first lets you select whether you want the device to be peripheral or central. At the central side, the program first scans for the peripheral with filter on Service UUID:
ScanSettings.Builder ssb = new ScanSettings.Builder();
ssb.setReportDelay(0);
ssb.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
ScanSettings ss = ssb.build();
ScanFilter.Builder sfb = new ScanFilter.Builder();
sfb.setServiceUuid(BLEShared.SERVICE_UUID);
LinkedList<ScanFilter> lsf = new LinkedList<ScanFilter>();
lsf.add(sfb.build());
BluetoothLeScanner leScanner = m_BluetoothAdapter.getBluetoothLeScanner();
if(leScanner != null)
{
leScanner.startScan(lsf, ss, blePeripheralScanner);
isScanning = true;
currentState = BLE_CENTRAL_STATE_SCANNING;
}
Then when the peripheral is scanned a handler will call the following from main thread.
stopScan();
mGatt = result.getDevice().connectGatt(BLECentral.this, false, m_BLECentralGattCallBack);
When the peripheral (acted by another MOTO E) is connected, the following is done at the onConnectionStageChange()
if(newState == BluetoothGatt.STATE_CONNECTED)
{
m_Handler.post(new Runnable(){
public void run()
{
gatt.discoverServices();
}
});
}
After all services are discovered, the program does the following:
Update descriptors to subscribe to notifications write some data and send to peripheral upon receiving data sent from central, the peripheral will notify value change. Upon receiving data change notification from peripheral will send data to the peripheral. The Write and notify process will be done 11 times. Then central call gatt.disconnect() to disconnect the ble connection.
The above process is looped to test the stability.
During normal connection, the above process can be done within 1.7-2.5 seconds. Between each write-notify process, it takes about 0.1s
The following problems are found during test:
- onConnectionStageChange() it takes long to be called device.connectGatt() for until up to 30 seconds. If such long wait occurs, the next onConnectionStageChange() is likely to be a failure connection ocassionally.
- onConnectionStageChange() is called quickly after device.connectGatt() but newState = STATE_DISCONNECTED occasionally
- It takes 0.5 seconds occasionally between each write command.
- The process either stucks or slows at any stage.
It seems to be some bugs underlying Android BLE stack. I therefore try to implement a watch dog, if any of the process is not going as quick as expected, the watchdog will activate and switch off the Bluetooth of central device's and switch it back on again thereby proactively stop waiting for the reply from the bluetooth stack which is expected to be some error values. As soon as the bluetooth is back on again, the central device will start scanning for the peripheral and continue the above test.
I tried to just close the Gatt, during watchdog activation, however after such force close of Gatt, the successive BLE connection tends to fail. So that it seems that the error tends to accumulate after each failure. So I resort to switching off and on the bluetooth device by BluetoothAdapter...disable()
Switching off the Bluetooth and turning it back on again is rather intrusive for some user's since they may be using other Bluetooth device. My questions are:
How can we enhance stability of the above test (is there anything wrong in my code, or anyway how I can better use the BLE stack)?
In case of failure, is it possible to reset the BLE stack only or close just enough amount of resource rather than resorting to switch of the BLE stack entirely?
The eclipse project is put underneath, if you are interested to give it a test or improve the project, please download it and have a try. https://drive.google.com/file/d/0B-w_C5ISF1UHRXUzd1FrUHpyV0k/view?usp=sharing