Skip to content

Commit e579722

Browse files
authored
Pair - wait for disconnect; Flash - restart after bonding (#73)
1 parent be90a8e commit e579722

File tree

5 files changed

+104
-18
lines changed

5 files changed

+104
-18
lines changed

app/src/main/java/com/samsung/microbit/ui/activity/PairingActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ public void run() {
255255
popupPairingFailed();
256256
}
257257
break;
258+
case AlreadyPaired:
259+
// micro:bit seems to need reset even if already paired
258260
case Paired:
259261
handlePairingSuccessful();
260262
break;

app/src/main/java/com/samsung/microbit/ui/activity/ProjectActivity.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ protected void onActivityResultPairing(int requestCode, int resultCode, Intent d
239239
case REQUEST_CODE_PAIR_BEFORE_FLASH_ALREADY_RESET:
240240
if (resultCode == RESULT_OK) {
241241
// micro:bit should still be in Bluetooth mode
242-
flashingChecks( true);
242+
flashingChecks( false);
243243
} else {
244244
onFlashComplete();
245245
}
@@ -2094,7 +2094,6 @@ public void onClick(View v) {
20942094
}
20952095
}, popupClickFlashComplete);
20962096
} else if(intent.getAction().equals(PartialFlashingService.BROADCAST_ERROR)) {
2097-
MBApp.getAppState().eventPairSendError();
20982097
final int errorCode = intent.getIntExtra(PartialFlashingService.EXTRA_DATA, 0);
20992098
String error_message = getString(R.string.connection_failed);
21002099

@@ -2108,9 +2107,16 @@ public void onClick(View v) {
21082107
case PartialFlashingService.ERROR_DFU_MODE:
21092108
error_message = getString(R.string.reset_to_dfu_mode_failed);
21102109
break;
2110+
case PartialFlashingService.ERROR_BROKEN:
2111+
error_message = getString(R.string.connection_broken);
2112+
break;
2113+
case PartialFlashingService.ERROR_BONDED:
2114+
restartPurpose();
2115+
return;
21112116
}
21122117

21132118
logi("PFResultReceiver.onReceive() :: " + error_message + " code " + errorCode);
2119+
MBApp.getAppState().eventPairSendError();
21142120

21152121
PopUp.show( error_message + "\n\n" + getString(R.string.retry),
21162122
getString(R.string.flashing_failed_title),
@@ -2400,6 +2406,10 @@ public void onClick(View v) {
24002406
error_message = getString(R.string.dfu_error_CODE, error_message);
24012407
break;
24022408
default:
2409+
if ( errorCode == DfuBaseService.ERROR_DEVICE_NOT_BONDED) {
2410+
restartPurpose();
2411+
return;
2412+
}
24032413
if ( errorCode == 0) {
24042414
error_message = getString(R.string.not_found);
24052415
} else {

app/src/main/java/com/samsung/microbit/utils/BLEPair.java

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,16 @@ public class BLEPair implements BluetoothAdapter.LeScanCallback {
6262
// Android 13 - I have seen 4 status 133s before a good connect and pair
6363
private int pairChecks = 0;
6464
private int pairTries = 0;
65-
private Boolean scanning = false;
66-
private Boolean pairing = false;
65+
private boolean scanning = false;
66+
private boolean pairing = false;
67+
private boolean waitingForDisconnect = false;
68+
private boolean wasNotBonded = false;
6769

6870
public enum enumResult {
6971
None,
7072
Found,
7173
Connected,
74+
AlreadyPaired,
7275
Paired,
7376
TimeoutScan,
7477
TimeoutConnect,
@@ -165,16 +168,49 @@ private void signalProgress( enumResult state) {
165168
}
166169

167170
@SuppressLint("MissingPermission")
168-
private void signalResultPairedIfBondedAndHardwareVersionDiscovered() {
169-
if (resultDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
170-
// Wait for service discovery to set resultHardwareVersion
171-
logi("Bonded resultHardwareVersion " + resultHardwareVersion);
172-
if ( resultHardwareVersion > 0) {
173-
signalResult(enumResult.Paired);
174-
}
171+
private boolean bondedAndHardwareVersionDiscovered() {
172+
logi("bondedAndHardwareVersionDiscovered state " + resultDevice.getBondState() + " resultHardwareVersion " + resultHardwareVersion);
173+
if ( resultDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
174+
wasNotBonded = true;
175+
return false;
176+
}
177+
// Wait for service discovery to set resultHardwareVersion
178+
if ( resultHardwareVersion <= 0) {
179+
return false;
180+
}
181+
return true;
182+
}
183+
184+
@SuppressLint("MissingPermission")
185+
private boolean startWaitingForDisconnectIfBondedAndHardwareVersionDiscovered() {
186+
if ( !bondedAndHardwareVersionDiscovered()) {
187+
return false;
175188
}
189+
// Wait for micro:bit to disconnect
190+
waitingForDisconnect = true;
191+
delayStopAll();
192+
delayStart( delayCallbackWaitingForDisconnect, 6000);
193+
logi("Start waiting for disconnect");
194+
return true;
176195
}
177196

197+
private void onDisconnect() {
198+
// If actually pairing, micro:bit will break the connection
199+
// Allow time for tick to appear
200+
logi("onDisconnect");
201+
if ( bondedAndHardwareVersionDiscovered()) {
202+
delayStopAll();
203+
delayStart( delayCallbackSignalResultPaired, 300);
204+
} else if ( waitingForDisconnect) {
205+
delayStopAll();
206+
delayStart( delayCallbackSignalResultPaired, 300);
207+
} else {
208+
logi("ERROR - disconnected");
209+
logi("Prepare delayed retry");
210+
gattState = enumGattState.Error;
211+
delayStart( delayCallbackConnect, 1000);
212+
}
213+
}
178214
private void logi(String message) {
179215
if(DEBUG) {
180216
Log.i(TAG, "### " + Thread.currentThread().getId() + " # " + message);
@@ -248,13 +284,15 @@ public void run() {
248284
}
249285
}
250286
};
251-
287+
252288
private final Runnable delayCallbackCheck = new Runnable() {
253289
@Override
254290
public void run() {
255291
logi("delayCallbackCheck pairChecks " + pairChecks);
256292
if (pairing) {
257-
signalResultPairedIfBondedAndHardwareVersionDiscovered();
293+
if ( startWaitingForDisconnectIfBondedAndHardwareVersionDiscovered()) {
294+
return;
295+
}
258296
if ( pairChecks > 0) {
259297
// We are connected and polling for bonding
260298
pairChecks -= 1;
@@ -266,6 +304,22 @@ public void run() {
266304
}
267305
};
268306

307+
private final Runnable delayCallbackWaitingForDisconnect = new Runnable() {
308+
@Override
309+
public void run() {
310+
logi("delayCallbackWaitingForDisconnect wasNotBonded = " + wasNotBonded);
311+
signalResult( wasNotBonded ? enumResult.Paired : enumResult.AlreadyPaired);
312+
}
313+
};
314+
315+
private final Runnable delayCallbackSignalResultPaired = new Runnable() {
316+
@Override
317+
public void run() {
318+
logi("delayCallbackSignalResultPaired wasNotBonded = " + wasNotBonded);
319+
signalResult( wasNotBonded ? enumResult.Paired : enumResult.AlreadyPaired);
320+
}
321+
};
322+
269323
private void delayStopAll()
270324
{
271325
logi("delayStopAll");
@@ -275,6 +329,8 @@ private void delayStopAll()
275329
mainLooperHandler.removeCallbacks( delayCallbackDiscover);
276330
mainLooperHandler.removeCallbacks( delayCallbackBond);
277331
mainLooperHandler.removeCallbacks( delayCallbackCheck);
332+
mainLooperHandler.removeCallbacks( delayCallbackWaitingForDisconnect);
333+
mainLooperHandler.removeCallbacks( delayCallbackSignalResultPaired);
278334
}
279335

280336
private void delayStop( Runnable callback)
@@ -460,8 +516,17 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
460516
return;
461517
}
462518

519+
if ( gatt.getDevice().getBondState() != BluetoothDevice.BOND_BONDED) {
520+
wasNotBonded = true;
521+
}
522+
463523
logi("onConnectionStateChange " + newState + " status " + status);
464-
if ( status != 0) {
524+
if ( status != BluetoothGatt.GATT_SUCCESS) {
525+
if ( newState == STATE_DISCONNECTED) {
526+
onDisconnect();
527+
return;
528+
}
529+
delayStopAll();
465530
pairStop();
466531
logi("ERROR - status");
467532
logi("Prepare for retry after a short delay");
@@ -487,6 +552,7 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
487552
// about 600ms after establishing connection. Values 600 - 1600ms should be OK.
488553
} else {
489554
logi("calling discoverServices()");
555+
wasNotBonded = true;
490556
gattState = enumGattState.WaitingForServices;
491557
boolean success = gatt.discoverServices();
492558
if (!success) {
@@ -502,7 +568,7 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
502568
else if( newState == STATE_DISCONNECTED) {
503569
// If actually pairing, micro:bit will break the connection
504570
logi("STATE_DISCONNECTED");
505-
delayStartCheck();
571+
onDisconnect();
506572
}
507573
}
508574

@@ -537,7 +603,10 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
537603

538604
gattState = enumGattState.ServicesDiscovered;
539605

540-
if (resultDevice.getBondState() == BluetoothDevice.BOND_NONE) {
606+
if ( startWaitingForDisconnectIfBondedAndHardwareVersionDiscovered())
607+
return;
608+
609+
if ( resultDevice.getBondState() == BluetoothDevice.BOND_NONE) {
541610
logi("Delay calling createBond() to wait for bonding to start automatically");
542611
delayStart( delayCallbackBond, 1500);
543612
}
@@ -571,6 +640,7 @@ private Boolean pairConnect() {
571640

572641
paramCallback.BLEPairGetActivity().registerReceiver( pairReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
573642

643+
waitingForDisconnect = false;
574644
resultHardwareVersion = 0;
575645
gattState = enumGattState.Connecting;
576646
pairing = true;
@@ -643,13 +713,16 @@ public void onReceive(Context context, Intent intent) {
643713
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
644714
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
645715
logi("pairReceiver -" + " name = " + name + " addr = " + addr + " state = " + state + " prevState = " + prevState);
716+
if ( state != BluetoothDevice.BOND_BONDED && prevState != BluetoothDevice.BOND_BONDED) {
717+
wasNotBonded = true;
718+
}
646719
if (name == null || name.isEmpty() || addr.isEmpty()) {
647720
return;
648721
}
649722
// Check the changed device is the one we are trying to pair
650723
if ( pairing && nameIsMicrobitWithCode(device.getName(), paramCallback.BLEPairGetDeviceCode())) {
651724
if (state == BluetoothDevice.BOND_BONDED) {
652-
signalResultPairedIfBondedAndHardwareVersionDiscovered();
725+
startWaitingForDisconnectIfBondedAndHardwareVersionDiscovered();
653726
}
654727
}
655728
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@
395395
<string name="connection_failed">Unable to connect</string>
396396
<string name="reconnection_failed">Unable to reconnect</string>
397397
<string name="reset_to_dfu_mode_failed">Unable to reset to DFU mode</string>
398+
<string name="connection_broken">Connection lost</string>
398399
<string name="retry">Retry?</string>
399400
<string name="menu_import">Import</string>
400401
<string name="menu_export">Export</string>

0 commit comments

Comments
 (0)