导航菜单

页面标题

页面副标题

xDrip+ v04633772025.07.16 - InPenService.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);
    }
}