public static void stopSensor() { if (acceptCommands()) { enqueueCommand( new SessionStopTxMessage( DexTimeKeeper.getDexTime(getTransmitterID(), JoH.tsl())), "Stop Sensor"); } }
private static void enqueueUniqueCommand(BaseMessage tm, String msg) { if (tm != null) { final Class searchClass = tm.getClass(); Ob1Work item; synchronized (commandQueue) { if (searchQueue(searchClass)) { UserError.Log.d(TAG, "Not adding duplicate: " + searchClass.getSimpleName()); 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); } backupCheck(item); } }
public static void removePendingCalibration(final int glucose) { if (Ob1G5StateMachine.deleteFirstQueueCalibration(glucose)) { JoH.static_toast_long("Deleted pending calibration for: " + Unitized.unitized_string_static(glucose)); } } }
private static void inevitableDisconnect(Ob1G5CollectionService parent, RxBleConnection connection, long guardTime) { Inevitable.task("Ob1G5 disconnect", 500 + guardTime + speakSlowlyDelay(), () -> disconnectNow(parent, connection)); }
private static void enqueueCommand(BaseMessage tm, String msg) { if (tm != null) { final Ob1Work item = new Ob1Work(tm, msg); synchronized (commandQueue) { commandQueue.add(item); } streamCheck(item); backupCheck(item); } }
UserError.Log.d(TAG, use_g5_internal_alg ? ("Requesting Glucose Data " + (usingG6() ? "G6" : "G5")) : "Requesting Sensor Data"); speakSlowly(); connection.writeCharacteristic(Control, nn(use_g5_internal_alg ? (getEGlucose() ? new EGlucoseTxMessage().byteSequence : new GlucoseTxMessage().byteSequence) : new SensorTxMessage().byteSequence)) .subscribe( characteristicValue -> { final PacketShop data_packet = classifyPacket(bytes); switch (data_packet.type) { case SensorRxMessage: if ((getVersionDetails) && (!haveFirmwareDetails())) { connection.writeCharacteristic(Control, nn(new VersionRequestTxMessage().byteSequence)) .subscribe(versionValue -> { UserError.Log.d(TAG, "Wrote version request"); UserError.Log.e(TAG, "Failed to write VersionRequestTxMessage: " + throwable); }); } else if ((getBatteryDetails) && (parent.getBatteryStatusNow || !haveCurrentBatteryStatus())) { enqueueUniqueCommand(new BatteryInfoTxMessage(), "Query battery"); parent.getBatteryStatusNow = false; processSensorRxMessage((SensorRxMessage) data_packet.msg); parent.msg("Got data"); parent.updateLast(JoH.tsl()); if (!setStoredFirmwareBytes(getTransmitterID(), bytes, true)) {
private static void authenticationProcessor(final Ob1G5CollectionService parent, final RxBleConnection connection, final byte[] readValue) { PacketShop pkt = classifyPacket(readValue); UserError.Log.d(TAG, "Read from auth request: " + pkt.type + " " + JoH.bytesToHex(readValue)); case AuthChallengeRxMessage: byte[] challengeHash = calculateChallengeHash(((AuthChallengeRxMessage) pkt.msg).challenge); if (d) UserError.Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); UserError.Log.d(TAG, "Transmitter trying auth challenge"); connection.writeCharacteristic(Authentication, nn(new BaseAuthChallengeTxMessage(challengeHash).byteSequence)) .subscribe( challenge_value -> { speakSlowly(); status_value -> { authenticationProcessor(parent, connection, status_value); }, throwable -> { if (throwable instanceof OperationSuccess) { break; threadSleep(1000);
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt()); UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence)); connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence)) .subscribe( characteristicValue -> { speakSlowly(); connection.readCharacteristic(Authentication).subscribe( readValue -> { authenticationProcessor(parent, connection, readValue); }, throwable -> { UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable); authenticationProcessor(parent, connection, bytes); threadSleep(15000);
private static void glucoseRxCommon(final BaseGlucoseRxMessage glucose, final Ob1G5CollectionService parent, final RxBleConnection connection) { if (JoH.ratelimit("ob1-g5-also-read-raw", 20)) { enqueueUniqueCommand(new SensorTxMessage(), "Also read raw"); } if (JoH.pratelimit("g5-tx-time-since", 7200) || glucose.calibrationState().warmingUp() || !DexSessionKeeper.isStarted()) { if (JoH.ratelimit("g5-tx-time-governer", 30)) { enqueueUniqueCommand(new TimeTxMessage(), "Periodic Query Time"); } } // TODO check firmware version if (glucose.calibrationState().readyForBackfill() && !parent.getBatteryStatusNow) { backFillIfNeeded(parent, connection); } processGlucoseRxMessage(parent, glucose); parent.updateLast(JoH.tsl()); parent.clearErrors(); }
public static void startSensor(long when) { if (acceptCommands()) { if (msSince(when) > MAX_START_TIME_REWIND) { when = JoH.tsl() - MAX_START_TIME_REWIND; UserError.Log.e(TAG, "Cannot rewind sensor start time beyond: " + JoH.dateTimeText(when)); } if (usingG6()) { final String code = G6CalibrationParameters.getCurrentSensorCode(); if (code == null) { UserError.Log.wtf(TAG, "Cannot start G6 sensor as calibration code not set!"); } else { UserError.Log.ueh(TAG, "Starting G6 sensor using calibration code: " + code); enqueueUniqueCommand(new SessionStartTxMessage(when, DexTimeKeeper.getDexTime(getTransmitterID(), when), code), "Start G6 Sensor"); } } else { UserError.Log.ueh(TAG, "Starting G5 sensor"); enqueueUniqueCommand(new SessionStartTxMessage(when, DexTimeKeeper.getDexTime(getTransmitterID(), when)), "Start G5 Sensor"); } } }
connection.writeCharacteristic(Authentication, nn(new KeepAliveTxMessage(60).byteSequence)) .subscribe( characteristicValue -> { UserError.Log.d(TAG, "Wrote keep-alive request successfully"); speakSlowly(); // is this really needed here? parent.unBond(); parent.instantCreateBondIfAllowed(); speakSlowly(); connection.writeCharacteristic(Authentication, nn(new BondRequestTxMessage().byteSequence)) .subscribe( bondRequestValue -> { UserError.Log.d(TAG, "Wrote bond request value: " + JoH.bytesToHex(bondRequestValue)); speakSlowly(); connection.readCharacteristic(Authentication) .observeOn(Schedulers.io()) status_value -> { UserError.Log.d(TAG, "Got status read after keepalive " + JoH.bytesToHex(status_value)); authenticationProcessor(parent, connection, status_value); throw new OperationSuccess("Bond requested"); }, throwable -> {
public static void restartSensorWithTimeTravel(long when) { if (acceptCommands()) { enqueueUniqueCommand( new SessionStopTxMessage( DexTimeKeeper.getDexTime(getTransmitterID(), when)), "Auto Stop Sensor"); final long when_started = when + SECOND_IN_MS; enqueueUniqueCommand(new SessionStartTxMessage(when, DexTimeKeeper.getDexTime(getTransmitterID(), when_started)), "Auto Start Sensor"); } }
public static void addCalibration(final int glucose, final long timestamp) { final long since = msSince(timestamp); if (since < 0) { final String msg = "Cannot send calibration in future to transmitter: " + glucose + " @ " + JoH.dateTimeText(timestamp); JoH.static_toast_long(msg); UserError.Log.wtf(TAG, msg); return; } if (since > HOUR_IN_MS) { final String msg = "Cannot send calibration older than 1 hour to transmitter: " + glucose + " @ " + JoH.dateTimeText(timestamp); JoH.static_toast_long(msg); UserError.Log.wtf(TAG, msg); return; } if ((glucose < 40 || glucose > 400)) { final String msg = "Calibration glucose value out of range: " + glucose; JoH.static_toast_long(msg); UserError.Log.wtf(TAG, msg); return; } UserError.Log.uel(TAG, "Queuing Calibration for transmitter: " + BgGraphBuilder.unitized_string_with_units_static(glucose) + " " + JoH.dateTimeText(timestamp)); // Send to potential listeners Ob1G5StateMachine.addCalibration(glucose, timestamp); Medtrum.addCalibration(glucose, timestamp); }
JoH.showNotification(devName() + " SENSOR FAILED", "Sensor reporting failed", null, Constants.G5_SENSOR_ERROR, true, true, false);
UserError.Log.d(TAG, use_g5_internal_alg ? ("Requesting Glucose Data " + (usingG6() ? "G6" : "G5")) : "Requesting Sensor Data"); speakSlowly(); connection.writeCharacteristic(Control, nn(use_g5_internal_alg ? (getEGlucose() ? new EGlucoseTxMessage().byteSequence : new GlucoseTxMessage().byteSequence) : new SensorTxMessage().byteSequence)) .subscribe( characteristicValue -> { final PacketShop data_packet = classifyPacket(bytes); switch (data_packet.type) { case SensorRxMessage: if ((getVersionDetails) && (!haveFirmwareDetails())) { connection.writeCharacteristic(Control, nn(new VersionRequestTxMessage().byteSequence)) .subscribe(versionValue -> { UserError.Log.d(TAG, "Wrote version request"); UserError.Log.e(TAG, "Failed to write VersionRequestTxMessage: " + throwable); }); } else if ((getBatteryDetails) && (parent.getBatteryStatusNow || !haveCurrentBatteryStatus())) { enqueueUniqueCommand(new BatteryInfoTxMessage(), "Query battery"); parent.getBatteryStatusNow = false; processSensorRxMessage((SensorRxMessage) data_packet.msg); parent.msg("Got data"); parent.updateLast(JoH.tsl()); if (!setStoredFirmwareBytes(getTransmitterID(), bytes, true)) {
private static void authenticationProcessor(final Ob1G5CollectionService parent, final RxBleConnection connection, final byte[] readValue) { PacketShop pkt = classifyPacket(readValue); UserError.Log.d(TAG, "Read from auth request: " + pkt.type + " " + JoH.bytesToHex(readValue)); case AuthChallengeRxMessage: byte[] challengeHash = calculateChallengeHash(((AuthChallengeRxMessage) pkt.msg).challenge); if (d) UserError.Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); UserError.Log.d(TAG, "Transmitter trying auth challenge"); connection.writeCharacteristic(Authentication, nn(new BaseAuthChallengeTxMessage(challengeHash).byteSequence)) .subscribe( challenge_value -> { speakSlowly(); status_value -> { authenticationProcessor(parent, connection, status_value); }, throwable -> { if (throwable instanceof OperationSuccess) { break; threadSleep(1000);
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt()); UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence)); connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence)) .subscribe( characteristicValue -> { speakSlowly(); connection.readCharacteristic(Authentication).subscribe( readValue -> { authenticationProcessor(parent, connection, readValue); }, throwable -> { UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable); authenticationProcessor(parent, connection, bytes); threadSleep(15000);
private static void glucoseRxCommon(final BaseGlucoseRxMessage glucose, final Ob1G5CollectionService parent, final RxBleConnection connection) { if (JoH.ratelimit("ob1-g5-also-read-raw", 20)) { enqueueUniqueCommand(new SensorTxMessage(), "Also read raw"); } if (JoH.pratelimit("g5-tx-time-since", 7200) || glucose.calibrationState().warmingUp() || !DexSessionKeeper.isStarted()) { if (JoH.ratelimit("g5-tx-time-governer", 30)) { enqueueUniqueCommand(new TimeTxMessage(), "Periodic Query Time"); } } // TODO check firmware version if (glucose.calibrationState().readyForBackfill() && !parent.getBatteryStatusNow) { backFillIfNeeded(parent, connection); } processGlucoseRxMessage(parent, glucose); parent.updateLast(JoH.tsl()); parent.clearErrors(); }
public static void startSensor(long when) { if (acceptCommands()) { if (msSince(when) > MAX_START_TIME_REWIND) { when = JoH.tsl() - MAX_START_TIME_REWIND; UserError.Log.e(TAG, "Cannot rewind sensor start time beyond: " + JoH.dateTimeText(when)); } if (usingG6()) { final String code = G6CalibrationParameters.getCurrentSensorCode(); if (code == null) { UserError.Log.wtf(TAG, "Cannot start G6 sensor as calibration code not set!"); } else { UserError.Log.ueh(TAG, "Starting G6 sensor using calibration code: " + code); enqueueUniqueCommand(new SessionStartTxMessage(when, DexTimeKeeper.getDexTime(getTransmitterID(), when), code), "Start G6 Sensor"); } } else { UserError.Log.ueh(TAG, "Starting G5 sensor"); enqueueUniqueCommand(new SessionStartTxMessage(when, DexTimeKeeper.getDexTime(getTransmitterID(), when)), "Start G5 Sensor"); } } }
connection.writeCharacteristic(Authentication, nn(new KeepAliveTxMessage(60).byteSequence)) .subscribe( characteristicValue -> { UserError.Log.d(TAG, "Wrote keep-alive request successfully"); speakSlowly(); // is this really needed here? parent.unBond(); parent.instantCreateBondIfAllowed(); speakSlowly(); connection.writeCharacteristic(Authentication, nn(new BondRequestTxMessage().byteSequence)) .subscribe( bondRequestValue -> { UserError.Log.d(TAG, "Wrote bond request value: " + JoH.bytesToHex(bondRequestValue)); speakSlowly(); connection.readCharacteristic(Authentication) .observeOn(Schedulers.io()) status_value -> { UserError.Log.d(TAG, "Got status read after keepalive " + JoH.bytesToHex(status_value)); authenticationProcessor(parent, connection, status_value); throw new OperationSuccess("Bond requested"); }, throwable -> {