diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39b6783 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +.idea/caches + +# Keystore files +# Uncomment the following line if you do not want to check your keystore files in. +#*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9b1ab37 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,41 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e97a449 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..8306744 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/MedtronicUploader.iml b/MedtronicUploader.iml deleted file mode 100644 index 757a667..0000000 --- a/MedtronicUploader.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Medtronic_NigthScout_Manual.pdf b/Medtronic_NightScout_Manual.pdf similarity index 100% rename from Medtronic_NigthScout_Manual.pdf rename to Medtronic_NightScout_Manual.pdf diff --git a/README.md b/README.md index 9edc2d1..6afcc9e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # MedtronicUploader -See "Medtronic_NigthScout_Manual.pdf" - -Special thanks to https://github.com/ksksue/PhysicaloidLibrary +See "Medtronic_NightScout_Manual.pdf" Medtronic Nightscout Uploader - Copyright (C) 2014 Medtronic Nightscout contributors + Copyright (C) 2014-2018 Medtronic Nightscout contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,4 +18,4 @@ Medtronic Nightscout Uploader You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see . - \ No newline at end of file + diff --git a/app/build.gradle b/app/build.gradle index 8662eee..1cd7ffc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,12 +30,16 @@ def gitVersionName = { -> android { compileSdkVersion 23 - buildToolsVersion '26.0.2' + buildToolsVersion '28.0.3' + + lintOptions { + abortOnError false + } defaultConfig { applicationId "com.nightscout.android" minSdkVersion 21 - targetSdkVersion 23 + targetSdkVersion 26 versionCode gitVersionCode() versionName gitVersionName() useLibrary 'org.apache.http.legacy' @@ -51,9 +55,6 @@ android { } dependencies { - compile files('libs/bugfender.jar') - compile files('libs/logback-android-1.1.1-3.jar') - compile files('libs/physicaloidlibrary.jar') - compile files('libs/slf4j-api-1.7.2.jar') - + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.github.felHR85:UsbSerial:4.5.2' } diff --git a/app/libs/logback-android-1.1.1-3.jar b/app/libs/logback-android-1.1.1-3.jar deleted file mode 100644 index f63ba7f..0000000 Binary files a/app/libs/logback-android-1.1.1-3.jar and /dev/null differ diff --git a/app/libs/physicaloidlibrary.jar b/app/libs/physicaloidlibrary.jar deleted file mode 100644 index 9ec2cc4..0000000 Binary files a/app/libs/physicaloidlibrary.jar and /dev/null differ diff --git a/app/libs/slf4j-api-1.7.2.jar b/app/libs/slf4j-api-1.7.2.jar deleted file mode 100644 index 1a88708..0000000 Binary files a/app/libs/slf4j-api-1.7.2.jar and /dev/null differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f25fa7b..7663da7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,18 +1,19 @@ + package="com.nightscout.android"> - - - - - - - + + + + + + + - + + 8){ - display.setText("", BufferType.EDITABLE); - msgsDisplayed = 0; - }*/ Log.i(TAG, msg.getData().getString("data")+"\n"); - if (ISDEBUG){ - display.append(msg.getData().getString("data")+"\n"); - msgsDisplayed++; - } + display.append(msg.getData().getString("data")+"\n"); mHandler.removeCallbacks(updateDataView); mHandler.post(updateDataView); break; - case MedtronicConstants.MSG_MEDTRONIC_CGM_CLEAR_DISPLAY: - if (ISDEBUG){ - display.setText("", BufferType.EDITABLE); - msgsDisplayed = 0; - } - break; + case MedtronicConstants.MSG_MEDTRONIC_CGM_NO_PERMISSION: + Log.e(TAG, "Message received - no USB permission"); usbAllowedPermission = false; mHandler.removeCallbacks(updateDataView); mHandler.post(updateDataView); break; - case MedtronicConstants.MSG_MEDTRONIC_GLUCMEASURE_DETECTED: - showUseCalibConfirmation(msg.getData().getFloat("data"), msg.getData().getBoolean("calibrating"), msg.getData().getBoolean("isCalFactorFromPump")); - break; case MedtronicConstants.MSG_MEDTRONIC_CGM_USB_GRANTED: + if (!usbAllowedPermission) + Log.i(TAG, "Message received - USB permission granted"); usbAllowedPermission = true; mHandler.removeCallbacks(updateDataView); mHandler.post(updateDataView); break; case MedtronicConstants.MSG_MEDTRONIC_CGM_ERROR_RECEIVED: - Log.i(TAG, msg.getData().getString("data")+"\n"); - if (ISDEBUG){ - if (msgsDisplayed > 8){ - display.setText("", BufferType.EDITABLE); - msgsDisplayed = 0; - } - String sText = display.getText().toString(); - String sError = msg.getData().getString("data"); - if (!(sText.indexOf(sError) >= 0)){ - display.setText(display.getText()+"Medtronic CGM Message: " + sError +"\n", BufferType.EDITABLE); - msgsDisplayed++; - } - } + Log.e(TAG, msg.getData().getString("data")+"\n"); + String sError = msg.getData().getString("data"); + display.setText(display.getText()+"Medtronic CGM Message: " + sError +"\n", BufferType.EDITABLE); break; case MedtronicConstants.MSG_MEDTRONIC_CALIBRATION_DONE: - Log.i(TAG, MedtronicConstants.MSG_MEDTRONIC_CALIBRATION_DONE+"\n"); + Log.i(TAG, "Calibration done message received"); + display.setText(display.getText() + "Calibration done\n"); mHandler.removeCallbacks(updateDataView); mHandler.post(updateDataView); break; case MedtronicConstants.MSG_MEDTRONIC_FAKE: - Log.i(TAG, MedtronicConstants.MSG_MEDTRONIC_FAKE+"\n"); + Log.i(TAG, "Fake message sent / " + MedtronicConstants.MSG_MEDTRONIC_FAKE+"\n"); mHandler.removeCallbacks(updateDataView); mHandler.post(updateDataView); break; @@ -167,68 +142,6 @@ public void handleMessage(Message msg) { } } } - private void showUseCalibConfirmation(final float num, final boolean calibrate, final boolean isCalFactorFromPump){ - AlertDialog.Builder alert = new AlertDialog.Builder(ctx); - alert.setTitle("Calibration Detected!!!"); - alert.setMessage("Do you want to use the received glucometer value for calibration?"); - - alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - if (mService != null){ - try { - Message msg = Message.obtain(null, MedtronicConstants.MSG_MEDTRONIC_GLUCMEASURE_APPROVED); - Bundle b = new Bundle(); - b.putBoolean("approved", true); - b.putFloat("data", num); - b.putBoolean("calibrating", calibrate); - b.putBoolean("isCalFactorFromPump", isCalFactorFromPump); - msg.setData(b); - msg.replyTo = mMessenger; - mService.send(msg); - } catch (RemoteException e) { - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION!!!!!! "+ e.getMessage()+" "+e.getCause()); - for (StackTraceElement st : e.getStackTrace()){ - sb1.append(st.toString()).append("\n"); - } - Log.e(TAG, "Error approving gluc. value \n "+sb1.toString()); - if (ISDEBUG){ - display.setText(display.getText()+"Error approving gluc. value\n", BufferType.EDITABLE); - } - } - } - } - }); - - alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - if (mService != null){ - try { - Message msg = Message.obtain(null, MedtronicConstants.MSG_MEDTRONIC_GLUCMEASURE_APPROVED); - Bundle b = new Bundle(); - - b.putBoolean("approved", false); - - msg.setData(b); - msg.replyTo = mMessenger; - mService.send(msg); - } catch (RemoteException e) { - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION!!!!!! "+ e.getMessage()+" "+e.getCause()); - for (StackTraceElement st : e.getStackTrace()){ - sb1.append(st.toString()).append("\n"); - } - Log.e(TAG, "Error approving gluc. value \n "+sb1.toString()); - if (ISDEBUG){ - display.setText(display.getText()+"Error approving gluc. value\n", BufferType.EDITABLE); - } - } - } - } - }); - - alert.show(); - } private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { @@ -239,16 +152,9 @@ public void onServiceConnected(ComponentName className, IBinder service) { msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException e) { - - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION!!!!!! "+ e.getMessage()+" "+e.getCause()); - for (StackTraceElement st : e.getStackTrace()){ - sb1.append(st.toString()).append("\n"); - } - Log.e(TAG,"Error Registering Client Service Connection\n"+sb1.toString()); - if (ISDEBUG){ - display.setText(display.getText()+"Error Registering Client Service Connection\n", BufferType.EDITABLE); - } + Log.e(TAG,"Error Registering Client Service Connection\n", e); + display.setText(display.getText()+"Error Registering Client Service Connection\n", BufferType.EDITABLE); + // In this case the service has crashed before we could even do anything with it } } @@ -258,14 +164,36 @@ public void onServiceDisconnected(ComponentName className) { mService = null; bService = null; Log.i(TAG,"Service Disconnected\n"); - if (ISDEBUG){ - display.setText(display.getText()+"Service Disconnected\n", BufferType.EDITABLE); - } + + display.setText(display.getText()+"Service Disconnected\n", BufferType.EDITABLE); + } }; + private void updateSensorDisplay() { + Record auxRecord = getLastRecord(); + + long calDate = -1; + if (settings.contains("lastCalibrationDate")) { + calDate = settings.getLong("lastCalibrationDate", -1); + } + + if (auxRecord instanceof MedtronicSensorRecord) { + + MedtronicSensorRecord record = (MedtronicSensorRecord) auxRecord; + displaySensor(record, calDate); + + } else { + if (auxRecord == null || auxRecord.getDate() == null) + mDumpTextView.setText("\n---\n---\n---\n"); + else + mDumpTextView.setText("\n" + auxRecord.getDate() + + "\n---\n---\n"); + } + } + //All I'm really doing here is creating a simple activity to launch and maintain the service private Runnable updateDataView = new Runnable() { public void run() { @@ -273,7 +201,8 @@ public void run() { if (!mHandlerActive) return; if (!isMyServiceRunning()) { - if (retryCount < maxRetries) { + int maxRetries = 20; + if (retryCount < maxRetries) { stopCGMServices(); startCGMServices(); mTitleTextView.setTextColor(Color.YELLOW); @@ -290,55 +219,13 @@ public void run() { if (usbAllowedPermission){ mTitleTextView.setTextColor(Color.GREEN); mTitleTextView.setText("CGM Service Started"); - b1.setText("Stop Uploading CGM Data"); - Record auxRecord = DexcomG4Activity.this.loadClassFile(new File(getBaseContext().getFilesDir(), "save.bin")); - long calDate = -1; - try{ - if (settings.contains("lastCalibrationDate")){ - calDate = settings.getLong("lastCalibrationDate", -1); - } - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - - - - DecimalFormat df = null; - df = new DecimalFormat("#.##"); - - if (auxRecord instanceof MedtronicSensorRecord){ - - MedtronicSensorRecord record = (MedtronicSensorRecord) auxRecord; - displaySensor(record, calDate,df); - - }else if (auxRecord instanceof EGVRecord){ - EGVRecord record = (EGVRecord)auxRecord; - if (prefs.getBoolean("mmolxl", false)){ - Float fBgValue = null; - try{ - fBgValue = (float)Integer.parseInt(record.bGValue); - log.info("mmolxl true --> "+record.bGValue); - record.bGValue = df.format(fBgValue/18f); - log.info("mmolxl/18 true --> "+record.bGValue); - }catch (Exception e){ - - } - }else - log.info("mmolxl false --> "+record.bGValue); - mDumpTextView.setTextColor(Color.WHITE); - mDumpTextView.setText("\n" + record.displayTime + "\n" + record.bGValue + " " + record.trendArrow + "\n"); - }else{ - mDumpTextView.setTextColor(Color.WHITE); - if (auxRecord == null || auxRecord.displayTime == null) - mDumpTextView.setText("\n---\n---\n---\n"); - else - mDumpTextView.setText("\n" + auxRecord.displayTime + "\n---\n---\n"); - } - }catch (Exception e){ - e.printStackTrace(); - } + startStopButton.setText("Stop Uploading CGM Data"); + updateSensorDisplay(); + }else{ - b1.setText("Start Uploading CGM Data"); + + startStopButton.setText("Start Uploading CGM Data"); mTitleTextView.setTextColor(Color.RED); mTitleTextView.setText("CGM Service Stopped"); } @@ -353,20 +240,19 @@ public void run() { }; - private void displaySensor(MedtronicSensorRecord record, long calDate, DecimalFormat df) { + private void displaySensor(MedtronicSensorRecord record, long calDate) { DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); - if (prefs.getBoolean("mmolxl", false)) { - Float fBgValue = null; - try { - fBgValue = (float) Integer.parseInt(record.bGValue); - log.info("mmolxl true --> " + record.bGValue); - record.bGValue = df.format(fBgValue / 18f); - log.info("mmolxl/18 true --> " + record.bGValue); - } catch (Exception e) { + float value = record.getBGValue(); + Date recordTime = record.getDate(); + String displayDate = ""; + String displayDiff = ""; + if (recordTime != null) { + displayDate = dateFormat.format(recordTime); + displayDiff = "" + ((System.currentTimeMillis() - record.getDate().getTime()) / 60000) + " mins ago\n"; + } + if (prefs.getBoolean("mmolxl", false)) + value = value / 18f; - } - } else - log.info("mmolxl false --> " + record.bGValue); boolean isCalibrating = record.isCalibrating; String calib = "---"; if (isCalibrating) { @@ -386,24 +272,14 @@ private void displaySensor(MedtronicSensorRecord record, long calDate, DecimalFo } calib += "" + lastCal + tail; calib += "\nat: " + dateFormat.format(new Date(calDate)) + "\n"; - if (prefs.getBoolean("isWarmingUp", false)) { - calib = ""; - record.bGValue = "W_Up"; - record.trendArrow = "---"; - } - mDumpTextView.setTextColor(Color.WHITE); - mSensorValue.setTextColor(Color.WHITE); - if (record.displayDateTime == 0) { - mDumpTextView.setText("\n" + record.displayTime + "\n" + calib + "\n"); - mSensorValue.setText(record.bGValue + " " + record.trendArrow + "\n"); - } else { - mDumpTextView.setText("Last record received:\n" + (System.currentTimeMillis() - record.displayDateTime) / 60000 + " min. ago\nat: " + dateFormat.format(new Date(record.displayDateTime)) + "\n"+ - calib + "\n"); - mSensorValue.setText(record.bGValue + " " + record.trendArrow + "\n"); + + mDumpTextView.setText("Last record received: " + displayDiff + "\nat: " + displayDate + "\n"+ + calib); + mSensorValue.setText(value + " " + record.trendArrow); + - } } private class BatteryReceiver extends BroadcastReceiver { @@ -431,8 +307,17 @@ public void onCreate(Bundle savedInstanceState) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); - this.settings = getBaseContext().getSharedPreferences( - MedtronicConstants.PREFS_NAME, 0); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Intent intent = new Intent(); + String packageName = getPackageName(); + PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); + if (!pm.isIgnoringBatteryOptimizations(packageName)) { + intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(Uri.parse("package:" + packageName)); + startActivity(intent); + } + } + this.settings = getBaseContext().getSharedPreferences(MedtronicConstants.PREFS_NAME, 0); PreferenceManager.getDefaultSharedPreferences(getBaseContext()).registerOnSharedPreferenceChangeListener(this); prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String type; @@ -455,14 +340,11 @@ else if ("2".equalsIgnoreCase(type)){ registerReceiver(mArrow,mIntentFilter); setContentView(R.layout.adb); manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - mTitleTextView = (TextView) findViewById(R.id.demoTitle); - mDumpTextView = (TextView) findViewById(R.id.demoText); + mTitleTextView = (TextView) findViewById(R.id.status); + mDumpTextView = (TextView) findViewById(R.id.sensorDetail); mSensorValue = (TextView) findViewById(R.id.sensorValue); - LinearLayout lnr = (LinearLayout) findViewById(R.id.container); - LinearLayout lnr2 = new LinearLayout(this); - LinearLayout lnr3 = new LinearLayout(this); - lnr3.setOrientation(LinearLayout.HORIZONTAL); - b1 = new Button(this); + + startStopButton = (Button) findViewById(R.id.buttonStartStop); if (!prefs.getBoolean("IUNDERSTAND", false)){ stopCGMServices(); @@ -478,26 +360,18 @@ else if ("2".equalsIgnoreCase(type)){ mTitleTextView.setTextColor(Color.YELLOW); mTitleTextView.setText("CGM Service Pending"); - b1.setText("Stop Uploading CGM Data"); - lnr.addView(b1); - lnr2.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - lnr3.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - Button b2 = new Button(this); - b2.setText("Clear Log"); - b2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,1.0f)); + startStopButton.setText("Stop Uploading CGM Data"); - Button b3 = new Button(this); - b3.setText("Send test data"); + Button clearButton = (Button) findViewById(R.id.buttonClear); - if (BuildConfig.DEBUG) { - lnr.addView(b3); + Button testButton = (Button) findViewById(R.id.buttonTest); + + if (!BuildConfig.DEBUG) { + testButton.setVisibility(View.GONE); } - // b4 = new Button(this); - // b4.setText("Calibrate"); - // b4.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,1.0f)); - //lnr3.addView(b4); - if (menu != null){ + + if (menu != null){ if (calibrationSelected == MedtronicConstants.CALIBRATION_MANUAL){ menu.getItem(1).setVisible(true); menu.getItem(2).setVisible(false); @@ -506,34 +380,24 @@ else if ("2".equalsIgnoreCase(type)){ menu.getItem(2).setVisible(true); } } - if (ISDEBUG){ - lnr3.addView(b2); - } - lnr.addView(lnr3); - lnr.addView(lnr2); - display = new TextView(this); - if (ISDEBUG){ - display.setText("", BufferType.EDITABLE); - display.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - display.setKeyListener(null); - display.setBackgroundColor(Color.BLACK); - display.setTextColor(Color.WHITE); - display.setMovementMethod(new ScrollingMovementMethod()); - display.setMaxLines(10); - - lnr2.addView(display); - } - b2.setOnClickListener(new OnClickListener() { + + + display = (TextView) findViewById(R.id.logView); + display.setText("", BufferType.EDITABLE); + display.setKeyListener(null); + display.setMovementMethod(new ScrollingMovementMethod()); + display.setMaxLines(10); + + clearButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { display.setText("", BufferType.EDITABLE); display.setKeyListener(null); - msgsDisplayed = 0; - } + } }); - b3.setOnClickListener(new OnClickListener() { + testButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { @@ -543,22 +407,21 @@ public void onClick(View v) { mService.send(msg); } catch (RemoteException re) { - - + Log.e(TAG, "Remote exception sending fake message"); } } }); - b1.setOnClickListener(new OnClickListener() { + startStopButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { synchronized (mHandlerActiveLock) { - if (b1.getText() == "Stop Uploading CGM Data") { + if (startStopButton.getText() == "Stop Uploading CGM Data") { mHandlerActive = false; mHandler.removeCallbacks(updateDataView); keepServiceAlive = false; stopCGMServices(); - b1.setText("Start Uploading CGM Data"); + startStopButton.setText("Start Uploading CGM Data"); mTitleTextView.setTextColor(Color.RED); mTitleTextView.setText("CGM Service Stopped"); finish(); @@ -580,7 +443,7 @@ public void onClick(View v) { } } mHandlerActive = true; - b1.setText("Stop Uploading CGM Data"); + startStopButton.setText("Stop Uploading CGM Data"); } } @@ -593,62 +456,22 @@ public void onClick(View v) { @Override protected void onPause() { - log.info("ON PAUSE!"); + Log.i(TAG,"ON PAUSE!"); super.onPause(); } + private Record getLastRecord() + { + return DexcomG4Activity.this.loadClassFile(new File(getBaseContext().getFilesDir(), "save.bin")); + } + @Override protected void onResume() { - log.info("ON RESUME!"); + Log.i(TAG, "ON RESUME!"); super.onResume(); // Refresh the status - try { - Record auxRecord = DexcomG4Activity.this.loadClassFile(new File( - getBaseContext().getFilesDir(), "save.bin")); - long calDate = -1; - if (settings.contains("lastCalibrationDate")) { - calDate = settings.getLong("lastCalibrationDate", -1); - } - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - - DecimalFormat df = new DecimalFormat("#.##"); - - if (auxRecord instanceof MedtronicSensorRecord) { - - MedtronicSensorRecord record = (MedtronicSensorRecord) auxRecord; - displaySensor(record, calDate,df); - - } else if (auxRecord instanceof EGVRecord) { - EGVRecord record = (EGVRecord) auxRecord; - if (prefs.getBoolean("mmolxl", false)){ - Float fBgValue = null; - try{ - fBgValue = (float)Integer.parseInt(record.bGValue); - log.info("mmolxl true --> "+record.bGValue); - record.bGValue = df.format(fBgValue/18f); - log.info("mmolxl/18 true --> "+record.bGValue); - }catch (Exception e){ - - } - }else - log.info("mmolxl false --> "+record.bGValue); - mDumpTextView.setTextColor(Color.WHITE); - mDumpTextView.setText("\n" + record.displayTime + "\n" - + record.bGValue + " " + record.trendArrow + "\n"); - } else { - mDumpTextView.setTextColor(Color.WHITE); - if (auxRecord == null || auxRecord.displayTime == null) - mDumpTextView.setText("\n---\n---\n---\n"); - else - mDumpTextView.setText("\n" + auxRecord.displayTime - + "\n---\n---\n"); - } - } catch (Exception e) { - e.printStackTrace(); - } - + updateSensorDisplay(); } //Check to see if service is running @@ -663,20 +486,13 @@ private boolean isMyServiceRunning() { //Deserialize the EGVRecord (most recent) value public Record loadClassFile(File f) { - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(new FileInputStream(f)); + try { + ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f)); Object o = ois.readObject(); ois.close(); return (Record) o; } catch (Exception ex) { Log.w(TAG, " unable to loadEGVRecord"); - try{ - if (ois != null) - ois.close(); - }catch(Exception e){ - Log.e(TAG, " Error closing ObjectInputStream"); - } } return new Record(); } @@ -687,8 +503,6 @@ public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; inflater.inflate(R.menu.menu, menu); - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); if (prefs.contains("calibrationType")) { String type = prefs.getString("calibrationType", "3"); if ("3".equalsIgnoreCase(type)) @@ -720,54 +534,50 @@ public boolean onOptionsItemSelected(MenuItem item) { break; case R.id.calibMan:{ - - log.debug("Manual Calibration"); + + Log.d(TAG, "Manual Calibration"); AlertDialog.Builder alert = new AlertDialog.Builder(ctx); alert.setTitle("Manual Calibration"); alert.setMessage("Insert your glucose value in mg/dl (only natural numbers)"); - - if (prefs.getBoolean("mmolxl", false)){ + + boolean mmolxl = prefs.getBoolean("mmolxl", false); + + if (mmolxl){ alert.setMessage("Insert your glucose value in mmol/l (only 2 decimals)"); - log.debug("mmol/l"); + Log.d(TAG,"mmol/l"); } - // Set an EditText view to get user input input = new EditText(ctx); input.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL); alert.setView(input); - - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - String value = input.getText().toString(); - log.debug("Manual Calibration send "+value); - if (mService == null && bService != null) { - mService = new Messenger(bService); - } - if (mService != null){ - try { - Message msg = Message.obtain(null, MedtronicConstants.MSG_MEDTRONIC_SEND_MANUAL_CALIB_VALUE); - Bundle b = new Bundle(); - b.putString("sgv", value); - prefs.edit().putString("manual_sgv", value).commit(); - msg.setData(b); - msg.replyTo = mMessenger; - mService.send(msg); - } catch (RemoteException e) { - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION!!!!!! "+ e.getMessage()+" "+e.getCause()); - for (StackTraceElement st : e.getStackTrace()){ - sb1.append(st.toString()).append("\n"); - } - Log.e(TAG, "Error sending Manual Calibration\n "+sb1.toString()); - if (ISDEBUG){ - display.setText(display.getText()+"Error sending Manual Calibration\n", BufferType.EDITABLE); - } - // In this case the service has crashed before we could even do anything with it - } - } - } - }); + + alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String value = input.getText().toString(); + boolean mmolxl = prefs.getBoolean("mmolxl", false); + float v = Float.parseFloat(value); + Log.d(TAG, "Manual Calibration send "+value); + if (mService == null && bService != null) { + mService = new Messenger(bService); + } + try { + Message msg = Message.obtain(null, MedtronicConstants.MSG_MEDTRONIC_SEND_MANUAL_CALIB_VALUE); + Bundle b = new Bundle(); + b.putInt("sgv", (int) (mmolxl ? v * 18 : v)); + prefs.edit().putString("manual_sgv", value).apply(); + msg.setData(b); + msg.replyTo = mMessenger; + mService.send(msg); + } catch (RemoteException e) { + Log.e(TAG, "Error sending Manual Calibration\n ", e); + display.setText(display.getText()+"Error sending Manual Calibration\n", BufferType.EDITABLE); + + // In this case the service has crashed before we could even do anything with it + } + + } + }); alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { @@ -779,16 +589,15 @@ public void onClick(DialogInterface dialog, int whichButton) { } break; case R.id.instantCalib:{ - log.debug("Instant Calibration "); + Log.d(TAG, "Instant Calibration "); AlertDialog.Builder alert2 = new AlertDialog.Builder(ctx); alert2.setTitle("Instant Calibration"); alert2.setMessage("Insert pump value in mg/dl (only natural numbers)"); - prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); + if (prefs.getBoolean("mmolxl", false)){ alert2.setMessage("Insert pump value in mmol/l (only 2 decimals)"); - log.debug("Instant Calibration mmol/l"); + Log.d(TAG, "Instant Calibration mmol/l"); } // Set an EditText view to get user input input = new EditText(ctx); @@ -808,27 +617,21 @@ public void onClick(DialogInterface dialog, int whichButton) { alert2.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { String value = input.getText().toString(); - log.debug("Instant Calibration send "+value); + boolean mmolxl = prefs.getBoolean("mmolxl", false); + float v = Float.parseFloat(value); + Log.d(TAG, "Instant Calibration send "+value); if (mService != null){ try { Message msg = Message.obtain(null, MedtronicConstants.MSG_MEDTRONIC_SEND_INSTANT_CALIB_VALUE); Bundle b = new Bundle(); - b.putString("sgv", value); - prefs.edit().putString("instant_sgv", value).commit(); + b.putInt("sgv", (int) (mmolxl ? v * 18 : v)); + prefs.edit().putString("instant_sgv", value).apply(); msg.setData(b); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException e) { - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION!!!!!! "+ e.getMessage()+" "+e.getCause()); - for (StackTraceElement st : e.getStackTrace()){ - sb1.append(st.toString()).append("\n"); - } - Log.e(TAG, "Error sending Instant Calibration\n "+sb1.toString()); - if (ISDEBUG){ - display.setText(display.getText()+"Error sending Instant Calibration\n", BufferType.EDITABLE); - } - + Log.e(TAG, "Error sending Instant Calibration\n ", e); + display.setText(display.getText()+"Error sending Instant Calibration\n", BufferType.EDITABLE); } } } @@ -874,7 +677,7 @@ private boolean isServiceAlive(String name){ @Override protected void onDestroy() { Log.i(TAG, "onDestroy called"); - log.info("onDestroy called"); + PreferenceManager.getDefaultSharedPreferences(getBaseContext()).unregisterOnSharedPreferenceChangeListener(this); unregisterReceiver(mArrow); synchronized (mHandlerActiveLock) { @@ -886,10 +689,7 @@ protected void onDestroy() { startService(service); } mHandlerActive = false; - SharedPreferences.Editor editor = getBaseContext().getSharedPreferences(MedtronicConstants.PREFS_NAME, 0).edit(); - editor.putLong("lastDestroy", System.currentTimeMillis()); - editor.commit(); - super.onDestroy(); + super.onDestroy(); } } @@ -957,7 +757,7 @@ else if ("2".equalsIgnoreCase(type)) { mHandler.removeCallbacks(updateDataView); mHandlerActive = false; } - b1.setText("Start Uploading CGM Data"); + startStopButton.setText("Start Uploading CGM Data"); mTitleTextView.setTextColor(Color.RED); mTitleTextView.setText("CGM Service Stopped"); stopCGMServices(); @@ -974,7 +774,7 @@ else if ("2".equalsIgnoreCase(type)) { mHandler.removeCallbacks(updateDataView); mHandlerActive = false; } - b1.setText("Start Uploading CGM Data"); + startStopButton.setText("Start Uploading CGM Data"); mTitleTextView.setTextColor(Color.RED); mTitleTextView.setText("CGM Service Stopped"); stopCGMServices(); diff --git a/app/src/main/java/com/nightscout/android/dexcom/EGVRecord.java b/app/src/main/java/com/nightscout/android/dexcom/EGVRecord.java index 9b0f08d..a6d4ecf 100644 --- a/app/src/main/java/com/nightscout/android/dexcom/EGVRecord.java +++ b/app/src/main/java/com/nightscout/android/dexcom/EGVRecord.java @@ -5,7 +5,7 @@ import com.nightscout.android.upload.Record; public class EGVRecord extends Record implements Serializable { - public String bGValue = "---"; + private float bGValue = 0; public String trend ="---"; public String trendArrow = "---"; @@ -13,10 +13,15 @@ public class EGVRecord extends Record implements Serializable { private static final long serialVersionUID = 4654897646L; - public void setBGValue (String input) { + public void setBGValue (float input) { this.bGValue = input; } - + + + public float getBGValue () { + return bGValue; + } + public void setTrend (String input) { this.trend = input; } diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/CdcAcmSerialDriver.java b/app/src/main/java/com/nightscout/android/dexcom/USB/CdcAcmSerialDriver.java deleted file mode 100644 index 2edfa3c..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/CdcAcmSerialDriver.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.nightscout.android.dexcom.USB; - -import android.hardware.usb.*; -import android.util.Log; - -import java.io.IOException; - -//import com.hoho.android.usbserial.driver.UsbId; - -/** - * USB CDC/ACM serial driver implementation. - * - * @author mike wakerly (opensource@hoho.com) - * @see Universal - * Serial Bus Class Definitions for Communication Devices, v1.1 - */ -public class CdcAcmSerialDriver extends CommonUsbSerialDriver { - - private final String TAG = CdcAcmSerialDriver.class.getSimpleName(); - - private UsbInterface mControlInterface; - private UsbInterface mDataInterface; - - private UsbEndpoint mControlEndpoint; - private UsbEndpoint mReadEndpoint; - private UsbEndpoint mWriteEndpoint; - - private boolean mRts = false; - private boolean mDtr = false; - - private boolean isConnectionOpen = false; - - private static final int USB_RECIP_INTERFACE = 0x01; - private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE; - - private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2 - private static final int GET_LINE_CODING = 0x21; - private static final int SET_CONTROL_LINE_STATE = 0x22; - private static final int SEND_BREAK = 0x23; - private static final String SET_POWER_ON_COMMAND = "echo 'on' > \"/sys/bus/usb/devices/1-1/power/level\""; - - public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) { - super(device, connection); - } - - @Override - public void open() throws IOException { - Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount()); - - Log.d(TAG, "Claiming control interface."); - mControlInterface = mDevice.getInterface(0); - Log.d(TAG, "Control iface=" + mControlInterface); - // class should be USB_CLASS_COMM - - if (!mConnection.claimInterface(mControlInterface, true)) { - isConnectionOpen = false; - throw new IOException("Could not claim control interface."); - } - mControlEndpoint = mControlInterface.getEndpoint(0); - Log.d(TAG, "Control endpoint direction: " + mControlEndpoint.getDirection()); - - Log.d(TAG, "Claiming data interface."); - mDataInterface = mDevice.getInterface(1); - Log.d(TAG, "data iface=" + mDataInterface); - // class should be USB_CLASS_CDC_DATA - - if (!mConnection.claimInterface(mDataInterface, true)) { - isConnectionOpen = false; - throw new IOException("Could not claim data interface."); - } - mReadEndpoint = mDataInterface.getEndpoint(1); - Log.d(TAG, "Read endpoint direction: " + mReadEndpoint.getDirection()); - mWriteEndpoint = mDataInterface.getEndpoint(0); - Log.d(TAG, "Write endpoint direction: " + mWriteEndpoint.getDirection()); - isConnectionOpen = true; - } - - private int sendAcmControlMessage(int request, int value, byte[] buf) { - return mConnection.controlTransfer( - USB_RT_ACM, request, value, 0, buf, buf != null ? buf.length : 0, 5000); - } - - @Override - public void close() throws IOException { - mConnection.close(); - isConnectionOpen = false; - } - - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - final int numBytesRead; - synchronized (mReadBufferLock) { - int readAmt = Math.min(dest.length, mReadBuffer.length); - numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt, - timeoutMillis); - if (numBytesRead < 0) { - // This sucks: we get -1 on timeout, not 0 as preferred. - // We *should* use UsbRequest, except it has a bug/api oversight - // where there is no way to determine the number of bytes read - // in response :\ -- http://b.android.com/28023 - return 0; - } - System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead); - } - return numBytesRead; - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - // TODO(mikey): Nearly identical to FtdiSerial write. Refactor. - int offset = 0; - - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, - timeoutMillis); - } - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; - } - return offset; - } - - @Override - public void setParameters(int baudRate, int dataBits, int stopBits, int parity) { - byte stopBitsByte; - switch (stopBits) { - case STOPBITS_1: stopBitsByte = 0; break; - case STOPBITS_1_5: stopBitsByte = 1; break; - case STOPBITS_2: stopBitsByte = 2; break; - default: throw new IllegalArgumentException("Bad value for stopBits: " + stopBits); - } - - byte parityBitesByte; - switch (parity) { - case PARITY_NONE: parityBitesByte = 0; break; - case PARITY_ODD: parityBitesByte = 1; break; - case PARITY_EVEN: parityBitesByte = 2; break; - case PARITY_MARK: parityBitesByte = 3; break; - case PARITY_SPACE: parityBitesByte = 4; break; - default: throw new IllegalArgumentException("Bad value for parity: " + parity); - } - - byte[] msg = { - (byte) ( baudRate & 0xff), - (byte) ((baudRate >> 8 ) & 0xff), - (byte) ((baudRate >> 16) & 0xff), - (byte) ((baudRate >> 24) & 0xff), - stopBitsByte, - parityBitesByte, - (byte) dataBits}; - sendAcmControlMessage(SET_LINE_CODING, 0, msg); - } - - @Override - public boolean getCD() throws IOException { - return false; // TODO - } - - @Override - public boolean getCTS() throws IOException { - return false; // TODO - } - - @Override - public boolean getDSR() throws IOException { - return false; // TODO - } - - @Override - public boolean getDTR() throws IOException { - return mDtr; - } - - @Override - public void setDTR(boolean value) throws IOException { - mDtr = value; - setDtrRts(); - } - - @Override - public boolean getRI() throws IOException { - return false; // TODO - } - - @Override - public boolean getRTS() throws IOException { - return mRts; - } - - @Override - public void setRTS(boolean value) throws IOException { - mRts = value; - setDtrRts(); - } - - private void setDtrRts() { - int value = (mRts ? 0x2 : 0) | (mDtr ? 0x1 : 0); - sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null); - } - - @Override - public boolean isConnectionOpen(){ - return isConnectionOpen; - } - - -/* public static Map getSupportedDevices() { - final Map supportedDevices = new LinkedHashMap(); - supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ARDUINO), - new int[] { - UsbId.ARDUINO_UNO, - UsbId.ARDUINO_UNO_R3, - UsbId.ARDUINO_MEGA_2560, - UsbId.ARDUINO_MEGA_2560_R3, - UsbId.ARDUINO_SERIAL_ADAPTER, - UsbId.ARDUINO_SERIAL_ADAPTER_R3, - UsbId.ARDUINO_MEGA_ADK, - UsbId.ARDUINO_MEGA_ADK_R3, - UsbId.ARDUINO_LEONARDO, - }); - supportedDevices.put(Integer.valueOf(UsbId.VENDOR_VAN_OOIJEN_TECH), - new int[] { - UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL, - }); - supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ATMEL), - new int[] { - UsbId.ATMEL_LUFA_CDC_DEMO_APP, - }); - supportedDevices.put(Integer.valueOf(UsbId.VENDOR_LEAFLABS), - new int[] { - UsbId.LEAFLABS_MAPLE, - }); - return supportedDevices; - }*/ - -} diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/CommonUsbSerialDriver.java b/app/src/main/java/com/nightscout/android/dexcom/USB/CommonUsbSerialDriver.java deleted file mode 100644 index 2bc8865..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/CommonUsbSerialDriver.java +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright 2013 Google Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Project home page: http://code.google.com/p/usb-serial-for-android/ - */ - -package com.nightscout.android.dexcom.USB; - -import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbDeviceConnection; - -import java.io.IOException; - - -/** - * A base class shared by several driver implementations. - * - * @author mike wakerly (opensource@hoho.com) - */ -abstract class CommonUsbSerialDriver implements UsbSerialDriver { - - public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024; - public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024; - - protected final UsbDevice mDevice; - protected final UsbDeviceConnection mConnection; - - protected final Object mReadBufferLock = new Object(); - protected final Object mWriteBufferLock = new Object(); - - /** Internal read buffer. Guarded by {@link #mReadBufferLock}. */ - protected byte[] mReadBuffer; - - /** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */ - protected byte[] mWriteBuffer; - - public CommonUsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) { - mDevice = device; - mConnection = connection; - - mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE]; - mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE]; - } - - /** - * Returns the currently-bound USB device. - * - * @return the device - */ - public final UsbDevice getDevice() { - return mDevice; - } - - /** - * Sets the size of the internal buffer used to exchange data with the USB - * stack for read operations. Most users should not need to change this. - * - * @param bufferSize the size in bytes - */ - public final void setReadBufferSize(int bufferSize) { - synchronized (mReadBufferLock) { - if (bufferSize == mReadBuffer.length) { - return; - } - mReadBuffer = new byte[bufferSize]; - } - } - - /** - * Sets the size of the internal buffer used to exchange data with the USB - * stack for write operations. Most users should not need to change this. - * - * @param bufferSize the size in bytes - */ - public final void setWriteBufferSize(int bufferSize) { - synchronized (mWriteBufferLock) { - if (bufferSize == mWriteBuffer.length) { - return; - } - mWriteBuffer = new byte[bufferSize]; - } - } - - @Override - public abstract void open() throws IOException; - - @Override - public abstract void close() throws IOException; - - @Override - public abstract int read(final byte[] dest, final int timeoutMillis) throws IOException; - - @Override - public abstract int write(final byte[] src, final int timeoutMillis) throws IOException; - - @Override - public abstract void setParameters( - int baudRate, int dataBits, int stopBits, int parity) throws IOException; - - @Override - public abstract boolean getCD() throws IOException; - - @Override - public abstract boolean getCTS() throws IOException; - - @Override - public abstract boolean getDSR() throws IOException; - - @Override - public abstract boolean getDTR() throws IOException; - - @Override - public abstract void setDTR(boolean value) throws IOException; - - @Override - public abstract boolean getRI() throws IOException; - - @Override - public abstract boolean getRTS() throws IOException; - - @Override - public abstract void setRTS(boolean value) throws IOException; - -} diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/SerialInputOutputManager.java b/app/src/main/java/com/nightscout/android/dexcom/USB/SerialInputOutputManager.java deleted file mode 100644 index c0a4bb6..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/SerialInputOutputManager.java +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright 2011 Google Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Project home page: http://code.google.com/p/usb-serial-for-android/ - */ - -package com.nightscout.android.dexcom.USB; - -import android.util.Log; - -import java.io.IOException; -import java.nio.ByteBuffer; - - -/** - * Utility class which services a {@link UsbSerialDriver} in its {@link #run()} - * method. - * - * @author mike wakerly (opensource@hoho.com) - */ -public class SerialInputOutputManager implements Runnable { - - private static final String TAG = SerialInputOutputManager.class.getSimpleName(); - private static final boolean DEBUG = true; - - private static final int READ_WAIT_MILLIS = 200; - private static final int BUFSIZ = 4096; - - private final UsbSerialDriver mDriver; - - private final ByteBuffer mReadBuffer = ByteBuffer.allocate(BUFSIZ); - - // Synchronized by 'mWriteBuffer' - private final ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ); - - private enum State { - STOPPED, - RUNNING, - STOPPING - } - - // Synchronized by 'this' - private State mState = State.STOPPED; - - // Synchronized by 'this' - private Listener mListener; - - public interface Listener { - /** - * Called when new incoming data is available. - */ - void onNewData(byte[] data); - - /** - * Called when {@link SerialInputOutputManager#run()} aborts due to an - * error. - */ - void onRunError(Exception e); - } - - /** - * Creates a new instance with no listener. - */ - public SerialInputOutputManager(UsbSerialDriver driver) { - this(driver, null); - } - - /** - * Creates a new instance with the provided listener. - */ - public SerialInputOutputManager(UsbSerialDriver driver, Listener listener) { - mDriver = driver; - mListener = listener; - } - - public synchronized void setListener(Listener listener) { - mListener = listener; - } - - public synchronized Listener getListener() { - return mListener; - } - - public void writeAsync(byte[] data) { - synchronized (mWriteBuffer) { - mWriteBuffer.put(data); - } - } - - public synchronized void stop() { - if (getState() == State.RUNNING) { - Log.i(TAG, "Stop requested"); - mState = State.STOPPING; - } - } - - private synchronized State getState() { - return mState; - } - - /** - * Continuously services the read and write buffers until {@link #stop()} is - * called, or until a driver exception is raised. - * - * NOTE(mikey): Uses inefficient read/write-with-timeout. - * TODO(mikey): Read asynchronously with {@link android.hardware.usb.UsbRequest#queue(java.nio.ByteBuffer, int)} - */ - @Override - public void run() { - synchronized (this) { - if (getState() != State.STOPPED) { - throw new IllegalStateException("Already running."); - } - mState = State.RUNNING; - } - - Log.i(TAG, "Running .."); - try { - while (true) { - if (getState() != State.RUNNING) { - Log.i(TAG, "Stopping mState=" + getState()); - break; - } - step(); - } - } catch (Exception e) { - Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e); - final Listener listener = getListener(); - if (listener != null) { - listener.onRunError(e); - } - } finally { - synchronized (this) { - mState = State.STOPPED; - Log.i(TAG, "Stopped."); - } - } - } - - private void step() throws IOException { - // Handle incoming data. - int len = mDriver.read(mReadBuffer.array(), READ_WAIT_MILLIS); - if (len > 0) { - if (DEBUG) Log.d(TAG, "Read data len=" + len); - final Listener listener = getListener(); - if (listener != null) { - final byte[] data = new byte[len]; - mReadBuffer.get(data, 0, len); - listener.onNewData(data); - } - mReadBuffer.clear(); - } - - // Handle outgoing data. - byte[] outBuff = null; - synchronized (mWriteBuffer) { - if (mWriteBuffer.position() > 0) { - len = mWriteBuffer.position(); - outBuff = new byte[len]; - mWriteBuffer.rewind(); - mWriteBuffer.get(outBuff, 0, len); - mWriteBuffer.clear(); - } - } - if (outBuff != null) { - if (DEBUG) { - Log.d(TAG, "Writing data len=" + len); - } - mDriver.write(outBuff, READ_WAIT_MILLIS); - } - } - -} diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/USBPower.java b/app/src/main/java/com/nightscout/android/dexcom/USB/USBPower.java deleted file mode 100644 index 451b613..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/USBPower.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.nightscout.android.dexcom.USB; - -import java.io.DataOutputStream; - -import android.util.Log; - -public class USBPower { - - private static final String TAG = "DexcomUSBPower"; - - private static final String SET_POWER_ON_COMMAND = "echo 'on' > \"/sys/bus/usb/devices/1-1/power/level\""; - private static final String SET_POWER_SUSPEND_COMMAND_A = "echo \"0\" > \"/sys/bus/usb/devices/1-1/power/autosuspend\""; - private static final String SET_POWER_SUSPEND_COMMAND_B = "echo \"auto\" > \"/sys/bus/usb/devices/1-1/power/level\""; - - public static void PowerOff() { - try { - runCommand(SET_POWER_SUSPEND_COMMAND_A); - runCommand(SET_POWER_SUSPEND_COMMAND_B); - Log.i(TAG, "PowerOff USB complete"); - } catch (Exception e) { - Log.e(TAG, "Unable to PowerOff USB"); - } - } - - public static void PowerOn(){ - try { - runCommand(SET_POWER_ON_COMMAND); - Log.i(TAG, "PowerOn USB complete"); - } catch (Exception e) { - Log.e(TAG, "Unable to PowerOn USB"); - } - } - - private static void runCommand(String command) throws Exception { - Process process = Runtime.getRuntime().exec("su"); - DataOutputStream os = new DataOutputStream(process.getOutputStream()); - os.writeBytes(command + "\n"); - os.flush(); - os.writeBytes("exit \n"); - os.flush(); - os.close(); - process.waitFor(); - } -} diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialDriver.java b/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialDriver.java deleted file mode 100644 index 146d98f..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialDriver.java +++ /dev/null @@ -1,207 +0,0 @@ -/* Copyright 2011 Google Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Project home page: http://code.google.com/p/usb-serial-for-android/ - */ - -package com.nightscout.android.dexcom.USB; - -import java.io.IOException; - -/** - * Driver interface for a USB serial device. - * - * @author mike wakerly (opensource@hoho.com) - */ -public interface UsbSerialDriver { - - /** 5 data bits. */ - int DATABITS_5 = 5; - - /** 6 data bits. */ - int DATABITS_6 = 6; - - /** 7 data bits. */ - int DATABITS_7 = 7; - - /** 8 data bits. */ - int DATABITS_8 = 8; - - /** No flow control. */ - int FLOWCONTROL_NONE = 0; - - /** RTS/CTS input flow control. */ - int FLOWCONTROL_RTSCTS_IN = 1; - - /** RTS/CTS output flow control. */ - int FLOWCONTROL_RTSCTS_OUT = 2; - - /** XON/XOFF input flow control. */ - int FLOWCONTROL_XONXOFF_IN = 4; - - /** XON/XOFF output flow control. */ - int FLOWCONTROL_XONXOFF_OUT = 8; - - /** No parity. */ - int PARITY_NONE = 0; - - /** Odd parity. */ - int PARITY_ODD = 1; - - /** Even parity. */ - int PARITY_EVEN = 2; - - /** Mark parity. */ - int PARITY_MARK = 3; - - /** Space parity. */ - int PARITY_SPACE = 4; - - /** 1 stop bit. */ - int STOPBITS_1 = 1; - - /** 1.5 stop bits. */ - int STOPBITS_1_5 = 3; - - /** 2 stop bits. */ - int STOPBITS_2 = 2; - - /** - * Opens and initializes the device as a USB serial device. Upon success, - * caller must ensure that {@link #close()} is eventually called. - * - * @throws java.io.IOException on error opening or initializing the device. - */ - void open() throws IOException; - - /** - * Closes the serial device. - * - * @throws java.io.IOException on error closing the device. - */ - void close() throws IOException; - - /** - * Reads as many bytes as possible into the destination buffer. - * - * @param dest the destination byte buffer - * @param timeoutMillis the timeout for reading - * @return the actual number of bytes read - * @throws java.io.IOException if an error occurred during reading - */ - int read(final byte[] dest, final int timeoutMillis) throws IOException; - - /** - * Writes as many bytes as possible from the source buffer. - * - * @param src the source byte buffer - * @param timeoutMillis the timeout for writing - * @return the actual number of bytes written - * @throws java.io.IOException if an error occurred during writing - */ - int write(final byte[] src, final int timeoutMillis) throws IOException; - - /** - * Sets various serial port parameters. - * - * @param baudRate baud rate as an integer, for example {@code 115200}. - * @param dataBits one of {@link #DATABITS_5}, {@link #DATABITS_6}, - * {@link #DATABITS_7}, or {@link #DATABITS_8}. - * @param stopBits one of {@link #STOPBITS_1}, {@link #STOPBITS_1_5}, or - * {@link #STOPBITS_2}. - * @param parity one of {@link #PARITY_NONE}, {@link #PARITY_ODD}, - * {@link #PARITY_EVEN}, {@link #PARITY_MARK}, or - * {@link #PARITY_SPACE}. - * @throws java.io.IOException on error setting the port parameters - */ - void setParameters( - int baudRate, int dataBits, int stopBits, int parity) throws IOException; - - /** - * Gets the CD (Carrier Detect) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getCD() throws IOException; - - /** - * Gets the CTS (Clear To Send) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getCTS() throws IOException; - - /** - * Gets the DSR (Data Set Ready) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getDSR() throws IOException; - - /** - * Gets the DTR (Data Terminal Ready) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getDTR() throws IOException; - - /** - * Sets the DTR (Data Terminal Ready) bit on the underlying UART, if - * supported. - * - * @param value the value to set - * @throws java.io.IOException if an error occurred during writing - */ - void setDTR(boolean value) throws IOException; - - /** - * Gets the RI (Ring Indicator) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getRI() throws IOException; - - /** - * Gets the RTS (Request To Send) bit from the underlying UART. - * - * @return the current state, or {@code false} if not supported. - * @throws java.io.IOException if an error occurred during reading - */ - boolean getRTS() throws IOException; - - /** - * Sets the RTS (Request To Send) bit on the underlying UART, if - * supported. - * - * @param value the value to set - * @throws java.io.IOException if an error occurred during writing - */ - void setRTS(boolean value) throws IOException; - /** - * Just to check if this device has the connection openned and claimed - * - * @return boolean - * @throws java.io.IOException if an error occurred during writing - */ - boolean isConnectionOpen(); - -} diff --git a/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialProber.java b/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialProber.java deleted file mode 100644 index c1bdfc1..0000000 --- a/app/src/main/java/com/nightscout/android/dexcom/USB/UsbSerialProber.java +++ /dev/null @@ -1,171 +0,0 @@ -/* Copyright 2011 Google Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - * Project home page: http://code.google.com/p/usb-serial-for-android/ - */ - -package com.nightscout.android.dexcom.USB; - -import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbDeviceConnection; -import android.hardware.usb.UsbManager; -import android.util.Log; - -import java.util.Map; - -//import com.hoho.android.usbserial.driver.Cp2102SerialDriver; -//import com.hoho.android.usbserial.driver.FtdiSerialDriver; - -/** - * Helper class to assist in detecting and building {@link UsbSerialDriver} - * instances from available hardware. - * - * @author mike wakerly (opensource@hoho.com) - */ -public enum UsbSerialProber { - - // TODO(mikey): Too much boilerplate. - - /** - * Prober for {@link FtdiSerialDriver}. - * - * @see FtdiSerialDriver - */ -/* FTDI_SERIAL { - @Override - public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) { - if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) { - return null; - } - final UsbDeviceConnection connection = manager.openDevice(usbDevice); - if (connection == null) { - return null; - } - return new FtdiSerialDriver(usbDevice, connection); - } - },*/ - - CDC_ACM_SERIAL { - @Override - public UsbSerialDriver getDevice(UsbManager manager, UsbDevice usbDevice) { -// if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) { -// return null; -// } - final UsbDeviceConnection connection = manager.openDevice(usbDevice); - if (connection == null) { - return null; - } - return new CdcAcmSerialDriver(usbDevice, connection); - } - }; //, - -/* SILAB_SERIAL { - @Override - public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) { - if (!testIfSupported(usbDevice, Cp2102SerialDriver.getSupportedDevices())) { - return null; - } - final UsbDeviceConnection connection = manager.openDevice(usbDevice); - if (connection == null) { - return null; - } - return new Cp2102SerialDriver(usbDevice, connection); - } - };*/ - - private static final String TAG = UsbSerialProber.class.getSimpleName(); - - /** - * Builds a new {@link UsbSerialDriver} instance from the raw device, or - * returns null if it could not be built (for example, if the - * probe failed). - * - * @param manager the {@link android.hardware.usb.UsbManager} to use - * @param usbDevice the raw {@link android.hardware.usb.UsbDevice} to use - * @return the first available {@link UsbSerialDriver}, or {@code null} if - * no devices could be acquired - */ - public abstract UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice); - - /** - * Acquires and returns the first available serial device among all - * available {@link android.hardware.usb.UsbDevice}s, or returns {@code null} if no device could - * be acquired. - * - * @param usbManager the {@link android.hardware.usb.UsbManager} to use - * @return the first available {@link UsbSerialDriver}, or {@code null} if - * no devices could be acquired - */ - public static UsbSerialDriver acquire(final UsbManager usbManager) { - for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) { - final UsbSerialDriver probedDevice = acquire(usbManager, usbDevice); - if (probedDevice != null) { - return probedDevice; - } - } - return null; - } - - /** - * Builds and returns a new {@link UsbSerialDriver} from the given - * {@link android.hardware.usb.UsbDevice}, or returns {@code null} if no drivers supported this - * device. - * - * @param usbManager the {@link android.hardware.usb.UsbManager} to use - * @param usbDevice the {@link android.hardware.usb.UsbDevice} to use - * @return a new {@link UsbSerialDriver}, or {@code null} if no devices - * could be acquired - */ - public static UsbSerialDriver acquire(final UsbManager usbManager, final UsbDevice usbDevice) { - if (!usbManager.hasPermission(usbDevice)) { - Log.i(TAG, "No permission for " + usbDevice.getVendorId() + " " + usbDevice.getProductId()); - return null; - } - for (final UsbSerialProber prober : values()) { - final UsbSerialDriver probedDevice = prober.getDevice(usbManager, usbDevice); - if (probedDevice != null) { - return probedDevice; - } - } - return null; - } - - /** - * Returns {@code true} if the given device is found in the vendor/product map. - * - * @param usbDevice the device to test - * @param supportedDevices map of vendor ids to product id(s) - * @return {@code true} if supported - */ - private static boolean testIfSupported(final UsbDevice usbDevice, - final Map supportedDevices) { - final int[] supportedProducts = supportedDevices.get( - Integer.valueOf(usbDevice.getVendorId())); - if (supportedProducts == null) { - return false; - } - - final int productId = usbDevice.getProductId(); - for (int supportedProductId : supportedProducts) { - if (productId == supportedProductId) { - return true; - } - } - return false; - } - -} diff --git a/app/src/main/java/com/nightscout/android/medtronic/MedtronicCGMService.java b/app/src/main/java/com/nightscout/android/medtronic/MedtronicCGMService.java index 9dcf996..996db71 100644 --- a/app/src/main/java/com/nightscout/android/medtronic/MedtronicCGMService.java +++ b/app/src/main/java/com/nightscout/android/medtronic/MedtronicCGMService.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -28,30 +29,28 @@ import android.widget.Toast; import java.text.DateFormat; import java.text.SimpleDateFormat; + +import com.felhr.usbserial.UsbSerialDevice; +import com.felhr.usbserial.UsbSerialInterface; import com.nightscout.android.dexcom.USB.HexDump; -import com.nightscout.android.upload.GlucometerRecord; import com.nightscout.android.upload.MedtronicSensorRecord; import com.nightscout.android.upload.Record; import com.nightscout.android.upload.UploadHelper; -import com.physicaloid.lib.Physicaloid; -import com.physicaloid.lib.usb.driver.uart.ReadLisener; -import com.physicaloid.lib.usb.driver.uart.UartConfig; import org.json.JSONArray; import org.json.JSONException; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; + -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; /** * This class is the service responsible of manage correctly the interface with the enlite. * @author lmmarguenda @@ -60,15 +59,12 @@ public class MedtronicCGMService extends Service implements OnSharedPreferenceChangeListener { - private Logger log = (Logger) LoggerFactory.getLogger(MedtronicReader.class.getName()); private static final String TAG = MedtronicCGMService.class.getSimpleName(); private boolean listenerAttached = false; private UploadHelper uploader; - - private Physicaloid mSerial; - private Handler mHandlerCheckSerial = new Handler();// This handler runs readAndUpload Runnable which checks the USB device and NET connection. - private Handler mHandlerRead = new Handler();// this Handler is used to read and parse the messages received from the USB, It is only activated after a Read. + private UsbSerialDevice mSerial; + private Handler mHandlerCheckSerial = new Handler();// This handler runs checkSerial Runnable which checks the USB device and NET connection. private Handler mHandlerProcessRead = new Handler();// this Handler is used to process the messages parsed. private Handler mHandlerReviewParameters = new Handler(); private boolean mHandlerActive = false; @@ -81,19 +77,13 @@ public class MedtronicCGMService extends Service implements private final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler. private SharedPreferences prefs = null;// common application preferences private int calibrationSelected = MedtronicConstants.CALIBRATION_GLUCOMETER;//calibration Selected - private Handler mHandlerSensorCalibration = new Handler();// this Handler is used to ask for SensorCalibration. - private Handler mHandlerReloadLost = new Handler();// this Handler is used to upload records which upload failed due to a network error. private boolean connectedSent = false; private boolean isDestroying = false; - private Object reloadLostLock = new Object(); private Object checkSerialLock = new Object(); private Object isUploadingLock = new Object(); - private Object readByListenerSizeLock = new Object(); private Object buffMessagesLock = new Object(); - private Object mSerialLock = new Object(); + private boolean faking = false; - private ReadByListener readByListener = new ReadByListener();//Listener to read data - private boolean isReloaded = false; @Override public IBinder onBind(Intent intent) { @@ -120,110 +110,41 @@ public void handleMessage(Message msg) { case MedtronicConstants.MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; - case MedtronicConstants.MSG_MEDTRONIC_GLUCMEASURE_APPROVED: - if (msg.getData().getBoolean("approved")) - medtronicReader.approveGlucValueForCalibration(msg.getData().getFloat("data"), msg.getData().getBoolean("calibrating"), msg.getData().getBoolean("isCalFactorFromPump")); - else { - medtronicReader.lastGlucometerRecord = new GlucometerRecord(); - medtronicReader.lastGlucometerRecord.numGlucometerValue = msg.getData().getFloat("data"); - medtronicReader.lastGlucometerValue = msg.getData().getFloat("data"); - Date d = new Date(); - medtronicReader.lastGlucometerRecord.lastDate = d.getTime(); - medtronicReader.lastGlucometerDate = d.getTime(); - medtronicReader.calculateDate(medtronicReader.lastGlucometerRecord, d, 0); - SharedPreferences.Editor editor = settings.edit(); - editor.putFloat("lastGlucometerValue", medtronicReader.lastGlucometerValue); - editor.putLong("glucometerLastDate", d.getTime()); - editor.commit(); - } - break; case MedtronicConstants.MSG_MEDTRONIC_SEND_MANUAL_CALIB_VALUE: - String value = msg.getData().getString("sgv"); - if (value == null || value.equals("")) { - value = prefs.getString("manual_sgv", ""); - if (value.indexOf(",") >= 0) - value = value.replace(",", "."); - } - log.debug("Manual Calibration Received SGV " + value); + int value = msg.getData().getInt("sgv"); + Log.d(TAG, "Manual Calibration Received SGV " + value); try { - Float val = null; - if (medtronicReader != null && value != null && !value.equals("")) { - if (prefs.getBoolean("mmolxl", false)) { - try { - if (value.indexOf(".") > -1) { - val = Float.parseFloat(value); - medtronicReader.processManualCalibrationDataMessage(val, false, true); - } else { - medtronicReader.processManualCalibrationDataMessage(Integer.parseInt(value), false, true); - } - sendMessageCalibrationDoneToUI(); - } catch (Exception e) { - sendExceptionToUI("Error parsing Calibration", e); - } - } else { - if (value.indexOf(".") > -1) { - val = Float.parseFloat(value); - medtronicReader.processManualCalibrationDataMessage(val.intValue(), false, true); - } else { - medtronicReader.processManualCalibrationDataMessage(Integer.parseInt(value), false, true); - } - sendMessageCalibrationDoneToUI(); - } + if (medtronicReader != null && value > 0) { + medtronicReader.processManualCalibrationDataMessage(value, false, true); + sendMessageCalibrationDoneToUI(); } + else { + sendErrorMessageToUI("Calibration value empty"); + } } catch (Exception e) { sendExceptionToUI("Error parsing Calibration", e); } break; case MedtronicConstants.MSG_MEDTRONIC_SEND_INSTANT_CALIB_VALUE: // manually entered calibration. - value = msg.getData().getString("sgv"); - if (value == null || value.equals("")) { - value = prefs.getString("instant_sgv", ""); - if (value.indexOf(",") >= 0) - value = value.replace(",", "."); - } + value = msg.getData().getInt("sgv"); Log.d(TAG, "Instant Calibration received SGV " + value); try { - Float val = null; - if (medtronicReader != null && !value.equals("")) { - if (prefs.getBoolean("mmolxl", false)) { - try { - if (value.indexOf(".") > -1) { - val = Float.parseFloat(value); - medtronicReader.calculateInstantCalibration(val * 18f); - } else { - medtronicReader.calculateInstantCalibration(Integer.parseInt(value) * 18f); - } - sendMessageCalibrationDoneToUI(); - } catch (Exception e) { - sendExceptionToUI("Error parsing Calibration", e); - } - } else { - if (value.indexOf(".") > -1) { - val = Float.parseFloat(value); - medtronicReader.calculateInstantCalibration(val.intValue()); - } else { - medtronicReader.calculateInstantCalibration(Integer.parseInt(value)); - } + if (medtronicReader != null && value > 0) { + { + medtronicReader.calculateInstantCalibration(value); sendMessageCalibrationDoneToUI(); } } else { - sendErrorMessageToUI("Error parsing Calibration"); + sendErrorMessageToUI("Calibration value empty"); } } catch (Exception e) { sendExceptionToUI("Error parsing Calibration", e); } break; - case MedtronicConstants.MSG_MEDTRONIC_SEND_GET_PUMP_INFO: - sendMessageToUI("Retrieving Pump info..."); - break; - case MedtronicConstants.MSG_MEDTRONIC_SEND_GET_SENSORCAL_FACTOR: - sendMessageToUI("Retrieve calibration factor...Now!"); - log.debug("Retrieve calibration factor...Now!"); - break; case MedtronicConstants.MSG_MEDTRONIC_CGM_REQUEST_PERMISSION: - openUsbSerial(false); + openUsbSerial(); break; default: super.handleMessage(msg); @@ -233,16 +154,8 @@ public void handleMessage(Message msg) { void sendExceptionToUI(String message, Exception e) { - Log.e(TAG, message); + Log.e(TAG, message, e); sendErrorMessageToUI(message); - StringBuffer sb1 = new StringBuffer(""); - sb1.append("EXCEPTION: " + e.getMessage() + " " + e.getCause()); - for (StackTraceElement st : e.getStackTrace()) - { - sb1.append(st.toString()); - } - sendErrorMessageToUI(sb1.toString()); - Log.e(TAG, sb1.toString()); } /** * Sends a message to be printed in the display (DEBUG) or launches a pop-up message. @@ -250,13 +163,13 @@ void sendExceptionToUI(String message, Exception e) { */ private void sendMessageToUI(String valuetosend) { - Log.i("medtronicCGMService", valuetosend); + Log.i("medtronicCGMService", "Sent message to UI" + valuetosend); DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss - "); //get current date time with Date() Date date = new Date(); valuetosend = dateFormat.format(date) + valuetosend; - log.debug("send Message To UI -> "+valuetosend); + Log.d(TAG,"send Message To UI -> "+valuetosend); if (mClients != null && mClients.size() > 0) { for (int i = mClients.size() - 1; i >= 0; i--) { try { @@ -285,8 +198,7 @@ private void sendMessageToUI(String valuetosend) { * */ private void sendErrorMessageToUI(String valuetosend) { - Log.e("medtronicCGMService", valuetosend); - log.error("Send Error Message to UI "+ valuetosend); + Log.e("medtronicCGMService", "Sent error message to UI: " + valuetosend); if (mClients != null && mClients.size() > 0) { for (int i = mClients.size() - 1; i >= 0; i--) { try { @@ -314,9 +226,8 @@ private void sendErrorMessageToUI(String valuetosend) { * Sends message to the UI to indicate that the device is connected. */ private void sendMessageConnectedToUI() { - Log.i("medtronicCGMService", "Connected"); if (!connectedSent){ - log.debug("Send Message Connected to UI"); + Log.d(TAG, "Send Message Connected to UI"); connectedSent = true; } for (int i = mClients.size() - 1; i >= 0; i--) { @@ -387,21 +298,10 @@ public void onCreate() { settings = getSharedPreferences(MedtronicConstants.PREFS_NAME, 0); prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); - prefs.edit().remove("isCheckedWUP").commit(); + prefs.registerOnSharedPreferenceChangeListener(this); - int level = Integer.parseInt(prefs.getString("logLevel", "1")); - switch (level) { - case 2: - log.setLevel(Level.INFO); - break; - case 3: - log.setLevel(Level.DEBUG); - break; - default: - log.setLevel(Level.ERROR); - break; - } + if (prefs.contains("monitor_type")){ String type = prefs.getString("monitor_type", "1"); @@ -420,51 +320,30 @@ else if ("2".equalsIgnoreCase(type)){ wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); - mSerial = new Physicaloid(this); - medtronicReader = new MedtronicReader(mSerial, getBaseContext(), - mClients); - - Record auxRecord = MedtronicCGMService.this.loadClassFile(new File(getBaseContext().getFilesDir(), "save.bin")); - - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(getBaseContext()); - - DecimalFormat df = new DecimalFormat("#.##"); - - if (auxRecord instanceof MedtronicSensorRecord){ - - MedtronicSensorRecord record = (MedtronicSensorRecord) auxRecord; - - if (prefs.getBoolean("mmolxl", false)){ - Float fBgValue; - try{ - fBgValue = (float)Integer.parseInt(record.bGValue); - log.info("mmolxl true --> "+record.bGValue); - record.bGValue = df.format(fBgValue/18f); - log.info("mmolxl/18 true --> "+record.bGValue); - }catch (Exception e){ - } - }else - Log.i(TAG,"mmolxl false --> "+record.bGValue); + medtronicReader = new MedtronicReader(getBaseContext(), mClients); + Record auxRecord = null; + medtronicReader.previousRecord = null; - if (prefs.getBoolean("isWarmingUp",false)){ - record.bGValue = "W_Up"; - record.trendArrow="---"; - } - medtronicReader.previousRecord = record; - } - - medtronicReader.mHandlerSensorCalibration = mHandlerSensorCalibration; - checker = medtronicReader.new CalibrationStatusChecker(mHandlerReviewParameters); + try { + auxRecord = MedtronicCGMService.this.loadClassFile(new File(getBaseContext().getFilesDir(), "save.bin")); + } + catch (Exception e) { + Log.e(TAG, "couldn't load last record during onCreate", e); + } + + if (auxRecord instanceof MedtronicSensorRecord) { + medtronicReader.previousRecord = (MedtronicSensorRecord) auxRecord; + } + + checker = medtronicReader.new CalibrationStatusChecker(mHandlerReviewParameters); mHandlerReviewParameters.postDelayed(checker, MedtronicConstants.TIME_5_MIN_IN_MS); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(mUsbReceiver, filter); - mHandlerCheckSerial.removeCallbacks(readAndUpload); - mHandlerCheckSerial.post(readAndUpload); - mHandlerReloadLost.postDelayed(reloadLostRecords, 60000); + mHandlerCheckSerial.removeCallbacks(checkSerial); + mHandlerCheckSerial.post(checkSerial); mHandlerActive = true; } @@ -476,17 +355,15 @@ public void onDestroy() { isDestroying = true; prefs.unregisterOnSharedPreferenceChangeListener(this); - synchronized (reloadLostLock) { - mHandlerReloadLost.removeCallbacks(reloadLostRecords); - } + synchronized (checkSerialLock) { Log.i(TAG, "onDestroy called"); - log.debug("Medtronic Service onDestroy called"); - mHandlerCheckSerial.removeCallbacks(readAndUpload); + + mHandlerCheckSerial.removeCallbacks(checkSerial); SharedPreferences.Editor editor = settings.edit(); editor.putLong("lastDestroy", System.currentTimeMillis()); - editor.commit(); + editor.apply(); closeUsbSerial(); mHandlerActive = false; unregisterReceiver(mUsbReceiver); @@ -499,34 +376,15 @@ public void onDestroy() { - /** - * Listener which throws a handler that manages the reading from the serial buffer, when a read happens - */ - private ReadLisener readListener = new ReadLisener() { - - @Override - public void onRead(int size) { - if (size <= 0) return; - Log.d(TAG, "On read received " + size); - synchronized (readByListenerSizeLock) { - if (readByListener.size > -1) - readByListener.size += size; - else - readByListener.size = size; - } - mHandlerRead.post(readByListener); - - } - }; /** * Runnable. * It checks that it is a serial device available, and there is Internet connection. * It also binds readByListener with the serial device and execute it the first time; */ - private Runnable readAndUpload = new Runnable() { + private Runnable checkSerial = new Runnable() { public void run() { - Log.d(TAG, "run readAndUpload"); + Log.d(TAG, "run checkSerial"); try { UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); boolean hasPermission = faking; @@ -540,45 +398,38 @@ public void run() { synchronized (checkSerialLock) { Log.d(TAG, "I have lost usb permission changing listener attached to false..."); listenerAttached = false; - mSerial.clearReadListener(); - mHandlerRead.removeCallbacks(readByListener); + sendMessageDisconnectedToUI(); if (!mHandlerActive || isDestroying){ Log.d(TAG,"destroy readAnd Upload "+ mHandlerActive + " isDes "+ isDestroying); return; } - mHandlerCheckSerial.removeCallbacks(readAndUpload); - mHandlerCheckSerial.postDelayed(readAndUpload, MedtronicConstants.FIVE_SECONDS__MS); + mHandlerCheckSerial.removeCallbacks(checkSerial); + mHandlerCheckSerial.postDelayed(checkSerial, MedtronicConstants.FIVE_SECONDS__MS * 2); return; } } else sendMessageConnectedToUI(); boolean connected; - synchronized (mSerialLock) { - connected = isConnected(); - } + + connected = isConnected(); + if (connected) { - if (!isOnline()) - sendErrorMessageToUI("NET connection error"); if (!listenerAttached) { Log.d(TAG, "!listener attached readByListener triggered"); - mSerial.clearReadListener(); - mHandlerRead.removeCallbacks(readByListener); - mSerial.addReadListener(readListener); - mHandlerRead.post(readByListener); + + listenerAttached = true; } } else { - openUsbSerial(false); + openUsbSerial(); connected = isConnected(); if (!connected) sendErrorMessageToUI("Receptor connection error"); - else if (!isOnline()) - sendErrorMessageToUI("Not online/connection error"); else { sendMessageConnectedToUI(); sendMessageToUI("connected"); @@ -588,42 +439,17 @@ else if (!isOnline()) } catch (Exception e) { sendExceptionToUI("Unable to read from receptor or upload", e); } - synchronized (checkSerialLock) { - if (!mHandlerActive || isDestroying){ - Log.d(TAG,"destroy readAnd Upload2 "+ mHandlerActive + " isDes "+ isDestroying); - return; - } - mHandlerCheckSerial.removeCallbacks(readAndUpload); - mHandlerCheckSerial.postDelayed(readAndUpload, MedtronicConstants.FIVE_SECONDS__MS); + + if (!mHandlerActive || isDestroying){ + Log.d(TAG,"destroy readAnd Upload2 "+ mHandlerActive + " isDes "+ isDestroying); + return; } + mHandlerCheckSerial.removeCallbacks(checkSerial); + mHandlerCheckSerial.postDelayed(checkSerial, MedtronicConstants.FIVE_SECONDS__MS * 2); + } }; - /** - * Runnable. - * Executes doReadAndUploadFunction; - */ - private class ReadByListener implements Runnable { - public Integer size = -1; - public void run() { - int auxSize = 0; - synchronized (readByListenerSizeLock) { - auxSize = size; - size = -1; - } - if (auxSize >= 0){ - Log.d(TAG, "Read "+auxSize+" bytes"); - doReadAndUpload(auxSize); - isReloaded = false; - }else{ -// Log.d(TAG, "ReadByListener - nothing to read"); - if (!isReloaded){ - openUsbSerial(true); - medtronicReader.mSerialDevice = mSerial; - } - } - } - } public void doFakeReadAndUpload() { @@ -633,24 +459,28 @@ public void doFakeReadAndUpload() { ArrayList bufferedMessages = new ArrayList<>(); + List devices = medtronicReader.getKnownDevices(); + String device = devices.get(0); + + //byte deviceData[] = {(byte) 0x21, (byte) 0x22, (byte) 0x23}; + byte deviceData[] = HexDump.hexStringToByteArray(device); - byte deviceData[] = {(byte) 0x21, (byte) 0x22, (byte) 0x23}; bufferedMessages.add(TestUSBData.fakeSensorData(deviceData,5500)); - log.debug("Stream Received"); + Log.d(TAG, "Fake Stream Received"); if (bufferedMessages.size() > 0) { - log.debug("Stream Received--> There are " + bufferedMessages.size() + " to process "); + Log.d(TAG, "Fake Stream Received--> There are " + bufferedMessages.size() + " to process "); synchronized (buffMessagesLock) { processBufferedMessages.bufferedMessages .addAll(bufferedMessages); } if (!isDestroying) { - log.debug("Stream Received--> order process bufferedMessages "); + Log.d(TAG, "Stream Received--> order process bufferedMessages "); mHandlerProcessRead.post(processBufferedMessages); } } else { - log.debug("NULL doReadAndUpload"); + Log.d(TAG, "NULL doReadAndUpload"); } } catch (Exception e) { @@ -662,30 +492,18 @@ public void doFakeReadAndUpload() { /** * Process all the parsed messages, checks if there is Records to upload and executes the uploader if necessary. */ - protected void doReadAndUpload(int size) { + protected void doReadAndUpload(byte[] bytes) { try { - synchronized (mSerialLock) { - if (mSerial.isOpened() && !isDestroying) { - - Log.d(TAG, "doReadAndUpload"); - ArrayList bufferedMessages = medtronicReader - .readFromReceiver(size); - if (bufferedMessages != null && bufferedMessages.size() > 0) { - Log.d(TAG, "doReadAndUpload: there are "+bufferedMessages.size()+" to process "); - synchronized (buffMessagesLock) { - processBufferedMessages.bufferedMessages - .addAll(bufferedMessages); - } - if (!isDestroying){ - log.debug("Stream Received--> order process bufferedMessages "); - mHandlerProcessRead.post(processBufferedMessages); - } - }else{ - Log.d(TAG, "Nothing to do in doReadAndUpload"); - } - - } + Log.d(TAG, "doReadAndUpload"); + ArrayList bufferedMessages = medtronicReader.readFromReceiver(bytes); + if (bufferedMessages != null && bufferedMessages.size() > 0) { + Log.d(TAG, "doReadAndUpload: there are " + bufferedMessages.size() + " to process "); + processBufferedMessages.bufferedMessages.addAll(bufferedMessages); + mHandlerProcessRead.post(processBufferedMessages); + } + else{ + Log.d(TAG, "Nothing to do in doReadAndUpload"); } } catch (Exception e) { sendExceptionToUI("doReadAndUpload exception", e); @@ -693,34 +511,7 @@ protected void doReadAndUpload(int size) { } - /** - * class This class process all the messages received after being correctly - * parsed. - */ - private Runnable reloadLostRecords = new Runnable() { - public void run() { - Log.d(TAG, "Reload any lost records from medtronic service"); - - try { - JSONArray recordsNotUploadedJson = new JSONArray(settings.getString("recordsNotUploadedJson","[]")); - synchronized (reloadLostLock) { - if (isOnline()) { - Log.d(TAG,"reloadnotuploaded is online -> " + recordsNotUploadedJson.length() + " " + !isDestroying); - if (recordsNotUploadedJson.length() > 0 && !isDestroying) { - Log.i(TAG, "Uploading" + recordsNotUploadedJson.length() + " lost records"); - uploader = new UploadHelper(getApplicationContext()); - } - } - } - } catch (JSONException e) { - sendExceptionToUI("Error Reloading Lost Records", e); - } - - if (!isDestroying) - mHandlerReloadLost.postDelayed(reloadLostRecords, 60000); - } - }; /** * class This class process all the messages received after being correctly * parsed. @@ -732,10 +523,10 @@ public void run() { synchronized (isUploadingLock) { try { - ArrayList bufferedMessages2Process = new ArrayList(); + ArrayList bufferedMessages2Process; synchronized (buffMessagesLock) { - bufferedMessages2Process.addAll(bufferedMessages); + bufferedMessages2Process = new ArrayList(bufferedMessages); bufferedMessages.clear(); } Log.d(TAG,"I am going to process "+ bufferedMessages2Process.size()+" Messages"); @@ -760,11 +551,7 @@ public void run() { listToUpload.add(medtronicReader.lastGlucometerRecord); medtronicReader.lastGlucometerRecord = null; } - // upload device info if available - if (medtronicReader.lastMedtronicPumpRecord != null) { - listToUpload.add(medtronicReader.lastMedtronicPumpRecord); - medtronicReader.lastMedtronicPumpRecord = null; - } + Record[] params = new Record[listToUpload.size()]; @@ -773,17 +560,15 @@ public void run() { params[listToUpload.size() - 1 - i] = record; } if (params.length > 0) { - synchronized (reloadLostLock) { + uploader = new UploadHelper(getApplicationContext()); uploader.execute(params); - } + } listToUpload.clear(); - if (prefs.getBoolean("EnableWifiHack", false)) { - doWifiHack(); - } + } catch (Exception e) { sendExceptionToUI("BufferedMessagesProcessor", e); } @@ -793,63 +578,13 @@ public void run() { } - private void doWifiHack() { - Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - @Override - // Interesting case: location with lousy wifi - // toggle it off to use cellular - // toggle back on for next try - public void run() { - Status dataUp = uploader.getStatus(); - if (dataUp == Status.RUNNING) { - uploader.cancel(true); - - if (wifiManager.isWifiEnabled()) { - wifiManager.setWifiEnabled(false); - try { - Thread.sleep(2500); - } catch (InterruptedException e) { - Log.e(TAG, - "Sleep after setWifiEnabled(false) interrupted", - e); - } - wifiManager.setWifiEnabled(true); - try { - Thread.sleep(2500); - } catch (InterruptedException e) { - Log.e(TAG, - "Sleep after setWifiEnabled(true) interrupted", - e); - } - } - } - } - }, 22500); - } private boolean isConnected() { - return mSerial.isOpened() || faking; + return mSerial != null || faking; } - private boolean isOnline() { - ConnectivityManager connectivity = (ConnectivityManager) getBaseContext().getSystemService(Context.CONNECTIVITY_SERVICE); - if (connectivity != null) { - NetworkInfo[] info = connectivity.getAllNetworkInfo(); - if (info != null) { - for (int i = 0; (i < info.length); i++) { - - if (info[i].getState() == NetworkInfo.State.CONNECTED) { - log.debug("INTERNET: connected!"); - return true; - } - } - log.debug("INTERNET nothing connected of "+String.valueOf(info.length)); - } - } - return false; - } + /** * Launches a pop up message @@ -870,46 +605,69 @@ private void displayMessage(String message) { } - private void openUsbSerial(boolean reload) { + private void openUsbSerial() { if (faking) return; + if (mSerial == null) { - Toast.makeText(this, "cannot open / null device", Toast.LENGTH_SHORT).show(); - Log.e(TAG, "mSerial==null"); - return; - } - if (mSerial.isOpened() && reload){ - mSerial.close(); - mSerial.clearReadListener(); - listenerAttached = false; - } - - synchronized (mSerialLock) { - if (!mSerial.isOpened()) { - if (!mSerial.open()) { - Toast.makeText(this, "cannot open / will not open", Toast.LENGTH_SHORT) - .show(); - Log.e(TAG, "mSerial noted opened and will not open"); - return; - } else { - if (!isReloaded && reload) - isReloaded = true; - boolean dtrOn = true; - boolean rtsOn = false; - mSerial.setConfig(new UartConfig(57600, 8, 1, 0, dtrOn, - rtsOn)); - if (!reload) - Toast.makeText(this, "connected", Toast.LENGTH_SHORT) - .show(); + UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); + UsbDevice device; + UsbDeviceConnection connection; + + HashMap usbDevices = usbManager.getDeviceList(); + if (!usbDevices.isEmpty()) { + boolean keep = true; + device = null; + connection = null; + for (Map.Entry entry : usbDevices.entrySet()) { + device = entry.getValue(); + int deviceVID = device.getVendorId(); + int devicePID = device.getProductId(); + if (deviceVID != 0x1d6b && devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) { + // Excludes USB hubs + Log.d(TAG, "Device: vendor " + deviceVID + " - ID " + devicePID); + connection = usbManager.openDevice(device); + keep = false; + } else { + connection = null; + device = null; + } + + if (!keep) + break;//stop search on first usb device } + + if (device != null && connection != null) mSerial = UsbSerialDevice.createUsbSerialDevice(device, connection); + } + if (mSerial == null) { + Toast.makeText(this, "cannot open / null device", Toast.LENGTH_SHORT).show(); + Log.e(TAG, "mSerial==null"); + return; + } + + if (mSerial.open()) { + + mSerial.setBaudRate(57600); + mSerial.setDataBits(8); + mSerial.setParity(0); + mSerial.setStopBits(1); + + mSerial.read(mCallback); + + + Toast.makeText(this, "connected", Toast.LENGTH_SHORT) + .show(); + } + else { + Toast.makeText(this, "couldn't open device", Toast.LENGTH_SHORT) + .show(); + Log.e(TAG, "could not open device)"); } - } - if (!listenerAttached && reload) { - mSerial.addReadListener(readListener); - listenerAttached = true; } } + + //Deserialize the EGVRecord (most recent) value public Record loadClassFile(File f) { ObjectInputStream ois = null; @@ -931,13 +689,13 @@ public Record loadClassFile(File f) { } private void closeUsbSerial() { - mSerial.clearReadListener(); - mHandlerRead.removeCallbacks(readByListener); + + mHandlerProcessRead.removeCallbacks(processBufferedMessages); mHandlerReviewParameters.removeCallbacks(checker); listenerAttached = false; - mSerial.close(); + } /** @@ -963,15 +721,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { try { - if (key.equalsIgnoreCase("logLevel")){ - String level = sharedPreferences.getString("logLevel", "1"); - if ("2".equalsIgnoreCase(level)) - log.setLevel(Level.INFO); - else if ("3".equalsIgnoreCase(level)) - log.setLevel(Level.DEBUG); - else - log.setLevel(Level.ERROR); - } + if (sharedPreferences.contains("monitor_type") && key.equalsIgnoreCase("monitor_type")){ String type = sharedPreferences.getString("monitor_type", "1"); if ("2".equalsIgnoreCase(type)){ @@ -1015,7 +765,7 @@ else if ("3".equalsIgnoreCase(level)) if (key.equals("medtronic_cgm_id") || key.equals("glucometer_cgm_id") || key.equals("sensor_cgm_id")) { String newID = sharedPreferences.getString("medtronic_cgm_id", ""); if (!"".equals(newID.replaceAll(" ", ""))) { - mHandlerCheckSerial.removeCallbacks(readAndUpload); + mHandlerCheckSerial.removeCallbacks(checkSerial); byte[] newIdPump = HexDump.hexStringToByteArray(newID); if (key.equals("medtronic_cgm_id") && !Arrays.equals(newIdPump, medtronicReader.idPump)) { SharedPreferences.Editor editor = settings.edit(); @@ -1033,16 +783,16 @@ else if ("3".equalsIgnoreCase(level)) editor.commit(); synchronized (checkSerialLock) { - mHandlerCheckSerial.removeCallbacks(readAndUpload); + mHandlerCheckSerial.removeCallbacks(checkSerial); mHandlerActive = false; } - medtronicReader = new MedtronicReader(mSerial, + medtronicReader = new MedtronicReader( getBaseContext(), mClients); medtronicReader.idPump = newIdPump; synchronized (checkSerialLock) { - mHandlerCheckSerial.post(readAndUpload); + mHandlerCheckSerial.post(checkSerial); mHandlerActive = true; } }else{ @@ -1058,7 +808,7 @@ else if ("3".equalsIgnoreCase(level)) if (prefs.getString("sensor_cgm_id", "").length() > 0) { String sensorID = HexDump.toHexString(Integer.parseInt(prefs .getString("sensor_cgm_id", "0"))); - while (sensorID != null && sensorID.length() > 6) { + while (sensorID.length() > 6) { sensorID = sensorID.substring(1); } if (!medtronicReader.knownDevices.contains(sensorID)){ @@ -1067,7 +817,7 @@ else if ("3".equalsIgnoreCase(level)) } } - mHandlerCheckSerial.post(readAndUpload); + mHandlerCheckSerial.post(checkSerial); } } } @@ -1078,4 +828,14 @@ else if ("3".equalsIgnoreCase(level)) } + private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { + + @Override + public void onReceivedData(byte[] arg0) + { + doReadAndUpload(arg0); + // Code here :) + } + }; + } diff --git a/app/src/main/java/com/nightscout/android/medtronic/MedtronicConstants.java b/app/src/main/java/com/nightscout/android/medtronic/MedtronicConstants.java index e8a4358..6a0b99f 100644 --- a/app/src/main/java/com/nightscout/android/medtronic/MedtronicConstants.java +++ b/app/src/main/java/com/nightscout/android/medtronic/MedtronicConstants.java @@ -19,9 +19,9 @@ public class MedtronicConstants { public static final int TIME_12_HOURS_IN_MS = 43200000; public static final String PREFS_NAME = "MyPrefsFile"; public static final float SENSOR_CONVERSION_CONSTANT_VALUE = 160.72f; - public static final float SENSOR_CONVERSION_CONSTANT_VALUE2 = Float.valueOf("5.8E-4").floatValue(); - public static final float SENSOR_CONVERSION_CONSTANT_VALUE3 = Float.valueOf("6.25E-6").floatValue(); - public static final float SENSOR_CONVERSION_CONSTANT_VALUE4 = Float.valueOf("1.5E-6").floatValue(); + public static final float SENSOR_CONVERSION_CONSTANT_VALUE2 = Float.valueOf("5.8E-4"); + public static final float SENSOR_CONVERSION_CONSTANT_VALUE3 = Float.valueOf("6.25E-6"); + public static final float SENSOR_CONVERSION_CONSTANT_VALUE4 = Float.valueOf("1.5E-6"); public static final int SENSOR_CONVERSION_CONSTANT_VALUE5 = 65536; @@ -44,9 +44,8 @@ public class MedtronicConstants { public static final String CALIBRATED_STR = "Calibrated"; public static final String CALIBRATION_MORE_THAN_12H_OLD_STR = "Last Calibration > 12H"; public static final String LAST_CALIBRATION_FAILED_USING_PREVIOUS_STR = "Using Prev. Calibration"; - public static final String CALIBRATED_IN_15MIN_STR = "Calibrated between 15min. and 20min."; public static final String CALIBRATING_STR = "Calibrating, wait 15 to 20min."; - public static final String CALIBRATING2_STR = "Calibrating, 2 values received wait 5min. more"; + public static final String CALIBRATING2_STR = "Calibrating, 2 values received wait 5-10min. more"; public static final byte MEDTRONIC_GET_PUMP_MODEL = (byte)0x8d; public static final byte MEDTRONIC_GET_ALARM_MODE = (byte)0x75; @@ -71,18 +70,13 @@ public class MedtronicConstants { public static final int MSG_REGISTER_CLIENT = 0; public static final int MSG_UNREGISTER_CLIENT = 1; public static final int MSG_MEDTRONIC_CGM_MESSAGE_RECEIVED = 2; - public static final int MSG_MEDTRONIC_CGM_CLEAR_DISPLAY = 4; public static final int MSG_MEDTRONIC_CGM_NO_PERMISSION = 5; public static final int MSG_MEDTRONIC_CGM_USB_GRANTED = 6; public static final int MSG_MEDTRONIC_CGM_REQUEST_PERMISSION = 7; public static final int MSG_MEDTRONIC_CGM_ERROR_RECEIVED = 8; public static final int MSG_MEDTRONIC_SEND_MANUAL_CALIB_VALUE = 9; - public static final int MSG_MEDTRONIC_SEND_GET_SENSORCAL_FACTOR = 10; - public static final int MSG_MEDTRONIC_SEND_GET_PUMP_INFO = 11; public static final int MSG_MEDTRONIC_SEND_INSTANT_CALIB_VALUE = 12; public static final int MSG_MEDTRONIC_CALIBRATION_DONE = 14; - public static final int MSG_MEDTRONIC_GLUCMEASURE_DETECTED = 15; - public static final int MSG_MEDTRONIC_GLUCMEASURE_APPROVED = 16; public static final int MSG_MEDTRONIC_FAKE = 17; @@ -93,8 +87,6 @@ public static String getCalibrationStrValue(int val){ return CALIBRATED_STR; case LAST_CALIBRATION_FAILED_USING_PREVIOUS: return LAST_CALIBRATION_FAILED_USING_PREVIOUS_STR; - case CALIBRATED_IN_15MIN: - return CALIBRATED_IN_15MIN_STR; case CALIBRATION_MORE_THAN_12H_OLD: return CALIBRATION_MORE_THAN_12H_OLD_STR; case CALIBRATING: diff --git a/app/src/main/java/com/nightscout/android/medtronic/MedtronicReader.java b/app/src/main/java/com/nightscout/android/medtronic/MedtronicReader.java index f921fea..44dae8e 100644 --- a/app/src/main/java/com/nightscout/android/medtronic/MedtronicReader.java +++ b/app/src/main/java/com/nightscout/android/medtronic/MedtronicReader.java @@ -1,15 +1,13 @@ package com.nightscout.android.medtronic; import java.text.DateFormat; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Locale; -import org.slf4j.LoggerFactory; import android.content.Context; import android.content.SharedPreferences; @@ -23,14 +21,13 @@ import android.text.TextUtils; import android.util.Log; -import ch.qos.logback.classic.Logger; - import com.nightscout.android.dexcom.USB.HexDump; import com.nightscout.android.upload.GlucometerRecord; -import com.nightscout.android.upload.MedtronicPumpRecord; import com.nightscout.android.upload.MedtronicSensorRecord; import com.nightscout.android.upload.Record; -import com.physicaloid.lib.Physicaloid; +import java.io.File; +import java.io.FileOutputStream; +import java.io.ObjectOutputStream; /** * Class: MedtronicReader This class manages all read operations over all the @@ -42,18 +39,14 @@ * */ public class MedtronicReader { - private Logger log = (Logger) LoggerFactory.getLogger(MedtronicReader.class - .getName()); private static final String TAG = MedtronicReader.class.getSimpleName(); - public Physicaloid mSerialDevice; + private Context context; protected byte[] idPump = null; protected byte[] notFinishedRead = null; - public MedtronicPumpRecord lastMedtronicPumpRecord = null;// last medtronic - // pump info - // received + public int crcErrorBytesToDiscard = 0; public boolean isCalibrating = false; public int calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; @@ -63,20 +56,13 @@ public class MedtronicReader { public long lastGlucometerDate = 0; public long lastSensorValueDate = 0; public float lastGlucometerValue = -1f; - public byte[] expectedSensorSortNumberForCalibration = { (byte) 0xff, - (byte) 0xff }; // expected indexes of the next sensor reading for - // correct calibration + public GlucometerRecord lastGlucometerRecord = null;// last glucometer // record read public byte expectedSensorSortNumber = (byte) 0xff; // expected index of the // next sensor reading - public Boolean expectedSensorSortNumberLock = false; // expectedSensorSortNumber - // Lock for - // synchronize - public float previousValue = -1f; // last sensor value read public MedtronicSensorRecord previousRecord = null; // last sensor record - public Byte lastCommandSend = null; // last command sent from this - public Object sendingCommandLock = new Object(); + // the receptor is sending a command // and we have no received the ACK @@ -93,29 +79,28 @@ public class MedtronicReader { // included). public int lastElementsAdded = 0; // last records read from sensor ArrayList mClients = new ArrayList(); - private byte[] lastGlucometerMessage = null; // last glucometer message - // received + SharedPreferences settings = null; SharedPreferences prefs = null; Integer calibrationSelected = MedtronicConstants.CALIBRATION_GLUCOMETER; - Handler mHandlerSensorCalibration = null; + private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss - "); /** * Constructor * - * @param device + * * @param context */ - public MedtronicReader(Physicaloid device, Context context, + public MedtronicReader(Context context, ArrayList mClients) { this.settings = context.getSharedPreferences( MedtronicConstants.PREFS_NAME, 0); this.mClients = mClients; - + this.context = context; knownDevices = new ArrayList(); - mSerialDevice = device; + prefs = PreferenceManager.getDefaultSharedPreferences(context); if (prefs.contains("calibrationType")) { @@ -147,10 +132,10 @@ else if ("2".equalsIgnoreCase(type)) { try { String sensorID = HexDump.toHexString(Integer.parseInt(prefs .getString("sensor_cgm_id", "0"))); - while (sensorID != null && sensorID.length() > 6) { + while (sensorID.length() > 6) { sensorID = sensorID.substring(1); } - log.debug("SensorID inserted " + Log.d(TAG, "SensorID inserted " + prefs.getString("sensor_cgm_id", "0") + " transformed to " + sensorID); knownDevices.add(sensorID); @@ -158,8 +143,6 @@ else if ("2".equalsIgnoreCase(type)) { catch(NumberFormatException nfe){ sendErrorMessageToUI("Sensor ID is incorrect - needs to be a number. Ignored."); } - - } } @@ -171,24 +154,13 @@ else if ("2".equalsIgnoreCase(type)) { MedtronicConstants.WITHOUT_ANY_CALIBRATION); if (settings.contains("isCalibrating")) isCalibrating = settings.getBoolean("isCalibrating", false); - if (settings.contains("lastGlucometerMessage") - && settings.getString("lastGlucometerMessage", "").length() > 0) - lastGlucometerMessage = HexDump.hexStringToByteArray(settings - .getString("lastGlucometerMessage", "")); + if (settings.contains("calibrationFactor")) calibrationFactor = settings.getFloat("calibrationFactor", this.calibrationFactor); if (settings.contains("lastCalibrationDate")) lastCalibrationDate = settings.getLong("lastCalibrationDate", 0); - if (settings.contains("previousValue")) - previousValue = settings.getFloat("previousValue", - this.previousValue); - if (settings.contains("expectedSensorSortNumber") - && settings.getString("expectedSensorSortNumber", "").length() > 0) { - expectedSensorSortNumber = HexDump.hexStringToByteArray(settings - .getString("expectedSensorSortNumber", ""))[0]; - } if (settings.contains("lastGlucometerValue") && settings.getFloat("lastGlucometerValue", -1) > 0) { lastGlucometerValue = settings.getFloat("lastGlucometerValue", -1); @@ -196,37 +168,14 @@ else if ("2".equalsIgnoreCase(type)) { if (settings.contains("lastGlucometerDate") && settings.getLong("lastGlucometerDate", -1) > 0) lastGlucometerDate = settings.getLong("lastGlucometerDate", -1); - if ((settings.contains("expectedSensorSortNumberForCalibration0") && settings - .getString("expectedSensorSortNumberForCalibration0", "") - .length() > 0) - && settings.contains("expectedSensorSortNumberForCalibration1") - && settings.getString( - "expectedSensorSortNumberForCalibration1", "").length() > 0) { - expectedSensorSortNumberForCalibration[0] = HexDump - .hexStringToByteArray(settings.getString( - "expectedSensorSortNumberForCalibration0", ""))[0]; - expectedSensorSortNumberForCalibration[1] = HexDump - .hexStringToByteArray(settings.getString( - "expectedSensorSortNumberForCalibration1", ""))[0]; - } else { - if (isCalibrating) { - expectedSensorSortNumberForCalibration[0] = (byte) 0x00; - expectedSensorSortNumberForCalibration[1] = (byte) 0x71; - } - } + checkCalibrationOutOfTime(); - if (settings.contains("last_read")) { - String lastRead = settings.getString("lastRead", ""); - if (lastRead.length() > 0) { - byte[] last_read = HexDump.hexStringToByteArray(lastRead); - ArrayList bufferedMessages = parseMessageData( - last_read, last_read.length); - if (bufferedMessages != null && bufferedMessages.size() > 0) - processBufferedMessages(bufferedMessages); - } - } } + public List getKnownDevices() + { + return Collections.unmodifiableList(knownDevices); + } /** * This method checks if the message received has its source in one of the * devices registered. @@ -237,7 +186,7 @@ else if ("2".equalsIgnoreCase(type)) { private boolean isMessageFromMyDevices(byte[] readData) { int initByte = firstByteOfDeviceId(readData); if (initByte < 0 || readData.length < initByte){ - log.error("Error checking initByte and received length, I can't check If is from 'My devices'"); + Log.e(TAG, "Error checking initByte and received length, I can't check If is from 'My devices'"); return false; } for (String knownDevice : knownDevices) { @@ -246,7 +195,7 @@ private boolean isMessageFromMyDevices(byte[] readData) { nBytes++; } if (readData.length < (nBytes + initByte)){ - log.error("Error checking received length, I can't check If is from 'My devices'"); + Log.e(TAG, "Error checking received length, I can't check If is from 'My devices'"); return false; } String deviceCode = HexDump.toHexString(readData, initByte, nBytes); @@ -254,7 +203,7 @@ private boolean isMessageFromMyDevices(byte[] readData) { if (knownDevice.toLowerCase().equals(deviceCode.toLowerCase())) return true; else - log.error("Current Known Device "+knownDevice+" Message Received From "+deviceCode); + Log.e(TAG, "Current Known Device "+knownDevice+" Message Received From "+deviceCode); } Log.i(TAG, "Message received from unknown device: " + HexDump.dumpHexString(readData) + " I am expecting any of: " + TextUtils.join(", ", knownDevices)); return false; @@ -263,8 +212,6 @@ private boolean isMessageFromMyDevices(byte[] readData) { private void sendMessageToUI(String valuetosend) { - DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss - "); - //get current date time with Date() Date date = new Date(); valuetosend = dateFormat.format(date) + valuetosend; Log.i(TAG, valuetosend); @@ -372,7 +319,7 @@ private void checkCalibrationOutOfTime() { calibrationStatus = MedtronicConstants.CALIBRATION_MORE_THAN_12H_OLD; SharedPreferences.Editor editor = settings.edit(); editor.putInt("calibrationStatus", calibrationStatus); - editor.commit(); + editor.apply(); } } @@ -380,237 +327,50 @@ private void checkCalibrationOutOfTime() { /** * This method reads from the serial device, and process the answer - * - * @param context - * @return String, for debug or notification purposes - */ - public ArrayList readFromReceiver(int size) { + * + * */ + public ArrayList readFromReceiver(byte[] readFromDevice) { ArrayList bufferedMessages = null; - byte[] readFromDevice = new byte[1024]; - int read = 0; - if (size >= 0) { - Log.d(TAG, "readFromReceiver: " + size + " bytes!!"); - try { - read = mSerialDevice.read(readFromDevice); - } catch (Exception e) { - Log.e(TAG, "Unable to read from serial device", e); - return null; - } - } - if (read > 0) { - Log.d(TAG, "READ " + read + " bytes: " + HexDump.dumpHexString(readFromDevice, 0, read)); - - SharedPreferences.Editor editor = settings.edit(); - editor.putLong("lastDestroy", System.currentTimeMillis()); - editor.commit(); - try { - - bufferedMessages = parseMessageData( - Arrays.copyOfRange(readFromDevice, 0, read), read); - checkCalibrationOutOfTime(); - } catch (Exception e) { - sendErrorMessageToUI(e.toString()); - bufferedMessages = new ArrayList(); - } + Log.d(TAG, "READ " + readFromDevice.length + " bytes: " + HexDump.dumpHexString(readFromDevice)); + + try { + bufferedMessages = parseMessageData( + Arrays.copyOfRange(readFromDevice, 0, readFromDevice.length), readFromDevice.length); + + checkCalibrationOutOfTime(); + + } catch (Exception e) { + sendErrorMessageToUI(e.toString()); + bufferedMessages = new ArrayList(); } return bufferedMessages; } private void processDataAnswer(byte[] readData) { - int calibrationSelectedAux; Log.d(TAG, "processDataAnswer"); - calibrationSelectedAux = calibrationSelected; - if (isMessageFromMyDevices(readData)) { Log.d(TAG, "IS FROM MY DEVICES"); switch (readData[2]) { case MedtronicConstants.MEDTRONIC_PUMP: - Log.d(TAG, "IS A PUMP MESSAGE"); - - processPumpDataMessage(readData - ); - if (lastMedtronicPumpRecord == null) { - lastMedtronicPumpRecord = new MedtronicPumpRecord(); - calculateDate(lastMedtronicPumpRecord, - new Date(), 0); - lastMedtronicPumpRecord.deviceId = prefs - .getString("medtronic_cgm_id", ""); - } - lastMedtronicPumpRecord.isWarmingUp = prefs - .getBoolean("isWarmingUp", false); + Log.d(TAG, "Pump message received"); + processPumpDataMessage(readData); break; - case MedtronicConstants.MEDTRONIC_GL: { - //if (calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER) { + case MedtronicConstants.MEDTRONIC_GL: Log.d(TAG, "GLUCOMETER DATA RECEIVED"); - if (lastGlucometerMessage == null - || lastGlucometerMessage.length == 0) { - lastGlucometerMessage = Arrays - .copyOfRange(readData, 0, - readData.length); - SharedPreferences.Editor editor = settings - .edit(); - editor.putString( - "lastGlucometerMessage", - HexDump.toHexString(lastGlucometerMessage)); - editor.commit(); - } else { - boolean isEqual = Arrays - .equals(lastGlucometerMessage, - readData); - if (isEqual - && (System.currentTimeMillis() - - lastGlucometerDate < MedtronicConstants.TIME_15_MIN_IN_MS)) { - return; - } - lastGlucometerDate = System - .currentTimeMillis(); - lastGlucometerMessage = Arrays - .copyOfRange(readData, 0, - readData.length); - } - processGlucometerDataMessage(readData); - if (lastGlucometerValue > 0) { - isCalibrating = calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER; - if (previousRecord == null) { - MedtronicSensorRecord auxRecord = new MedtronicSensorRecord(); - - auxRecord.isCalibrating = calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER; - Log.d(TAG, "No previous record - 1"); - - } else { - previousRecord.isCalibrating = calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER; - Log.d(TAG, "Has previous record - 2"); - - } - SharedPreferences.Editor editor = settings - .edit(); - - editor.putBoolean("isCalibrating", calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER); - if (calibrationSelectedAux == MedtronicConstants.CALIBRATION_GLUCOMETER) - sendMessageToUI("isCalibrating"); - sendMessageToUI("glucometer data received"); - - editor.commit(); - } - - } - break; - case MedtronicConstants.MEDTRONIC_SENSOR1: { - Log.d(TAG, "SENSOR1 DATA RECEIVED"); - if (prefs.getString("glucSrcTypes", "1") - .equals("2")) { - Log.d(TAG, "Sensor value received, but value is took only by pump logs"); - break; - } - Log.d(TAG, "WARMING_UP"); - SharedPreferences.Editor editor = settings - .edit(); - editor.remove("lastGlucometerMessage"); - editor.remove("previousValue"); - editor.remove("expectedSensorSortNumber"); - editor.remove("isCalibrating"); - calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; - editor.putInt( - "calibrationStatus", - MedtronicConstants.WITHOUT_ANY_CALIBRATION); - editor.remove("calibrationFactor"); - Log.d(TAG, "remove lastCalibrationDate"); - editor.remove("lastCalibrationDate"); - editor.remove("lastGlucometerValue"); - editor.remove("lastGlucometerDate"); - editor.remove("expectedSensorSortNumber"); - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.remove("isCheckedWUP"); - if (!prefs.getBoolean("isWarmingUp", false)) { - if (lastMedtronicPumpRecord == null) { - lastMedtronicPumpRecord = new MedtronicPumpRecord(); - calculateDate(lastMedtronicPumpRecord, - new Date(), 0); - lastMedtronicPumpRecord.deviceId = prefs - .getString("medtronic_cgm_id", - ""); - } - - editor.putBoolean("isWarmingUp", true); - - lastMedtronicPumpRecord.isWarmingUp = true; - } - - if (previousRecord == null) { - MedtronicSensorRecord auxRecord = new MedtronicSensorRecord(); - calculateDate(auxRecord, new Date(), 0); - Log.d(TAG, "no previous record - 3"); - - } else { - calculateDate(previousRecord, new Date(), 0); - Log.d(TAG, "previous record - 4"); - - } - sendMessageToUI("sensor data wUp."); - editor.commit(); break; - } + case MedtronicConstants.MEDTRONIC_SENSOR1: case MedtronicConstants.MEDTRONIC_SENSOR2: - Log.d(TAG, "SENSOR2 DATA RECEIVED"); - if (lastMedtronicPumpRecord != null) - lastMedtronicPumpRecord.isWarmingUp = false; + Log.d(TAG, "SENSOR DATA RECEIVED"); if (prefs.getString("glucSrcTypes", "1") .equals("2")) { - if (prefs.getBoolean("isWarmingUp", false)) { - if (lastMedtronicPumpRecord == null) { - lastMedtronicPumpRecord = new MedtronicPumpRecord(); - calculateDate( - lastMedtronicPumpRecord, - new Date(), 0); - lastMedtronicPumpRecord.deviceId = prefs - .getString( - "medtronic_cgm_id", - ""); - } - lastMedtronicPumpRecord.isWarmingUp = false; - SharedPreferences.Editor editor1 = prefs - .edit(); - editor1.putBoolean("isWarmingUp", false); - editor1.commit(); - } Log.d(TAG,"Sensor value received, but value is took only by pump logs"); break; } - Log.i(TAG, "process sensor2"); - log.debug("SENSOR DATA RECEIVED"); - if (prefs.getBoolean("isWarmingUp", false)) { - if (lastMedtronicPumpRecord == null) { - lastMedtronicPumpRecord = new MedtronicPumpRecord(); - calculateDate(lastMedtronicPumpRecord, - new Date(), 0); - lastMedtronicPumpRecord.deviceId = prefs - .getString("medtronic_cgm_id", - ""); - } - lastMedtronicPumpRecord.isWarmingUp = false; - SharedPreferences.Editor editor = prefs - .edit(); - editor.remove("isWarmingUp"); - editor.commit(); - } - boolean calculateCalibration = false; - if (isCalibrating) { - calculateCalibration = true; - } - processSensorDataMessage(readData); - - if (calculateCalibration && !isCalibrating) { - SharedPreferences.Editor editor = settings - .edit(); - editor.putBoolean("isCalibrating", false); - editor.commit(); - } - sendMessageToUI("sensor data value received"); + sendMessageToUI("sensor data value processed"); break; default: Log.i(TAG, "No Match"); @@ -619,7 +379,6 @@ private void processDataAnswer(byte[] readData) } else { Log.i(TAG, "I don't have to listen to this. This message comes from another source: " + HexDump.dumpHexString(readData)); - log.debug("I don't have to listen to this message. This message comes from another source."); } @@ -646,8 +405,6 @@ public void processBufferedMessages(ArrayList bufferedMessages) { break; case MedtronicConstants.COMMAND_ANSWER: Log.d(TAG, "ACK Received"); - synchronized (sendingCommandLock) { - } break; case MedtronicConstants.FILTER_COMMAND: if (readData[0] == (byte) 0x13) @@ -662,15 +419,14 @@ public void processBufferedMessages(ArrayList bufferedMessages) { } } } else { - Log.d(TAG, "CRC ERROR!!! " + HexDump.dumpHexString(readData)); + Log.d(TAG, "Invalid message start packet:" + HexDump.dumpHexString(readData)); } } } catch (Exception ex2) { + Log.e(TAG, ex2.toString(), ex2); sendErrorMessageToUI(ex2.toString()); } - SharedPreferences.Editor editor = settings.edit(); - editor.remove("last_read"); - editor.commit(); + } /** @@ -685,7 +441,7 @@ public void processBufferedMessages(ArrayList bufferedMessages) { */ private ArrayList parseMessageData(byte[] readData, int read) { byte[] readBuffer = null; - Log.d(TAG, "Parsing message"); + Log.d(TAG, "Parsing message (" + read + " bytes)"); ArrayList messageList = new ArrayList(); if (notFinishedRead == null || notFinishedRead.length <= 0) { readBuffer = Arrays.copyOf(readData, read); @@ -697,10 +453,7 @@ private ArrayList parseMessageData(byte[] readData, int read) { } notFinishedRead = null; } - SharedPreferences.Editor editor = settings.edit(); - editor.putString("last_read", HexDump.toHexString(Arrays.copyOfRange( - readBuffer, 0, readBuffer.length))); - editor.commit(); + int i = 0; if (crcErrorBytesToDiscard > 0) i = crcErrorBytesToDiscard; @@ -743,7 +496,6 @@ private ArrayList parseMessageData(byte[] readData, int read) { return messageList; } } else if (answer == MedtronicConstants.DATA_ANSWER) { - Log.d(TAG, "DATA_ANSWER"); if (readBuffer.length <= i + 1) { notFinishedRead = Arrays.copyOfRange(readBuffer, i, readBuffer.length); @@ -781,8 +533,6 @@ public void processPumpDataMessage(byte[] readData) { int commandByte = firstByteAfterDeviceId(readData); if (commandByte < 0) return; - if (lastCommandSend == null) - return; switch (readData[commandByte]) { case MedtronicConstants.MEDTRONIC_GET_LAST_PAGE: Log.d(TAG,"Pump get last page command received"); @@ -833,7 +583,6 @@ public void processPumpDataMessage(byte[] readData) { return; default: Log.e(TAG, "Undecoded Command"); - return; } } @@ -860,101 +609,90 @@ public void processGlucometerDataMessage(byte[] readData) { int ub = readData[firstMeasureByte] & 0xff; int lb = readData[firstMeasureByte + 1] & 0xff; int num = lb + (ub << 8); + + + if (lastGlucometerRecord != null + && num == lastGlucometerRecord.getValue() + && lastGlucometerDate > 0 + && (System.currentTimeMillis() - lastGlucometerDate < MedtronicConstants.TIME_15_MIN_IN_MS)) + { + Log.d(TAG, String.format("Glucometer is a repeat of previous. reading seen: %d / %.2f", num, ((float)num )/18.0)); + return; + } + sendMessageToUI(String.format("Glucometer reading seen: %d / %.2f", num, ((float)num )/18.0)); - if (num < 0 || num > 1535) { + lastGlucometerDate = System.currentTimeMillis(); + + if (num < 0 || num > 1535) { Log.e(TAG, "Glucometer value under 0 or over 0x5ff. Possible ACK or malfunction."); return; } processManualCalibrationDataMessage(num, true, false); - } - - - public void approveGlucValueForCalibration(float num, boolean calibrate, boolean isSensorFactorFromPump){ - if (!isSensorFactorFromPump) { - processManualCalibrationDataMessage(num, false, calibrate); - } - else{ - sendMessageToUI( - "Glucometer Detected!!..Waiting 15 min. to retrieve calibration factor..."); - log.debug("Glucometer Detected!!..Waiting 15 min. to retrieve calibration factor..."); - Log.d(TAG,"glucometer handler or glucometer runnable is null"); - lastGlucometerRecord = new GlucometerRecord(); - lastGlucometerRecord.numGlucometerValue = num; - lastGlucometerValue = num; - Date d = new Date(); - lastGlucometerRecord.lastDate = d.getTime(); - lastGlucometerDate = d.getTime(); - calculateDate(lastGlucometerRecord, d, 0); - SharedPreferences.Editor editor = settings.edit(); - editor.putFloat("lastGlucometerValue", lastGlucometerValue); - editor.putLong("glucometerLastDate", d.getTime()); - editor.commit(); + if (lastGlucometerValue > 0) { + if (calibrationSelected == MedtronicConstants.CALIBRATION_GLUCOMETER) + isCalibrating = true; + + if (previousRecord == null) { + MedtronicSensorRecord auxRecord = new MedtronicSensorRecord(); + + auxRecord.isCalibrating = isCalibrating; + writeLocalCSV(auxRecord, context); + Log.d(TAG, "No previous record - 1"); + + } else { + previousRecord.isCalibrating = isCalibrating; + writeLocalCSV(previousRecord, context); + Log.d(TAG, "Has previous record - 2"); + + } + SharedPreferences.Editor editor = settings + .edit(); + + editor.putBoolean("isCalibrating", isCalibrating); + if (isCalibrating) sendMessageToUI("Glucometer data received - and calibrating from it"); + else sendMessageToUI("Glucometer data received - to use for calibration, go to manual/instant calibration"); + + editor.apply(); } } + + + /** * This method process the Manual Calibration message * - * @param readData - * @return String, for debug or notification purposes */ public void processManualCalibrationDataMessage(float value, boolean instant, boolean doCalibration) { - float mult = 1f; - //if (prefs.getBoolean("mmolxl", false)) - //mult = 1f/18f; - float num = value * mult; + + float num = value; lastGlucometerRecord = new GlucometerRecord(); lastGlucometerRecord.numGlucometerValue = num; lastGlucometerValue = num; Date d = new Date(); - lastGlucometerRecord.lastDate = d.getTime(); + lastGlucometerRecord.setDate(d); lastGlucometerDate = d.getTime(); - calculateDate(lastGlucometerRecord, d, 0); - if (!instant && doCalibration) { - if (HexDump.unsignedByte(expectedSensorSortNumber) == HexDump - .unsignedByte((byte) 0xff)) { - expectedSensorSortNumberForCalibration[0] = (byte) 0x00; - expectedSensorSortNumberForCalibration[1] = (byte) 0x71; - } else { - synchronized (expectedSensorSortNumberLock) { - byte expectedAux = expectedSensorSortNumber; - if ((expectedSensorSortNumber & (byte) 0x01) > 0) - expectedAux = (byte) (expectedSensorSortNumber & (byte) 0xFE); - expectedSensorSortNumberForCalibration[0] = calculateNextSensorSortNameFrom( - 6, expectedAux); - expectedSensorSortNumberForCalibration[1] = calculateNextSensorSortNameFrom( - 10, expectedAux); - } - } - } + + SharedPreferences.Editor editor = settings.edit(); editor.putFloat("lastGlucometerValue", num); editor.putLong("glucometerLastDate", d.getTime()); - if (!instant && doCalibration) { - editor.putString("expectedSensorSortNumberForCalibration0", HexDump - .toHexString(expectedSensorSortNumberForCalibration[0])); - editor.putString("expectedSensorSortNumberForCalibration1", HexDump - .toHexString(expectedSensorSortNumberForCalibration[1])); - } else { - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - } + if (lastGlucometerValue > 0) { isCalibrating = !instant && doCalibration; if (previousRecord == null) { MedtronicSensorRecord auxRecord = new MedtronicSensorRecord(); auxRecord.isCalibrating = !instant; - log.debug("8"); + } else { previousRecord.isCalibrating = !instant; - log.debug("9"); + } editor.putBoolean("isCalibrating", !instant); - editor.commit(); } - editor.commit(); + editor.apply(); Log.i(TAG, "Manual calibration:" + num); } @@ -964,67 +702,61 @@ public void processManualCalibrationDataMessage(float value, * * @param previousCalibrationFactor * @param previousCalibrationStatus - * @param isig * @param record * @param added * @param currentTime */ private void calibratingBackwards(float previousCalibrationFactor, - int previousCalibrationStatus, float isig, + int previousCalibrationStatus, MedtronicSensorRecord record, int added, Date currentTime) { if (previousCalibrationFactor > 0) { + record.setUnfilteredGlucose(record.isig * previousCalibrationFactor); + record.setBGValue((applyFilterToRecord(record)) ); + record.isCalibrating = false; + record.calibrationFactor = previousCalibrationFactor; if (previousCalibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION) { - record.setUnfilteredGlucose(isig * previousCalibrationFactor); - record.setBGValue((applyFilterToRecord(record)) + ""); - record.isCalibrating = false; - record.calibrationFactor = previousCalibrationFactor; record.calibrationStatus = previousCalibrationStatus; } else { - record.setUnfilteredGlucose(isig * previousCalibrationFactor); - record.setBGValue((applyFilterToRecord(record)) + ""); - record.isCalibrating = false; - record.calibrationFactor = previousCalibrationFactor; record.calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; } } - calculateDate(record, currentTime, added); + setRecordDateHistoric(record, currentTime, added); } /** * Apply calibration to the "current" value of the sensor message * * @param difference - * @param isig - * @param readData - * @param index + * @param record * @param num * @param currentTime */ - private void calibratingCurrentElement(long difference, float isig, - byte[] readData, int index, MedtronicSensorRecord record, int num, + private void calibratingCurrentElement(long difference, MedtronicSensorRecord record, int num, Date currentTime) { boolean calibrated = false; - // currentMeasure = num; if (isCalibrating) { if (num > 0) { - calculateCalibration(difference, isig, readData[index]); + calculateCalibration(difference, record.isig); + + record.isCalibrating = isCalibrating; + record.calibrationStatus = calibrationStatus; + if (calibrationFactor > 0) { if (!isCalibrating) { if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION && calibrationStatus != MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS && calibrationStatus != MedtronicConstants.CALIBRATION_MORE_THAN_12H_OLD) { - record.setBGValue(((int) lastGlucometerValue) + ""); + record.setBGValue( lastGlucometerValue ); record.setUnfilteredGlucose(lastGlucometerValue); record.calibrationFactor = calibrationFactor; - record.isCalibrating = false; - record.calibrationStatus = calibrationStatus; + lastCalibrationDate = currentTime.getTime(); SharedPreferences.Editor editor = settings.edit(); - log.debug("change lastCalibrationDate"); + editor.putLong("lastCalibrationDate", lastCalibrationDate); - editor.commit(); + editor.apply(); calibrated = true; } } @@ -1032,67 +764,52 @@ private void calibratingCurrentElement(long difference, float isig, } } if (calibrationFactor > 0 && !calibrated) { - + record.setUnfilteredGlucose(record.isig * calibrationFactor); + record.setBGValue(applyFilterToRecord(record)); + record.isCalibrating = false; + record.calibrationFactor = calibrationFactor; if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION) { - record.setUnfilteredGlucose(isig * calibrationFactor); - record.setBGValue((applyFilterToRecord(record)) + ""); - record.isCalibrating = false; - record.calibrationFactor = calibrationFactor; record.calibrationStatus = calibrationStatus; } else { - record.setUnfilteredGlucose(isig * calibrationFactor); - record.setBGValue((applyFilterToRecord(record)) + ""); - record.isCalibrating = false; - record.calibrationFactor = calibrationFactor; record.calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; } } - calculateDate(record, currentTime, 0); + record.setDate(currentTime); previousRecord = record; } + /* + + Apply calibration to all upcoming data, immediately. + + */ public void calculateInstantCalibration(float currentMeasure) { - log.debug("Instant Calibration"); if (previousRecord != null && previousRecord.isig != 0) { - log.debug("I have isig " + previousRecord.isig); calibrationFactor = currentMeasure / previousRecord.isig; - log.debug("Instant Calibration result " + calibrationFactor); + Log.d(TAG,"Instant Calibration result " + calibrationFactor + "; ISIG is " + previousRecord.isig); if (calibrationFactor > 0) { - previousRecord.bGValue = "" + ((int) currentMeasure); - log.debug("Instant Calibration Success!! "); + previousRecord.setBGValue(currentMeasure); calibrationStatus = MedtronicConstants.CALIBRATED; lastCalibrationDate = System.currentTimeMillis(); isCalibrating = false; previousRecord.isCalibrating = false; previousRecord.calibrationStatus = calibrationStatus; - log.debug("10"); + + writeLocalCSV(previousRecord, context); SharedPreferences.Editor editor = settings.edit(); - log.debug("change instant lastCalibrationDate"); + editor.putLong("lastCalibrationDate", lastCalibrationDate); - editor.putBoolean("isCalibrating", false); + editor.putBoolean("isCalibrating", isCalibrating); editor.putFloat("calibrationFactor", calibrationFactor); - editor.putInt("calibrationStatus", - calibrationStatus); - editor.commit(); + editor.putInt("calibrationStatus", calibrationStatus); + editor.apply(); } - return; - } else{ - sendErrorMessageToUI("I can't calibrate, I don't have any ISIG stored yet."); - log.debug("I dont have isig"); } - if (previousRecord == null) - previousRecord = new MedtronicSensorRecord(); - if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION - && calibrationFactor != -1f) { - calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; - } else { - calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; + else { + sendErrorMessageToUI("I can't calibrate, I don't have any recent stored sensor reading yet. Try after sensor transmits again."); + Log.d(TAG,"Could not instant calibrate. I dont have ISIG from a previous record yet."); } - previousRecord.calibrationStatus = calibrationStatus; - log.debug("11"); - - log.debug("Instant Calibration Failure!! "); } /** @@ -1108,10 +825,9 @@ public void processSensorDataMessage(byte[] readData) { difference = d.getTime() - lastGlucometerDate; } - int added = 8; + int backcountToBeAdded; int firstMeasureByte = firstByteAfterDeviceId(readData); - int currentMeasure = -1; - float isig = 0; + if (firstMeasureByte < 0) return; @@ -1123,97 +839,32 @@ public void processSensorDataMessage(byte[] readData) { float previousCalibrationFactor = calibrationFactor; short adjustement = (short) readData[firstMeasureByte + 2]; long firstTimeOut = d.getTime() - lastSensorValueDate; - if (expectedSensorSortNumber == (byte) 0xff - || lastSensorValueDate == 0 - || (firstTimeOut >= MedtronicConstants.TIME_10_MIN_IN_MS)) { - Log.i("Medtronic", "First reading - or missed last 40 minutes - Backfilling old data"); - - lastElementsAdded = 0; - // I must read ALL THE MEASURES - synchronized (expectedSensorSortNumberLock) { - expectedSensorSortNumber = readData[firstMeasureByte + 3]; - } - - for (int i = 20; i >= 0; i -= 2) { - if (i >= 4 && i < 8) { - continue; - } - lastElementsAdded++; - int ub = readData[firstMeasureByte + 4 + i] & 0xff; - int lb = readData[firstMeasureByte + 5 + i] & 0xff; - int num = lb + (ub << 8); - - MedtronicSensorRecord record = new MedtronicSensorRecord(); - record.isCalibrating = isCalibrating; - isig = calculateISIG(num, adjustement); - record.setIsig(isig); - if (i == 0) { - currentMeasure = num; - calibratingCurrentElement(difference, isig, readData, - firstMeasureByte + 3, record, num, d); - } else { - calibratingBackwards(previousCalibrationFactor, - previousCalibrationStatus, isig, record, added, d); - } - added--; - lastRecordsInMemory.add(record); - calculateTrendAndArrow(record, lastRecordsInMemory); - - } - - } else { + int dataLost = 0; + if (expectedSensorSortNumber == readData[firstMeasureByte + 3] && isSensorRepeatedMessage(expectedSensorSortNumber)) { + Log.d(TAG, "Sensor repeat of previously read reading, ignored"); // ignore - we saw its previous entry + // nothing to add! + } + else { if (expectedSensorSortNumber == readData[firstMeasureByte + 3] - ||calculateNextSensorSortNameFrom(1, expectedSensorSortNumber) == readData[firstMeasureByte + 3]) { + || calculateNextSensorSortNameFrom(1, expectedSensorSortNumber) == readData[firstMeasureByte + 3]) { // is either the one we need, or the repeat message we need Log.i("Medtronic", "Expected sensor number received!!"); - - lastElementsAdded = 0; - // I must read only the first value except if byte ends in "1" - // then I skip this value - if (!isSensorRepeatedMessage(readData[firstMeasureByte + 3]) - || HexDump - .unsignedByte((byte) (expectedSensorSortNumber & (byte) 0x01)) < 1 - && HexDump - .unsignedByte((byte) (readData[firstMeasureByte + 3] & (byte) 0x01)) == 1) { - - int ub = readData[firstMeasureByte + 4] & 0xff; - int lb = readData[firstMeasureByte + 5] & 0xff; - int num = lb + (ub << 8); - - Log.d(TAG, "Read from sensor: value is " + num); - MedtronicSensorRecord record = new MedtronicSensorRecord(); - isig = calculateISIG(num, adjustement); - record.setIsig(isig); - record.isCalibrating = isCalibrating; - currentMeasure = num; - calibratingCurrentElement(difference, isig, readData, - firstMeasureByte + 3, record, num, d); - lastRecordsInMemory.add(record); - calculateTrendAndArrow(record, lastRecordsInMemory); - - lastElementsAdded++; - } else { - // sendMessageToUI("ES REPETIDO NO LO EVALUO ", false); - synchronized (expectedSensorSortNumberLock) { - expectedSensorSortNumber = calculateNextSensorSortNameFrom( - 1, expectedSensorSortNumber); - } - return; - } + dataLost = 0; + backcountToBeAdded = 0; } else { - Log.i("Medtronic", "NOT Expected sensor number received!!"); - log.debug("SENSOR MEASURE, NOT Expected sensor measure received!!"); - int dataLost = -1; + Log.i(TAG, "NOT Expected sensor number received nor immediate sensor repeat!!"); if (previousRecord != null || lastSensorValueDate > 0) { long timeDiff = 0; - if (previousRecord != null) - timeDiff = d.getTime() - previousRecord.displayDateTime; + + if (previousRecord != null && previousRecord.getDate() != null) + timeDiff = d.getTime() - previousRecord.getDate().getTime(); else timeDiff = d.getTime() - lastSensorValueDate; + if (timeDiff > (MedtronicConstants.TIME_30_MIN_IN_MS + MedtronicConstants.TIME_10_MIN_IN_MS)) { dataLost = 10; - added = 8; + backcountToBeAdded = 8; } else { int valPrev = transformSequenceToIndex(expectedSensorSortNumber); int currentVal = transformSequenceToIndex(readData[firstMeasureByte + 3]); @@ -1223,104 +874,74 @@ public void processSensorDataMessage(byte[] readData) { if (dataLost < 0) dataLost *= -1; dataLost--; - added = dataLost; + backcountToBeAdded = dataLost; Log.i(TAG, " valPrev " + valPrev + " currentVal " + currentVal + " dataLost " - + dataLost + " added " + added); + + dataLost + " added " + backcountToBeAdded); + + if (dataLost > (int) (timeDiff / 60 / 1000 / 5)) { + dataLost = (int) (timeDiff / 60 / 1000 / 5); + } } } else { dataLost = 10; - added = 8; + backcountToBeAdded = 8; } + Log.i(TAG, "Data Lost " + dataLost); if (dataLost >= 0) { if (dataLost >= 2) dataLost += 2; if (dataLost > 10) { dataLost = 10; - added = 8; + backcountToBeAdded = 8; } - log.debug("SENSOR MEASURE, I am going to retrieve " - + (dataLost) + " previous values"); dataLost *= 2; lastElementsAdded = 0; // I must read ALL THE MEASURES - if (dataLost == 20 || dataLost == 0) { - synchronized (expectedSensorSortNumberLock) { - expectedSensorSortNumber = readData[firstMeasureByte + 3]; - } - } - - for (int i = dataLost; i >= 0; i -= 2) { - if (i >= 4 && i < 8) { - continue; - } - lastElementsAdded++; - - int ub = readData[firstMeasureByte + 4 + i] & 0xff; - int lb = readData[firstMeasureByte + 5 + i] & 0xff; - int num = lb + (ub << 8); - MedtronicSensorRecord record = new MedtronicSensorRecord(); - record.isCalibrating = isCalibrating; - isig = calculateISIG(num, adjustement); - record.setIsig(isig); - if (i == 0) { - currentMeasure = num; - calibratingCurrentElement(difference, isig, - readData, firstMeasureByte + 3, record, - num, d); - } else { - calibratingBackwards(previousCalibrationFactor, - previousCalibrationStatus, isig, record, - added, d); - } - added--; - lastRecordsInMemory.add(record); - calculateTrendAndArrow(record, lastRecordsInMemory); + } + } - } + for (int i = dataLost; i >= 0; i -= 2) { + if (i >= 4 && i < 8) { + continue; + } + int ub = readData[firstMeasureByte + 4 + i] & 0xff; + int lb = readData[firstMeasureByte + 5 + i] & 0xff; + int num = lb + (ub << 8); + MedtronicSensorRecord record = new MedtronicSensorRecord(); + record.isCalibrating = isCalibrating; + record.setIsig(calculateISIG(num, adjustement)); + if (i == 0) { + calibratingCurrentElement(difference, record, num, d); } else { - - int ub = readData[firstMeasureByte + 4] & 0xff; - int lb = readData[firstMeasureByte + 5] & 0xff; - int num = lb + (ub << 8); - - MedtronicSensorRecord record = new MedtronicSensorRecord(); - isig = calculateISIG(num, adjustement); - record.setIsig(isig); - record.isCalibrating = isCalibrating; - currentMeasure = num; - calibratingCurrentElement(difference, isig, readData, - firstMeasureByte + 3, record, num, d); - lastRecordsInMemory.add(record); - calculateTrendAndArrow(record, lastRecordsInMemory); - - lastElementsAdded++; + calibratingBackwards(previousCalibrationFactor, + previousCalibrationStatus, record, + backcountToBeAdded, d); } + backcountToBeAdded--; + lastElementsAdded++; + lastRecordsInMemory.add(record); + previousRecord = record; + calculateTrendAndArrow(record, lastRecordsInMemory); + + Log.v(TAG, "Read Record: backposition [" + (backcountToBeAdded + 1) + "] " + record.getBGValue() + " / " + dateFormat.format(record.getDate())); } - Log.i("Medtronic", "Fill next expected"); - expectedSensorSortNumber = readData[firstMeasureByte + 3]; } - previousValue = currentMeasure; + // I must recalculate next message!!!! - synchronized (expectedSensorSortNumberLock) { - expectedSensorSortNumber = calculateNextSensorSortNameFrom(1, - expectedSensorSortNumber); - } + expectedSensorSortNumber = readData[firstMeasureByte + 3]; + expectedSensorSortNumber = calculateNextSensorSortNameFrom(1, + expectedSensorSortNumber); + SharedPreferences.Editor editor = settings.edit(); - editor.putFloat("previousValue", previousValue); - editor.putString("expectedSensorSortNumber", - HexDump.toHexString(expectedSensorSortNumber)); + editor.putInt("calibrationStatus", calibrationStatus); lastSensorValueDate = d.getTime(); editor.putLong("lastSensorValueDate", lastSensorValueDate); - editor.commit(); - log.debug("12"); - - Log.i("Medtronic", "BYE!!!!"); - log.debug("sensorprocessed end expected " - + HexDump.toHexString(expectedSensorSortNumber)); + editor.apply(); + writeLocalCSV(previousRecord, context); } @@ -1363,37 +984,6 @@ private int transformSequenceToIndex(byte aux) { return (seq == 0) ? 8 : seq; } - /** - * This function checks if the measure index is between a range of indexes - * previously stored. - * - * @param measureIndex - * , index to check - * @param range - * , - * @return true if the measure index is between a range of indexes - * previously stored. - */ - private boolean isSensorMeasureInRange(byte measureIndex, byte[] range) { - byte minRange = range[0]; - byte maxRange = range[1]; - if (HexDump.unsignedByte(maxRange) < HexDump.unsignedByte(minRange)) { - return ((HexDump.unsignedByte(measureIndex) >= HexDump - .unsignedByte(minRange)) && (HexDump - .unsignedByte(measureIndex) <= HexDump - .unsignedByte((byte) 0x71))) - || (HexDump.unsignedByte(measureIndex) <= HexDump - .unsignedByte(maxRange)) - && (HexDump.unsignedByte(measureIndex) >= HexDump - .unsignedByte((byte) 0x00)); - } else { - return (HexDump.unsignedByte(measureIndex) >= HexDump - .unsignedByte(minRange)) - && (HexDump.unsignedByte(measureIndex) <= HexDump - .unsignedByte(maxRange)); - } - } - /** * This method calculates the date of the sensor readings @@ -1406,7 +996,7 @@ private boolean isSensorMeasureInRange(byte measureIndex, byte[] range) { * , index of this reading respectively the initTime reading. * Each increment subtracts 5 minutes to "initTime" */ - public void calculateDate(Record record, Date initTime, int subtract) { + public void setRecordDateHistoric(Record record, Date initTime, int subtract) { long milliseconds = initTime.getTime(); @@ -1428,99 +1018,46 @@ public void calculateDate(Record record, Date initTime, int subtract) { * if (!tz.inDaylightTime(new Date())) timeAdd = timeAdd - 3600000L; */ Date display = new Date(timeAdd); - record.displayTime = new SimpleDateFormat("MM/dd/yyy hh:mm:ss aa", - Locale.getDefault()).format(display); + if (record instanceof MedtronicSensorRecord) { - ((MedtronicSensorRecord) record).displayDateTime = display - .getTime(); + ((MedtronicSensorRecord) record).setDate(display); } } /** - * This method checks if a calibration is valid. + * This method checks if it is time to use the current sensor as the calibration value. * * @param difference * @param currentMeasure - * @param currentIndex */ - private void calculateCalibration(long difference, float currentMeasure, - byte currentIndex) { + private void calculateCalibration(long difference, float currentMeasure) { + SharedPreferences.Editor editor = settings.edit(); + if (difference >= MedtronicConstants.TIME_15_MIN_IN_MS - && difference < MedtronicConstants.TIME_20_MIN_IN_MS) { - if (isSensorMeasureInRange(currentIndex, - expectedSensorSortNumberForCalibration)) { - isCalibrating = false; - calibrationStatus = MedtronicConstants.CALIBRATED; - calibrationIsigValue = currentMeasure; - SharedPreferences.Editor editor = settings.edit(); - calibrationFactor = lastGlucometerValue / calibrationIsigValue; - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.putFloat("calibrationFactor", calibrationFactor); - editor.putInt("calibrationStatus", - calibrationStatus); - editor.commit(); - } else { - if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION - && currentIndex != expectedSensorSortNumber) { - calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; - isCalibrating = false; - } else { - calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; - } - SharedPreferences.Editor editor = settings.edit(); - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.commit(); - } - } else if (difference >= MedtronicConstants.TIME_20_MIN_IN_MS) { - if (isSensorMeasureInRange(currentIndex, - expectedSensorSortNumberForCalibration)) { - calibrationStatus = MedtronicConstants.CALIBRATED_IN_15MIN; - calibrationIsigValue = currentMeasure; - SharedPreferences.Editor editor = settings.edit(); - calibrationFactor = lastGlucometerValue / calibrationIsigValue; - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.putFloat("calibrationFactor", calibrationFactor); - editor.putInt("calibrationStatus", - calibrationStatus); - editor.commit(); - } else { - if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION) - calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; - else { - calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; - } - SharedPreferences.Editor editor = settings.edit(); - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.commit(); - } + && difference < MedtronicConstants.TIME_30_MIN_IN_MS) { + isCalibrating = false; + calibrationStatus = MedtronicConstants.CALIBRATED; + calibrationIsigValue = currentMeasure; + calibrationFactor = lastGlucometerValue / calibrationIsigValue; + editor.putFloat("calibrationFactor", calibrationFactor); + + } + else if (difference >= MedtronicConstants.TIME_30_MIN_IN_MS) { + if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION) + calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; + else + calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; isCalibrating = false; - } else { - if (isCalibrating){ - if (difference < MedtronicConstants.TIME_5_MIN_IN_MS) { - calibrationStatus = MedtronicConstants.CALIBRATING; - } else if (difference >= MedtronicConstants.TIME_5_MIN_IN_MS - && difference <= MedtronicConstants.TIME_15_MIN_IN_MS) - calibrationStatus = MedtronicConstants.CALIBRATING2; - else - calibrationStatus = MedtronicConstants.CALIBRATING; - }else{ - if (calibrationStatus != MedtronicConstants.WITHOUT_ANY_CALIBRATION) - calibrationStatus = MedtronicConstants.LAST_CALIBRATION_FAILED_USING_PREVIOUS; - else { - calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; - } - SharedPreferences.Editor editor = settings.edit(); - editor.remove("expectedSensorSortNumberForCalibration0"); - editor.remove("expectedSensorSortNumberForCalibration1"); - editor.putInt("calibrationStatus", - calibrationStatus); - editor.commit(); - } } + else if (difference <= MedtronicConstants.TIME_5_MIN_IN_MS){ + calibrationStatus = MedtronicConstants.CALIBRATING; + } + else { + calibrationStatus = MedtronicConstants.CALIBRATING2; + } + + editor.putInt("calibrationStatus", calibrationStatus); + editor.apply(); } /** @@ -1534,16 +1071,9 @@ private void calculateCalibration(long difference, float currentMeasure, */ public Float getGlucoseDifferentialIn(int size, CircleList list) { List auxList = list.getListFromTail(size); - SimpleDateFormat formatter = new SimpleDateFormat( - "MM/dd/yyyy hh:mm:ss a", Locale.getDefault()); if (auxList.size() == size) { Log.d(TAG, "I Have the correct size"); - for (int i = 1; i < size; i++) { - if (!(auxList.get(i) instanceof MedtronicSensorRecord)) { - Log.d(TAG, "but not the correct records"); - return null; - } - } + float diff = 0; long dateDif = 0; for (int i = 1; i < size; i++) { @@ -1552,29 +1082,17 @@ public Float getGlucoseDifferentialIn(int size, CircleList list) { .get(i - 1); MedtronicSensorRecord record = (MedtronicSensorRecord) auxList .get(i); - Date prevDate = null; - Date date = null; - try { - prevDate = formatter.parse(prevRecord.displayTime); - date = formatter.parse(record.displayTime); - dateDif += (prevDate.getTime() - date.getTime()); - Log.d(TAG, "DATE_diff " + dateDif); - } catch (ParseException e1) { - Log.e(TAG, "Bad current or previous value for date", e1); - } + + Date prevDate = prevRecord.getDate(); + Date date = record.getDate(); + dateDif += (prevDate.getTime() - date.getTime()); float prevRecordValue = 0; float recordValue = 0; - try { - prevRecordValue = Float.parseFloat(prevRecord.bGValue); - } catch (Exception e) { - Log.e(TAG, "Bad previous bGValue: " + prevRecord.bGValue, e); - } - try { - recordValue = Float.parseFloat(record.bGValue); - } catch (Exception e) { - Log.e(TAG, "Bad current bGValue: " + record.bGValue, e); - } + + prevRecordValue = prevRecord.getBGValue(); + recordValue = record.getBGValue(); + if (prevRecordValue > 0 && recordValue <= 0) { Log.d(TAG, "AdjustRecordValue prev " + prevRecordValue @@ -1732,7 +1250,6 @@ else if ((diff > 0.06f) && (diff <= 0.11f)) { * @param valuetosend */ private void sendErrorMessageToUI(String valuetosend) { - DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss - "); //get current date time with Date() Date date = new Date(); valuetosend = dateFormat.format(date) + valuetosend; @@ -1827,8 +1344,7 @@ public List getListFromTail(int size) { synchronized (listLock) { auxEndOffset = endOffset; auxStartOffset = startOffset; - aux = new ArrayList(); - aux.addAll(list); + aux = new ArrayList(list); } int auxSize = size; @@ -1889,4 +1405,27 @@ public void run() { } } + + private void writeLocalCSV(MedtronicSensorRecord mostRecentData, + Context context) { + + // Write EGV Binary of last (most recent) data + try { + if (mostRecentData == null || mostRecentData.getBGValue() == 0) + Log.d(TAG, "writeLocalCSV SAVING EMPTY!!"); + else + Log.d(TAG, "writeLocalCSV SAVING --> " + mostRecentData.getBGValue()); + ObjectOutputStream oos = new ObjectOutputStream( + new FileOutputStream(new File(context.getFilesDir(), + "save.bin"))); // Select where you wish to save the + // file... + oos.writeObject(mostRecentData); // write the class as an 'object' + oos.flush(); // flush the stream to insure all of the information + // was written to 'save.bin' + oos.close();// close the stream + } catch (Exception e) { + Log.e(TAG, "write to OutputStream failed", e); + } + } + } diff --git a/app/src/main/java/com/nightscout/android/upload/GlucometerRecord.java b/app/src/main/java/com/nightscout/android/upload/GlucometerRecord.java index c6cd6bc..6b64426 100644 --- a/app/src/main/java/com/nightscout/android/upload/GlucometerRecord.java +++ b/app/src/main/java/com/nightscout/android/upload/GlucometerRecord.java @@ -4,8 +4,10 @@ public class GlucometerRecord extends Record implements Serializable{ public float numGlucometerValue = 0; - public long lastDate = 0; private static final long serialVersionUID = 4654897648L; + public float getValue() { + return numGlucometerValue; + } } diff --git a/app/src/main/java/com/nightscout/android/upload/MedtronicSensorRecord.java b/app/src/main/java/com/nightscout/android/upload/MedtronicSensorRecord.java index d933a6f..a31bfc2 100644 --- a/app/src/main/java/com/nightscout/android/upload/MedtronicSensorRecord.java +++ b/app/src/main/java/com/nightscout/android/upload/MedtronicSensorRecord.java @@ -14,8 +14,7 @@ public class MedtronicSensorRecord extends EGVRecord { public int calibrationStatus = MedtronicConstants.WITHOUT_ANY_CALIBRATION; public float unfilteredGlucose = 0; public boolean isCalibrating = false; - public long displayDateTime = 0; - + public void setIsig(float isig) { this.isig = isig; @@ -29,7 +28,5 @@ public void setCalibrationStatus(int calibrationStatus) { public void setUnfilteredGlucose(float unfilteredGlucose) { this.unfilteredGlucose = unfilteredGlucose; } - public long getDisplayDateTime() { - return displayDateTime; - } + } diff --git a/app/src/main/java/com/nightscout/android/upload/Record.java b/app/src/main/java/com/nightscout/android/upload/Record.java index e2d70b7..da6df5b 100644 --- a/app/src/main/java/com/nightscout/android/upload/Record.java +++ b/app/src/main/java/com/nightscout/android/upload/Record.java @@ -1,17 +1,26 @@ package com.nightscout.android.upload; import java.io.Serializable; +import java.util.Date; public class Record implements Serializable { - public String displayTime = "---"; + + private Date date; + + public void setDate(Date d) + { + date = d; + } + + public Date getDate() + { + return date; + } /** * */ private static final long serialVersionUID = -1381174446348390503L; - public void setDisplayTime (String input) { - this.displayTime = input; - } } diff --git a/app/src/main/java/com/nightscout/android/upload/UploadHelper.java b/app/src/main/java/com/nightscout/android/upload/UploadHelper.java index 4954701..20ba87a 100644 --- a/app/src/main/java/com/nightscout/android/upload/UploadHelper.java +++ b/app/src/main/java/com/nightscout/android/upload/UploadHelper.java @@ -1,82 +1,44 @@ package com.nightscout.android.upload; -import java.security.MessageDigest; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import org.apache.http.client.ResponseHandler; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.BasicResponseHandler; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.json.JSONArray; -import org.json.JSONObject; - -import org.slf4j.LoggerFactory; - import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; import android.preference.PreferenceManager; import android.util.Log; -import ch.qos.logback.classic.Logger; - import com.nightscout.android.dexcom.DexcomG4Activity; import com.nightscout.android.dexcom.EGVRecord; -import com.nightscout.android.medtronic.MedtronicConstants; -import com.nightscout.android.medtronic.MedtronicReader; -public class UploadHelper extends AsyncTask { +import org.json.JSONObject; - private Logger log = (Logger) LoggerFactory.getLogger(MedtronicReader.class.getName()); - private static final String TAG = "UploadHelper"; - private SharedPreferences settings = null;// common application preferences - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss aa", Locale.getDefault()); - private static final int SOCKET_TIMEOUT = 60 * 1000; - private static final int CONNECTION_TIMEOUT = 30 * 1000; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.ProtocolException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; - Context context; +public class UploadHelper extends AsyncTask { - private List recordsNotUploadedListJson = new ArrayList(); - public static Object isModifyingRecordsLock = new Object(); + private static final String TAG = "UploadHelper"; + private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss aa", Locale.getDefault()); + private static final int READ_TIMEOUT = 30 * 1000; + private static final int CONNECTION_TIMEOUT = 30 * 1000; + private String baseURLSettings; public UploadHelper(Context context) { - this.context = context; - settings = context.getSharedPreferences(MedtronicConstants.PREFS_NAME, 0); - synchronized (isModifyingRecordsLock) { - try { - long currentTime = System.currentTimeMillis(); - long diff = currentTime - settings.getLong("lastDestroy", 0); - if (diff != currentTime && diff > (6 * MedtronicConstants.TIME_60_MIN_IN_MS)) { - Log.d(TAG, "Remove older records"); - recordsNotUploadedListJson = new ArrayList(); - } - else { - JSONArray recordsNotUploadedJson = new JSONArray(settings.getString("recordsNotUploadedJson", "[]")); - for (int i = 0; i < recordsNotUploadedJson.length(); i++) { - recordsNotUploadedListJson.add(recordsNotUploadedJson.getJSONObject(i)); - } - Log.d(TAG, "retrieved older json records -->" + recordsNotUploadedJson.length()); - } - } catch (Exception e) { - recordsNotUploadedListJson = new ArrayList(); - } - - SharedPreferences.Editor editor = settings.edit(); - if (settings.contains("recordsNotUploadedJson")) - editor.remove("recordsNotUploadedJson"); - editor.commit(); - } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + baseURLSettings = prefs.getString("API Base URL", ""); } @@ -93,34 +55,28 @@ private String getSelectedDeviceName() { */ protected Long doInBackground(Record... records) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.context); try { long start = System.currentTimeMillis(); Log.i(TAG, String.format("Starting upload of %s record using a REST API", records.length)); - log.info(String.format("Starting upload of %s record using a REST API", records.length)); - doRESTUpload(prefs, records); + doRESTUpload(records); Log.i(TAG, String.format("Finished upload of %s record using a REST API in %s ms", records.length, System.currentTimeMillis() - start)); - log.info(String.format("Finished upload of %s record using a REST API in %s ms", records.length, System.currentTimeMillis() - start)); } catch (Exception e) { - log.error("ERROR uploading data!!!!!", e); + Log.e(TAG, "ERROR uploading data!!!!!", e); } - return 1L; } protected void onPostExecute(Long result) { super.onPostExecute(result); Log.i(TAG, "Post execute, Result: " + result + ", Status: FINISHED"); - log.info("Post execute, Result: " + result + ", Status: FINISHED"); - } - private void doRESTUpload(SharedPreferences prefs, Record... records) { - String baseURLSettings = prefs.getString("API Base URL", ""); - ArrayList baseURIs = new ArrayList(); + private void doRESTUpload(Record... records) { + + ArrayList baseURIs = new ArrayList<>(); try { for (String baseURLSetting : baseURLSettings.split(" ")) { @@ -130,7 +86,6 @@ private void doRESTUpload(SharedPreferences prefs, Record... records) { } } catch (Exception e) { Log.e(TAG, "Unable to process API Base URL setting: " + baseURLSettings, e); - log.error("Unable to process API Base URL setting: " + baseURLSettings, e); return; } @@ -139,18 +94,16 @@ private void doRESTUpload(SharedPreferences prefs, Record... records) { doRESTUploadTo(baseURI, records); } catch (Exception e) { Log.e(TAG, "Unable to do REST API Upload to: " + baseURI, e); - log.error("Unable to do REST API Upload to: " + baseURI, e); } } } private void doRESTUploadTo(String baseURI, Record[] records) throws Exception { - int apiVersion = 1; + if (!baseURI.endsWith("/v1/")) throw new Exception("REST API URL must start end with /v1/"); - Integer typeSaved = null; try { String baseURL = null; @@ -158,6 +111,7 @@ private void doRESTUploadTo(String baseURI, Record[] records) throws Exception { String[] uriParts = baseURI.split("@"); String error = null; + //noinspection IfCanBeSwitch if (uriParts.length == 1) { error = "Passphrase is required in REST API URL"; } else if (uriParts.length == 2) { @@ -180,194 +134,196 @@ private void doRESTUploadTo(String baseURI, Record[] records) throws Exception { } if (error != null) { - JSONArray jsonArray = new JSONArray(recordsNotUploadedListJson); - SharedPreferences.Editor editor = settings.edit(); - editor.putString("recordsNotUploadedJson", jsonArray.toString()); - editor.commit(); throw new Exception(error); } - HttpParams params = new BasicHttpParams(); - HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT); - HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT); + postDeviceStatus(baseURL); - DefaultHttpClient httpclient = new DefaultHttpClient(params); + for (Record record : records) { - postDeviceStatus(baseURL, httpclient); + String postURL = determineUrlForRecord(baseURL, record); + postRecord(postURL, secret, record); + } + } catch (Exception e) { + Log.e(TAG, "Unable to post data", e); + } - if (recordsNotUploadedListJson.size() > 0) { - List auxList = new ArrayList(recordsNotUploadedListJson); - recordsNotUploadedListJson.clear(); - for (int i = 0; i < auxList.size(); i++) { - JSONObject json = auxList.get(i); - String postURL = baseURL; - postURL += "entries"; - Log.i(TAG, "postURL: " + postURL); + } - HttpPost post = new HttpPost(postURL); + private String determineUrlForRecord(String baseURL, Record record) { + String postURL; + if (record instanceof GlucometerRecord) { + postURL = baseURL + "entries"; + } else if (record instanceof MedtronicPumpRecord) { + postURL = baseURL + "deviceentries"; + } else { + postURL = baseURL + "entries"; + } + Log.i(TAG, "postURL: " + postURL); + return postURL; + } - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - byte[] bytes = secret.getBytes("UTF-8"); - digest.update(bytes, 0, bytes.length); - bytes = digest.digest(); - StringBuilder sb = new StringBuilder(bytes.length * 2); - for (byte b : bytes) { - sb.append(String.format("%02x", b & 0xff)); - } - String token = sb.toString(); - post.setHeader("api-secret", token); + private void postRecord(String postURL, String secret, Record record) throws NoSuchAlgorithmException, IOException { + HttpURLConnection urlConnection = null; + OutputStream os = null; + BufferedWriter writer = null; - String jsonString = json.toString(); + try { + urlConnection = (HttpURLConnection) new URL(postURL).openConnection(); + setPostConnectionProperties(urlConnection); + setAuthenticationToken(secret, urlConnection); + + String jsonString = convertRecordToJsonString(record); + if (jsonString == null) { + return; + } - Log.i(TAG, "JSON to upload " + jsonString); + try { + urlConnection.setRequestProperty("Accept", "application/json"); + urlConnection.setRequestProperty("Content-type", "application/json"); - try { - StringEntity se = new StringEntity(jsonString); - post.setEntity(se); - post.setHeader("Accept", "application/json"); - post.setHeader("Content-type", "application/json"); + // stream the body + os = urlConnection.getOutputStream(); + writer = new BufferedWriter( + new OutputStreamWriter(os, StandardCharsets.UTF_8)); + writer.write(jsonString); - ResponseHandler responseHandler = new BasicResponseHandler(); - httpclient.execute(post, responseHandler); - } catch (Exception e) { - Log.w(TAG, "Unable to post data to: '" + post.getURI().toString() + "'", e); - } + writer.flush(); + } catch (Exception e) { + Log.w(TAG, "Unable to post data to: '" + postURL + "'", e); + } + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); } } - - for (Record record : records) { - String postURL = baseURL; - if (record instanceof GlucometerRecord) { - typeSaved = 0; - postURL += "entries"; - } else if (record instanceof MedtronicPumpRecord) { - typeSaved = 3; - postURL += "deviceentries"; - } else { - typeSaved = 0; - postURL += "entries"; + if (os != null) { + try { + os.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); } - Log.i(TAG, "postURL: " + postURL); - log.info("postURL: " + postURL); - - HttpPost post = new HttpPost(postURL); - - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - byte[] bytes = secret.getBytes("UTF-8"); - digest.update(bytes, 0, bytes.length); - bytes = digest.digest(); - StringBuilder sb = new StringBuilder(bytes.length * 2); - for (byte b : bytes) { - sb.append(String.format("%02x", b & 0xff)); + } + + if (urlConnection != null) { + try { + Log.i(TAG, "Post to Url: '" + postURL + "' returned Http-Status " + urlConnection.getResponseCode()); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); } - String token = sb.toString(); - post.setHeader("api-secret", token); + urlConnection.disconnect(); + } + } + } - JSONObject json = new JSONObject(); + private void setAuthenticationToken(String secret, HttpURLConnection urlConnection) throws NoSuchAlgorithmException { - try { - populateV1APIEntry(json, record); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + byte[] bytes = secret.getBytes(StandardCharsets.UTF_8); + digest.update(bytes, 0, bytes.length); + bytes = digest.digest(); + StringBuilder sb = new StringBuilder(bytes.length * 2); + for (byte b : bytes) { + sb.append(String.format("%02x", b & 0xff)); + } + String token = sb.toString(); - } catch (Exception e) { - Log.w(TAG, "Unable to populate entry, apiVersion: " + apiVersion, e); - continue; - } + urlConnection.setRequestProperty("api-secret", token); + } + + private String convertRecordToJsonString(Record record) { + + JSONObject json = new JSONObject(); + try { + populateV1APIEntry(json, record); + + } catch (Exception e) { + Log.w(TAG, "Unable to populate entry.", e); + return null; + } + String jsonString = json.toString(); + + Log.i(TAG, "JSON: " + jsonString); + return jsonString; + } - String jsonString = json.toString(); + private void postDeviceStatus(String baseURL) { - Log.i(TAG, "DEXCOM JSON: " + jsonString); + HttpURLConnection urlConnection = null; + OutputStream os = null; + BufferedWriter writer = null; + String devicestatusURL = ""; + try { + + devicestatusURL = baseURL + "devicestatus"; + + Log.i(TAG, "devicestatusURL: " + devicestatusURL); + + JSONObject json = new JSONObject(); + json.put("uploaderBattery", DexcomG4Activity.batLevel); + String jsonString = json.toString(); + + urlConnection = (HttpURLConnection) new URL(devicestatusURL).openConnection(); + setPostConnectionProperties(urlConnection); + + urlConnection.setRequestProperty("Accept", "application/json"); + urlConnection.setRequestProperty("Content-type", "application/json"); + + // stream the body + os = urlConnection.getOutputStream(); + writer = new BufferedWriter( + new OutputStreamWriter(os, StandardCharsets.UTF_8)); + writer.write(jsonString); + writer.flush(); + } catch (Exception e) { + Log.w(TAG, "Could not send device status", e); + + } finally { + if (writer != null) { try { - StringEntity se = new StringEntity(jsonString); - post.setEntity(se); - post.setHeader("Accept", "application/json"); - post.setHeader("Content-type", "application/json"); - - ResponseHandler responseHandler = new BasicResponseHandler(); - httpclient.execute(post, responseHandler); - } catch (Exception e) { - Log.e(TAG, "Exception uploading: ", e); - if (typeSaved == 0) {//Only EGV records are important enough. - if (recordsNotUploadedListJson.size() > 49) { - recordsNotUploadedListJson.remove(0); - recordsNotUploadedListJson.add(49, json); - } else { - recordsNotUploadedListJson.add(json); - } - } - Log.w(TAG, "Unable to post data to: '" + post.getURI().toString() + "'", e); + writer.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); } } - postDeviceStatus(baseURL, httpclient); - } catch (Exception e) { - Log.e(TAG, "Unable to post data", e); - } - if (recordsNotUploadedListJson.size() > 0) { - synchronized (isModifyingRecordsLock) { + if (os != null) { try { - JSONArray recordsNotUploadedJson = new JSONArray(settings.getString("recordsNotUploadedJson", "[]")); - if (recordsNotUploadedJson.length() > 0 && recordsNotUploadedJson.length() < recordsNotUploadedListJson.size()) { - for (int i = 0; i < recordsNotUploadedJson.length(); i++) { - if (recordsNotUploadedListJson.size() > 49) { - recordsNotUploadedListJson.remove(0); - recordsNotUploadedListJson.add(49, recordsNotUploadedJson.getJSONObject(i)); - } else { - recordsNotUploadedListJson.add(recordsNotUploadedJson.getJSONObject(i)); - } - } - } else { - for (int i = 0; i < recordsNotUploadedListJson.size(); i++) { - recordsNotUploadedJson.put(recordsNotUploadedListJson.get(i)); - } - int start = 0; - if (recordsNotUploadedJson.length() > 50) { - start = recordsNotUploadedJson.length() - 51; - } - recordsNotUploadedListJson.clear(); - for (int i = start; i < recordsNotUploadedJson.length(); i++) { - recordsNotUploadedListJson.add(recordsNotUploadedJson.getJSONObject(i)); - } - } - log.debug("retrieve older json records -->" + recordsNotUploadedJson.length()); + os.close(); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); + } + } - } catch (Exception e) { - Log.i(TAG, "ERROR RETRIEVING OLDER LISTs, I HAVE LOST THEM"); + if (urlConnection != null) { + try { + Log.i(TAG, "Post to Url: '" + devicestatusURL + "' returned Http-Status " + urlConnection.getResponseCode()); + } catch (IOException e) { + Log.e(TAG, e.getMessage(), e); } - SharedPreferences.Editor editor = settings.edit(); - if (settings.contains("recordsNotUploadedJson")) - editor.remove("recordsNotUploadedJson"); - JSONArray jsonArray = new JSONArray(recordsNotUploadedListJson); - editor.putString("recordsNotUploadedJson", jsonArray.toString()); - editor.commit(); + urlConnection.disconnect(); } } - } - @SuppressWarnings({"rawtypes", "unchecked"}) - private void postDeviceStatus(String baseURL, DefaultHttpClient httpclient) throws Exception { - String devicestatusURL = baseURL + "devicestatus"; - Log.i(TAG, "devicestatusURL: " + devicestatusURL); - - JSONObject json = new JSONObject(); - json.put("uploaderBattery", DexcomG4Activity.batLevel); - String jsonString = json.toString(); - - HttpPost post = new HttpPost(devicestatusURL); - StringEntity se = new StringEntity(jsonString); - post.setEntity(se); - post.setHeader("Accept", "application/json"); - post.setHeader("Content-type", "application/json"); + } - ResponseHandler responseHandler = new BasicResponseHandler(); - httpclient.execute(post, responseHandler); + private void setPostConnectionProperties(HttpURLConnection urlConnection) throws ProtocolException { + urlConnection.setReadTimeout(READ_TIMEOUT); + urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); + urlConnection.setRequestMethod("POST"); + urlConnection.setDoInput(true); + urlConnection.setDoOutput(true); } private void populateV1APIEntry(JSONObject json, Record oRecord) throws Exception { - Date date = DATE_FORMAT.parse(oRecord.displayTime); + Date date = oRecord.getDate(); json.put("date", date.getTime()); - + json.put("dateString", DATE_FORMAT.format(date)); if (oRecord instanceof GlucometerRecord) { json.put("gdValue", ((GlucometerRecord) oRecord).numGlucometerValue); json.put("device", getSelectedDeviceName()); @@ -376,7 +332,7 @@ private void populateV1APIEntry(JSONObject json, Record oRecord) throws Exceptio } else if (oRecord instanceof EGVRecord) { EGVRecord record = (EGVRecord) oRecord; json.put("device", getSelectedDeviceName()); - json.put("sgv", Integer.parseInt(record.bGValue)); + json.put("sgv", (int) record.getBGValue()); json.put("direction", record.trend); if (oRecord instanceof MedtronicSensorRecord) { json.put("isig", ((MedtronicSensorRecord) record).isig); diff --git a/app/src/main/java/com/nightscout/android/widget/CGMWidget.java b/app/src/main/java/com/nightscout/android/widget/CGMWidget.java index d97f22c..0ec4dc0 100644 --- a/app/src/main/java/com/nightscout/android/widget/CGMWidget.java +++ b/app/src/main/java/com/nightscout/android/widget/CGMWidget.java @@ -16,7 +16,6 @@ import com.nightscout.android.R; import com.nightscout.android.dexcom.DexcomG4Activity; -import com.nightscout.android.dexcom.EGVRecord; import com.nightscout.android.medtronic.MedtronicConstants; import com.nightscout.android.upload.MedtronicSensorRecord; import com.nightscout.android.upload.Record; @@ -47,14 +46,10 @@ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] a calib = "*"; else calib = MedtronicConstants.getWidgetCalAppend(record.calibrationStatus); - views.setTextViewText(R.id.sgv_id, record.bGValue+calib); + views.setTextViewText(R.id.sgv_id, record.getBGValue()+calib); views.setTextViewText(R.id.arrow_id, record.trendArrow); - }else if (auxRecord instanceof EGVRecord){ - EGVRecord record = (EGVRecord)auxRecord; - views.setTextViewText(R.id.sgv_id, record.bGValue); - views.setTextViewText(R.id.arrow_id, record.trendArrow); - }else{ + } else{ views.setTextViewText(R.id.sgv_id, "---"); views.setTextViewText(R.id.arrow_id, "---"); } @@ -75,7 +70,7 @@ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] a service = PendingIntent.getService(context, 0, in, PendingIntent.FLAG_CANCEL_CURRENT); } - m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 30, service); + m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 60, service); } } @Override diff --git a/app/src/main/java/com/nightscout/android/widget/CGMWidgetUpdater.java b/app/src/main/java/com/nightscout/android/widget/CGMWidgetUpdater.java index 8488933..b8e8cfd 100644 --- a/app/src/main/java/com/nightscout/android/widget/CGMWidgetUpdater.java +++ b/app/src/main/java/com/nightscout/android/widget/CGMWidgetUpdater.java @@ -19,15 +19,13 @@ import com.nightscout.android.R; import com.nightscout.android.dexcom.DexcomG4Activity; -import com.nightscout.android.dexcom.EGVRecord; import com.nightscout.android.medtronic.MedtronicConstants; import com.nightscout.android.upload.MedtronicSensorRecord; import com.nightscout.android.upload.Record; public class CGMWidgetUpdater extends Service{ - - public static int UPDATE_FREQUENCY_SEC = 10; - @Override + + @Override public void onCreate() { super.onCreate(); @@ -76,17 +74,13 @@ private void updateValues(Record auxRecord, RemoteViews views){ calib = MedtronicConstants.getWidgetCalAppend(record.calibrationStatus); if (prefs.getBoolean("isWarmingUp",false)){ calib = ""; - record.bGValue = "W._Up"; + record.setBGValue(0); record.trendArrow="---"; } - views.setTextViewText(R.id.sgv_id, record.bGValue+calib); + views.setTextViewText(R.id.sgv_id, record.getBGValue()+calib); views.setTextViewText(R.id.arrow_id, record.trendArrow); - }else if (auxRecord instanceof EGVRecord){ - EGVRecord record = (EGVRecord)auxRecord; - views.setTextViewText(R.id.sgv_id, record.bGValue); - views.setTextViewText(R.id.arrow_id, record.trendArrow); - }else{ + } else{ views.setTextViewText(R.id.sgv_id, "---"); views.setTextViewText(R.id.arrow_id, "---"); } diff --git a/app/src/main/res/drawable-hdpi/ic_action_warning.png b/app/src/main/res/drawable-hdpi/ic_action_warning.png deleted file mode 100644 index 98b90c2..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_warning.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/icon36x36.png b/app/src/main/res/drawable-ldpi/icon36x36.png deleted file mode 100644 index 70129cd..0000000 Binary files a/app/src/main/res/drawable-ldpi/icon36x36.png and /dev/null differ diff --git a/app/src/main/res/layout/adb.xml b/app/src/main/res/layout/adb.xml index ea36f59..e050c82 100644 --- a/app/src/main/res/layout/adb.xml +++ b/app/src/main/res/layout/adb.xml @@ -1,49 +1,88 @@ - + android:orientation="vertical"> + + + + android:text="@string/title" + android:textSize="40dp" /> + + + android:text="@string/dummy" + android:textSize="25dp" /> - - - - - - - + android:layout_height="211dp" + android:gravity="center" + + android:textSize="20dp" /> + + + + +