正在查看: xDrip+ v04633772025.07.16 应用的 InPenService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 InPenService.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package com.eveningoutpost.dexdrip.insulin.inpen;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Intent;
import android.os.PowerManager;
import androidx.health.platform.client.error.ErrorCode;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.driver.UsbId;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.util.HexDump;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.AdvertRx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.BatteryRx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.BondTx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.KeepAliveTx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.RecordRx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.RecordTx;
import com.eveningoutpost.dexdrip.insulin.inpen.messages.TimeRx;
import com.eveningoutpost.dexdrip.insulin.shared.ProcessPenData;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.PenData;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.services.JamBaseBluetoothSequencer;
import com.eveningoutpost.dexdrip.services.JamBaseBluetoothService;
import com.eveningoutpost.dexdrip.utilitymodels.Inevitable;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Pref;
import com.eveningoutpost.dexdrip.utilitymodels.StatusItem;
import com.eveningoutpost.dexdrip.utils.bt.Helper;
import com.eveningoutpost.dexdrip.utils.framework.WakeLockTrampoline;
import com.eveningoutpost.dexdrip.utils.math.Converters;
import com.eveningoutpost.dexdrip.utils.time.SlidingWindowConstraint;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.polidea.rxandroidble2.RxBleDeviceServices;
import com.polidea.rxandroidble2.exceptions.BleDisconnectedException;
import com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException;
import com.polidea.rxandroidble2.exceptions.BleGattException;
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.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class InPenService extends JamBaseBluetoothSequencer {
private static TimeRx currentPenAttachTime = null;
private static TimeRx currentPenTime = null;
private static long failover_time = 0;
private static boolean gotAll = false;
static final List<UUID> huntCharacterstics;
private static boolean infosLoaded = false;
private static int lastBattery = -1;
private static volatile String lastError = null;
private static PenData lastPenData = null;
private static volatile long lastReceivedData = -1;
private static volatile String lastState = "None";
private static volatile long lastStateUpdated = -1;
private static volatile boolean needsAuthentication = false;
private static PendingIntent serviceFailoverIntent;
private static ConcurrentHashMap<UUID, Object> staticCharacteristics;
private final ConcurrentLinkedQueue<byte[]> records = new ConcurrentLinkedQueue<>();
private int lastIndex = -1;
private int gotIndex = -2;
public void lambda$getRecords$16(byte[] bArr) throws Exception {
}
public static ObservableSource lambda$getRecords$23(Observable observable) throws Exception {
return observable;
}
public InPenService() {
this.mState = new InPenState().setLI(this.I);
this.I.backgroundStepDelay = 0;
this.I.autoConnect = true;
this.I.autoReConnect = true;
this.I.playSounds = true;
this.I.connectTimeoutMinutes = 25;
this.I.reconnectConstraint = new SlidingWindowConstraint(30.0d, 60000L, "max_reconnections");
}
static class InPenState extends JamBaseBluetoothSequencer.BaseState {
InPenState() {
this.sequence.clear();
this.sequence.add("Initializing");
this.sequence.add("Connecting");
this.sequence.add("Discover Services");
this.sequence.add("Get Identity");
this.sequence.add("Get Attach Time");
this.sequence.add("Get Auth");
this.sequence.add("Keep Alive");
this.sequence.add("Bond Authority");
this.sequence.add("Bonding");
this.sequence.add("Get Post Auth");
this.sequence.add("Sleeping");
this.sequence.add("Get Index");
this.sequence.add("Get Time");
this.sequence.add("Get Battery");
this.sequence.add("Get Records");
this.sequence.add("Sleeping");
this.sequence.add("Prototype Test");
this.sequence.add("Sending Queue");
this.sequence.add("Sleeping");
}
}
@Override
protected synchronized boolean automata() {
char c;
extendWakeLock(1000L);
msg(this.I.state);
String str = this.I.state;
switch (str.hashCode()) {
case -235759507:
if (str.equals("Initializing")) {
c = 0;
break;
}
c = 65535;
break;
case 370629256:
if (str.equals("Get Identity")) {
c = 1;
break;
}
c = 65535;
break;
case 461528254:
if (str.equals("Get Post Auth")) {
c = '\n';
break;
}
c = 65535;
break;
case 654926595:
if (str.equals("Get Battery")) {
c = 2;
break;
}
c = 65535;
break;
case 1158100446:
if (str.equals("Get Attach Time")) {
c = 3;
break;
}
c = 65535;
break;
case 1308074824:
if (str.equals("Get Index")) {
c = 11;
break;
}
c = 65535;
break;
case 1728207391:
if (str.equals("Bonding")) {
c = '\b';
break;
}
c = 65535;
break;
case 1802914930:
if (str.equals("Keep Alive")) {
c = 6;
break;
}
c = 65535;
break;
case 1981627506:
if (str.equals("Get Auth")) {
c = '\t';
break;
}
c = 65535;
break;
case 1982181783:
if (str.equals("Get Time")) {
c = 4;
break;
}
c = 65535;
break;
case 1983707686:
if (str.equals("Bond Authority")) {
c = 7;
break;
}
c = 65535;
break;
case 2068763448:
if (str.equals("Get Records")) {
c = 5;
break;
}
c = 65535;
break;
default:
c = 65535;
break;
}
switch (c) {
case 0:
changeNextState();
break;
case 1:
getIdentity(null);
break;
case 2:
getBattery();
break;
case 3:
getAttachTime();
break;
case 4:
getTime();
break;
case 5:
getRecords();
break;
case 6:
keepAlive();
break;
case 7:
bondAuthority();
break;
case '\b':
bondAsRequired(true);
break;
case '\t':
case '\n':
getAuthState();
break;
case 11:
getIndex();
break;
default:
if (shouldServiceRun()) {
if (JoH.msSince(lastReceivedData) < 60000) {
Inevitable.task("inpen-set-failover", 1000L, new Runnable() {
@Override
public final void run() {
InPenService.this.setFailOverTimer();
}
});
}
return super.automata();
}
UserError.Log.d(this.TAG, "Service should be shut down so stopping automata");
break;
}
return true;
}
@Override
public int onStartCommand(Intent intent, int i, int i2) {
String stringExtra;
char c;
PowerManager.WakeLock wakeLock = JoH.getWakeLock("inpen service", UsbId.SILABS_CP2102);
try {
InPenEntry.started_at = JoH.tsl();
UserError.Log.d(this.TAG, "WAKE UP WAKE UP WAKE UP");
if (shouldServiceRun()) {
String mac = InPen.getMac();
if (JoH.emptyString(mac)) {
new FindNearby().scan();
} else {
setAddress(mac);
commonServiceStart();
if (intent != null && (stringExtra = intent.getStringExtra("function")) != null) {
switch (stringExtra.hashCode()) {
case -598792926:
if (stringExtra.equals("prototype")) {
c = 3;
break;
}
c = 65535;
break;
case 108404047:
if (stringExtra.equals("reset")) {
c = 1;
break;
}
c = 65535;
break;
case 675763442:
if (stringExtra.equals("failover")) {
c = 0;
break;
}
c = 65535;
break;
case 1085444827:
if (stringExtra.equals("refresh")) {
c = 2;
break;
}
c = 65535;
break;
default:
c = 65535;
break;
}
if (c == 0) {
changeState("Closing");
} else if (c == 1) {
JoH.static_toast_long("Searching for Pen");
InPen.setMac("");
InPenEntry.startWithRefresh();
} else if (c == 2) {
currentPenAttachTime = null;
currentPenTime = null;
changeState("Initializing");
}
}
}
setFailOverTimer();
return 1;
}
UserError.Log.d(this.TAG, "Service is NOT set be active - shutting down");
stopSelf();
return 2;
} finally {
JoH.releaseWakeLock(wakeLock);
}
}
private void commonServiceStart() {
this.I.playSounds = false;
}
@Override
public void onDestroy() {
super.onDestroy();
InPenEntry.started_at = -1L;
}
private void getAuthState() {
this.I.connection.readCharacteristic(Constants.AUTHENTICATION).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getAuthState$0((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getAuthState$1((Throwable) obj);
}
});
}
public void lambda$getAuthState$0(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Authentication result: " + HexDump.dumpHexString(bArr));
authenticationProcessor(bArr);
}
public void lambda$getAuthState$1(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after Authentication status: " + th);
changeState("Closing");
}
private void authenticationProcessor(byte[] bArr) {
if (bArr == null || bArr.length < 1 || bArr[0] != 0) {
UserError.Log.d(this.TAG, "authenticationProcessor: not authenticated: " + JoH.bytesToHex(bArr));
needsAuthentication = true;
changeNextState();
return;
}
UserError.Log.d(this.TAG, "authenticationProcessor: we are authenticated: " + JoH.bytesToHex(bArr));
needsAuthentication = false;
changeState("Get Index");
}
private boolean checkMissingIndex() {
long missingIndex = PenData.getMissingIndex(this.I.address);
if (missingIndex == -1) {
return false;
}
UserError.Log.d(this.TAG, "Index: " + missingIndex + " is missing");
int i = (int) missingIndex;
getRecords(i, i);
return true;
}
private void getIndex() {
this.I.connection.readCharacteristic(Constants.RECORD_INDEX).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIndex$4((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIndex$5((Throwable) obj);
}
});
}
public void lambda$getIndex$4(final byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "GetIndex result: " + HexDump.dumpHexString(bArr));
lastReceivedData = JoH.tsl();
this.I.connection.readCharacteristic(Constants.REMAINING_INDEX).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIndex$2(bArr, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIndex$3((Throwable) obj);
}
});
}
public void lambda$getIndex$3(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after Remaining status: " + th);
}
public void lambda$getIndex$5(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after Index status: " + th);
}
public void lambda$getIndex$2(byte[] bArr, byte[] bArr2) {
int unsignedBytesToInt = Converters.unsignedBytesToInt(bArr);
this.lastIndex = unsignedBytesToInt;
gotAll = unsignedBytesToInt == this.gotIndex;
UserError.Log.d(this.TAG, "Index value: " + this.lastIndex);
UserError.Log.d(this.TAG, "Remain value: " + Converters.unsignedBytesToInt(bArr2));
changeNextState();
}
private void getTime() {
if (currentPenTime == null || JoH.ratelimit("inpen-get-time", ErrorCode.INVALID_OWNERSHIP)) {
this.I.connection.readCharacteristic(Constants.PEN_TIME).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getTime$6((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getTime$7((Throwable) obj);
}
});
} else {
UserError.Log.d(this.TAG, "Skipping get time, already have epoch");
changeNextState();
}
}
public void lambda$getTime$6(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "GetTime result: " + HexDump.dumpHexString(bArr));
TimeRx fromBytes = new TimeRx().fromBytes(bArr);
currentPenTime = fromBytes;
if (fromBytes != null) {
UserError.Log.d(this.TAG, "Current pen epoch: " + JoH.dateTimeText(currentPenTime.getPenEpoch()));
changeNextState();
return;
}
UserError.Log.e(this.TAG, "Current pen time invalid");
}
public void lambda$getTime$7(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after get time status: " + th);
}
private void getAttachTime() {
if (currentPenAttachTime == null || JoH.ratelimit("inpen-get-time", 180000)) {
this.I.connection.readCharacteristic(Constants.PEN_ATTACH_TIME).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getAttachTime$8((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getAttachTime$9((Throwable) obj);
}
});
} else {
UserError.Log.d(this.TAG, "Skipping get attach time, already have epoch");
changeNextState();
}
}
public void lambda$getAttachTime$8(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "GetAttachTime result: " + HexDump.dumpHexString(bArr));
TimeRx fromBytes = new TimeRx().fromBytes(bArr);
currentPenAttachTime = fromBytes;
if (fromBytes != null) {
UserError.Log.d(this.TAG, "Current pen attach epoch: " + currentPenAttachTime.getPenTime());
changeNextState();
return;
}
UserError.Log.e(this.TAG, "Current pen attach time invalid");
}
public void lambda$getAttachTime$9(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after get attach time status: " + th);
if (th instanceof BleDisconnectedException) {
changeState("Closing");
} else {
changeNextState();
}
}
private void getBattery() {
if (JoH.pratelimit("inpen-battery-poll-" + this.I.address, 40000)) {
this.I.connection.readCharacteristic(Constants.BATTERY).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getBattery$10((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getBattery$11((Throwable) obj);
}
});
return;
}
UserError.Log.d(this.TAG, "Skipping battery read");
if (lastBattery == -1) {
int i = (int) PersistentStore.getLong("InPen-battery-" + this.I.address);
lastBattery = i;
if (i == 0) {
lastBattery = -1;
} else {
UserError.Log.d(this.TAG, "Loaded battery from store: " + lastBattery);
}
}
changeNextState();
}
public void lambda$getBattery$10(byte[] bArr) throws Exception {
BatteryRx fromBytes = new BatteryRx().fromBytes(bArr);
if (fromBytes != null) {
lastBattery = fromBytes.getBatteryPercent();
PersistentStore.setLong("InPen-battery-" + this.I.address, lastBattery);
UserError.Log.d(this.TAG, "GetBattery result: " + fromBytes.getBatteryPercent());
changeNextState();
return;
}
UserError.Log.e(this.TAG, "Invalid GetBattery result: " + HexDump.dumpHexString(bArr));
changeNextState();
}
public void lambda$getBattery$11(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after Battery status: " + th);
changeNextState();
}
private void getIdentity(final Queue<UUID> queue) {
if (queue == null) {
UserError.Log.d(this.TAG, "IDENTITY: creating queue: " + this.I.characteristics.size());
loadInfos();
ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue();
for (UUID uuid : Constants.INFO_CHARACTERISTICS) {
if (this.I.characteristics.containsKey(uuid)) {
if (!(this.I.characteristics.get(uuid) instanceof byte[])) {
concurrentLinkedQueue.add(uuid);
} else {
UserError.Log.d(this.TAG, "Already have value for: " + Helper.getCharactersticName(uuid.toString()));
}
} else {
UserError.Log.d(this.TAG, "Characteristic not found in discover services: " + Helper.getCharactersticName(uuid.toString()));
}
}
if (!concurrentLinkedQueue.isEmpty()) {
getIdentity(concurrentLinkedQueue);
return;
} else {
changeNextState();
return;
}
}
if (!queue.isEmpty()) {
final UUID poll = queue.poll();
UserError.Log.d(this.TAG, "IDENTITY: list not empty: uuid: " + poll);
this.I.connection.readCharacteristic(poll).timeout(5L, TimeUnit.SECONDS).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIdentity$12(poll, queue, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getIdentity$13(poll, (Throwable) obj);
}
});
return;
}
UserError.Log.d(this.TAG, "Info Queue empty");
saveInfos();
changeNextState();
}
public void lambda$getIdentity$12(UUID uuid, Queue queue, byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, Helper.getCharactersticName(uuid.toString()) + " result: " + HexDump.dumpHexString(bArr));
this.I.characteristics.put(uuid, bArr);
staticCharacteristics = this.I.characteristics;
getIdentity(queue);
}
public void lambda$getIdentity$13(UUID uuid, Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not read after " + Helper.getCharactersticName(uuid.toString()) + " status: " + th);
changeNextState();
}
private void loadInfos() {
try {
if (infosLoaded) {
return;
}
Iterator<Map.Entry<UUID, Object>> it = this.I.characteristics.entrySet().iterator();
while (it.hasNext()) {
if (it.next().getValue() instanceof byte[]) {
UserError.Log.d(this.TAG, "Found item skipping load infos");
return;
}
}
Gson create = new GsonBuilder().create();
String string = PersistentStore.getString("InPen-infos-" + this.I.address);
if (string.length() > 10) {
for (Map.Entry entry : ((HashMap) create.fromJson(string, new TypeToken<Map<UUID, Object>>() {
}.getType())).entrySet()) {
if (entry.getValue() instanceof ArrayList) {
ArrayList arrayList = (ArrayList) entry.getValue();
int size = arrayList.size();
byte[] bArr = new byte[size];
for (int i = 0; i < size; i++) {
bArr[i] = ((Double) arrayList.get(i)).byteValue();
}
this.I.characteristics.put((UUID) entry.getKey(), bArr);
}
}
}
staticCharacteristics = this.I.characteristics;
infosLoaded = true;
UserError.Log.d(this.TAG, "loadInfos() loaded");
} catch (Exception e) {
UserError.Log.wtf(this.TAG, "Got exception in loadInfos " + e);
}
}
private void saveInfos() {
String json = new GsonBuilder().create().toJson(staticCharacteristics);
PersistentStore.setString("InPen-infos-" + this.I.address, json);
UserError.Log.d(this.TAG, json);
}
private void getRecords() {
if (checkMissingIndex()) {
return;
}
if (this.lastIndex < 0) {
UserError.Log.e(this.TAG, "Cannot get records as index is not defined");
return;
}
long highestIndex = PenData.getHighestIndex(this.I.address);
int i = highestIndex > 0 ? 1 + ((int) highestIndex) : 1;
int i2 = this.lastIndex;
if (i > i2) {
UserError.Log.e(this.TAG, "First index is greater than last index: " + i + " " + this.lastIndex);
return;
}
if (i2 - i > 80) {
i = i2 - 80;
UserError.Log.d(this.TAG, "Restricting first index to: " + i);
}
getRecords(i, this.lastIndex);
}
private void getRecords(int i, int i2) {
final int i3 = i2 - i;
if (i3 > 30) {
this.I.connection.writeCharacteristic(Constants.KEEPALIVE, new KeepAliveTx().getBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$14(i3, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$15((Throwable) obj);
}
});
}
final RecordTx recordTx = new RecordTx(i, i2);
UserError.Log.d(this.TAG, "getRecords called, loading: " + i + " to " + i2);
this.I.connection.setupIndication(Constants.RECORD_INDICATE).doOnNext(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$22(recordTx, (Observable) obj);
}
}).flatMap(new Function() {
public final Object apply(Object obj) {
ObservableSource lambda$getRecords$23;
lambda$getRecords$23 = InPenService.lambda$getRecords$23((Observable) obj);
return lambda$getRecords$23;
}
}).timeout(120L, TimeUnit.SECONDS).observeOn(Schedulers.newThread()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$24((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$25((Throwable) obj);
}
});
}
public void lambda$getRecords$14(int i, byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Wrote keep alive for " + i);
}
public void lambda$getRecords$15(Throwable th) throws Exception {
UserError.Log.d(this.TAG, "Got exception in keep alive" + th);
}
public void lambda$getRecords$22(final RecordTx recordTx, Observable observable) throws Exception {
this.I.connection.writeCharacteristic(Constants.RECORD_START, recordTx.startBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$20(recordTx, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$21((Throwable) obj);
}
});
}
public void lambda$getRecords$20(final RecordTx recordTx, byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Wrote record start: " + JoH.bytesToHex(bArr));
this.I.connection.writeCharacteristic(Constants.RECORD_END, recordTx.endBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$18(recordTx, (byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$19((Throwable) obj);
}
});
}
public void lambda$getRecords$18(RecordTx recordTx, byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Wrote record end: " + JoH.bytesToHex(bArr));
this.I.connection.writeCharacteristic(Constants.RECORD_REQUEST, recordTx.triggerBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$16((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$getRecords$17((Throwable) obj);
}
});
}
public void lambda$getRecords$17(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Failed to write record request: " + th);
if (th instanceof BleGattCharacteristicException) {
int status = ((BleGattCharacteristicException) th).getStatus();
UserError.Log.e(this.TAG, "Got status message: " + Helper.getStatusName(status));
}
}
public void lambda$getRecords$19(Throwable th) throws Exception {
UserError.Log.d(this.TAG, "Throwable in Record End write: " + th);
}
public void lambda$getRecords$21(Throwable th) throws Exception {
UserError.Log.d(this.TAG, "Throwable in Record Start write: " + th);
}
public void lambda$getRecords$24(byte[] bArr) throws Exception {
this.records.add(bArr);
UserError.Log.d(this.TAG, "INDICATE INDICATE: " + HexDump.dumpHexString(bArr));
}
public void lambda$getRecords$25(Throwable th) throws Exception {
if (th instanceof JamBaseBluetoothService.OperationSuccess) {
return;
}
if (th instanceof BleDisconnectedException) {
UserError.Log.d(this.TAG, "Disconnected when waiting to receive indication: " + th);
} else {
UserError.Log.e(this.TAG, "Error receiving indication: " + th);
}
Inevitable.task("check-records-queue", 100L, new Runnable() {
@Override
public final void run() {
InPenService.this.processRecordsQueue();
}
});
}
public synchronized void processRecordsQueue() {
boolean z = false;
while (!this.records.isEmpty()) {
byte[] poll = this.records.poll();
if (poll != null) {
RecordRx fromBytes = new RecordRx(currentPenTime).fromBytes(poll);
if (fromBytes != null) {
UserError.Log.d(this.TAG, "RECORD RECORD: " + fromBytes.toS());
PenData create = PenData.create(this.I.address, "InPen", fromBytes.index, (double) fromBytes.units, fromBytes.getRealTimeStamp(), (double) fromBytes.temperature, poll);
if (create == null) {
UserError.Log.wtf(this.TAG, "Error creating PenData record from " + HexDump.dumpHexString(poll));
} else {
create.battery = fromBytes.battery;
create.flags = fromBytes.flags;
UserError.Log.d(this.TAG, "Saving Record index: " + create.index);
create.save();
int i = (int) create.index;
this.gotIndex = i;
gotAll = this.lastIndex == i;
if (InPen.soundsEnabled() && JoH.ratelimit("pen_data_in", 1)) {
JoH.playResourceAudio(2131689474);
}
lastPenData = create;
z = true;
}
} else {
UserError.Log.e(this.TAG, "Error creating record from: " + HexDump.dumpHexString(poll));
}
}
}
if (z) {
Inevitable.task("process-inpen-data", 1000L, new Runnable() {
@Override
public final void run() {
ProcessPenData.process();
}
});
}
}
private void keepAlive() {
this.I.connection.writeCharacteristic(Constants.KEEPALIVE, new KeepAliveTx().getBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$keepAlive$26((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$keepAlive$27((Throwable) obj);
}
});
}
public void lambda$keepAlive$26(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Sent KeepAlive ok: ");
changeNextState();
}
public void lambda$keepAlive$27(Throwable th) throws Exception {
UserError.Log.e(this.TAG, "Could not write keepAlive " + th);
}
private void bondAuthority() {
AdvertRx fromBytes = new AdvertRx().fromBytes(PersistentStore.getBytes("InPen-advert-" + this.I.address));
if (fromBytes != null) {
final float roundFloat = JoH.roundFloat((float) Pref.getStringToDouble("inpen_prime_units", 2.0d), 1);
this.I.connection.writeCharacteristic(Constants.BONDCONTROL, new BondTx(roundFloat, fromBytes.getFlagBytes()).getBytes()).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$bondAuthority$28((byte[]) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$bondAuthority$29(roundFloat, (Throwable) obj);
}
});
} else {
err("Cannot find valid scan record for: " + this.I.address);
}
}
public void lambda$bondAuthority$28(byte[] bArr) throws Exception {
UserError.Log.d(this.TAG, "Sent BondAuthority ok: " + JoH.bytesToHex(bArr));
changeNextState();
}
public void lambda$bondAuthority$29(float f, Throwable th) throws Exception {
if (isErrorResponse(th)) {
err("Cannot bond with pen as incorrect number of units dialed up for pairing. Should be " + f + " or other error");
bondAsRequired(false);
return;
}
UserError.Log.e(this.TAG, "Could not write BondAuthority " + th);
}
@TargetApi(19)
private void bondAsRequired(boolean z) {
BluetoothDevice bluetoothDevice = this.I.bleDevice.getBluetoothDevice();
int bondState = bluetoothDevice.getBondState();
if (bondState == 10) {
boolean createBond = bluetoothDevice.createBond();
UserError.Log.d(this.TAG, "Attempted create bond: result: " + createBond);
} else {
UserError.Log.d(this.TAG, "Device is already in bonding state: " + Helper.bondStateToString(bondState));
}
if (z) {
for (int i = 0; i < 10; i++) {
if (bluetoothDevice.getBondState() == 12) {
UserError.Log.d(this.TAG, "Bond created!");
changeNextState();
return;
}
UserError.Log.d(this.TAG, "Sleeping waiting for bond: " + i);
JoH.threadSleep(1000L);
}
}
}
public void tryGattRefresh() {
if (JoH.ratelimit("inpen-gatt-refresh", 60)) {
if (Pref.getBoolean("use_gatt_refresh", true)) {
try {
if (this.I.connection != null) {
UserError.Log.d(this.TAG, "Trying gatt refresh queue");
}
this.I.connection.queue(new JamBaseBluetoothService.GattRefreshOperation(0L)).timeout(2L, TimeUnit.SECONDS).subscribe(new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$tryGattRefresh$30((Void) obj);
}
}, new Consumer() {
public final void accept(Object obj) {
InPenService.this.lambda$tryGattRefresh$31((Throwable) obj);
}
});
return;
} catch (NullPointerException e) {
UserError.Log.d(this.TAG, "Probably harmless gatt refresh exception: " + e);
return;
} catch (Exception e2) {
UserError.Log.d(this.TAG, "Got exception trying gatt refresh: " + e2);
return;
}
}
UserError.Log.d(this.TAG, "Gatt refresh rate limited");
}
}
public void lambda$tryGattRefresh$30(Void r4) throws Exception {
UserError.Log.d(this.TAG, "Refresh OK: " + r4);
}
public void lambda$tryGattRefresh$31(Throwable th) throws Exception {
UserError.Log.d(this.TAG, "Refresh exception: " + th);
}
static {
ArrayList arrayList = new ArrayList();
huntCharacterstics = arrayList;
arrayList.add(Constants.BATTERY);
}
@Override
protected void onServicesDiscovered(RxBleDeviceServices rxBleDeviceServices) {
super.onServicesDiscovered(rxBleDeviceServices);
Iterator it = rxBleDeviceServices.getBluetoothGattServices().iterator();
boolean z = false;
while (it.hasNext()) {
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : ((BluetoothGattService) it.next()).getCharacteristics()) {
for (UUID uuid : huntCharacterstics) {
if (bluetoothGattCharacteristic.getUuid().equals(uuid)) {
this.I.readCharacteristic = uuid;
z = true;
}
}
}
}
if (z) {
this.I.isDiscoveryComplete = true;
this.I.discoverOnce = true;
loadInfos();
changeState(this.mState.next());
return;
}
UserError.Log.e(this.TAG, "Could not find characteristic during service discovery. This is very unusual");
tryGattRefresh();
}
private boolean isErrorResponse(Object obj) {
return (obj instanceof BleGattCharacteristicException) && ((BleGattException) obj).getStatus() == 1;
}
public void setFailOverTimer() {
if (shouldServiceRun()) {
if (JoH.quietratelimit("inpen-failover-cooldown", 30)) {
UserError.Log.d(this.TAG, "setFailOverTimer: Restarting in: 2700 seconds");
PendingIntent pendingIntent = WakeLockTrampoline.getPendingIntent(getClass(), 1022, "failover");
serviceFailoverIntent = pendingIntent;
failover_time = JoH.wakeUpIntent(this, 2700000L, pendingIntent);
return;
}
return;
}
UserError.Log.d(this.TAG, "Not setting retry timer as service should not be running");
}
private static boolean shouldServiceRun() {
return InPenEntry.isEnabled();
}
private static void msg(String str) {
lastState = str + " " + JoH.hourMinuteString();
lastStateUpdated = JoH.tsl();
}
private void err(String str) {
lastError = str + " " + JoH.hourMinuteString();
UserError.Log.wtf(this.TAG, str);
}
public static List<StatusItem> megaStatus() {
TimeRx timeRx;
ArrayList arrayList = new ArrayList();
if (lastError != null) {
arrayList.add(new StatusItem("Last Error", lastError, StatusItem.Highlight.BAD));
}
if (InPenEntry.isStarted()) {
arrayList.add(new StatusItem("Service Running", JoH.niceTimeScalar(JoH.msSince(InPenEntry.started_at))));
arrayList.add(new StatusItem("Brain State", lastState));
if (needsAuthentication) {
arrayList.add(new StatusItem("Authentication", "Required", StatusItem.Highlight.BAD));
}
} else {
arrayList.add(new StatusItem("Service Stopped", "Not running"));
}
if (lastReceivedData != -1) {
arrayList.add(new StatusItem("Last Connected", JoH.dateTimeText(lastReceivedData)));
}
PenData penData = lastPenData;
if (penData != null) {
arrayList.add(new StatusItem("Last record", penData.brief(), gotAll ? StatusItem.Highlight.GOOD : StatusItem.Highlight.NORMAL));
}
if (lastBattery != -1) {
arrayList.add(new StatusItem("Battery", lastBattery + "%"));
}
for (UUID uuid : Constants.INFO_CHARACTERISTICS) {
addStatusForCharacteristic(arrayList, Helper.getCharactersticName(uuid.toString()), uuid);
}
if (currentPenAttachTime != null && (timeRx = currentPenTime) != null) {
arrayList.add(new StatusItem("Epoch time", JoH.dateTimeText(timeRx.getPenEpoch())));
arrayList.add(new StatusItem("Attach time", JoH.dateTimeText(currentPenTime.fromPenTime(currentPenAttachTime.getPenTime()))));
}
return arrayList;
}
private static void addStatusForCharacteristic(List<StatusItem> list, String str, UUID uuid) {
String characteristicHexString;
if (Arrays.asList(Constants.PRINTABLE_INFO_CHARACTERISTICS).contains(uuid)) {
characteristicHexString = getCharacteristicString(uuid);
} else {
characteristicHexString = Arrays.asList(Constants.HEXDUMP_INFO_CHARACTERISTICS).contains(uuid) ? getCharacteristicHexString(uuid) : null;
}
if (characteristicHexString != null) {
list.add(new StatusItem(str, characteristicHexString));
}
}
private static String getCharacteristicString(UUID uuid) {
Object obj;
ConcurrentHashMap<UUID, Object> concurrentHashMap = staticCharacteristics;
if (concurrentHashMap == null || (obj = concurrentHashMap.get(uuid)) == null || !(obj instanceof byte[])) {
return null;
}
return new String((byte[]) obj);
}
private static String getCharacteristicHexString(UUID uuid) {
Object obj;
ConcurrentHashMap<UUID, Object> concurrentHashMap = staticCharacteristics;
if (concurrentHashMap == null || (obj = concurrentHashMap.get(uuid)) == null || !(obj instanceof byte[])) {
return null;
}
return JoH.bytesToHex((byte[]) obj);
}
}