Added some automatic reconnection code for BLE data source. Still not as reliable as I would like though.

This commit is contained in:
Graham Jones
2020-08-16 22:28:12 +01:00
parent 3cc11dfab8
commit b924519dd2
3 changed files with 72 additions and 36 deletions

View File

@@ -53,7 +53,7 @@ interface SdDataReceiver {
* network data source. * network data source.
*/ */
public abstract class SdDataSource { public abstract class SdDataSource {
private Handler mHandler = new Handler(); protected Handler mHandler = new Handler();
private Timer mStatusTimer; private Timer mStatusTimer;
private Timer mSettingsTimer; private Timer mSettingsTimer;
private Timer mFaultCheckTimer; private Timer mFaultCheckTimer;

View File

@@ -126,34 +126,41 @@ public class SdDataSourceBLE extends SdDataSource {
} }
private void bleConnect() { private void bleConnect() {
// Now we have selected a BLE Device, open the bluetooth adapter and connect to it. mSdData.watchConnected = false;
mSdData.watchAppRunning = false;
mBluetoothGatt = null;
mConnectionState = STATE_DISCONNECTED;
if (mBluetoothManager == null) { if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) { if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager."); Log.e(TAG, "bleConnect(): Unable to initialize BluetoothManager.");
return;
} }
} }
mBluetoothAdapter = mBluetoothManager.getAdapter(); mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) { if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter."); Log.e(TAG, "bleConnect(): Unable to obtain a BluetoothAdapter.");
return;
} }
if (mBluetoothAdapter == null || mBleDeviceAddr == null) { if (mBluetoothAdapter == null || mBleDeviceAddr == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address."); Log.w(TAG, "bleConnect(): BluetoothAdapter not initialized or unspecified address.");
return;
} }
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mBleDeviceAddr); final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mBleDeviceAddr);
if (device == null) { if (device == null) {
Log.w(TAG, "Device not found. Unable to connect."); Log.w(TAG, "bleConnect(): Device not found. Unable to connect.");
} return;
} else {
// We want to directly connect to the device, so we are setting the autoConnect // We want to directly connect to the device, so we are setting the autoConnect
// parameter to false. // parameter to false.
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback); mBluetoothGatt = device.connectGatt(mContext, true, mGattCallback);
Log.d(TAG, "Trying to create a new connection."); Log.d(TAG, "bleConnect(): Trying to create a new connection.");
mBluetoothDeviceAddress = mBleDeviceAddr; mBluetoothDeviceAddress = mBleDeviceAddr;
mConnectionState = STATE_CONNECTING; mConnectionState = STATE_CONNECTING;
}
} }
private void bleDisconnect() { private void bleDisconnect() {
@@ -167,6 +174,9 @@ public class SdDataSourceBLE extends SdDataSource {
} }
mBluetoothGatt.close(); mBluetoothGatt.close();
mBluetoothGatt = null; mBluetoothGatt = null;
mSdData.watchAppRunning = false;
mSdData.watchConnected = false;
mConnectionState = STATE_DISCONNECTED;
} }
@@ -190,21 +200,27 @@ public class SdDataSourceBLE extends SdDataSource {
if (newState == BluetoothProfile.STATE_CONNECTED) { if (newState == BluetoothProfile.STATE_CONNECTED) {
mConnectionState = STATE_CONNECTED; mConnectionState = STATE_CONNECTED;
mSdData.watchConnected = true; mSdData.watchConnected = true;
Log.i(TAG, "Connected to GATT server."); Log.i(TAG, "onConnectionStateChange(): Connected to GATT server.");
// Attempts to discover services after successful connection. // Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:"); Log.i(TAG, "onConnectionStateChange(): Attempting to start service discovery:");
mBluetoothGatt.discoverServices(); mBluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mConnectionState = STATE_DISCONNECTED; mConnectionState = STATE_DISCONNECTED;
mSdData.watchConnected = false; mSdData.watchConnected = false;
Log.i(TAG, "Disconnected from GATT server - retrying..."); Log.i(TAG, "onConnectionStateChange(): Disconnected from GATT server - reconnecting after delay...");
bleDisconnect(); // Tidy up connections //bleDisconnect(); // Tidy up connections
// Wait 2 seconds to give the server chance to shutdown, then re-start it
mHandler.postDelayed(new Runnable() {
public void run() {
bleConnect(); bleConnect();
} }
}, 2000);
}
} }
@Override @Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) { public void onServicesDiscovered(BluetoothGatt gatt, int status) {
boolean foundOsdService = false;
if (status == BluetoothGatt.GATT_SUCCESS) { if (status == BluetoothGatt.GATT_SUCCESS) {
Log.v(TAG, "Services discovered"); Log.v(TAG, "Services discovered");
List<BluetoothGattService> serviceList = mBluetoothGatt.getServices(); List<BluetoothGattService> serviceList = mBluetoothGatt.getServices();
@@ -226,6 +242,7 @@ public class SdDataSourceBLE extends SdDataSource {
} }
} else if (uuidStr.equals(SERV_OSD)) { } else if (uuidStr.equals(SERV_OSD)) {
Log.v(TAG, "OpenSeizureDetector Service Discovered"); Log.v(TAG, "OpenSeizureDetector Service Discovered");
foundOsdService = true;
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
String charUuidStr = gattCharacteristic.getUuid().toString(); String charUuidStr = gattCharacteristic.getUuid().toString();
if (charUuidStr.equals(CHAR_OSD_ACC_DATA)) { if (charUuidStr.equals(CHAR_OSD_ACC_DATA)) {
@@ -239,7 +256,18 @@ public class SdDataSourceBLE extends SdDataSource {
} }
} }
} }
if (foundOsdService) {
mGatt = gatt; mGatt = gatt;
} else {
Log.v(TAG, "device is not offering the OSD Gatt Service - re-trying connection");
bleDisconnect();
// Wait 1 second to give the server chance to shutdown, then re-start it
mHandler.postDelayed(new Runnable() {
public void run() {
bleConnect();
}
}, 1000);
}
} else { } else {
Log.w(TAG, "onServicesDiscovered received: " + status); Log.w(TAG, "onServicesDiscovered received: " + status);
} }

View File

@@ -677,9 +677,23 @@ public class SdServer extends Service implements SdDataReceiver {
mSdData.alarmPhrase = "FAULT"; mSdData.alarmPhrase = "FAULT";
mSdData.alarmStanding = false; mSdData.alarmStanding = false;
if (webServer != null) webServer.setSdData(mSdData); if (webServer != null) webServer.setSdData(mSdData);
if (mAudibleFaultWarning) { // We only take action to warn the user and re-start the data source to attempt to fix it
// ourselves if we have been in a fault condition for a while - signified by the mFaultTimerCompleted
// flag.
if (mFaultTimerCompleted) {
faultWarningBeep(); faultWarningBeep();
//mSdDataSource.stop();
//mHandler.postDelayed(new Runnable() {
// public void run() {
// mSdDataSource.start();
// }
//}, 190);
} else {
startFaultTimer();
Log.v(TAG, "onSdDataFault() - starting Fault Timer");
mUtil.writeToSysLogFile("onSdDataFault() - starting Fault Timer");
} }
showNotification(-1); showNotification(-1);
} }
@@ -703,7 +717,6 @@ public class SdServer extends Service implements SdDataReceiver {
* beep, provided mAudibleAlarm is set * beep, provided mAudibleAlarm is set
*/ */
public void faultWarningBeep() { public void faultWarningBeep() {
if (mFaultTimerCompleted) {
if (mCancelAudible) { if (mCancelAudible) {
Log.v(TAG, "faultWarningBeep() - CancelAudible Active - silent beep..."); Log.v(TAG, "faultWarningBeep() - CancelAudible Active - silent beep...");
} else { } else {
@@ -719,11 +732,6 @@ public class SdServer extends Service implements SdDataReceiver {
Log.v(TAG, "faultWarningBeep() - silent..."); Log.v(TAG, "faultWarningBeep() - silent...");
} }
} }
} else {
startFaultTimer();
Log.v(TAG, "faultWarningBeep() - starting Fault Timer");
mUtil.writeToSysLogFile("faultWarningBeep() - starting Fault Timer");
}
} }