正在查看: xDrip+ v04633772025.07.16 应用的 BluetoothGlucoseMeter.java JAVA 源代码文件
本页面展示 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;
}
}
}
}