导航菜单

页面标题

页面副标题

xDrip+ v04633772025.07.16 - BluetoothGlucoseMeter.java 源代码

正在查看: xDrip+ v04633772025.07.16 应用的 BluetoothGlucoseMeter.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package com.eveningoutpost.dexdrip.services;

import android.annotation.TargetApi;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.PowerManager;
import android.util.Log;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.eveningoutpost.dexdrip.GcmActivity;
import com.eveningoutpost.dexdrip.Home;
import com.eveningoutpost.dexdrip.Home$$ExternalSyntheticLambda11;
import com.eveningoutpost.dexdrip.cgm.carelinkfollow.message.TextMap;
import com.eveningoutpost.dexdrip.glucosemeter.CurrentTimeRx;
import com.eveningoutpost.dexdrip.glucosemeter.GlucoseReadingRx;
import com.eveningoutpost.dexdrip.glucosemeter.RecordsCmdTx;
import com.eveningoutpost.dexdrip.glucosemeter.VerioHelper;
import com.eveningoutpost.dexdrip.glucosemeter.caresens.ContextRx;
import com.eveningoutpost.dexdrip.glucosemeter.caresens.TimeTx;
import com.eveningoutpost.dexdrip.importedlibraries.usbserial.driver.UsbId;
import com.eveningoutpost.dexdrip.models.BloodTest;
import com.eveningoutpost.dexdrip.models.Calibration;
import com.eveningoutpost.dexdrip.models.CalibrationRequest;
import com.eveningoutpost.dexdrip.models.JoH;
import com.eveningoutpost.dexdrip.models.UserError;
import com.eveningoutpost.dexdrip.utilitymodels.BgGraphBuilder;
import com.eveningoutpost.dexdrip.utilitymodels.Inevitable;
import com.eveningoutpost.dexdrip.utilitymodels.PersistentStore;
import com.eveningoutpost.dexdrip.utilitymodels.Pref;
import com.eveningoutpost.dexdrip.xdrip;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;

@TargetApi(19)
public class BluetoothGlucoseMeter extends Service {
    private static final String TAG = "BluetoothGlucoseMeter";
    private static CurrentTimeRx ct;
    private static Bluetooth_CMD last_queue_command;
    private static BluetoothAdapter mBluetoothAdapter;
    public static String mBluetoothDeviceAddress;
    private static BluetoothGatt mBluetoothGatt;
    private static String mLastConnectedDeviceAddress;
    private GlucoseReadingRx awaitingContext;
    private List<ScanFilter> filters;
    private BloodTest lastBloodTest;
    private BluetoothManager mBluetoothManager;
    private BluetoothLeScanner mLEScanner;
    private ScanCallback mScanCallback;
    private ScanSettings settings;
    private static final UUID GLUCOSE_SERVICE = UUID.fromString("00001808-0000-1000-8000-00805f9b34fb");
    private static final UUID CURRENT_TIME_SERVICE = UUID.fromString("00001805-0000-1000-8000-00805f9b34fb");
    private static final UUID DEVICE_INFO_SERVICE = UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb");
    private static final UUID CONTOUR_SERVICE = UUID.fromString("00000000-0002-11e2-9e96-0800200c9a66");
    private static final UUID CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    private static final UUID GLUCOSE_CHARACTERISTIC = UUID.fromString("00002a18-0000-1000-8000-00805f9b34fb");
    private static final UUID CONTEXT_CHARACTERISTIC = UUID.fromString("00002a34-0000-1000-8000-00805f9b34fb");
    private static final UUID RECORDS_CHARACTERISTIC = UUID.fromString("00002a52-0000-1000-8000-00805f9b34fb");
    private static final UUID TIME_CHARACTERISTIC = UUID.fromString("00002a2b-0000-1000-8000-00805f9b34fb");
    private static final UUID DATE_TIME_CHARACTERISTIC = UUID.fromString("00002a08-0000-1000-8000-00805f9b34fb");
    private static final UUID CONTOUR_1022 = UUID.fromString("00001022-0002-11e2-9e96-0800200c9a66");
    private static final UUID CONTOUR_1025 = UUID.fromString("00001025-0002-11e2-9e96-0800200c9a66");
    private static final UUID CONTOUR_1026 = UUID.fromString("00001026-0002-11e2-9e96-0800200c9a66");
    private static final UUID ISENS_TIME_SERVICE = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
    private static final UUID ISENS_TIME_CHARACTERISTIC = UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb");
    private static final UUID MANUFACTURER_NAME = UUID.fromString("00002a29-0000-1000-8000-00805f9b34fb");
    private static final ConcurrentLinkedQueue<Bluetooth_CMD> queue = new ConcurrentLinkedQueue<>();
    private static final Object mLock = new Object();
    private static boolean await_acks = false;
    public static boolean awaiting_ack = false;
    public static boolean awaiting_data = false;
    private static int bondingstate = -1;
    private static long started_at = -1;
    private static String mLastManufacturer = "";
    private static int mConnectionState = 0;
    private static int service_discovery_count = 0;
    private static boolean services_discovered = false;
    private static int highestSequenceStore = 0;
    private static final BroadcastReceiver mPairingRequestRecevier = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            JoH.doPairingRequest(context, this, intent, BluetoothGlucoseMeter.mBluetoothDeviceAddress);
        }
    };
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt bluetoothGatt, int i, int i2) {
            if (i2 != 2) {
                if (i2 == 0) {
                    int i3 = BluetoothGlucoseMeter.mConnectionState;
                    int unused = BluetoothGlucoseMeter.mConnectionState = 0;
                    BluetoothGlucoseMeter.statusUpdate("Disconnected");
                    if (i3 == 2 && BluetoothGlucoseMeter.playSounds() && JoH.ratelimit("bt_meter_disconnect_sound", 3)) {
                        JoH.playResourceAudio(2131689475);
                    }
                    BluetoothGlucoseMeter.close();
                    BluetoothGlucoseMeter.this.refreshDeviceCache(BluetoothGlucoseMeter.mBluetoothGatt);
                    Bluetooth_CMD.poll_queue();
                    BluetoothGlucoseMeter.this.reconnect();
                    return;
                }
                return;
            }
            if (BluetoothGlucoseMeter.mConnectionState == 2) {
                Log.e(BluetoothGlucoseMeter.TAG, "Apparently already connected - ignoring");
                return;
            }
            JoH.getWakeLock("bluetooth-meter-connected", UsbId.SILABS_CP2102);
            int unused2 = BluetoothGlucoseMeter.mConnectionState = 2;
            String unused3 = BluetoothGlucoseMeter.mLastConnectedDeviceAddress = bluetoothGatt.getDevice().getAddress();
            BluetoothGlucoseMeter.statusUpdate("Connected to device: " + BluetoothGlucoseMeter.mLastConnectedDeviceAddress);
            if (BluetoothGlucoseMeter.playSounds() && JoH.ratelimit("bt_meter_connect_sound", 3)) {
                JoH.playResourceAudio(2131689473);
            }
            Log.d(BluetoothGlucoseMeter.TAG, "Delay for settling");
            BluetoothGlucoseMeter.waitFor(600);
            BluetoothGlucoseMeter.statusUpdate("Discovering services");
            int unused4 = BluetoothGlucoseMeter.service_discovery_count = 0;
            BluetoothGlucoseMeter.this.discover_services();
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt bluetoothGatt, int i) {
            if (i == 0) {
                boolean unused = BluetoothGlucoseMeter.services_discovered = true;
                BluetoothGlucoseMeter.statusUpdate("Services discovered");
                int unused2 = BluetoothGlucoseMeter.bondingstate = BluetoothGlucoseMeter.mBluetoothGatt.getDevice().getBondState();
                if (BluetoothGlucoseMeter.bondingstate == 12) {
                    Log.d(BluetoothGlucoseMeter.TAG, "Device is already bonded - good");
                } else {
                    BluetoothGlucoseMeter.statusUpdate("Attempting to create pairing bond - device must be in pairing mode!");
                    BluetoothGlucoseMeter.sendDeviceUpdate(bluetoothGatt.getDevice());
                    BluetoothGlucoseMeter.mBluetoothGatt.getDevice().createBond();
                    BluetoothGlucoseMeter.waitFor(1000);
                    int unused3 = BluetoothGlucoseMeter.bondingstate = BluetoothGlucoseMeter.mBluetoothGatt.getDevice().getBondState();
                    if (BluetoothGlucoseMeter.bondingstate == 12) {
                        BluetoothGlucoseMeter.sendDeviceUpdate(bluetoothGatt.getDevice());
                    } else {
                        BluetoothGlucoseMeter.statusUpdate("Pairing appeared to fail");
                    }
                }
                if (!BluetoothGlucoseMeter.queue.isEmpty()) {
                    Log.e(BluetoothGlucoseMeter.TAG, "Queue is not empty so not scheduling anything..");
                    return;
                }
                BluetoothGlucoseMeter.statusUpdate("Requesting data from meter");
                Bluetooth_CMD.read(BluetoothGlucoseMeter.DEVICE_INFO_SERVICE, BluetoothGlucoseMeter.MANUFACTURER_NAME, "get device manufacturer");
                Bluetooth_CMD.read(BluetoothGlucoseMeter.CURRENT_TIME_SERVICE, BluetoothGlucoseMeter.TIME_CHARACTERISTIC, "get device time");
                Bluetooth_CMD.notify(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.GLUCOSE_CHARACTERISTIC, "notify new glucose record");
                Bluetooth_CMD.enable_notification_value(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.GLUCOSE_CHARACTERISTIC, "notify new glucose value");
                if (hasContextCharacteristic(bluetoothGatt)) {
                    Bluetooth_CMD.enable_notification_value(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.CONTEXT_CHARACTERISTIC, "notify new context value");
                    Bluetooth_CMD.notify(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.CONTEXT_CHARACTERISTIC, "notify new glucose context");
                }
                Bluetooth_CMD.enable_indications(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, "readings indication request");
                Bluetooth_CMD.notify(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, "notify glucose record");
                Bluetooth_CMD.write(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, RecordsCmdTx.getAllRecords(), "request all readings");
                Bluetooth_CMD.notify(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.GLUCOSE_CHARACTERISTIC, "notify new glucose record again");
                Bluetooth_CMD.poll_queue();
                return;
            }
            Log.w(BluetoothGlucoseMeter.TAG, "onServicesDiscovered received: " + i);
        }

        private boolean hasContextCharacteristic(BluetoothGatt bluetoothGatt) {
            BluetoothGattService service = bluetoothGatt.getService(BluetoothGlucoseMeter.GLUCOSE_SERVICE);
            return (service == null || service.getCharacteristic(BluetoothGlucoseMeter.CONTEXT_CHARACTERISTIC) == null) ? false : true;
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt bluetoothGatt, BluetoothGattDescriptor bluetoothGattDescriptor, int i) {
            Log.d(BluetoothGlucoseMeter.TAG, "Descriptor written to: " + bluetoothGattDescriptor.getUuid() + " getvalue: " + JoH.bytesToHex(bluetoothGattDescriptor.getValue()) + " status: " + i);
            if (i != 0) {
                Log.e(BluetoothGlucoseMeter.TAG, "Got gatt descriptor write failure: " + i);
                Bluetooth_CMD.retry_last_command(i);
                return;
            }
            Bluetooth_CMD.poll_queue();
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic, int i) {
            Log.d(BluetoothGlucoseMeter.TAG, "Written to: " + bluetoothGattCharacteristic.getUuid() + " getvalue: " + JoH.bytesToHex(bluetoothGattCharacteristic.getValue()) + " status: " + i);
            if (i == 0) {
                if (BluetoothGlucoseMeter.ack_blocking()) {
                    return;
                }
                Bluetooth_CMD.poll_queue();
            } else {
                Log.e(BluetoothGlucoseMeter.TAG, "Got gatt write failure: " + i);
                Bluetooth_CMD.retry_last_command(i);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic, int i) {
            if (i == 0) {
                if (bluetoothGattCharacteristic.getUuid().equals(BluetoothGlucoseMeter.TIME_CHARACTERISTIC)) {
                    UserError.Log.d(BluetoothGlucoseMeter.TAG, "Got time characteristic read data");
                    CurrentTimeRx unused = BluetoothGlucoseMeter.ct = new CurrentTimeRx(bluetoothGattCharacteristic.getValue());
                    BluetoothGlucoseMeter.statusUpdate("Device time: " + BluetoothGlucoseMeter.ct.toNiceString());
                } else if (bluetoothGattCharacteristic.getUuid().equals(BluetoothGlucoseMeter.DATE_TIME_CHARACTERISTIC)) {
                    UserError.Log.d(BluetoothGlucoseMeter.TAG, "Got date time characteristic read data");
                    CurrentTimeRx unused2 = BluetoothGlucoseMeter.ct = new CurrentTimeRx(bluetoothGattCharacteristic.getValue());
                    BluetoothGlucoseMeter.statusUpdate("Device time: " + BluetoothGlucoseMeter.ct.toNiceString());
                } else if (bluetoothGattCharacteristic.getUuid().equals(BluetoothGlucoseMeter.MANUFACTURER_NAME)) {
                    String unused3 = BluetoothGlucoseMeter.mLastManufacturer = bluetoothGattCharacteristic.getStringValue(0);
                    UserError.Log.d(BluetoothGlucoseMeter.TAG, "Manufacturer Name: " + BluetoothGlucoseMeter.mLastManufacturer);
                    BluetoothGlucoseMeter.statusUpdate("Device from: " + BluetoothGlucoseMeter.mLastManufacturer);
                    boolean unused4 = BluetoothGlucoseMeter.await_acks = false;
                    if (BluetoothGlucoseMeter.mLastManufacturer.startsWith("Roche")) {
                        Bluetooth_CMD.transmute_command(BluetoothGlucoseMeter.CURRENT_TIME_SERVICE, BluetoothGlucoseMeter.TIME_CHARACTERISTIC, BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.DATE_TIME_CHARACTERISTIC);
                    }
                    if (BluetoothGlucoseMeter.mLastManufacturer.startsWith("TaiDoc")) {
                        Bluetooth_CMD.delete_command(BluetoothGlucoseMeter.CURRENT_TIME_SERVICE, BluetoothGlucoseMeter.TIME_CHARACTERISTIC);
                        CurrentTimeRx unused5 = BluetoothGlucoseMeter.ct = new CurrentTimeRx();
                        BluetoothGlucoseMeter.ct.noClockAccess = true;
                        BluetoothGlucoseMeter.ct.sequenceNotReliable = true;
                        Bluetooth_CMD.delete_command(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.CONTEXT_CHARACTERISTIC);
                        Bluetooth_CMD.delete_command(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.CONTEXT_CHARACTERISTIC);
                        Bluetooth_CMD.replace_command(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, "W", new Bluetooth_CMD("W", BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, RecordsCmdTx.getFirstRecord(), "request newest reading"));
                    }
                    if (BluetoothGlucoseMeter.mLastManufacturer.startsWith("i-SENS")) {
                        Bluetooth_CMD.delete_command(BluetoothGlucoseMeter.CURRENT_TIME_SERVICE, BluetoothGlucoseMeter.TIME_CHARACTERISTIC);
                        CurrentTimeRx unused6 = BluetoothGlucoseMeter.ct = new CurrentTimeRx();
                        BluetoothGlucoseMeter.ct.noClockAccess = true;
                        Bluetooth_CMD.notify(BluetoothGlucoseMeter.ISENS_TIME_SERVICE, BluetoothGlucoseMeter.ISENS_TIME_CHARACTERISTIC, "notify isens clock");
                        Bluetooth_CMD.write(BluetoothGlucoseMeter.ISENS_TIME_SERVICE, BluetoothGlucoseMeter.ISENS_TIME_CHARACTERISTIC, new TimeTx(JoH.tsl()).getByteSequence(), "set isens clock");
                        Bluetooth_CMD.write(BluetoothGlucoseMeter.ISENS_TIME_SERVICE, BluetoothGlucoseMeter.ISENS_TIME_CHARACTERISTIC, new TimeTx(JoH.tsl()).getByteSequence(), "set isens clock");
                        Bluetooth_CMD.replace_command(BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, "W", new Bluetooth_CMD("W", BluetoothGlucoseMeter.GLUCOSE_SERVICE, BluetoothGlucoseMeter.RECORDS_CHARACTERISTIC, RecordsCmdTx.getNewerThanSequence(BluetoothGlucoseMeter.getHighestSequence()), "request reading newer than " + BluetoothGlucoseMeter.getHighestSequence()));
                    }
                    if (BluetoothGlucoseMeter.mLastManufacturer.startsWith("LifeScan")) {
                        boolean unused7 = BluetoothGlucoseMeter.await_acks = true;
                        Bluetooth_CMD.empty_queue();
                        UUID uuid = VerioHelper.VERIO_F7A1_SERVICE;
                        UUID uuid2 = VerioHelper.VERIO_F7A3_NOTIFICATION;
                        Bluetooth_CMD.notify(uuid, uuid2, "verio general notification");
                        Bluetooth_CMD.enable_notification_value(uuid, uuid2, "verio general notify value");
                        UUID uuid3 = VerioHelper.VERIO_F7A2_WRITE;
                        Bluetooth_CMD.write(uuid, uuid3, VerioHelper.getTimeCMD(), "verio ask time");
                        Bluetooth_CMD.write(uuid, uuid3, VerioHelper.getTcounterCMD(), "verio T data query");
                        Bluetooth_CMD.write(uuid, uuid3, VerioHelper.getRcounterCMD(), "verio R data query");
                    }
                } else {
                    Log.d(BluetoothGlucoseMeter.TAG, "Got a different charactersitic! " + bluetoothGattCharacteristic.getUuid().toString());
                }
                Bluetooth_CMD.poll_queue();
                return;
            }
            Log.e(BluetoothGlucoseMeter.TAG, "Got gatt read failure: " + i);
            Bluetooth_CMD.retry_last_command(i);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) {
            PowerManager.WakeLock wakeLock = JoH.getWakeLock("bt-meter-characterstic-change", 30000);
            try {
                BluetoothGlucoseMeter.this.processCharacteristicChange(bluetoothGatt, bluetoothGattCharacteristic);
                Bluetooth_CMD.poll_queue();
            } finally {
                JoH.releaseWakeLock(wakeLock);
            }
        }
    };
    private String lastScannedDeviceAddress = "";
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bArr) {
            JoH.runOnUiThreadDelayed(new Runnable() {
                @Override
                public void run() {
                    if (!BluetoothGlucoseMeter.this.lastScannedDeviceAddress.equals(bluetoothDevice.getAddress()) || JoH.ratelimit("bt-scan-repeated-address", 2)) {
                        BluetoothGlucoseMeter.this.lastScannedDeviceAddress = bluetoothDevice.getAddress();
                        BluetoothGlucoseMeter.sendDeviceUpdate(bluetoothDevice);
                    }
                }
            }, 0L);
        }
    };

    public static void sendDeviceUpdate(BluetoothDevice bluetoothDevice) {
        sendDeviceUpdate(bluetoothDevice, false);
    }

    private static void sendDeviceUpdate(BluetoothDevice bluetoothDevice, boolean z) {
        if (bluetoothDevice == null) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(bluetoothDevice.getAddress());
        sb.append("^");
        sb.append(bluetoothDevice.getBondState());
        sb.append("^");
        sb.append(bluetoothDevice.getName() != null ? bluetoothDevice.getName().replace("^", "") : "");
        sb.append(z ? " " : "");
        broadcastUpdate("com.eveningoutpost.dexdrip.BLUETOOTH_GLUCOSE_METER_NEW_SCAN_DEVICE", sb.toString());
    }

    public static boolean isBonded() {
        return bondingstate == 12;
    }

    public static boolean playSounds() {
        return Pref.getBoolean("bluetooth_meter_play_sounds", true);
    }

    private static synchronized void forgetDevice(String str) {
        BluetoothAdapter bluetoothAdapter;
        synchronized (BluetoothGlucoseMeter.class) {
            Log.d(TAG, "forgetDevice() start");
            try {
                bluetoothAdapter = mBluetoothAdapter;
            } catch (Exception e) {
                Log.wtf(TAG, "Exception forgetting: " + str + " " + e);
            }
            if (bluetoothAdapter != null && str != null) {
                Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
                if (bondedDevices.size() > 0) {
                    for (BluetoothDevice bluetoothDevice : bondedDevices) {
                        if (bluetoothDevice.getName() != null && bluetoothDevice.getAddress().equals(str)) {
                            Log.e(TAG, "Unpairing.. " + str);
                            JoH.static_toast_long("Unpairing: " + str);
                            try {
                                bluetoothDevice.getClass().getMethod("removeBond", null).invoke(bluetoothDevice, null);
                            } catch (Exception e2) {
                                Log.e(TAG, e2.getMessage(), e2);
                            }
                        }
                    }
                }
                Log.d(TAG, "forgetDevice() finished");
            }
        }
    }

    public static synchronized void close() {
        synchronized (BluetoothGlucoseMeter.class) {
            if (mBluetoothGatt == null) {
                return;
            }
            Log.d(TAG, "Closing gatt");
            mBluetoothGatt.close();
            mBluetoothGatt = null;
        }
    }

    protected static void waitFor(int i) {
        Object obj = mLock;
        synchronized (obj) {
            try {
                Log.e(TAG, "waiting " + i + "ms");
                obj.wait((long) i);
            } catch (InterruptedException e) {
                Log.e(TAG, "Sleeping interrupted", e);
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT < 26) {
            IntentFilter intentFilter = new IntentFilter("android.bluetooth.device.action.PAIRING_REQUEST");
            intentFilter.setPriority(999);
            registerReceiver(mPairingRequestRecevier, intentFilter);
            return;
        }
        UserError.Log.d(TAG, "Not registering pairing receiver on Android 8+");
    }

    @Override
    public int onStartCommand(Intent intent, int i, int i2) {
        if (intent == null) {
            stopSelf();
            return 2;
        }
        started_at = JoH.tsl();
        initialize();
        String stringExtra = intent.getStringExtra("service_action");
        if (stringExtra == null) {
            return 1;
        }
        if (stringExtra.equals("connect")) {
            close();
            mLastConnectedDeviceAddress = "";
            bondingstate = -1;
            mConnectionState = 0;
            scanLeDevice(false);
            connect(intent.getStringExtra("connect_address"));
            return 1;
        }
        if (stringExtra.equals("scan")) {
            beginScan();
            return 1;
        }
        if (!stringExtra.equals("forget")) {
            return 1;
        }
        forgetDevice(intent.getStringExtra("forget_address"));
        beginScan();
        return 1;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        close();
        try {
            unregisterReceiver(mPairingRequestRecevier);
        } catch (Exception e) {
            Log.e(TAG, "Error unregistering pairing receiver: " + e);
        }
        started_at = -1L;
    }

    public void startup() {
        UserError.Log.d(TAG, "startup()");
        initScanCallback();
    }

    public synchronized void discover_services() {
        String str = TAG;
        UserError.Log.d(str, "discover_services()");
        awaiting_data = false;
        awaiting_ack = false;
        services_discovered = false;
        service_discovery_count++;
        BluetoothGatt bluetoothGatt = mBluetoothGatt;
        if (bluetoothGatt != null) {
            if (mConnectionState == 2) {
                bluetoothGatt.discoverServices();
                JoH.runOnUiThreadDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (BluetoothGlucoseMeter.services_discovered || BluetoothGlucoseMeter.service_discovery_count >= 10) {
                            return;
                        }
                        Log.d(BluetoothGlucoseMeter.TAG, "Timeout discovering services - retrying...");
                        BluetoothGlucoseMeter.this.discover_services();
                    }
                }, (service_discovery_count * 500) + 5000);
            } else {
                Log.e(str, "Cannot discover services as we are not connected");
            }
        } else {
            Log.e(str, "mBluetoothGatt is null!");
        }
    }

    public void reconnect() {
        statusUpdate("Attempting reconnection: " + mBluetoothDeviceAddress);
        connect(mBluetoothDeviceAddress);
    }

    public boolean refreshDeviceCache(BluetoothGatt bluetoothGatt) {
        if (bluetoothGatt == null) {
            return false;
        }
        try {
            Method method = bluetoothGatt.getClass().getMethod("refresh", new Class[0]);
            if (method != null) {
                return ((Boolean) method.invoke(bluetoothGatt, new Object[0])).booleanValue();
            }
        } catch (Exception unused) {
            Log.e(TAG, "An exception occured while refreshing device");
        }
        return false;
    }

    public static void statusUpdate(String str) {
        broadcastUpdate("com.eveningoutpost.dexdrip.BLUETOOTH_GLUCOSE_METER_SERVICE_UPDATE", str);
        UserError.Log.d(TAG, "StatusUpdate: " + str);
    }

    private static void broadcastUpdate(String str, String str2) {
        Intent intent = new Intent(str);
        intent.putExtra("data", str2);
        LocalBroadcastManager.getInstance(xdrip.getAppContext()).sendBroadcast(intent);
    }

    public static boolean ack_blocking() {
        return await_acks && (awaiting_ack || awaiting_data);
    }

    private synchronized void markDeviceAsSuccessful(BluetoothGatt bluetoothGatt) {
        if (!Pref.getStringDefaultBlank("selected_bluetooth_meter_address").equals(mLastConnectedDeviceAddress)) {
            Pref.setString("selected_bluetooth_meter_address", mLastConnectedDeviceAddress);
            Pref.setString("selected_bluetooth_meter_info", mLastManufacturer + "   " + mLastConnectedDeviceAddress);
            Pref.setBoolean("bluetooth_meter_enabled", true);
            JoH.static_toast_long("Success with: " + mLastConnectedDeviceAddress + "  Enabling auto-start");
            if (bluetoothGatt != null) {
                sendDeviceUpdate(bluetoothGatt.getDevice(), true);
            }
        }
    }

    private void processGlucoseReadingRx(GlucoseReadingRx glucoseReadingRx) {
        if (glucoseReadingRx.sampleType != 10) {
            if (ct.sequenceNotReliable) {
                glucoseReadingRx.sequence = (int) ((glucoseReadingRx.time / 5000) - 299351124);
            } else {
                setHighestSequence(glucoseReadingRx.sequence);
            }
            if (ct.noClockAccess && Pref.getBooleanDefaultFalse("meter_recent_reading_as_now")) {
                if (JoH.absMsSince(glucoseReadingRx.time) < 4200000) {
                    if (PersistentStore.getBoolean("Glucose Reading From: " + mLastConnectedDeviceAddress)) {
                        long j = glucoseReadingRx.time;
                        glucoseReadingRx.time = JoH.tsl() - 30000;
                        UserError.Log.e(TAG, "Munged meter reading time from: " + JoH.dateTimeText(j) + " to " + JoH.dateTimeText(glucoseReadingRx.time));
                    }
                }
                if (JoH.quietratelimit("Glucose Reading From: ", 10)) {
                    PersistentStore.setBoolean("Glucose Reading From: " + mLastConnectedDeviceAddress, true);
                }
            }
            BloodTest create = BloodTest.create((glucoseReadingRx.time - ct.timediff) + glucoseReadingRx.offsetMs(), glucoseReadingRx.mgdl, "Bluetooth Glucose Meter:\n" + mLastManufacturer + "   " + mLastConnectedDeviceAddress, glucoseReadingRx.getUuid().toString());
            if (create != null) {
                String str = TAG;
                UserError.Log.d(str, "Successfully created new BloodTest: " + create.toS());
                create.glucoseReadingRx = glucoseReadingRx;
                this.lastBloodTest = create;
                UserError.Log.uel(str, "New blood test data: " + BgGraphBuilder.unitized_string_static(create.mgdl) + " @ " + JoH.dateTimeText(create.timestamp) + " " + create.source);
                Inevitable.task("evaluate-meter-records", 2000L, new Runnable() {
                    @Override
                    public final void run() {
                        BluetoothGlucoseMeter.this.evaluateLastRecords();
                    }
                });
                return;
            }
            return;
        }
        UserError.Log.d(TAG, "Ignoring control solution test");
    }

    public synchronized void processCharacteristicChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) {
        if (GLUCOSE_CHARACTERISTIC.equals(bluetoothGattCharacteristic.getUuid())) {
            GlucoseReadingRx glucoseReadingRx = new GlucoseReadingRx(bluetoothGattCharacteristic.getValue(), bluetoothGatt.getDevice().getAddress());
            String str = TAG;
            UserError.Log.d(str, "Result: " + glucoseReadingRx.toString());
            if (ct == null) {
                statusUpdate("Cannot process glucose record as we do not know device time!");
            } else {
                if (JoH.quietratelimit("mark-meter-device-success", 10)) {
                    markDeviceAsSuccessful(bluetoothGatt);
                }
                statusUpdate("Glucose Record: " + JoH.dateTimeText((glucoseReadingRx.time - ct.timediff) + glucoseReadingRx.offsetMs()) + "\n" + BgGraphBuilder.unitized_string_with_units_static(glucoseReadingRx.mgdl));
                if (playSounds() && JoH.ratelimit("bt_meter_data_in", 1)) {
                    JoH.playResourceAudio(2131689474);
                }
                if (!glucoseReadingRx.contextInfoFollows) {
                    processGlucoseReadingRx(glucoseReadingRx);
                } else {
                    UserError.Log.d(str, "Record has context information so delaying processing");
                    this.awaitingContext = glucoseReadingRx;
                }
            }
        } else if (RECORDS_CHARACTERISTIC.equals(bluetoothGattCharacteristic.getUuid())) {
            UserError.Log.d(TAG, "Change notification for RECORDS: " + JoH.bytesToHex(bluetoothGattCharacteristic.getValue()));
        } else if (CONTEXT_CHARACTERISTIC.equals(bluetoothGattCharacteristic.getUuid())) {
            UserError.Log.d(TAG, "Change notification for CONTEXT: " + JoH.bytesToHex(bluetoothGattCharacteristic.getValue()));
            processContextData(bluetoothGattCharacteristic.getValue());
        } else if (VerioHelper.VERIO_F7A3_NOTIFICATION.equals(bluetoothGattCharacteristic.getUuid())) {
            String str2 = TAG;
            UserError.Log.d(str2, "Change notification for VERIO: " + JoH.bytesToHex(bluetoothGattCharacteristic.getValue()));
            try {
                GlucoseReadingRx parseMessage = VerioHelper.parseMessage(bluetoothGattCharacteristic.getValue());
                if (parseMessage != null) {
                    markDeviceAsSuccessful(bluetoothGatt);
                    statusUpdate("Glucose Record: " + JoH.dateTimeText(parseMessage.time + parseMessage.offsetMs()) + "\n" + BgGraphBuilder.unitized_string_with_units_static(parseMessage.mgdl));
                    if (playSounds() && JoH.ratelimit("bt_meter_data_in", 1)) {
                        JoH.playResourceAudio(2131689474);
                    }
                    BloodTest create = BloodTest.create(parseMessage.time + parseMessage.offsetMs(), parseMessage.mgdl, "Bluetooth Glucose Meter:\n" + mLastManufacturer + "   " + mLastConnectedDeviceAddress);
                    if (create != null) {
                        UserError.Log.d(str2, "Successfully created new BloodTest: " + create.toS());
                        create.glucoseReadingRx = parseMessage;
                        this.lastBloodTest = create;
                        UserError.Log.uel(str2, "New verio blood test data: " + BgGraphBuilder.unitized_string_static(create.mgdl) + " @ " + JoH.dateTimeText(create.timestamp) + " " + create.source);
                        final long j = this.lastBloodTest.timestamp;
                        JoH.runOnUiThreadDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (BluetoothGlucoseMeter.this.lastBloodTest.timestamp == j) {
                                    CurrentTimeRx unused = BluetoothGlucoseMeter.ct = new CurrentTimeRx();
                                    BluetoothGlucoseMeter.this.evaluateLastRecords();
                                }
                            }
                        }, 1000L);
                    }
                }
            } catch (Exception e) {
                UserError.Log.wtf(TAG, "Got exception processing Verio data " + e);
            }
        } else {
            UserError.Log.e(TAG, "Unknown characteristic change: " + bluetoothGattCharacteristic.getUuid().toString() + " " + JoH.bytesToHex(bluetoothGattCharacteristic.getValue()));
        }
    }

    private synchronized void processContextData(byte[] bArr) {
        ContextRx contextRx = new ContextRx(bArr);
        GlucoseReadingRx glucoseReadingRx = this.awaitingContext;
        if (glucoseReadingRx != null) {
            if (glucoseReadingRx.sequence == contextRx.sequence) {
                if (contextRx.ketone()) {
                    UserError.Log.e(TAG, "Received Ketone data: " + this.awaitingContext.asKetone());
                    this.awaitingContext = null;
                } else if (contextRx.normalRecord()) {
                    processGlucoseReadingRx(this.awaitingContext);
                    this.awaitingContext = null;
                } else {
                    UserError.Log.e(TAG, "Received context packet but we're not sure what its for: " + contextRx.toString());
                }
            } else {
                UserError.Log.e(TAG, "Received out of sequence context: " + this.awaitingContext.sequence + " vs " + contextRx.toString());
            }
        } else {
            UserError.Log.d(TAG, "Received context but nothing awaiting context: " + contextRx.toString());
        }
    }

    public static void verioScheduleRequestBg(int i) {
        Bluetooth_CMD.write(VerioHelper.VERIO_F7A1_SERVICE, VerioHelper.VERIO_F7A2_WRITE, VerioHelper.getRecordCMD(i), "verio get record " + i);
    }

    public synchronized void evaluateLastRecords() {
        if (this.lastBloodTest != null) {
            GcmActivity.syncBloodTests();
            GlucoseReadingRx glucoseReadingRx = this.lastBloodTest.glucoseReadingRx;
            if (glucoseReadingRx != null && glucoseReadingRx.device != null && ct != null) {
                String str = "last-btm-sequence-" + glucoseReadingRx.device;
                String str2 = "last-btm-timestamp" + glucoseReadingRx.device;
                if (glucoseReadingRx.sequence + 1 > PersistentStore.getLong(str)) {
                    PersistentStore.setLong(str, glucoseReadingRx.sequence + 1);
                    if (this.lastBloodTest.timestamp > PersistentStore.getLong(str2)) {
                        PersistentStore.setLong(str2, this.lastBloodTest.timestamp);
                        String str3 = TAG;
                        Log.d(str3, "evaluateLastRecords: appears to be a new record: sequence:" + glucoseReadingRx.sequence);
                        JoH.runOnUiThreadDelayed(new Home$$ExternalSyntheticLambda11(), 300L);
                        if (Pref.getBooleanDefaultFalse("bluetooth_meter_for_calibrations") || Pref.getBooleanDefaultFalse("bluetooth_meter_for_calibrations_auto")) {
                            final long msSince = JoH.msSince(this.lastBloodTest.timestamp);
                            if (msSince < 0) {
                                UserError.Log.e(str3, "evaluateLastRecords: time is in the future - ignoring");
                            } else if (msSince < 43200000) {
                                Calibration lastValid = Calibration.lastValid();
                                if (lastValid != null && this.lastBloodTest.timestamp <= lastValid.timestamp) {
                                    UserError.Log.e(str3, "evaluateLastRecords: meter reading is at least as old as last calibration - ignoring");
                                }
                                UserError.Log.ueh(str3, "Prompting for calibration for: " + BgGraphBuilder.unitized_string_with_units_static(this.lastBloodTest.mgdl) + " from: " + JoH.dateTimeText(this.lastBloodTest.timestamp));
                                JoH.clearCache();
                                Home.startHomeWithExtra(getApplicationContext(), "HOME_FULL_WAKEUP", "1");
                                JoH.runOnUiThreadDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        Home.staticRefreshBGCharts();
                                        if (Pref.getBooleanDefaultFalse("bluetooth_meter_for_calibrations_auto") && CalibrationRequest.isSlopeFlatEnough()) {
                                            Log.d(BluetoothGlucoseMeter.TAG, "Slope flat enough for auto calibration");
                                            Log.d(BluetoothGlucoseMeter.TAG, "Delaying calibration for later");
                                            JoH.static_toast_long("Waiting for 15 minutes more sensor data for calibration");
                                        } else if (!Pref.getBooleanDefaultFalse("bluetooth_meter_for_calibrations")) {
                                            Log.d(BluetoothGlucoseMeter.TAG, "Not flat enough slope for auto calibration and manual calibration not enabled");
                                        } else {
                                            Home.startHomeWithExtra(xdrip.getAppContext(), "BLUETOOTH_METER_CALIBRATION", BgGraphBuilder.unitized_string_static(BluetoothGlucoseMeter.this.lastBloodTest.mgdl), Long.toString(msSince), "manual");
                                        }
                                    }
                                }, 500L);
                            } else {
                                UserError.Log.e(str3, "evaluateLastRecords: meter reading is too far in the past: " + JoH.dateTimeText(this.lastBloodTest.timestamp));
                            }
                        }
                    }
                } else {
                    UserError.Log.d(TAG, "evaluateLastRecords: sequence isn't newer");
                }
            } else {
                UserError.Log.e(TAG, "evaluateLastRecords: Data missing for evaluation");
            }
        } else {
            UserError.Log.e(TAG, "evaluateLastRecords: lastBloodTest is Null!!");
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    private boolean initialize() {
        if (this.mBluetoothManager == null) {
            BluetoothManager bluetoothManager = (BluetoothManager) getSystemService("bluetooth");
            this.mBluetoothManager = bluetoothManager;
            if (bluetoothManager == null) {
                UserError.Log.e(TAG, "Unable to initialize BluetoothManager.");
                return false;
            }
        }
        BluetoothAdapter adapter = this.mBluetoothManager.getAdapter();
        mBluetoothAdapter = adapter;
        if (adapter == null) {
            UserError.Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
            return false;
        }
        startup();
        return true;
    }

    public synchronized boolean connect(String str) {
        BluetoothGatt bluetoothGatt;
        if (str != null) {
            if (!str.equals("00:00:00:00:00:00")) {
                String str2 = TAG;
                Log.d(str2, "connect() called with address: " + str);
                if (mBluetoothAdapter == null) {
                    Log.w(str2, "BluetoothAdapter not initialized or unspecified address.");
                    return false;
                }
                if (mConnectionState == 2 && mLastConnectedDeviceAddress.equals(str) && JoH.ratelimit("bt-meter-connect-repeat", 7)) {
                    Log.e(str2, "We are already connected - not connecting");
                    if (service_discovery_count == 0) {
                        discover_services();
                    }
                    return false;
                }
                statusUpdate("Trying to connect to: " + str);
                String str3 = mBluetoothDeviceAddress;
                if (str3 != null && str.equals(str3) && (bluetoothGatt = mBluetoothGatt) != null) {
                    if (!bluetoothGatt.connect()) {
                        return false;
                    }
                    mConnectionState = 1;
                    return true;
                }
                BluetoothDevice remoteDevice = mBluetoothAdapter.getRemoteDevice(str);
                if (remoteDevice == null) {
                    statusUpdate("Device not found.  Unable to connect.");
                    return false;
                }
                BluetoothGatt connectGatt = remoteDevice.connectGatt(this, true, this.mGattCallback);
                mBluetoothGatt = connectGatt;
                refreshDeviceCache(connectGatt);
                mBluetoothDeviceAddress = str;
                mConnectionState = 1;
                return true;
            }
        }
        return false;
    }

    @TargetApi(21)
    private void initScanCallback() {
        Log.d(TAG, "init v21 ScanCallback()");
        this.mScanCallback = new ScanCallback() {
            @Override
            public void onScanResult(int i, ScanResult scanResult) {
                Log.i(BluetoothGlucoseMeter.TAG, "onScanResult result: " + scanResult.toString());
                BluetoothDevice device = scanResult.getDevice();
                BluetoothGlucoseMeter.this.scanLeDevice(false);
                BluetoothGlucoseMeter.this.connect(device.getAddress());
            }

            @Override
            public void onBatchScanResults(List<ScanResult> list) {
                Iterator<ScanResult> it = list.iterator();
                while (it.hasNext()) {
                    Log.i("ScanResult - Results", it.next().toString());
                }
            }

            @Override
            public void onScanFailed(int i) {
                Log.e(BluetoothGlucoseMeter.TAG, "Scan Failed Error Code: " + i);
                if (i == 1) {
                    Log.e(BluetoothGlucoseMeter.TAG, "Already Scanning: ");
                }
            }
        };
    }

    public void scanLeDevice(boolean z) {
        statusUpdate(z ? "Starting Scanning\nMake sure meter is turned on - For pairing hold the meter power button until it flashes blue" : "Stopped Scanning");
        if (z) {
            JoH.runOnUiThreadDelayed(new Runnable() {
                @Override
                public void run() {
                    BluetoothGlucoseMeter.mBluetoothAdapter.stopLeScan(BluetoothGlucoseMeter.this.mLeScanCallback);
                }
            }, 10000L);
            Log.d(TAG, "Starting old scan");
            mBluetoothAdapter.startLeScan(this.mLeScanCallback);
            return;
        }
        mBluetoothAdapter.stopLeScan(this.mLeScanCallback);
    }

    private void beginScan() {
        this.mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
        this.settings = new ScanSettings.Builder().setScanMode(2).build();
        ArrayList arrayList = new ArrayList();
        this.filters = arrayList;
        arrayList.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(GLUCOSE_SERVICE)).build());
        scanLeDevice(true);
    }

    public static void immortality() {
        if (started_at == -1) {
            startIfEnabled();
        } else {
            startIfNoRecentData();
        }
    }

    public static void startIfNoRecentData() {
        if (JoH.quietratelimit("bluetooth-recent-check", 1800) && Pref.getBoolean("bluetooth_meter_enabled", false)) {
            List<BloodTest> lastMatching = BloodTest.lastMatching(1, "Bluetooth Glucose Meter%");
            if ((lastMatching == null || lastMatching.size() == 0 || JoH.msSince(lastMatching.get(0).created_timestamp) > 21600000) && JoH.pratelimit("restart_bluetooth_service", 18000)) {
                UserError.Log.uel(TAG, "Restarting Bluetooth Glucose meter service");
                startIfEnabled();
            }
        }
    }

    public static void startIfEnabled() {
        if (Pref.getBoolean("bluetooth_meter_enabled", false)) {
            String stringDefaultBlank = Pref.getStringDefaultBlank("selected_bluetooth_meter_address");
            if (stringDefaultBlank.length() > 5) {
                if (JoH.pratelimit("bluetooth-glucose-immortality", 10)) {
                    UserError.Log.d(TAG, "Starting Service");
                    start_service(stringDefaultBlank);
                } else {
                    UserError.Log.e(TAG, "Not starting due to rate limit");
                }
            }
        }
    }

    public static void stop_service() {
        xdrip.getAppContext().stopService(new Intent(xdrip.getAppContext(), (Class<?>) BluetoothGlucoseMeter.class));
    }

    public static void start_service(String str) {
        stop_service();
        Intent intent = new Intent(xdrip.getAppContext(), (Class<?>) BluetoothGlucoseMeter.class);
        if (str != null && str.length() > 0) {
            if (str.equals("auto")) {
                str = Pref.getStringDefaultBlank("selected_bluetooth_meter_address");
            }
            intent.putExtra("service_action", "connect");
            intent.putExtra("connect_address", str);
        } else {
            intent.putExtra("service_action", "scan");
        }
        xdrip.getAppContext().startService(intent);
    }

    public static void start_forget(String str) {
        stop_service();
        Intent intent = new Intent(xdrip.getAppContext(), (Class<?>) BluetoothGlucoseMeter.class);
        if (str == null || str.length() <= 0) {
            return;
        }
        intent.putExtra("service_action", "forget");
        intent.putExtra("forget_address", str);
        xdrip.getAppContext().startService(intent);
    }

    public static void sendImmediateData(UUID uuid, UUID uuid2, byte[] bArr, String str) {
        Log.d(TAG, "Sending immediate data: " + str);
        Bluetooth_CMD.process_queue_entry(Bluetooth_CMD.gen_write(uuid, uuid2, bArr, str));
    }

    public static int getHighestSequence() {
        return (int) PersistentStore.getLong("bt-glucose-sequence-max-" + mBluetoothDeviceAddress);
    }

    private static void setHighestSequence(int i) {
        highestSequenceStore = i;
        Inevitable.task("set-bt-glucose-highest", 1000L, new Runnable() {
            @Override
            public void run() {
                if (BluetoothGlucoseMeter.highestSequenceStore > 0) {
                    PersistentStore.setLong("bt-glucose-sequence-max-" + BluetoothGlucoseMeter.mBluetoothDeviceAddress, BluetoothGlucoseMeter.highestSequenceStore);
                }
            }
        });
    }

    private static class Bluetooth_CMD {
        static long queue_check_scheduled;
        public UUID characteristic;
        public String cmd;
        public byte[] data;
        public String note;
        public int resent;
        public UUID service;
        public long timestamp;

        private Bluetooth_CMD(String str, UUID uuid, UUID uuid2, byte[] bArr, String str2) {
            this.cmd = str;
            this.service = uuid;
            this.characteristic = uuid2;
            this.data = bArr;
            this.note = str2;
            this.timestamp = System.currentTimeMillis();
            this.resent = 0;
        }

        private static synchronized void add_item(String str, UUID uuid, UUID uuid2, byte[] bArr, String str2) {
            synchronized (Bluetooth_CMD.class) {
                BluetoothGlucoseMeter.queue.add(gen_item(str, uuid, uuid2, bArr, str2));
            }
        }

        private static Bluetooth_CMD gen_item(String str, UUID uuid, UUID uuid2, byte[] bArr, String str2) {
            return new Bluetooth_CMD(str, uuid, uuid2, bArr, str2);
        }

        public static Bluetooth_CMD gen_write(UUID uuid, UUID uuid2, byte[] bArr, String str) {
            return gen_item("W", uuid, uuid2, bArr, str);
        }

        public static void write(UUID uuid, UUID uuid2, byte[] bArr, String str) {
            add_item("W", uuid, uuid2, bArr, str);
        }

        public static void read(UUID uuid, UUID uuid2, String str) {
            add_item("R", uuid, uuid2, null, str);
        }

        public static void notify(UUID uuid, UUID uuid2, String str) {
            add_item(TextMap.ERROR_TEXT_PREFIX_NGP, uuid, uuid2, new byte[]{1}, str);
        }

        public static void enable_indications(UUID uuid, UUID uuid2, String str) {
            add_item("D", uuid, uuid2, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE, str);
        }

        public static void enable_notification_value(UUID uuid, UUID uuid2, String str) {
            add_item("D", uuid, uuid2, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, str);
        }

        public static synchronized void check_queue_age() {
            Bluetooth_CMD bluetooth_CMD;
            synchronized (Bluetooth_CMD.class) {
                queue_check_scheduled = 0L;
                if (!BluetoothGlucoseMeter.queue.isEmpty() && (bluetooth_CMD = (Bluetooth_CMD) BluetoothGlucoseMeter.queue.peek()) != null && System.currentTimeMillis() - bluetooth_CMD.timestamp > 10000) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("Timed out on: ");
                    sb.append(bluetooth_CMD.note);
                    sb.append(BluetoothGlucoseMeter.isBonded() ? "" : "\nYou may need to enable the meter's pairing mode by holding the power button when turning it on until it flashes blue");
                    BluetoothGlucoseMeter.statusUpdate(sb.toString());
                    BluetoothGlucoseMeter.queue.clear();
                    Bluetooth_CMD unused = BluetoothGlucoseMeter.last_queue_command = null;
                    BluetoothGlucoseMeter.close();
                    BluetoothGlucoseMeter.waitFor(3000);
                }
            }
        }

        public static synchronized void empty_queue() {
            synchronized (Bluetooth_CMD.class) {
                BluetoothGlucoseMeter.queue.clear();
            }
        }

        public static synchronized void delete_command(java.util.UUID r4, java.util.UUID r5) {
            throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.services.BluetoothGlucoseMeter.Bluetooth_CMD.delete_command(java.util.UUID, java.util.UUID):void");
        }

        public static synchronized void transmute_command(java.util.UUID r4, java.util.UUID r5, java.util.UUID r6, java.util.UUID r7) {
            throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.services.BluetoothGlucoseMeter.Bluetooth_CMD.transmute_command(java.util.UUID, java.util.UUID, java.util.UUID, java.util.UUID):void");
        }

        public static synchronized void replace_command(java.util.UUID r4, java.util.UUID r5, java.lang.String r6, com.eveningoutpost.dexdrip.services.BluetoothGlucoseMeter.Bluetooth_CMD r7) {
            throw new UnsupportedOperationException("Method not decompiled: com.eveningoutpost.dexdrip.services.BluetoothGlucoseMeter.Bluetooth_CMD.replace_command(java.util.UUID, java.util.UUID, java.lang.String, com.eveningoutpost.dexdrip.services.BluetoothGlucoseMeter$Bluetooth_CMD):void");
        }

        public static synchronized void poll_queue() {
            synchronized (Bluetooth_CMD.class) {
                poll_queue(false);
            }
        }

        private static synchronized void poll_queue(boolean z) {
            synchronized (Bluetooth_CMD.class) {
                if (BluetoothGlucoseMeter.mConnectionState == 0) {
                    Log.e(BluetoothGlucoseMeter.TAG, "Connection is disconnecting, deleting queue");
                    Bluetooth_CMD unused = BluetoothGlucoseMeter.last_queue_command = null;
                    BluetoothGlucoseMeter.queue.clear();
                    return;
                }
                if (BluetoothGlucoseMeter.mBluetoothGatt == null) {
                    Log.e(BluetoothGlucoseMeter.TAG, "mBluetoothGatt is null - connect and defer");
                    return;
                }
                if (z && BluetoothGlucoseMeter.queue.size() > 1) {
                    Log.d(BluetoothGlucoseMeter.TAG, "Queue busy deferring poll");
                    return;
                }
                long currentTimeMillis = System.currentTimeMillis();
                if (currentTimeMillis - queue_check_scheduled > 10000) {
                    JoH.runOnUiThreadDelayed(new Runnable() {
                        @Override
                        public void run() {
                            Bluetooth_CMD.check_queue_age();
                        }
                    }, 11000L);
                    queue_check_scheduled = currentTimeMillis;
                }
                if (BluetoothGlucoseMeter.ack_blocking()) {
                    return;
                }
                Bluetooth_CMD bluetooth_CMD = (Bluetooth_CMD) BluetoothGlucoseMeter.queue.poll();
                if (bluetooth_CMD != null) {
                    Log.d(BluetoothGlucoseMeter.TAG, "Processing queue " + bluetooth_CMD.cmd + " :: " + bluetooth_CMD.note + " :: " + bluetooth_CMD.characteristic.toString() + " " + JoH.bytesToHex(bluetooth_CMD.data));
                    Bluetooth_CMD unused2 = BluetoothGlucoseMeter.last_queue_command = bluetooth_CMD;
                    process_queue_entry(bluetooth_CMD);
                }
            }
        }

        public static synchronized void retry_last_command(int i) {
            synchronized (Bluetooth_CMD.class) {
                if (BluetoothGlucoseMeter.last_queue_command != null) {
                    if (BluetoothGlucoseMeter.last_queue_command.resent <= 3) {
                        BluetoothGlucoseMeter.last_queue_command.resent++;
                        BluetoothGlucoseMeter.waitFor(200);
                        Log.d(BluetoothGlucoseMeter.TAG, "Retrying try:(" + BluetoothGlucoseMeter.last_queue_command.resent + ") last command: " + BluetoothGlucoseMeter.last_queue_command.note);
                        process_queue_entry(BluetoothGlucoseMeter.last_queue_command);
                    } else {
                        Log.e(BluetoothGlucoseMeter.TAG, "Exceeded max resend for: " + BluetoothGlucoseMeter.last_queue_command.note);
                        Bluetooth_CMD unused = BluetoothGlucoseMeter.last_queue_command = null;
                    }
                } else {
                    Log.d(BluetoothGlucoseMeter.TAG, "No last command to retry");
                }
            }
        }

        public static void process_queue_entry(Bluetooth_CMD bluetooth_CMD) {
            UUID uuid;
            if (BluetoothGlucoseMeter.mBluetoothAdapter == null || BluetoothGlucoseMeter.mBluetoothGatt == null) {
                Log.w(BluetoothGlucoseMeter.TAG, "BluetoothAdapter not initialized");
                return;
            }
            final BluetoothGattCharacteristic bluetoothGattCharacteristic = null;
            BluetoothGattService service = bluetooth_CMD.service != null ? BluetoothGlucoseMeter.mBluetoothGatt.getService(bluetooth_CMD.service) : null;
            if (service == null && bluetooth_CMD.service != null) {
                Log.e(BluetoothGlucoseMeter.TAG, "Got null service error on: " + bluetooth_CMD.service);
                return;
            }
            if (service != null && (uuid = bluetooth_CMD.characteristic) != null) {
                bluetoothGattCharacteristic = service.getCharacteristic(uuid);
            }
            if (bluetoothGattCharacteristic == null) {
                Log.e(BluetoothGlucoseMeter.TAG, "Characteristic was null!!!!");
            }
            String str = bluetooth_CMD.cmd;
            str.hashCode();
            switch (str) {
                case "D":
                    BluetoothGattDescriptor descriptor = bluetoothGattCharacteristic.getDescriptor(BluetoothGlucoseMeter.CLIENT_CHARACTERISTIC_CONFIG);
                    descriptor.setValue(bluetooth_CMD.data);
                    BluetoothGlucoseMeter.mBluetoothGatt.writeDescriptor(descriptor);
                    break;
                case "N":
                    BluetoothGlucoseMeter.mBluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
                    BluetoothGlucoseMeter.waitFor(100);
                    poll_queue();
                    break;
                case "R":
                    BluetoothGlucoseMeter.mBluetoothGatt.readCharacteristic(bluetoothGattCharacteristic);
                    break;
                case "U":
                    BluetoothGlucoseMeter.mBluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, false);
                    break;
                case "W":
                    bluetoothGattCharacteristic.setValue(bluetooth_CMD.data);
                    if (BluetoothGlucoseMeter.await_acks && bluetoothGattCharacteristic.getValue().length > 1) {
                        BluetoothGlucoseMeter.awaiting_ack = true;
                        BluetoothGlucoseMeter.awaiting_data = true;
                        if (bluetooth_CMD.note.startsWith("verio get record")) {
                            VerioHelper.updateRequestedRecord(Integer.parseInt(bluetooth_CMD.note.substring(17)));
                        }
                    }
                    JoH.runOnUiThreadDelayed(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (BluetoothGlucoseMeter.mBluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic)) {
                                    return;
                                }
                                Log.d(BluetoothGlucoseMeter.TAG, "Failed in write characteristic");
                                BluetoothGlucoseMeter.waitFor(150);
                                if (BluetoothGlucoseMeter.mBluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic)) {
                                    return;
                                }
                                Log.e(BluetoothGlucoseMeter.TAG, "Failed second time in write charactersitic");
                            } catch (NullPointerException unused) {
                                UserError.Log.e(BluetoothGlucoseMeter.TAG, "Got null pointer exception writing characteristic - probably temporary failure");
                            }
                        }
                    }, 0L);
                    break;
                default:
                    Log.e(BluetoothGlucoseMeter.TAG, "Unknown queue cmd: " + bluetooth_CMD.cmd);
                    break;
            }
        }
    }
}