From a7fd172cd4a3795f88f33d20bd05d0987441a140 Mon Sep 17 00:00:00 2001 From: Jamorham Date: Tue, 17 Oct 2017 18:48:42 +0100 Subject: [PATCH] Sync wear with recent features --- .../dexdrip/G5Model/Ob1G5StateMachine.java | 4 +- .../eveningoutpost/dexdrip/Models/JoH.java | 5 + .../dexdrip/UtilityModels/Blukon.java | 98 ++++++++++++++++--- .../UtilityModels/NotificationChannels.java | 12 +++ .../dexdrip/utils/FileUtils.java | 63 ++++++++++++ 5 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java create mode 100644 wear/src/main/java/com/eveningoutpost/dexdrip/utils/FileUtils.java diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java index d01418c08d..2dc577905e 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/G5Model/Ob1G5StateMachine.java @@ -11,6 +11,7 @@ import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.Services.Ob1G5CollectionService; import com.eveningoutpost.dexdrip.UtilityModels.Constants; +import com.eveningoutpost.dexdrip.UtilityModels.NotificationChannels; import com.eveningoutpost.dexdrip.UtilityModels.PersistentStore; import com.eveningoutpost.dexdrip.utils.PowerStateReceiver; import com.eveningoutpost.dexdrip.xdrip; @@ -542,7 +543,8 @@ public synchronized static boolean setStoredBatteryBytes(String transmitterId, b if (batteryInfoRxMessage.voltagea < LOW_BATTERY_WARNING_LEVEL) { if (JoH.pratelimit("g5-low-battery-warning", 40000)) { final boolean loud = !PowerStateReceiver.is_power_connected(); - JoH.showNotification("G5 Battery Low", "G5 Transmitter battery has dropped to: " + batteryInfoRxMessage.voltagea + " it may fail soon", null, 770, loud, loud, false); + JoH.showNotification("G5 Battery Low", "G5 Transmitter battery has dropped to: " + batteryInfoRxMessage.voltagea + " it may fail soon", + null, 770, NotificationChannels.LOW_TRANSMITTER_BATTERY_CHANNEL, loud, loud, null, null, null); } } PersistentStore.setLong(G5_BATTERY_LEVEL_MARKER + transmitterId, batteryInfoRxMessage.voltagea); diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java index 3fc1398fb9..b6a06d3643 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/Models/JoH.java @@ -1037,6 +1037,11 @@ public static void showNotification(String title, String content, PendingIntent showNotification(title, content, intent, notificationId, sound, vibrate, null, null); } + // ignore channel id and bigmsg + public static void showNotification(String title, String content, PendingIntent intent, int notificationId, String channelId, boolean sound, boolean vibrate, PendingIntent deleteIntent, Uri sound_uri, String bigmsg) { + showNotification(title, content, intent, notificationId, sound, vibrate, deleteIntent, sound_uri); + } + public static void showNotification(String title, String content, PendingIntent intent, int notificationId, boolean sound, boolean vibrate, PendingIntent deleteIntent, Uri sound_uri) { final Notification.Builder mBuilder = notificationBuilder(title, content, intent); final long[] vibratePattern = {0, 1000, 300, 1000, 300, 1000}; diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java index 03a77e4829..5b885fa68b 100644 --- a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/Blukon.java @@ -1,5 +1,6 @@ package com.eveningoutpost.dexdrip.UtilityModels; +import android.content.Context; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; @@ -7,6 +8,7 @@ import android.view.WindowManager; import android.widget.EditText; + import com.eveningoutpost.dexdrip.Home; import com.eveningoutpost.dexdrip.Models.BgReading; import com.eveningoutpost.dexdrip.Models.JoH; @@ -17,7 +19,9 @@ import com.eveningoutpost.dexdrip.Services.DexCollectionService; import com.eveningoutpost.dexdrip.utils.CheckBridgeBattery; import com.eveningoutpost.dexdrip.utils.CipherUtils; +import com.eveningoutpost.dexdrip.utils.FileUtils; import com.eveningoutpost.dexdrip.xdrip; +import com.eveningoutpost.dexdrip.ImportedLibraries.usbserial.util.HexDump; /** * Created by gregorybel / jamorham on 02/09/2017. @@ -50,6 +54,8 @@ private static enum BLUKON_STATES { private static boolean m_getNowGlucoseDataCommand = false;// to be sure we wait for a GlucoseData Block and not using another block private static long m_timeLastBg = 0; private static long m_persistentTimeLastBg; + private static int m_blockNumber = 0; + private static byte[] m_full_data = new byte [344]; public static String getPin() { final String thepin = Home.getPreferencesStringWithDefault(BLUKON_PIN_PREF, null); @@ -77,6 +83,7 @@ public static void initialize() { m_getNowGlucoseDataIndexCommand = false; m_getOlderReading = false; + m_blockNumber = 0; // @keencave - initialize only once during initial to ensure no backfilling at start // m_timeLastBg = 0; @@ -91,9 +98,8 @@ public static boolean checkBlukonPacket(byte[] buffer) { return isBlukonPacket(buffer) && getPin() != null; // TODO can't be unset yet and isn't proper subtype test yet } - // .*(dexdrip|gatt|Blukon). - public static byte[] decodeBlukonPacket(byte[] buffer) { + public static byte[] decodeBlukonPacket(byte[] buffer) { int cmdFound = 0; Boolean gotLowBat = false; @@ -104,7 +110,7 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { //BluCon code by gregorybel final String strRecCmd = CipherUtils.bytesToHex(buffer).toLowerCase(); - UserError.Log.i(TAG, "BlueCon data: " + strRecCmd); + UserError.Log.i(TAG, "BlueCon data: " + strRecCmd + " " + HexDump.dumpHexString(buffer)); if (strRecCmd.equalsIgnoreCase("cb010000")) { UserError.Log.i(TAG, "Reset currentCommand"); @@ -132,9 +138,16 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { currentCommand = "010d0e0127"; UserError.Log.i(TAG, "getSensorAge"); } else { - currentCommand = "010d0e0103"; - m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) - UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + if(Home.getPreferencesBooleanDefaultFalse("external_blukon_algorithm")) { + // Send the command to getHistoricData (read all blcoks from 0 to 0x2b) + UserError.Log.i(TAG, "getHistoricData (1)"); + currentCommand = "010d0f02002b"; + m_blockNumber = 0; + } else { + currentCommand = "010d0e0103"; + m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) + UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + } } } @@ -206,6 +219,7 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { currentCommand = ""; } /* + //Uncoment this code to allow reading dead sensors. currentCommand = "810a00"; UserError.Log.i(TAG, "Send ACK"); */ @@ -240,9 +254,16 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { currentCommand = "010d0e0127"; UserError.Log.i(TAG, "getSensorAge"); } else { - currentCommand = "010d0e0103"; - m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) - UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + if(Home.getPreferencesBooleanDefaultFalse("external_blukon_algorithm")) { + // Send the command to getHistoricData (read all blcoks from 0 to 0x2b) + UserError.Log.i(TAG, "getHistoricData (2)"); + currentCommand = "010d0f02002b"; + m_blockNumber = 0; + } else { + currentCommand = "010d0e0103"; + m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) + UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + } } } else if (currentCommand.startsWith("010d0e0127") /*getSensorAge*/ && strRecCmd.startsWith("8bde")) { @@ -254,9 +275,16 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { if ((sensorAge > 0) && (sensorAge < 200000)) { Home.setPreferencesInt("nfc_sensor_age", sensorAge);//in min } - currentCommand = "010d0e0103"; - m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) - UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + if(Home.getPreferencesBooleanDefaultFalse("external_blukon_algorithm")) { + // Send the command to getHistoricData (read all blcoks from 0 to 0x2b) + UserError.Log.i(TAG, "getHistoricData (3)"); + currentCommand = "010d0f02002b"; + m_blockNumber = 0; + } else { + currentCommand = "010d0e0103"; + m_getNowGlucoseDataIndexCommand = true;//to avoid issue when gotNowDataIndex cmd could be same as getNowGlucoseData (case block=3) + UserError.Log.i(TAG, "getNowGlucoseDataIndexCommand"); + } } else if (currentCommand.startsWith("010d0e0103") /*getNowDataIndex*/ && m_getNowGlucoseDataIndexCommand == true && strRecCmd.startsWith("8bde")) { cmdFound = 1; @@ -315,8 +343,8 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { m_timeLastBg = JoH.tsl(); - PersistentStore.setLong("blukon-time-of-last-reading", m_timeLastBg); - UserError.Log.i(TAG, "time of current reading: " + JoH.dateTimeText(m_timeLastBg)); + PersistentStore.setLong("blukon-time-of-last-reading", m_timeLastBg); + UserError.Log.i(TAG, "time of current reading: " + JoH.dateTimeText(m_timeLastBg)); currentCommand = "010c0e00"; UserError.Log.i(TAG, "Send sleep cmd"); @@ -339,9 +367,12 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { int delayedBlockNumber = blockNumberForNowGlucoseDataDelayed(delayedTrendIndex); currentCommand = "010d0e010" + Integer.toHexString(delayedBlockNumber);//getNowGlucoseData UserError.Log.i(TAG, "bf: read next block: " + currentCommand); - } + } + } else if ((currentCommand.startsWith("010d0f02002b") /*getHistoricData */ || (currentCommand.isEmpty() && m_blockNumber > 0)) && strRecCmd.startsWith("8bdf")) { + cmdFound = 1; + handlegetHistoricDataResponse(buffer); } else if (strRecCmd.startsWith("cb020000")) { cmdFound = 1; UserError.Log.e(TAG, "is bridge battery low????!"); @@ -373,7 +404,44 @@ public static byte[] decodeBlukonPacket(byte[] buffer) { } + private static void handlegetHistoricDataResponse(byte[] buffer) + { + UserError.Log.e(TAG, "recieved historic data, m_block_number = " + m_blockNumber); + // We are looking for 43 blocks of 8 bytes. + // The bluekon will send them as 21 blocks of 16 bytes, and the last one of 8 bytes. + // The packet will look like "0x8b 0xdf 0xblocknumber 0x02 DATA" (so data starts at place 4) + if(m_blockNumber > 42) { + UserError.Log.e(TAG, "recieved historic data, but block number is too big " + m_blockNumber); + return; + } + + int len = buffer.length - 4; + UserError.Log.e(TAG,"len = " + len +" " + len + " blocknum " + buffer[2]); + + if(buffer[2] != m_blockNumber) { + UserError.Log.e(TAG, "We have recieved a bad block number buffer[2] = " + buffer[2] + " m_blockNumber = " + m_blockNumber); + return; + } + if(8 * m_blockNumber + len > m_full_data.length) { + UserError.Log.e(TAG, "We have recieved too much data m_blockNumber = " + m_blockNumber + " len = " + len + + " m_full_data.length = " + m_full_data.length); + return; + } + + System.arraycopy(buffer, 4, m_full_data, 8 * m_blockNumber, len); + m_blockNumber += len / 8; + + if(m_blockNumber >= 43) { + currentCommand = "010c0e00"; + UserError.Log.i(TAG, "Send sleep cmd"); + + UserError.Log.e(TAG, "Full data that was recieved is " + HexDump.dumpHexString(m_full_data)); + FileUtils.writeToFileWithCurrentDate(TAG, "xDripData", m_full_data); + } else { + currentCommand = ""; + } + } private static boolean isSensorReady(byte sensorStatusByte) { diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java new file mode 100644 index 0000000000..54369b91f0 --- /dev/null +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/UtilityModels/NotificationChannels.java @@ -0,0 +1,12 @@ + +// stub class just to satisfy unified source trees while wear is not on sdk 26+ + +package com.eveningoutpost.dexdrip.UtilityModels; + +public class NotificationChannels { + + public final static String LOW_TRANSMITTER_BATTERY_CHANNEL = "stub"; +} + + + diff --git a/wear/src/main/java/com/eveningoutpost/dexdrip/utils/FileUtils.java b/wear/src/main/java/com/eveningoutpost/dexdrip/utils/FileUtils.java new file mode 100644 index 0000000000..e534070ee0 --- /dev/null +++ b/wear/src/main/java/com/eveningoutpost/dexdrip/utils/FileUtils.java @@ -0,0 +1,63 @@ +package com.eveningoutpost.dexdrip.utils; + +import android.content.Context; +import android.os.Environment; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.eveningoutpost.dexdrip.xdrip; +import com.eveningoutpost.dexdrip.Models.UserError; + +public class FileUtils { + + public static boolean makeSureDirectoryExists( final String dir ) { + final File file = new File( dir ); + return file.exists() || file.mkdirs(); + } + + public static String getExternalDir() { + final StringBuilder sb = new StringBuilder(); + sb.append( Environment.getExternalStorageDirectory().getAbsolutePath() ); + sb.append( "/xdrip" ); + + final String dir = sb.toString(); + return dir; + } + + public static String combine( final String path1, final String path2 ) { + final File file1 = new File( path1 ); + final File file2 = new File( file1, path2 ); + return file2.getPath(); + } + + public static void writeToFileWithCurrentDate(String TAG, String file, byte []data) { + Context context = xdrip.getAppContext(); + + String dir = context.getFilesDir().getPath(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); + String currentDateandTime = sdf.format(new Date()); + + String fileName = dir + '/' + file+ "_" + currentDateandTime + ".dat"; + writeToFile(TAG, fileName, data); + } + + public static void writeToFile(String TAG, String fileName, byte []data) { + + + UserError.Log.i(TAG, "Writing to file" + fileName); + try { + FileOutputStream f = new FileOutputStream(new File(fileName)); + if(data != null) { + // if no data exists, file will be written with zero length to let the user know what is happening. + f.write(data); + } + f.close(); + }catch (IOException e) { + UserError.Log.e(TAG, "Cought exception when trying to write file", e); + } + } +}