@@ -154,6 +154,10 @@ private enum PAIRING_STATE {
154154
155155 private boolean justPaired ;
156156
157+ private final Object lock = new Object ();
158+
159+ private int hardwareVersion = 0 ;
160+
157161 /**
158162 * Occurs after successfully finished pairing process and
159163 * redirects to the first screen of the pairing activity.
@@ -223,7 +227,7 @@ public void onReceive(Context context, Intent intent) {
223227 Log .e (TAG , "device code empty. State = " + state + ", prevState = " + prevState + "." );
224228 } else {
225229 ConnectedDevice newDev = new ConnectedDevice (newDeviceCode .toUpperCase (), newDeviceCode
226- .toUpperCase (), false , newDeviceAddress , 0 , null , System .currentTimeMillis (), 0 );
230+ .toUpperCase (), false , newDeviceAddress , 0 , null , System .currentTimeMillis (), hardwareVersion );
227231 handlePairingSuccessful (newDev );
228232 }
229233 } else if (state == BluetoothDevice .BOND_NONE && prevState == BluetoothDevice .BOND_BONDING ) {
@@ -1107,13 +1111,18 @@ public void onClick(final View v) {
11071111
11081112 case R .id .connected_device_status_button :
11091113 logi ("onClick() :: connectBtn" );
1114+ Toast .makeText (MBApp .getApp (), getString (R .string .no_longer_required_to_connect ), Toast .LENGTH_LONG ).show ();
1115+
1116+ break ;
1117+ /*
11101118 if(!BluetoothChecker.getInstance().isBluetoothON()) {
11111119 setActivityState(PairingActivityState.STATE_ENABLE_BT_FOR_CONNECT);
11121120 enableBluetooth();
11131121 return;
11141122 }
11151123 toggleConnection();
11161124 break;
1125+ */
11171126
11181127 //TODO: there is no ability to delete paired device on Connect screen, so add or remove the case.
11191128 // Delete Microbit
@@ -1396,7 +1405,12 @@ public void run() {
13961405 tvSearchingStep .setText (R .string .searching_microbit_found_message );
13971406 }
13981407 tvSearchingInstructions .setText (R .string .searching_tip_text_instructions );
1399- startPairingSecureBle (device );
1408+ try {
1409+ startPairingSecureBle (device );
1410+ } catch (InterruptedException e ) {
1411+ Log .v (TAG , "startPairingSecureBle Interrupted" );
1412+ e .printStackTrace ();
1413+ }
14001414 }
14011415 }
14021416 });
@@ -1413,7 +1427,7 @@ public void run() {
14131427 *
14141428 * @param device Device to pair with.
14151429 */
1416- private void startPairingSecureBle (BluetoothDevice device ) {
1430+ private void startPairingSecureBle (BluetoothDevice device ) throws InterruptedException {
14171431 logi ("###>>>>>>>>>>>>>>>>>>>>> startPairingSecureBle" );
14181432 // Service to connect
14191433 //Check if the device is already bonded
@@ -1426,8 +1440,33 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState
14261440
14271441 Log .v (TAG , "onConnectionStateChange" );
14281442 if (newState == STATE_CONNECTED ) {
1429- Log .v (TAG , "gattDiscoverServices" );
1430- Log .v (TAG , String .valueOf (gatt .discoverServices ()));
1443+
1444+ final boolean success = gatt .discoverServices ();
1445+
1446+ /* Taken from Nordic. See reasoning here: https://github.com/NordicSemiconductor/Android-DFU-Library/blob/e0ab213a369982ae9cf452b55783ba0bdc5a7916/dfu/src/main/java/no/nordicsemi/android/dfu/DfuBaseService.java#L888 */
1447+ if (gatt .getDevice ().getBondState () == BluetoothDevice .BOND_BONDED ) {
1448+ Log .v (TAG , "Already bonded" );
1449+ synchronized (lock ) {
1450+ try {
1451+ lock .wait (1600 );
1452+
1453+ } catch (InterruptedException e ) {
1454+ e .printStackTrace ();
1455+ }
1456+ Log .v (TAG , "Bond timeout" );
1457+ }
1458+ // After 1.6s the services are already discovered so the following gatt.discoverServices() finishes almost immediately.
1459+ // NOTE: This also works with shorted waiting time. The gatt.discoverServices() must be called after the indication is received which is
1460+ // about 600ms after establishing connection. Values 600 - 1600ms should be OK.
1461+ }
1462+ gatt .discoverServices ();
1463+
1464+ if (!success ) {
1465+ Log .e (TAG ,"ERROR_SERVICE_DISCOVERY_NOT_STARTED" );
1466+ } else {
1467+ // Wait for service discovery to clear lock
1468+ return ;
1469+ }
14311470 }
14321471
14331472 if (newState == STATE_DISCONNECTED ) {
@@ -1443,43 +1482,49 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
14431482 if (gatt .getService (UUID .fromString ("0000fe59-0000-1000-8000-00805f9b34fb" )) != null ) {
14441483 Log .v (TAG , "Hardware Type: V2" );
14451484 cD .mhardwareVersion = 2 ;
1485+ hardwareVersion = 2 ;
14461486 } else {
14471487 Log .v (TAG , "Hardware Type: V1" );
14481488 cD .mhardwareVersion = 1 ;
1489+ hardwareVersion = 1 ;
14491490 }
14501491 BluetoothUtils .setPairedMicroBit (MBApp .getApp (), cD );
1451- gatt .disconnect ();
1492+ synchronized (lock ) {
1493+ lock .notifyAll ();
1494+ }
14521495 }
14531496 };
14541497
1455- BluetoothGatt gatt = device .connectGatt (this , false , bluetoothGattCallback );
1498+ BluetoothGatt gatt = device .connectGatt (this , true , bluetoothGattCallback );
1499+ synchronized (lock ) { // Wait for services to be discovered
1500+ lock .wait ();
1501+ }
14561502
1457- if (device .getBondState () == BluetoothDevice .BOND_BONDED ) {
1458- logi ("Device is already bonded." );
14591503 stopScanning ();
14601504
1461- // Rebond
1505+ /* Rebond */
1506+ Log .v (TAG , "rebond, just in case" );
14621507 try {
14631508 Method m = device .getClass ().getMethod ("removeBond" , (Class []) null );
14641509 m .invoke (device , (Object []) null );
14651510 } catch (Exception e ) { Log .e (TAG , e .getMessage ()); }
14661511
1467- // Sleep for 200ms
1512+ // Sleep for 2000ms
14681513 try {
1469- Thread .sleep (200 );
1514+ Thread .sleep (2000 );
14701515 } catch (InterruptedException e ) {
14711516 e .printStackTrace ();
14721517 }
1473- device .createBond ();
1518+
1519+ // Create bond
1520+ boolean newbond = device .createBond ();
1521+ Log .v (TAG , "create bond: newbond" );
14741522
14751523 //Get device name from the System settings if present and add to our list
14761524 ConnectedDevice newDev = new ConnectedDevice (newDeviceCode .toUpperCase (),
14771525 newDeviceCode .toUpperCase (), false , newDeviceAddress , 0 , null ,
1478- System .currentTimeMillis (), 0 );
1526+ System .currentTimeMillis (), hardwareVersion );
14791527 handlePairingSuccessful (newDev );
1480- } else {
1481- logi ("device.createBond returns " + device .createBond ());
1482- }
14831528 }
14841529
14851530 @ Override
0 commit comments