From 4524141ae048e6ee1109448d072d18349a105632 Mon Sep 17 00:00:00 2001 From: Jamorham Date: Fri, 29 Jun 2018 13:16:43 +0100 Subject: [PATCH] OB1 G5: update for bonding sequence --- .../dexdrip/G5Model/DexTimeKeeper.java | 2 +- .../dexdrip/G5Model/Ob1G5StateMachine.java | 25 +++++--- .../dexdrip/G5Model/TransmitterMessage.java | 2 +- .../Services/Ob1G5CollectionService.java | 61 +++++++++++++------ .../dexdrip/G5Model/DexTimeKeeper.java | 2 +- .../dexdrip/G5Model/Ob1G5StateMachine.java | 30 +++++---- .../dexdrip/G5Model/TransmitterMessage.java | 2 +- .../Services/Ob1G5CollectionService.java | 61 +++++++++++++------ 8 files changed, 126 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java index 86661b450b..cc70c73747 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java @@ -65,7 +65,7 @@ public static int getDexTime(String transmitterId, long timestamp) { return -4; } lastTransmitterId = transmitterId; - return (int) (ms_since / 1000); + return (int) (ms_since / 1000L); } public static long fromDexTimeCached(int dexTimeStamp) { diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java index 5852eb235f..081e1b5ece 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java @@ -5,6 +5,7 @@ import android.os.Build; import android.os.PowerManager; +import com.eveningoutpost.dexdrip.ImportedLibraries.usbserial.util.HexDump; import com.eveningoutpost.dexdrip.Models.BgReading; import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.Sensor; @@ -27,13 +28,6 @@ import com.polidea.rxandroidble.exceptions.BleDisconnectedException; import com.polidea.rxandroidble.exceptions.BleGattCharacteristicException; - -/* -import com.polidea.rxandroidble2.RxBleConnection; -import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; -import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; -import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; -*/ import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.nio.ByteBuffer; @@ -72,6 +66,13 @@ import static com.eveningoutpost.dexdrip.UtilityModels.Constants.MINUTE_IN_MS; import static com.eveningoutpost.dexdrip.UtilityModels.Constants.SECOND_IN_MS; +/* +import com.polidea.rxandroidble2.RxBleConnection; +import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; +import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; +import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; +*/ + /** * Created by jamorham on 17/09/2017. @@ -313,7 +314,7 @@ public synchronized static boolean doKeepAliveAndBondRequest(Ob1G5CollectionServ UserError.Log.d(TAG, "Wrote keep-alive request successfully"); speakSlowly(); // is this really needed here? parent.unBond(); - parent.instantCreateBond(); + parent.instantCreateBondIfAllowed(); speakSlowly(); connection.writeCharacteristic(Authentication, new BondRequestTxMessage().byteSequence) .subscribe( @@ -330,7 +331,7 @@ public synchronized static boolean doKeepAliveAndBondRequest(Ob1G5CollectionServ UserError.Log.d(TAG, "Wrote bond request successfully"); parent.waitingBondConfirmation = 1; // waiting - parent.instantCreateBond(); + parent.instantCreateBondIfAllowed(); UserError.Log.d(TAG, "Sleeping for bond"); for (int i = 0; i < 9; i++) { if (parent.waitingBondConfirmation == 2) { @@ -722,6 +723,9 @@ private static void enqueueUniqueCommand(TransmitterMessage tm, String msg) { return; } item = new Ob1Work(tm, msg); + if (d) { + UserError.Log.d(TAG, "Adding to queue packet: " + msg + " " + HexDump.dumpHexString(tm.byteSequence)); + } commandQueue.add(item); streamCheck(item); } @@ -892,6 +896,9 @@ private static void reprocessTxMessage(TransmitterMessage tm) { tm.byteSequence = new SessionStartTxMessage(ssm.getStartTime(), DexTimeKeeper.getDexTime(getTransmitterID(), ssm.getStartTime())).byteSequence; } UserError.Log.d(TAG, "New session start: " + ssm.getDexTime() + " for time: " + JoH.dateTimeText(ssm.getStartTime())); + if (d) { + UserError.Log.d(TAG, "New packet: " + HexDump.dumpHexString(tm.byteSequence)); + } } } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java index b15b4d0835..211cbf2f9b 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java @@ -18,7 +18,7 @@ public class TransmitterMessage { long postExecuteGuardTime = 50; @Expose - public byte[] byteSequence = null; + public volatile byte[] byteSequence = null; public ByteBuffer data = null; diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java index 68e75e1a61..369ae4c39e 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java @@ -174,7 +174,8 @@ public class Ob1G5CollectionService extends G5BaseService { private static final boolean d = false; - private static boolean always_scan = false; + private static volatile boolean always_scan = false; + private static volatile boolean scan_next_run = true; private static boolean always_discover = false; private static boolean always_connect = false; private static boolean do_discovery = true; @@ -302,8 +303,12 @@ private synchronized void automata() { } break; case BOND: + if (getInitiateBondingFlag()) { + UserError.Log.d(TAG, "State bond attempting to create bond"); + } else { + UserError.Log.d(TAG, "State bond currently does nothing as setting disabled"); + } create_bond(); - UserError.Log.d(TAG, "State bond may currently do nothing depending on settings"); break; case RESET: UserError.Log.d(TAG, "Entering hard reset state"); @@ -376,7 +381,8 @@ private synchronized void scan_for_device() { msg("Scanning"); stopScan(); tryLoadingSavedMAC(); // did we already find it? - if (always_scan || (transmitterMAC == null) || (!transmitterID.equals(transmitterIDmatchingMAC)) || (static_last_timestamp < 1)) { + if (always_scan || scan_next_run || (transmitterMAC == null) || (!transmitterID.equals(transmitterIDmatchingMAC)) || (static_last_timestamp < 1)) { + scan_next_run = false; // reset if set transmitterMAC = null; // reset if set last_scan_started = JoH.tsl(); scanWakeLock = JoH.getWakeLock("xdrip-jam-g5-scan", (int) Constants.MINUTE_IN_MS * 6); @@ -510,11 +516,20 @@ public synchronized void reset_bond(boolean allow) { } private synchronized void do_create_bond() { - UserError.Log.d(TAG, "Attempting to create bond, device is : " + (isDeviceLocallyBonded() ? "BONDED" : "NOT Bonded")); - try { - instantCreateBond(); - } catch (Exception e) { - UserError.Log.wtf(TAG, "Got exception in do_create_bond() " + e); + final boolean isDeviceLocallyBonded = isDeviceLocallyBonded(); + UserError.Log.d(TAG, "Attempting to create bond, device is : " + (isDeviceLocallyBonded ? "BONDED" : "NOT Bonded")); + + if (isDeviceLocallyBonded && getInitiateBondingFlag()) { + UserError.Log.d(TAG,"Device is marked as bonded but we are being asked to bond so attempting to unbond first"); + unbondIfAllowed(); + changeState(CLOSE); + } else { + + try { + instantCreateBondIfAllowed(); + } catch (Exception e) { + UserError.Log.wtf(TAG, "Got exception in do_create_bond() " + e); + } } } @@ -928,6 +943,21 @@ private synchronized void onScanFailure(Throwable throwable) { } } + private void unbondIfAllowed() { + if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { + unBond(); + } else { + UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it. (unbond)"); + } + } + + private void resetBondIfAllowed(boolean force) { + if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { + reset_bond(force); + } else { + UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it. (resetbond)"); + } + } // Connection has been terminated or failed // - quite normal when device switches to sleep between readings @@ -938,11 +968,7 @@ private void onConnectionFailure(Throwable throwable) { if (state == DISCOVER) { // possible encryption failure - if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { - reset_bond(false); - } else { - UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it."); - } + resetBondIfAllowed(false); } if (state == STATE.CONNECT_NOW) { @@ -1202,7 +1228,7 @@ public void onReceive(Context context, Intent intent) { } catch (InterruptedException e) { // } - instantCreateBond(); + instantCreateBondIfAllowed(); } } } @@ -1214,7 +1240,7 @@ public void onReceive(Context context, Intent intent) { } }; - public void instantCreateBond() { + public void instantCreateBondIfAllowed() { if (getInitiateBondingFlag()) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -1225,7 +1251,7 @@ public void instantCreateBond() { UserError.Log.e(TAG, "Got exception in instantCreateBond() " + e); } } else { - UserError.Log.e(TAG, "instantCreateBond blocked by initiate_bonding flag"); + UserError.Log.e(TAG, "instantCreateBond blocked by lack of initiate_bonding flag"); } } @@ -1551,8 +1577,9 @@ public void run() { public static void resetSomeInternalState() { UserError.Log.d(TAG, "Resetting internal state by request"); - transmitterMAC = null; + transmitterMAC = null; // probably gets reloaded from cache state = INIT; + scan_next_run = true; } // remember needs proguard exclusion due to access by reflection diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java index 86661b450b..cc70c73747 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/DexTimeKeeper.java @@ -65,7 +65,7 @@ public static int getDexTime(String transmitterId, long timestamp) { return -4; } lastTransmitterId = transmitterId; - return (int) (ms_since / 1000); + return (int) (ms_since / 1000L); } public static long fromDexTimeCached(int dexTimeStamp) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java index 71e507aaf6..081e1b5ece 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java @@ -5,6 +5,7 @@ import android.os.Build; import android.os.PowerManager; +import com.eveningoutpost.dexdrip.ImportedLibraries.usbserial.util.HexDump; import com.eveningoutpost.dexdrip.Models.BgReading; import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.Sensor; @@ -27,13 +28,6 @@ import com.polidea.rxandroidble.exceptions.BleDisconnectedException; import com.polidea.rxandroidble.exceptions.BleGattCharacteristicException; - -/* -import com.polidea.rxandroidble2.RxBleConnection; -import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; -import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; -import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; -*/ import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.nio.ByteBuffer; @@ -72,6 +66,13 @@ import static com.eveningoutpost.dexdrip.UtilityModels.Constants.MINUTE_IN_MS; import static com.eveningoutpost.dexdrip.UtilityModels.Constants.SECOND_IN_MS; +/* +import com.polidea.rxandroidble2.RxBleConnection; +import com.polidea.rxandroidble2.exceptions.BleCannotSetCharacteristicNotificationException; +import com.polidea.rxandroidble2.exceptions.BleDisconnectedException; +import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException; +*/ + /** * Created by jamorham on 17/09/2017. @@ -313,7 +314,7 @@ public synchronized static boolean doKeepAliveAndBondRequest(Ob1G5CollectionServ UserError.Log.d(TAG, "Wrote keep-alive request successfully"); speakSlowly(); // is this really needed here? parent.unBond(); - parent.instantCreateBond(); + parent.instantCreateBondIfAllowed(); speakSlowly(); connection.writeCharacteristic(Authentication, new BondRequestTxMessage().byteSequence) .subscribe( @@ -330,7 +331,7 @@ public synchronized static boolean doKeepAliveAndBondRequest(Ob1G5CollectionServ UserError.Log.d(TAG, "Wrote bond request successfully"); parent.waitingBondConfirmation = 1; // waiting - parent.instantCreateBond(); + parent.instantCreateBondIfAllowed(); UserError.Log.d(TAG, "Sleeping for bond"); for (int i = 0; i < 9; i++) { if (parent.waitingBondConfirmation == 2) { @@ -722,6 +723,9 @@ private static void enqueueUniqueCommand(TransmitterMessage tm, String msg) { return; } item = new Ob1Work(tm, msg); + if (d) { + UserError.Log.d(TAG, "Adding to queue packet: " + msg + " " + HexDump.dumpHexString(tm.byteSequence)); + } commandQueue.add(item); streamCheck(item); } @@ -892,6 +896,9 @@ private static void reprocessTxMessage(TransmitterMessage tm) { tm.byteSequence = new SessionStartTxMessage(ssm.getStartTime(), DexTimeKeeper.getDexTime(getTransmitterID(), ssm.getStartTime())).byteSequence; } UserError.Log.d(TAG, "New session start: " + ssm.getDexTime() + " for time: " + JoH.dateTimeText(ssm.getStartTime())); + if (d) { + UserError.Log.d(TAG, "New packet: " + HexDump.dumpHexString(tm.byteSequence)); + } } } @@ -1024,7 +1031,7 @@ private static void processGlucoseRxMessage(Ob1G5CollectionService parent, Gluco DexTimeKeeper.updateAge(getTransmitterID(), glucose.timestamp); if (glucose.usable() || (glucose.insufficient() && Pref.getBooleanDefaultFalse("ob1_g5_use_insufficiently_calibrated"))) { UserError.Log.d(TAG, "Got usable glucose data from G5!!"); - final BgReading bgReading = BgReading.bgReadingInsertFromG5(glucose.glucose, JoH.tsl()); + final BgReading bgReading = BgReading.bgReadingInsertFromG5(glucose.glucose, JoH.tsl(), null); if (bgReading != null) { try { bgReading.calculated_value_slope = glucose.getTrend() / Constants.MINUTE_IN_MS; // note this is different to the typical calculated slope, (normally delta) @@ -1232,8 +1239,7 @@ private static void processBacksies(List backsies) { UserError.Log.wtf(TAG, "Backfill timestamp unrealistic: " + JoH.dateTimeText(time) + " (ignored)"); } else { if (BgReading.getForPreciseTimestamp(time, Constants.MINUTE_IN_MS * 4) == null) { - final BgReading bgr = BgReading.bgReadingInsertFromG5(backsie.getGlucose(), time); - if (bgr != null) bgr.appendSourceInfo("Backfill"); + final BgReading bgr = BgReading.bgReadingInsertFromG5(backsie.getGlucose(), time, "Backfill"); lastGlucoseBgReading = bgr; UserError.Log.d(TAG, "Adding backfilled reading: " + JoH.dateTimeText(time) + " " + BgGraphBuilder.unitized_string_static(backsie.getGlucose())); changed = true; diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java index b15b4d0835..211cbf2f9b 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/TransmitterMessage.java @@ -18,7 +18,7 @@ public class TransmitterMessage { long postExecuteGuardTime = 50; @Expose - public byte[] byteSequence = null; + public volatile byte[] byteSequence = null; public ByteBuffer data = null; diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java index 68e75e1a61..369ae4c39e 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Services/Ob1G5CollectionService.java @@ -174,7 +174,8 @@ public class Ob1G5CollectionService extends G5BaseService { private static final boolean d = false; - private static boolean always_scan = false; + private static volatile boolean always_scan = false; + private static volatile boolean scan_next_run = true; private static boolean always_discover = false; private static boolean always_connect = false; private static boolean do_discovery = true; @@ -302,8 +303,12 @@ private synchronized void automata() { } break; case BOND: + if (getInitiateBondingFlag()) { + UserError.Log.d(TAG, "State bond attempting to create bond"); + } else { + UserError.Log.d(TAG, "State bond currently does nothing as setting disabled"); + } create_bond(); - UserError.Log.d(TAG, "State bond may currently do nothing depending on settings"); break; case RESET: UserError.Log.d(TAG, "Entering hard reset state"); @@ -376,7 +381,8 @@ private synchronized void scan_for_device() { msg("Scanning"); stopScan(); tryLoadingSavedMAC(); // did we already find it? - if (always_scan || (transmitterMAC == null) || (!transmitterID.equals(transmitterIDmatchingMAC)) || (static_last_timestamp < 1)) { + if (always_scan || scan_next_run || (transmitterMAC == null) || (!transmitterID.equals(transmitterIDmatchingMAC)) || (static_last_timestamp < 1)) { + scan_next_run = false; // reset if set transmitterMAC = null; // reset if set last_scan_started = JoH.tsl(); scanWakeLock = JoH.getWakeLock("xdrip-jam-g5-scan", (int) Constants.MINUTE_IN_MS * 6); @@ -510,11 +516,20 @@ public synchronized void reset_bond(boolean allow) { } private synchronized void do_create_bond() { - UserError.Log.d(TAG, "Attempting to create bond, device is : " + (isDeviceLocallyBonded() ? "BONDED" : "NOT Bonded")); - try { - instantCreateBond(); - } catch (Exception e) { - UserError.Log.wtf(TAG, "Got exception in do_create_bond() " + e); + final boolean isDeviceLocallyBonded = isDeviceLocallyBonded(); + UserError.Log.d(TAG, "Attempting to create bond, device is : " + (isDeviceLocallyBonded ? "BONDED" : "NOT Bonded")); + + if (isDeviceLocallyBonded && getInitiateBondingFlag()) { + UserError.Log.d(TAG,"Device is marked as bonded but we are being asked to bond so attempting to unbond first"); + unbondIfAllowed(); + changeState(CLOSE); + } else { + + try { + instantCreateBondIfAllowed(); + } catch (Exception e) { + UserError.Log.wtf(TAG, "Got exception in do_create_bond() " + e); + } } } @@ -928,6 +943,21 @@ private synchronized void onScanFailure(Throwable throwable) { } } + private void unbondIfAllowed() { + if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { + unBond(); + } else { + UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it. (unbond)"); + } + } + + private void resetBondIfAllowed(boolean force) { + if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { + reset_bond(force); + } else { + UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it. (resetbond)"); + } + } // Connection has been terminated or failed // - quite normal when device switches to sleep between readings @@ -938,11 +968,7 @@ private void onConnectionFailure(Throwable throwable) { if (state == DISCOVER) { // possible encryption failure - if (Pref.getBoolean("ob1_g5_allow_resetbond", true)) { - reset_bond(false); - } else { - UserError.Log.e(TAG, "Would have tried to unpair but preference setting prevents it."); - } + resetBondIfAllowed(false); } if (state == STATE.CONNECT_NOW) { @@ -1202,7 +1228,7 @@ public void onReceive(Context context, Intent intent) { } catch (InterruptedException e) { // } - instantCreateBond(); + instantCreateBondIfAllowed(); } } } @@ -1214,7 +1240,7 @@ public void onReceive(Context context, Intent intent) { } }; - public void instantCreateBond() { + public void instantCreateBondIfAllowed() { if (getInitiateBondingFlag()) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -1225,7 +1251,7 @@ public void instantCreateBond() { UserError.Log.e(TAG, "Got exception in instantCreateBond() " + e); } } else { - UserError.Log.e(TAG, "instantCreateBond blocked by initiate_bonding flag"); + UserError.Log.e(TAG, "instantCreateBond blocked by lack of initiate_bonding flag"); } } @@ -1551,8 +1577,9 @@ public void run() { public static void resetSomeInternalState() { UserError.Log.d(TAG, "Resetting internal state by request"); - transmitterMAC = null; + transmitterMAC = null; // probably gets reloaded from cache state = INIT; + scan_next_run = true; } // remember needs proguard exclusion due to access by reflection