正在查看: xDrip+ v04633772025.07.16 应用的 PendiqService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 PendiqService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.insulin.pendiq;
import android.bluetooth.BluetoothGattService;
import android.os.PowerManager;
import com.eveningoutpost.dexdrip.Home;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.driver.UsbId;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.util.HexDump;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.InsulinLogRx;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.InsulinLogTx;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.SetInjectTx;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.SetTimeTx;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.StatusRx;
import com.eveningoutpost.dexdrip.insulin.pendiq.messages.StatusTx;
import com.eveningoutpost.dexdrip.models.BgReading;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.Treatments;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.services.JamBaseBluetoothService;
import com.eveningoutpost.dexdrip.utilitymodels.Inevitable;
import com.eveningoutpost.dexdrip.utilitymodels.RxBleProvider;
import com.eveningoutpost.dexdrip.utils.bt.Subscription;
import com.eveningoutpost.dexdrip.xdrip;
import com.polidea.rxandroidble2.RxBleClient;
import com.polidea.rxandroidble2.RxBleConnection;
import com.polidea.rxandroidble2.RxBleDevice;
import com.polidea.rxandroidble2.RxBleDeviceServices;
import com.polidea.rxandroidble2.exceptions.BleDisconnectedException;
import com.polidea.rxandroidble2.exceptions.BleScanException;
import com.polidea.rxandroidble2.scan.ScanFilter;
import com.polidea.rxandroidble2.scan.ScanResult;
import com.polidea.rxandroidble2.scan.ScanSettings;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class PendiqService extends JamBaseBluetoothService {
private static volatile String address;
private static volatile Subscription connectionSubscription;
private static volatile PowerManager.WakeLock connection_linger;
private static volatile Subscription discoverSubscription;
private static volatile String name;
private static volatile Subscription scanSubscription;
private static volatile Subscription stateSubscription;
private volatile RxBleDevice bleDevice;
private volatile RxBleConnection connection;
private volatile int loaded_records;
private static volatile STATE state = STATE.INIT;
private static volatile STATE last_automata_state = STATE.CLOSED;
private final RxBleClient rxBleClient = RxBleProvider.getSingleton();
private volatile long lastProcessedIncomingData = -1;
private volatile double dose_prep_waiting = -1.0d;
private final ConcurrentLinkedQueue<QueueItem> write_queue = new ConcurrentLinkedQueue<>();
private boolean auto_connect = false;
public static ObservableSource lambda$enableNotification$2(Observable observable) throws Exception {
return observable;
}
public PendiqService() {
this.TAG = getClass().getSimpleName();
}
public enum STATE {
INIT("Initializing"),
SCAN("Scanning"),
CONNECT("Waiting connect"),
CONNECT_NOW("Power connect"),
DISCOVER("Examining"),
GET_STATUS("Checking Status"),
SET_TIME("Setting time"),
DOSE_PREP("Prepare dose"),
GET_HISTORY("Getting history"),
CLOSE("Sleeping"),
CLOSED("Deep Sleeping"),
SLEEP("Light Sleep");
private static List<STATE> sequence;
private String str;
static {
STATE state = GET_STATUS;
STATE state2 = SET_TIME;
STATE state3 = DOSE_PREP;
STATE state4 = GET_HISTORY;
STATE state5 = SLEEP;
ArrayList arrayList = new ArrayList();
sequence = arrayList;
arrayList.add(state);
sequence.add(state3);
sequence.add(state2);
sequence.add(state4);
sequence.add(state5);
}
STATE(String str) {
this.str = str;
}
public STATE next() {
try {
List<STATE> list = sequence;
return list.get(list.indexOf(this) + 1);
} catch (Exception unused) {
return SLEEP;
}
}
}
public synchronized void changeState(STATE state2) {
if (state == null) {
return;
}
if (state == state2 && state != STATE.INIT) {
STATE state3 = state;
STATE state4 = STATE.CLOSE;
if (state3 != state4) {
UserError.Log.d(this.TAG, "Already in state: " + state2 + " changing to CLOSE");
changeState(state4);
}
} else if ((state == STATE.CLOSED || state == STATE.CLOSE) && state2 == STATE.CLOSE) {
UserError.Log.d(this.TAG, "Not closing as already closed");
} else {
UserError.Log.d(this.TAG, "Changing state from: " + state + " to " + state2);
state = state2;
background_automata();
}
}
@Override
protected synchronized boolean automata() {
UserError.Log.d(this.TAG, "automata state: " + state);
extendWakeLock(3000L);
switch (AnonymousClass2.$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[state.ordinal()]) {
case 1:
initialize();
break;
case 2:
scan_for_device();
break;
case 3:
connect_to_device(true);
break;
case 4:
connect_to_device(false);
break;
case 5:
discover_services();
break;
case 6:
getStatus();
break;
case 7:
dosePrep();
break;
case 8:
setTime();
break;
case 9:
this.loaded_records = 0;
getInsulinLog();
break;
case 10:
if (!this.auto_connect) {
stopConnect();
break;
}
break;
}
return true;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
stopScan();
super.onDestroy();
}
@Override
public int onStartCommand(android.content.Intent r7, int r8, int r9) {
throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.insulin.pendiq.PendiqService.onStartCommand(android.content.Intent, int, int):int");
}
private void decideServiceStartStateChange() {
int i = AnonymousClass2.$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[state.ordinal()];
changeState(STATE.INIT);
}
private void initialize() {
changeState(STATE.SCAN);
}
private synchronized void scan_for_device() {
extendWakeLock(31000L);
stopScan();
scanSubscription = new Subscription(this.rxBleClient.scanBleDevices(new ScanSettings.Builder().setCallbackType(1).setScanMode(2).build(), new ScanFilter[0]).timeout(30L, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onScanResult((ScanResult) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onScanFailure((Throwable) obj);
}
}));
Inevitable.task("stop_pendiq_scan", 30000L, new Runnable() {
@Override
public final void run() {
PendiqService.this.stopScan();
}
});
}
public synchronized void stopScan() {
UserError.Log.d(this.TAG, "stopScan called");
if (scanSubscription != null) {
scanSubscription.unsubscribe();
UserError.Log.d(this.TAG, "stopScan stopped scan");
scanSubscription = null;
Inevitable.kill("stop_pendiq_scan");
}
}
private synchronized void stopConnect() {
UserError.Log.d(this.TAG, "Stopping connection with: " + address);
if (connectionSubscription != null) {
connectionSubscription.unsubscribe();
}
if (stateSubscription != null) {
stateSubscription.unsubscribe();
}
}
private synchronized void stopDiscover() {
if (discoverSubscription != null) {
discoverSubscription.unsubscribe();
}
}
public synchronized void onScanResult(ScanResult scanResult) {
int rssi = scanResult.getRssi();
if (rssi > -80) {
String name2 = scanResult.getBleDevice().getName();
boolean isPendiqName = Pendiq.isPendiqName(name2);
String str = this.TAG;
StringBuilder sb = new StringBuilder();
sb.append("Found a device with name: ");
sb.append(name2);
sb.append(" rssi: ");
sb.append(rssi);
sb.append(" ");
sb.append(isPendiqName ? "-> MATCH" : "");
UserError.Log.d(str, sb.toString());
if (isPendiqName) {
stopScan();
address = scanResult.getBleDevice().getMacAddress();
name = name2;
UserError.Log.d(this.TAG, "Set address to: " + address);
if (this.auto_connect) {
changeState(STATE.CONNECT);
} else {
changeState(STATE.CONNECT_NOW);
}
}
} else if (JoH.quietratelimit("log-low-rssi", 2)) {
UserError.Log.d(this.TAG, "Low rssi device: " + scanResult.getBleDevice().getMacAddress());
}
}
public synchronized void onScanFailure(Throwable th) {
UserError.Log.d(this.TAG, "onScanFailure: " + th);
if (th instanceof BleScanException) {
UserError.Log.d(this.TAG, handleBleScanException((BleScanException) th));
if (((BleScanException) th).getReason() == 1 && JoH.ratelimit("bluetooth_toggle_on", 30)) {
UserError.Log.d(this.TAG, "Pause before Turn Bluetooth on");
try {
Thread.sleep(2000L);
} catch (InterruptedException unused) {
}
UserError.Log.e(this.TAG, "Trying to Turn Bluetooth on");
JoH.setBluetoothEnabled(xdrip.getAppContext(), true);
}
}
stopScan();
releaseWakeLock();
background_automata(5000);
}
private synchronized void connect_to_device(boolean z) {
if (state != STATE.CONNECT && state != STATE.CONNECT_NOW) {
UserError.Log.wtf(this.TAG, "Attempt to connect when not in CONNECT state");
}
if (address != null) {
if (state == STATE.CONNECT_NOW) {
if (connection_linger != null) {
JoH.releaseWakeLock(connection_linger);
}
connection_linger = JoH.getWakeLock("jam-pendiq-pconnect", UsbId.SILABS_CP2102);
}
stopConnect();
this.bleDevice = this.rxBleClient.getBleDevice(address);
stateSubscription = new Subscription(this.bleDevice.observeConnectionStateChanges().subscribeOn(Schedulers.io()).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onConnectionStateChange((RxBleConnection.RxBleConnectionState) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$connect_to_device$0((Throwable) obj);
}
}));
connectionSubscription = new Subscription(this.bleDevice.establishConnection(z).timeout(7L, TimeUnit.MINUTES).subscribeOn(Schedulers.io()).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onConnectionReceived((RxBleConnection) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onConnectionFailure((Throwable) obj);
}
}));
} else {
UserError.Log.wtf(this.TAG, "No transmitter mac address!");
changeState(STATE.SCAN);
}
}
public void lambda$connect_to_device$0(Throwable th) throws Exception {
UserError.Log.wtf(this.TAG, "Got Error from state subscription: " + th);
}
static class AnonymousClass2 {
static final int[] $SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE;
static final int[] $SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState;
static {
int[] iArr = new int[RxBleConnection.RxBleConnectionState.values().length];
$SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState = iArr;
try {
iArr[RxBleConnection.RxBleConnectionState.CONNECTING.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
$SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState[RxBleConnection.RxBleConnectionState.CONNECTED.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
$SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState[RxBleConnection.RxBleConnectionState.DISCONNECTING.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
try {
$SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState[RxBleConnection.RxBleConnectionState.DISCONNECTED.ordinal()] = 4;
} catch (NoSuchFieldError unused4) {
}
int[] iArr2 = new int[STATE.values().length];
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE = iArr2;
try {
iArr2[STATE.INIT.ordinal()] = 1;
} catch (NoSuchFieldError unused5) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.SCAN.ordinal()] = 2;
} catch (NoSuchFieldError unused6) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.CONNECT.ordinal()] = 3;
} catch (NoSuchFieldError unused7) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.CONNECT_NOW.ordinal()] = 4;
} catch (NoSuchFieldError unused8) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.DISCOVER.ordinal()] = 5;
} catch (NoSuchFieldError unused9) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.GET_STATUS.ordinal()] = 6;
} catch (NoSuchFieldError unused10) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.DOSE_PREP.ordinal()] = 7;
} catch (NoSuchFieldError unused11) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.SET_TIME.ordinal()] = 8;
} catch (NoSuchFieldError unused12) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.GET_HISTORY.ordinal()] = 9;
} catch (NoSuchFieldError unused13) {
}
try {
$SwitchMap$com$eveningoutpost$dexdrip$insulin$pendiq$PendiqService$STATE[STATE.CLOSE.ordinal()] = 10;
} catch (NoSuchFieldError unused14) {
}
}
}
public synchronized void onConnectionStateChange(RxBleConnection.RxBleConnectionState rxBleConnectionState) {
String str = "Unknown";
int i = AnonymousClass2.$SwitchMap$com$polidea$rxandroidble2$RxBleConnection$RxBleConnectionState[rxBleConnectionState.ordinal()];
if (i == 1) {
str = "Connecting";
} else if (i == 2) {
str = "Connected";
} else if (i == 3) {
str = "Disconnecting";
} else if (i == 4) {
str = "Disconnected";
}
UserError.Log.d(this.TAG, str);
str.equals("Disconnecting");
}
public void onConnectionReceived(RxBleConnection rxBleConnection) {
if (connection_linger != null) {
JoH.releaseWakeLock(connection_linger);
}
this.connection = rxBleConnection;
if (JoH.ratelimit("pendiq-to-discover", 1)) {
changeState(STATE.DISCOVER);
}
}
public void onConnectionFailure(Throwable th) {
UserError.Log.d(this.TAG, "Connection Disconnected/Failed: " + th);
stopConnect();
changeState(STATE.CLOSE);
JoH.releaseWakeLock(connection_linger);
}
private synchronized void discover_services() {
if (state == STATE.DISCOVER) {
if (this.connection != null) {
stopDiscover();
discoverSubscription = new Subscription(this.connection.discoverServices(10L, TimeUnit.SECONDS).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onServicesDiscovered((RxBleDeviceServices) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.onDiscoverFailed((Throwable) obj);
}
}));
} else {
UserError.Log.e(this.TAG, "No connection when in DISCOVER state - reset");
changeState(STATE.INIT);
}
} else {
UserError.Log.wtf(this.TAG, "Attempt to discover when not in DISCOVER state");
}
}
public void onServicesDiscovered(RxBleDeviceServices rxBleDeviceServices) {
Iterator it = rxBleDeviceServices.getBluetoothGattServices().iterator();
while (it.hasNext()) {
if (((BluetoothGattService) it.next()).getUuid().equals(Const.PENDIQ_SERVICE)) {
enableNotification();
return;
}
}
UserError.Log.e(this.TAG, "Could not locate Pendiq service during discovery on " + address + " called: " + name);
}
public void onDiscoverFailed(Throwable th) {
UserError.Log.e(this.TAG, "Discover failure: " + th.toString());
stopConnect();
changeState(STATE.CLOSE);
}
private void enableNotification() {
UserError.Log.d(this.TAG, "Enabling notifications");
this.connection.setupNotification(Const.INCOMING_CHAR).timeout(15L, TimeUnit.SECONDS).doOnNext(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$enableNotification$1((Observable) obj);
}
}).flatMap(new Function() {
public final Object apply(Object obj) {
ObservableSource lambda$enableNotification$2;
lambda$enableNotification$2 = PendiqService.lambda$enableNotification$2((Observable) obj);
return lambda$enableNotification$2;
}
}).observeOn(Schedulers.newThread()).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$enableNotification$3((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$enableNotification$4((Throwable) obj);
}
});
}
public void lambda$enableNotification$1(Observable observable) throws Exception {
JoH.threadSleep(1000L);
changeState(STATE.GET_STATUS);
}
public void lambda$enableNotification$4(Throwable th) throws Exception {
if (!(th instanceof TimeoutException)) {
UserError.Log.e(this.TAG, "Throwable inside setup notification: " + th);
} else {
UserError.Log.d(this.TAG, "OUTER TIMEOUT INSIDE NOTIFICATION LISTENER");
}
stopConnect();
}
private boolean gotData() {
return JoH.msSince(this.lastProcessedIncomingData) < 15000;
}
public void lambda$enableNotification$3(byte[] bArr) {
this.lastProcessedIncomingData = JoH.tsl();
List<byte[]> addBytes = PacketStream.addBytes(bArr);
if (addBytes != null) {
for (byte[] bArr2 : addBytes) {
if (bArr2 != null) {
UserError.Log.d(this.TAG, "Received decoded: " + HexDump.dumpHexString(bArr2) + " " + bArr2.length);
int errorCode = Pendiq.getErrorCode(bArr2);
if (errorCode > 0) {
UserError.Log.e(this.TAG, "Got error code: " + errorCode + " on " + HexDump.dumpHexString(bArr2));
} else if (Pendiq.isResultPacket(bArr2)) {
int resultPacketType = Pendiq.getResultPacketType(bArr2);
if (resultPacketType == 1) {
handleStatusRecord(bArr2);
} else if (resultPacketType == 4) {
handleInsulinRecord(bArr2);
Inevitable.task("pendiq-logs-done", 2000L, new Runnable() {
@Override
public final void run() {
PendiqService.this.lambda$processAndAction$5();
}
});
} else {
UserError.Log.e(this.TAG, "Unhandled result packet type: " + Pendiq.getResultPacketType(bArr2) + " " + HexDump.dumpHexString(bArr2));
changeState(state.next());
}
} else if (Pendiq.isProgressPacket(bArr2)) {
UserError.Log.d(this.TAG, "Progress packet classified - success");
changeState(state.next());
} else if (Pendiq.isReportPacket(bArr2)) {
UserError.Log.d(this.TAG, "Live report packet received");
if (JoH.ratelimit("pendiq-restart-poll", 60)) {
UserError.Log.d(this.TAG, "Retstarting sequence in 5 seconds");
Inevitable.task("pendiq-restart-sequence", 5000L, new Runnable() {
@Override
public final void run() {
PendiqService.this.lambda$processAndAction$6();
}
});
}
}
}
}
}
}
public void lambda$processAndAction$5() {
changeState(state.next());
}
public void lambda$processAndAction$6() {
changeState(STATE.GET_STATUS);
}
private void handleStatusRecord(byte[] bArr) {
UserError.Log.d(this.TAG, "Received status record");
StatusRx statusRx = new StatusRx(bArr);
UserError.Log.d(this.TAG, statusRx.getLastDateString() + statusRx.toS());
if (Pendiq.checkPin(statusRx.pin)) {
if (!JoH.ratelimit("status-record-no-wakeup-dupe", 2)) {
UserError.Log.d(this.TAG, "Ignoring duplicate status transition due to possible dupe from wake up");
return;
} else if (this.dose_prep_waiting > BgReading.BESTOFFSET) {
changeState(STATE.DOSE_PREP);
return;
} else {
changeState(STATE.SET_TIME);
return;
}
}
if (JoH.ratelimit("pendiq pin mismatch", 600)) {
UserError.Log.wtf(this.TAG, "Pin doesn't match on device: " + address + " called: " + name);
changeState(STATE.CLOSE);
}
}
private void handleInsulinRecord(byte[] bArr) {
boolean isResultPacketOk = Pendiq.isResultPacketOk(bArr);
String str = this.TAG;
StringBuilder sb = new StringBuilder();
sb.append("Received ");
sb.append(isResultPacketOk ? "OK" : "NOT OK");
sb.append(" insulin record");
UserError.Log.d(str, sb.toString());
if (isResultPacketOk) {
InsulinLogRx insulinLogRx = new InsulinLogRx(bArr);
UserError.Log.d(this.TAG, insulinLogRx.getTimeStampString() + insulinLogRx.toS());
if (insulinLogRx.timestamp > JoH.tsl()) {
UserError.Log.wtf(this.TAG, "Rejecting injection record in the future! " + insulinLogRx.getSummary());
return;
}
if (JoH.msSince(insulinLogRx.timestamp) < 172800000) {
String uuid = UUID.nameUUIDFromBytes(("Pendiq Sync" + address + insulinLogRx.timestamp).getBytes(Charset.forName("UTF-8"))).toString();
if (Treatments.byuuid(uuid) != null) {
UserError.Log.d(this.TAG, "Existing record matching uuid: " + uuid);
return;
}
Treatments byTimestamp = Treatments.byTimestamp(insulinLogRx.timestamp, 120000);
if (byTimestamp != null && Math.abs(byTimestamp.insulin - insulinLogRx.insulin) < 0.01d && !byTimestamp.enteredBy.contains("Pendiq Sync")) {
UserError.Log.d(this.TAG, "Record: " + insulinLogRx.getSummary() + " already processed");
return;
}
UserError.Log.d(this.TAG, "NEW record: " + insulinLogRx.getSummary());
getInsulinLog();
Treatments create = Treatments.create(BgReading.BESTOFFSET, insulinLogRx.insulin, insulinLogRx.timestamp, uuid);
if (create != null) {
create.enteredBy += " Pendiq Sync";
create.save();
} else {
UserError.Log.wtf(this.TAG, "Could not create treatment entry, possible dupe: " + uuid);
}
if (JoH.ratelimit("pendiq-data-in-sound", 1)) {
JoH.playResourceAudio(2131689474);
}
Home.staticRefreshBGChartsOnIdle();
return;
}
UserError.Log.d(this.TAG, "Rejecting injection record too far in the past >2 days: " + insulinLogRx.getSummary());
}
}
private synchronized void dosePrep() {
if (this.dose_prep_waiting > BgReading.BESTOFFSET) {
setInsulinDose(this.dose_prep_waiting);
this.dose_prep_waiting = BgReading.BESTOFFSET;
} else {
changeState(state.next());
}
}
private void getStatus() {
addToWriteQueueWithWakeup(new StatusTx().getFragmentStream(), 50L, 10, true, "Get Status");
}
private void getInsulinLog() {
int i = this.loaded_records;
this.loaded_records = i + 1;
if (i < 100) {
addToWriteQueueWithWakeup(new InsulinLogTx(0L).getFragmentStream(), 50L, 10, true, "Get Insulin Log");
} else {
UserError.Log.wtf(this.TAG, "Attempted to exceed maximum record loading");
}
}
private void setInsulinDose(double d) {
addToWriteQueueWithWakeup(new SetInjectTx(d).getFragmentStream(), 50L, 10, true, "Set Insulin Dose");
}
private void setTime() {
JoH.threadSleep(1000L);
addToWriteQueueWithWakeup(new SetTimeTx().getFragmentStream(), 50L, 10, true, "Set Time");
}
class QueueItem {
final byte[] data;
public final String description;
final long post_delay;
int retries = 0;
final int timeoutSeconds;
public QueueItem(byte[] bArr, int i, long j, String str) {
this.data = bArr;
this.timeoutSeconds = i;
this.post_delay = j;
this.description = str;
}
}
private void addToWriteQueueWithWakeup(List<byte[]> list, long j, int i, boolean z, String str) {
if (gotData()) {
addToWriteQueue(list, j, i, z, str);
return;
}
addToWriteQueue(list, j, i, false, str + " :: WAKE UP");
addToWriteQueue(list, j, i, z, str);
}
private void addToWriteQueue(List<byte[]> list, long j, int i, boolean z, String str) {
Iterator<byte[]> it = list.iterator();
while (it.hasNext()) {
this.write_queue.add(new QueueItem(it.next(), i, j, str));
}
if (z) {
writeMultipleFromQueue(this.write_queue);
}
}
private void writeMultipleFromQueue(ConcurrentLinkedQueue<QueueItem> concurrentLinkedQueue) {
QueueItem poll = concurrentLinkedQueue.poll();
if (poll != null) {
writeQueueItem(concurrentLinkedQueue, poll);
} else {
UserError.Log.d(this.TAG, "write queue empty");
}
}
public void writeQueueItem(final ConcurrentLinkedQueue<QueueItem> concurrentLinkedQueue, final QueueItem queueItem) {
extendWakeLock(2000L);
this.connection.writeCharacteristic(Const.OUTGOING_CHAR, queueItem.data).timeout(queueItem.timeoutSeconds, TimeUnit.SECONDS).subscribe(new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$writeQueueItem$7(queueItem, concurrentLinkedQueue, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
PendiqService.this.lambda$writeQueueItem$8(queueItem, concurrentLinkedQueue, (Throwable) obj);
}
});
}
public void lambda$writeQueueItem$7(QueueItem queueItem, ConcurrentLinkedQueue concurrentLinkedQueue, byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Wrote request: " + queueItem.description + " -> " + JoH.bytesToHex(bArr));
expectReply(concurrentLinkedQueue, queueItem);
long j = queueItem.post_delay;
if (j > 0) {
long j2 = j + (queueItem.description.contains("WAKE UP") ? 2000 : 0);
UserError.Log.d(this.TAG, "sleeping " + j2);
JoH.threadSleep(j2);
}
writeMultipleFromQueue(concurrentLinkedQueue);
throw new JamBaseBluetoothService.OperationSuccess("write complete: " + queueItem.description);
}
public void lambda$writeQueueItem$8(QueueItem queueItem, ConcurrentLinkedQueue concurrentLinkedQueue, Throwable th) throws Exception {
if (th instanceof JamBaseBluetoothService.OperationSuccess) {
return;
}
UserError.Log.d(this.TAG, "Throwable in: " + queueItem.description + " -> " + th);
int i = queueItem.retries + 1;
queueItem.retries = i;
if (th instanceof BleDisconnectedException) {
UserError.Log.d(this.TAG, "Disconnected so not attempting retries");
return;
}
if (i > 3) {
UserError.Log.d(this.TAG, queueItem.description + " failed max retries @ " + queueItem.retries + " shutting down queue");
concurrentLinkedQueue.clear();
changeState(STATE.CLOSE);
return;
}
writeQueueItem(concurrentLinkedQueue, queueItem);
}
private void expectReply(final ConcurrentLinkedQueue<QueueItem> concurrentLinkedQueue, final QueueItem queueItem) {
Inevitable.task("pendiq-expect-reply-" + queueItem.description, 3000L, new Runnable() {
@Override
public void run() {
if (JoH.msSince(PendiqService.this.lastProcessedIncomingData) > 3000) {
UserError.Log.d(((JamBaseBluetoothService) PendiqService.this).TAG, "GOT NO REPLY FOR: " + queueItem.description + " @ " + queueItem.retries);
QueueItem queueItem2 = queueItem;
int i = queueItem2.retries + 1;
queueItem2.retries = i;
if (i <= 3) {
UserError.Log.d(((JamBaseBluetoothService) PendiqService.this).TAG, "Retrying due to no reply: " + queueItem.description);
PendiqService.this.writeQueueItem(concurrentLinkedQueue, queueItem);
}
}
}
});
}
}