From da1902da6174cdb6c7e54fc03cead3815c063b1d Mon Sep 17 00:00:00 2001 From: Jamorham Date: Fri, 25 Nov 2016 21:25:31 +0000 Subject: [PATCH] G5: debug version for new collection method --- .../dexdrip/G5Model/GlucoseRxMessage.java | 64 +++++ .../dexdrip/G5Model/GlucoseTxMessage.java | 21 ++ .../dexdrip/Services/G5CollectionService.java | 263 +++++++++--------- .../dexdrip/utils/Preferences.java | 3 + app/src/main/res/xml/pref_data_source.xml | 5 + 5 files changed, 226 insertions(+), 130 deletions(-) create mode 100644 app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseRxMessage.java create mode 100644 app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseTxMessage.java diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseRxMessage.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseRxMessage.java new file mode 100644 index 0000000000..7c0f21ce8b --- /dev/null +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseRxMessage.java @@ -0,0 +1,64 @@ +package com.eveningoutpost.dexdrip.G5Model; + +import com.eveningoutpost.dexdrip.Models.JoH; +import com.eveningoutpost.dexdrip.Models.UserError; +import com.eveningoutpost.dexdrip.Services.G5CollectionService; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Created by jamorham on 25/11/2016. + * + * Alternate mechanism for reading data cribbed from LoopKit + * totally experimental and untested + */ + +public class GlucoseRxMessage extends TransmitterMessage { + + private final static String TAG = G5CollectionService.class.getSimpleName(); // meh + + public static final byte opcode = 0x31; + public TransmitterStatus status; + public int status_raw; + public int timestamp; + public int unfiltered; + public int filtered; + public int sequence; // : UInt32 + public boolean glucoseIsDisplayOnly; // : Bool + public int glucose; // : UInt16 + public int state; //: UInt8 + public int trend; // : Int8 + + + public GlucoseRxMessage(byte[] packet) { + UserError.Log.e(TAG, "GlucoseRX dbg: " + JoH.bytesToHex(packet)); + if (packet.length >= 14) { + // TODO check CRC?? + if (packet[0] == opcode) { + data = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN); + + status_raw = data.get(1); + status = TransmitterStatus.getBatteryLevel(data.get(1)); + sequence = data.getInt(2); + timestamp = data.getInt(6); + + + int glucoseBytes = data.getShort(10); // check signed vs unsigned!! + glucoseIsDisplayOnly = (glucoseBytes & 0xf000) > 0; + glucose = glucoseBytes & 0xfff; + + state = data.get(12); + trend = data.get(13); + + unfiltered = glucose * 1000; + filtered = glucose * 1000; + + UserError.Log.e(TAG, "GlucoseRX: " + sequence + " ts:" + timestamp + " sg:" + glucose + " do:" + glucoseIsDisplayOnly + " ss:" + status + " sr:" + status_raw + " st:" + state + " tr:" + trend); + + } + } else { + UserError.Log.e(TAG, "GlucoseRxMessage packet length received wrong: " + packet.length); + } + } +} diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseTxMessage.java b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseTxMessage.java new file mode 100644 index 0000000000..9f78807215 --- /dev/null +++ b/app/src/main/java/com/eveningoutpost/dexdrip/G5Model/GlucoseTxMessage.java @@ -0,0 +1,21 @@ +package com.eveningoutpost.dexdrip.G5Model; + +import java.nio.ByteBuffer; + +/** + * Created by jamorham on 25/11/2016. + */ + +public class GlucoseTxMessage extends TransmitterMessage { + + byte opcode = 0x30; + byte[] crc = CRC.calculate(opcode); + + public GlucoseTxMessage() { + data = ByteBuffer.allocate(3); + data.put(opcode); + data.put(crc); + byteSequence = data.array(); + } +} + diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java b/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java index ae068f3e3c..4a25456ba4 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/Services/G5CollectionService.java @@ -30,7 +30,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; -import android.os.ParcelUuid; import android.os.PowerManager; import android.preference.PreferenceManager; @@ -43,13 +42,17 @@ import com.eveningoutpost.dexdrip.G5Model.BondRequestTxMessage; import com.eveningoutpost.dexdrip.G5Model.DisconnectTxMessage; import com.eveningoutpost.dexdrip.G5Model.Extensions; +import com.eveningoutpost.dexdrip.G5Model.GlucoseRxMessage; +import com.eveningoutpost.dexdrip.G5Model.GlucoseTxMessage; import com.eveningoutpost.dexdrip.G5Model.SensorRxMessage; import com.eveningoutpost.dexdrip.G5Model.SensorTxMessage; import com.eveningoutpost.dexdrip.G5Model.TransmitterStatus; +import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.Models.BgReading; import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.Sensor; import com.eveningoutpost.dexdrip.Models.TransmitterData; +import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.Models.UserError.Log; import com.eveningoutpost.dexdrip.G5Model.Transmitter; @@ -191,6 +194,12 @@ public int onStartCommand(Intent intent, int flags, int startId) { if ((!service_running) && (keep_running)) { service_running = true; + if (useG5NewMethod()) { + if (!Home.getPreferencesStringDefaultBlank("extra_tags_for_logging").contains("G5CollectionService")) { + Home.setPreferencesString("extra_tags_for_logging", "G5CollectionService:v,"); + } + } + Log.d(TAG, "onG5StartCommand wakeup: "+JoH.dateTimeText(JoH.tsl())); //Log.d(TAG, "SDK: " + Build.VERSION.SDK_INT); //stopScan(); @@ -304,6 +313,7 @@ public synchronized void keepAlive(int wake_in_ms) { if (pendingIntent != null) alarm.cancel(pendingIntent); pendingIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), 0); + // TODO use wakeIntent feature if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, wakeTime, pendingIntent); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -407,6 +417,7 @@ public synchronized void cycleScan(int delay) { if (!keep_running) return; if (JoH.ratelimit("G5-timeout",60) || !scan_scheduled) { + Log.d(TAG,"cycleScan running"); scan_scheduled=true; //Log.e(TAG, "Scheduling cycle scan, delay: " + delay); final Timer single_timer = new Timer(); @@ -437,7 +448,7 @@ public void run() { } catch (NullPointerException e) { //Known bug in Samsung API 21 stack - System.out.print("Caught the NullPointerException"); + Log.e(TAG,"Caught the NullPointerException in cyclescan"); } finally { scan_scheduled=false; } @@ -508,7 +519,7 @@ public void run() { } public synchronized void startScan() { - android.util.Log.e(TAG, "Initial scan?" + isIntialScan); + UserError.Log.e(TAG, "Initial scan?" + isIntialScan); if (isScanning) { Log.d(TAG, "alreadyScanning"); scan_interval_timer.cancel(); @@ -650,7 +661,7 @@ private void initScanCallback(){ mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { - android.util.Log.i(TAG, "result: " + result.toString()); + UserError.Log.i(TAG, "result: " + result.toString()); BluetoothDevice btDevice = result.getDevice(); // // Check if the device has a name, the Dexcom transmitter always should. Match it with the transmitter id that was entered. // // We get the last 2 characters to connect to the correct transmitter if there is more than 1 active or in the room. @@ -679,7 +690,7 @@ public void onScanResult(int callbackType, ScanResult result) { public void onScanFailed(int errorCode) { Log.e(TAG, "Scan Failed Error Code: " + errorCode); if (errorCode == 1) { - android.util.Log.e(TAG, "Already Scanning: " + isScanning); + UserError.Log.e(TAG, "Already Scanning: " + isScanning); //isScanning = true; } else if (errorCode == 2){ cycleBT(); @@ -694,11 +705,11 @@ public synchronized void fullAuthenticate() { forgetDevice(); } try { - android.util.Log.i(TAG, "Start Auth Process(fullAuthenticate)"); + Log.i(TAG, "Start Auth Process(fullAuthenticate)"); authRequest = new AuthRequestTxMessage(); if (authCharacteristic != null) { authCharacteristic.setValue(authRequest.byteSequence); - android.util.Log.i(TAG, authRequest.byteSequence.toString()); + Log.i(TAG, authRequest.byteSequence.toString()); mGatt.writeCharacteristic(authCharacteristic); } } catch (NullPointerException e) { @@ -710,7 +721,7 @@ public synchronized void authenticate() { try { mGatt.setCharacteristicNotification(authCharacteristic, true); if (!mGatt.readCharacteristic(authCharacteristic)) { - android.util.Log.e(TAG, "onCharacteristicRead : ReadCharacteristicError"); + Log.e(TAG, "onCharacteristicRead : ReadCharacteristicError"); } } catch (NullPointerException e) { Log.e(TAG, "Got Nullpointer exception in authenticate(): " + e); @@ -718,14 +729,21 @@ public synchronized void authenticate() { } public synchronized void getSensorData() { - android.util.Log.i(TAG, "Request Sensor Data"); + Log.i(TAG, "Request Sensor Data"); try { if (mGatt != null) { mGatt.setCharacteristicNotification(controlCharacteristic, true); BluetoothGattDescriptor descriptor = controlCharacteristic.getDescriptor(BluetoothServices.CharacteristicUpdateNotification); descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); - SensorTxMessage sensorTx = new SensorTxMessage(); - controlCharacteristic.setValue(sensorTx.byteSequence); + if (useG5NewMethod()) { + // new style + GlucoseTxMessage glucoseTxMessage = new GlucoseTxMessage(); + controlCharacteristic.setValue(glucoseTxMessage.byteSequence); + } else { + // old style + SensorTxMessage sensorTx = new SensorTxMessage(); + controlCharacteristic.setValue(sensorTx.byteSequence); + } mGatt.writeDescriptor(descriptor); } } catch (NullPointerException e) { @@ -745,7 +763,7 @@ private synchronized void connectToDevice(BluetoothDevice device) { } mGatt = null; } - android.util.Log.i(TAG, "Request Connect"); + Log.i(TAG, "Request Connect"); if (enforceMainThread()){ Handler iHandler = new Handler(Looper.getMainLooper()); final BluetoothDevice mDevice = device; @@ -753,15 +771,15 @@ private synchronized void connectToDevice(BluetoothDevice device) { @Override public void run() { - android.util.Log.i(TAG, "mGatt Null, connecting..."); - android.util.Log.i(TAG, "connectToDevice On Main Thread? " + isOnMainThread()); + Log.i(TAG, "mGatt Null, connecting..."); + Log.i(TAG, "connectToDevice On Main Thread? " + isOnMainThread()); mGatt = mDevice.connectGatt(getApplicationContext(), false, gattCallback); } }); } else { - android.util.Log.i(TAG, "mGatt Null, connecting..."); - android.util.Log.i(TAG, "connectToDevice On Main Thread? " + isOnMainThread()); + Log.i(TAG, "mGatt Null, connecting..."); + Log.i(TAG, "connectToDevice On Main Thread? " + isOnMainThread()); mGatt = device.connectGatt(getApplicationContext(), false, gattCallback); } @@ -786,7 +804,7 @@ public void onConnectionStateChange(BluetoothGatt gatt, final int status, final iHandler.post(new Runnable() { @Override public void run() { //Log.e(TAG, "last disconnect status? " + lastGattStatus); - android.util.Log.i(TAG, "onConnectionStateChange On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onConnectionStateChange On Main Thread? " + isOnMainThread()); switch (newState) { case BluetoothProfile.STATE_CONNECTED: Log.e(TAG, "STATE_CONNECTED"); @@ -797,13 +815,13 @@ public void onConnectionStateChange(BluetoothGatt gatt, final int status, final iHandler.post(new Runnable() { @Override public void run() { - android.util.Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); + Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); if (mGatt != null) mGatt.discoverServices(); } }); } else { - android.util.Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); + Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); if (mGatt != null) mGatt.discoverServices(); } @@ -827,7 +845,7 @@ public void run() { } mGatt = null; if (status == 0 && !encountered133) {// || status == 59) { - android.util.Log.i(TAG, "clean disconnect"); + Log.i(TAG, "clean disconnect"); max133RetryCounter = 0; if (scanConstantly()) cycleScan(15000); @@ -870,7 +888,7 @@ public void run() { } ); } else { - android.util.Log.i(TAG, "onConnectionStateChange On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onConnectionStateChange On Main Thread? " + isOnMainThread()); switch (newState) { case BluetoothProfile.STATE_CONNECTED: Log.e(TAG, "STATE_CONNECTED"); @@ -881,13 +899,13 @@ public void run() { iHandler.post(new Runnable() { @Override public void run() { - android.util.Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); + Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); if (mGatt != null) mGatt.discoverServices(); } }); } else { - android.util.Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); + Log.i(TAG, "discoverServices On Main Thread? " + isOnMainThread()); if (mGatt != null) mGatt.discoverServices(); } @@ -907,7 +925,7 @@ public void run() { mGatt.close(); mGatt = null; if (status == 0 && !encountered133) {// || status == 59) { - android.util.Log.i(TAG, "clean disconnect"); + Log.i(TAG, "clean disconnect"); max133RetryCounter = 0; if (scanConstantly()) cycleScan(15000); @@ -958,7 +976,7 @@ public void onServicesDiscovered(BluetoothGatt gatt, final int status) { iHandler.post(new Runnable() { @Override public void run() { - android.util.Log.i(TAG, "onServicesDiscovered On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onServicesDiscovered On Main Thread? " + isOnMainThread()); Log.e(TAG, "onServicesDiscovered: " + status); if (status == BluetoothGatt.GATT_SUCCESS) { if (mGatt != null) { @@ -992,7 +1010,7 @@ public void run() { } }); } else { - android.util.Log.i(TAG, "onServicesDiscovered On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onServicesDiscovered On Main Thread? " + isOnMainThread()); Log.e(TAG, "onServicesDiscovered: " + status); if (status == BluetoothGatt.GATT_SUCCESS) { if (mGatt != null) { @@ -1035,7 +1053,7 @@ public void onDescriptorWrite(BluetoothGatt gatt, final BluetoothGattDescriptor iHandler.post(new Runnable() { @Override public void run() { - android.util.Log.i(TAG, "onDescriptorWrite On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onDescriptorWrite On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { mGatt.writeCharacteristic(descriptor.getCharacteristic()); Log.e(TAG, "Writing descriptor: " + status); @@ -1049,7 +1067,7 @@ public void run() { } }); } else { - android.util.Log.i(TAG, "onDescriptorWrite On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onDescriptorWrite On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { mGatt.writeCharacteristic(descriptor.getCharacteristic()); Log.e(TAG, "Writing descriptor: " + status); @@ -1073,18 +1091,18 @@ public void onCharacteristicWrite(BluetoothGatt gatt, final BluetoothGattCharact public void run() { Log.e(TAG, "Success Write " + String.valueOf(status)); //Log.e(TAG, "Characteristic " + String.valueOf(characteristic.getUuid())); - android.util.Log.i(TAG, "onCharacteristicWrite On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onCharacteristicWrite On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { if (String.valueOf(characteristic.getUuid()).equalsIgnoreCase(String.valueOf(authCharacteristic.getUuid()))) { - android.util.Log.i(TAG, "Char Value: " + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "auth? " + String.valueOf(characteristic.getUuid())); + Log.i(TAG, "Char Value: " + Arrays.toString(characteristic.getValue())); + Log.i(TAG, "auth? " + String.valueOf(characteristic.getUuid())); if (characteristic.getValue() != null && characteristic.getValue()[0] != 0x6) { mGatt.readCharacteristic(characteristic); } } else { - android.util.Log.i(TAG, "control? " + String.valueOf(characteristic.getUuid())); - android.util.Log.i(TAG, "status? " + status); + Log.i(TAG, "control? " + String.valueOf(characteristic.getUuid())); + Log.i(TAG, "status? " + status); } } @@ -1097,18 +1115,18 @@ public void run() { } else { Log.e(TAG, "Success Write " + String.valueOf(status)); //Log.e(TAG, "Characteristic " + String.valueOf(characteristic.getUuid())); - android.util.Log.i(TAG, "onCharacteristicWrite On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onCharacteristicWrite On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { if (String.valueOf(characteristic.getUuid()).equalsIgnoreCase(String.valueOf(authCharacteristic.getUuid()))) { - android.util.Log.i(TAG, "Char Value: " + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "auth? " + String.valueOf(characteristic.getUuid())); + Log.i(TAG, "Char Value: " + Arrays.toString(characteristic.getValue())); + Log.i(TAG, "auth? " + String.valueOf(characteristic.getUuid())); if (characteristic.getValue() != null && characteristic.getValue()[0] != 0x6) { mGatt.readCharacteristic(characteristic); } } else { - android.util.Log.i(TAG, "control? " + String.valueOf(characteristic.getUuid())); - android.util.Log.i(TAG, "status? " + status); + Log.i(TAG, "control? " + String.valueOf(characteristic.getUuid())); + Log.i(TAG, "status? " + status); } } @@ -1128,11 +1146,11 @@ public void onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacte @Override public void run() { Log.e(TAG, "ReadStatus: " + String.valueOf(status)); - android.util.Log.i(TAG, "onCharacteristicRead On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onCharacteristicRead On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "CharBytes-or " + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "CharHex-or " + Extensions.bytesToHex(characteristic.getValue())); + Log.i(TAG, "CharHex-or " + Extensions.bytesToHex(characteristic.getValue())); byte[] buffer = characteristic.getValue(); byte code = buffer[0]; @@ -1146,17 +1164,17 @@ public void run() { isBondedOrBonding = true; getSensorData(); } else if (authStatus.authenticated == 1 && authStatus.bonded == 2) { - android.util.Log.i(TAG, "Let's Bond!"); + Log.i(TAG, "Let's Bond!"); BondRequestTxMessage bondRequest = new BondRequestTxMessage(); characteristic.setValue(bondRequest.byteSequence); mGatt.writeCharacteristic(characteristic); isBondedOrBonding = true; device.createBond(); } else { - android.util.Log.i(TAG, "Transmitter NOT already authenticated"); + Log.i(TAG, "Transmitter NOT already authenticated"); authRequest = new AuthRequestTxMessage(); characteristic.setValue(authRequest.byteSequence); - android.util.Log.i(TAG, authRequest.byteSequence.toString()); + Log.i(TAG, authRequest.byteSequence.toString()); mGatt.writeCharacteristic(characteristic); } break; @@ -1166,25 +1184,25 @@ public void run() { if (authRequest == null) { authRequest = new AuthRequestTxMessage(); } - android.util.Log.i(TAG, "tokenHash " + Arrays.toString(authChallenge.tokenHash)); - android.util.Log.i(TAG, "singleUSe " + Arrays.toString(calculateHash(authRequest.singleUseToken))); + Log.i(TAG, "tokenHash " + Arrays.toString(authChallenge.tokenHash)); + Log.i(TAG, "singleUSe " + Arrays.toString(calculateHash(authRequest.singleUseToken))); byte[] challengeHash = calculateHash(authChallenge.challenge); - android.util.Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); + Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); if (challengeHash != null) { - android.util.Log.d(TAG, "Transmitter try auth challenge"); + Log.d(TAG, "Transmitter try auth challenge"); AuthChallengeTxMessage authChallengeTx = new AuthChallengeTxMessage(challengeHash); - android.util.Log.i(TAG, "Auth Challenge: " + Arrays.toString(authChallengeTx.byteSequence)); + Log.i(TAG, "Auth Challenge: " + Arrays.toString(authChallengeTx.byteSequence)); characteristic.setValue(authChallengeTx.byteSequence); mGatt.writeCharacteristic(characteristic); } break; default: - android.util.Log.i(TAG, code + " - Transmitter NOT already authenticated"); + Log.i(TAG, code + " - Transmitter NOT already authenticated"); authRequest = new AuthRequestTxMessage(); characteristic.setValue(authRequest.byteSequence); - android.util.Log.i(TAG, authRequest.byteSequence.toString()); + Log.i(TAG, authRequest.byteSequence.toString()); mGatt.writeCharacteristic(characteristic); break; } @@ -1198,11 +1216,11 @@ public void run() { }); } else { Log.e(TAG, "ReadStatus: " + String.valueOf(status)); - android.util.Log.i(TAG, "onCharacteristicRead On Main Thread? " + isOnMainThread()); + Log.i(TAG, "onCharacteristicRead On Main Thread? " + isOnMainThread()); if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "CharBytes-or " + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "CharHex-or " + Extensions.bytesToHex(characteristic.getValue())); + Log.i(TAG, "CharHex-or " + Extensions.bytesToHex(characteristic.getValue())); byte[] buffer = characteristic.getValue(); byte code = buffer[0]; @@ -1216,17 +1234,17 @@ public void run() { isBondedOrBonding = true; getSensorData(); } else if (authStatus.authenticated == 1 && authStatus.bonded == 2) { - android.util.Log.i(TAG, "Let's Bond!"); + Log.i(TAG, "Let's Bond!"); BondRequestTxMessage bondRequest = new BondRequestTxMessage(); characteristic.setValue(bondRequest.byteSequence); mGatt.writeCharacteristic(characteristic); isBondedOrBonding = true; device.createBond(); } else { - android.util.Log.i(TAG, "Transmitter NOT already authenticated"); + Log.i(TAG, "Transmitter NOT already authenticated"); authRequest = new AuthRequestTxMessage(); characteristic.setValue(authRequest.byteSequence); - android.util.Log.i(TAG, authRequest.byteSequence.toString()); + Log.i(TAG, authRequest.byteSequence.toString()); mGatt.writeCharacteristic(characteristic); } break; @@ -1236,25 +1254,25 @@ public void run() { if (authRequest == null) { authRequest = new AuthRequestTxMessage(); } - android.util.Log.i(TAG, "tokenHash " + Arrays.toString(authChallenge.tokenHash)); - android.util.Log.i(TAG, "singleUSe " + Arrays.toString(calculateHash(authRequest.singleUseToken))); + Log.i(TAG, "tokenHash " + Arrays.toString(authChallenge.tokenHash)); + Log.i(TAG, "singleUSe " + Arrays.toString(calculateHash(authRequest.singleUseToken))); byte[] challengeHash = calculateHash(authChallenge.challenge); - android.util.Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); + Log.d(TAG, "challenge hash" + Arrays.toString(challengeHash)); if (challengeHash != null) { - android.util.Log.d(TAG, "Transmitter try auth challenge"); + Log.d(TAG, "Transmitter try auth challenge"); AuthChallengeTxMessage authChallengeTx = new AuthChallengeTxMessage(challengeHash); - android.util.Log.i(TAG, "Auth Challenge: " + Arrays.toString(authChallengeTx.byteSequence)); + Log.i(TAG, "Auth Challenge: " + Arrays.toString(authChallengeTx.byteSequence)); characteristic.setValue(authChallengeTx.byteSequence); mGatt.writeCharacteristic(characteristic); } break; default: - android.util.Log.i(TAG, code + " - Transmitter NOT already authenticated"); + Log.i(TAG, code + " - Transmitter NOT already authenticated"); authRequest = new AuthRequestTxMessage(); characteristic.setValue(authRequest.byteSequence); - android.util.Log.i(TAG, authRequest.byteSequence.toString()); + Log.i(TAG, authRequest.byteSequence.toString()); mGatt.writeCharacteristic(characteristic); break; } @@ -1277,83 +1295,61 @@ public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGat iHandler.post(new Runnable() { @Override public void run() { - Log.e(TAG, "CharBytes-nfy" + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "CharHex-nfy" + Extensions.bytesToHex(characteristic.getValue())); - - android.util.Log.i(TAG, "onCharacteristicChanged On Main Thread? " + isOnMainThread()); - - byte[] buffer = characteristic.getValue(); - byte firstByte = buffer[0]; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && gatt != null) { - mGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); - } - if (firstByte == 0x2f) { - SensorRxMessage sensorRx = new SensorRxMessage(characteristic.getValue()); - - ByteBuffer sensorData = ByteBuffer.allocate(buffer.length); - sensorData.order(ByteOrder.LITTLE_ENDIAN); - sensorData.put(buffer, 0, buffer.length); - - int sensor_battery_level = 0; - if (sensorRx.status == TransmitterStatus.BRICKED) { - //TODO Handle this in UI/Notification - sensor_battery_level = 206; //will give message "EMPTY" - } else if (sensorRx.status == TransmitterStatus.LOW) { - sensor_battery_level = 209; //will give message "LOW" - } else { - sensor_battery_level = 216; //no message, just system status "OK" - } - - //Log.e(TAG, "filtered: " + sensorRx.filtered); - Log.e(TAG, "unfiltered: " + sensorRx.unfiltered); - disconnected133=0; - disconnected59=0; - doDisconnectMessage(gatt, characteristic); - processNewTransmitterData(sensorRx.unfiltered, sensorRx.filtered, sensor_battery_level, new Date().getTime()); - } + processRxCharacteristic(gatt, characteristic); } }); } else { - Log.e(TAG, "CharBytes-nfy" + Arrays.toString(characteristic.getValue())); - android.util.Log.i(TAG, "CharHex-nfy" + Extensions.bytesToHex(characteristic.getValue())); + processRxCharacteristic(gatt, characteristic); + } + } - android.util.Log.i(TAG, "onCharacteristicChanged On Main Thread? " + isOnMainThread()); - byte[] buffer = characteristic.getValue(); - byte firstByte = buffer[0]; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && gatt != null) { - mGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); - } - if (firstByte == 0x2f) { - SensorRxMessage sensorRx = new SensorRxMessage(characteristic.getValue()); - - ByteBuffer sensorData = ByteBuffer.allocate(buffer.length); - sensorData.order(ByteOrder.LITTLE_ENDIAN); - sensorData.put(buffer, 0, buffer.length); - - int sensor_battery_level = 0; - if (sensorRx.status == TransmitterStatus.BRICKED) { - //TODO Handle this in UI/Notification - sensor_battery_level = 206; //will give message "EMPTY" - } else if (sensorRx.status == TransmitterStatus.LOW) { - sensor_battery_level = 209; //will give message "LOW" - } else { - sensor_battery_level = 216; //no message, just system status "OK" - } + private synchronized void processRxCharacteristic(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + Log.e(TAG, "CharBytes-nfy" + Arrays.toString(characteristic.getValue())); + Log.i(TAG, "CharHex-nfy" + Extensions.bytesToHex(characteristic.getValue())); - //Log.e(TAG, "filtered: " + sensorRx.filtered); - disconnected133=0; - disconnected59=0; - Log.e(TAG, "unfiltered: " + sensorRx.unfiltered); - doDisconnectMessage(gatt, characteristic); - processNewTransmitterData(sensorRx.unfiltered, sensorRx.filtered, sensor_battery_level, new Date().getTime()); - } - } + Log.i(TAG, "onCharacteristicChanged On Main Thread? " + isOnMainThread()); + byte[] buffer = characteristic.getValue(); + byte firstByte = buffer[0]; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && gatt != null) { + mGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); + } + Log.d(TAG, "Received opcode reply: " + firstByte); + if (firstByte == 0x2f) { + SensorRxMessage sensorRx = new SensorRxMessage(characteristic.getValue()); + + ByteBuffer sensorData = ByteBuffer.allocate(buffer.length); + sensorData.order(ByteOrder.LITTLE_ENDIAN); + sensorData.put(buffer, 0, buffer.length); + + int sensor_battery_level = 0; + if (sensorRx.status == TransmitterStatus.BRICKED) { + //TODO Handle this in UI/Notification + sensor_battery_level = 206; //will give message "EMPTY" + } else if (sensorRx.status == TransmitterStatus.LOW) { + sensor_battery_level = 209; //will give message "LOW" + } else { + sensor_battery_level = 216; //no message, just system status "OK" + } + //Log.e(TAG, "filtered: " + sensorRx.filtered); + disconnected133 = 0; + disconnected59 = 0; + Log.e(TAG, "unfiltered: " + sensorRx.unfiltered); + doDisconnectMessage(gatt, characteristic); + processNewTransmitterData(sensorRx.unfiltered, sensorRx.filtered, sensor_battery_level, new Date().getTime()); + } else if (firstByte == GlucoseRxMessage.opcode) { + GlucoseRxMessage glucoseRx = new GlucoseRxMessage(characteristic.getValue()); + Log.e(TAG, "glucose unfiltered: " + glucoseRx.unfiltered); + processNewTransmitterData(glucoseRx.unfiltered, glucoseRx.filtered, 216, new Date().getTime()); + } } }; + + + private synchronized void processNewTransmitterData(int raw_data , int filtered_data,int sensor_battery_level, long captureTime) { TransmitterData transmitterData = TransmitterData.create(raw_data, sensor_battery_level, captureTime); @@ -1372,7 +1368,7 @@ private synchronized void processNewTransmitterData(int raw_data , int filtered_ //TODO : LOG if unfiltered or filtered values are zero Sensor.updateBatteryLevel(sensor, transmitterData.sensor_battery_level); - android.util.Log.i("timestamp create", Long.toString(transmitterData.timestamp)); + Log.i("timestamp create", Long.toString(transmitterData.timestamp)); BgReading.create(transmitterData.raw_data, filtered_data, this, transmitterData.timestamp); @@ -1386,7 +1382,7 @@ private synchronized void processNewTransmitterData(int raw_data , int filtered_ @SuppressLint("GetInstance") private byte[] calculateHash(byte[] data) { if (data.length != 8) { - android.util.Log.e("Decrypt", "Data length should be exactly 8."); + Log.e(TAG, "Decrypt Data length should be exactly 8."); return null; } @@ -1476,4 +1472,11 @@ public boolean enforceMainThread() { return sharedPreferences.getBoolean("run_G5_ble_tasks_on_uithread", false); } + // TODO this could be cached for performance + public boolean useG5NewMethod() { + return Home.getPreferencesBooleanDefaultFalse("g5_non_raw_method"); + } + + + } \ No newline at end of file diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java index e00b6a4d3f..58cb4ff5c4 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utils/Preferences.java @@ -649,6 +649,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { bindTTSListener(); final Preference collectionMethod = findPreference("dex_collection_method"); final Preference runInForeground = findPreference("run_service_in_foreground"); + final Preference g5nonraw = findPreference("g5_non_raw_method"); final Preference scanConstantly = findPreference("run_ble_scan_constantly"); final Preference runOnMain = findPreference("run_G5_ble_tasks_on_uithread"); final Preference reAuth = findPreference("always_get_new_keys"); @@ -962,6 +963,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { if (collectionType == DexCollectionType.DexcomG5) { collectionCategory.addPreference(transmitterId); + collectionCategory.addPreference(g5nonraw); collectionCategory.addPreference(scanConstantly); collectionCategory.addPreference(reAuth); collectionCategory.addPreference(reBond); @@ -969,6 +971,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } else { // collectionCategory.removePreference(transmitterId); collectionCategory.removePreference(scanConstantly); + collectionCategory.removePreference(g5nonraw); collectionCategory.removePreference(reAuth); collectionCategory.removePreference(reBond); collectionCategory.removePreference(runOnMain); diff --git a/app/src/main/res/xml/pref_data_source.xml b/app/src/main/res/xml/pref_data_source.xml index cc09a94bf3..e9c0b47a0d 100644 --- a/app/src/main/res/xml/pref_data_source.xml +++ b/app/src/main/res/xml/pref_data_source.xml @@ -94,6 +94,11 @@ android:summary="@string/shows_a_persistent_notification" android:title="@string/run_collector_in_foreground" /> +