diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
index 9b46b76a7c1261f278ce403d497c7495e08c24da..e897ef8fb36da16a096f1e38f41a47c6e76ba823 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
@@ -104,152 +104,148 @@ public class MedtronicCnlIntentService extends IntentService {
 
     protected void onHandleIntent(Intent intent) {
         Log.d(TAG, "onHandleIntent called");
+        try {
 
-        long timePollStarted = System.currentTimeMillis(),
-                timePollExpected = timePollStarted,
-                timeLastGoodSGV = dataStore.getLastPumpStatus().getEventDate().getTime();
+            long timePollStarted = System.currentTimeMillis(),
+                    timePollExpected = timePollStarted,
+                    timeLastGoodSGV = dataStore.getLastPumpStatus().getEventDate().getTime();
 
-        short pumpBatteryLevel = dataStore.getLastPumpStatus().getBatteryPercentage();
+            short pumpBatteryLevel = dataStore.getLastPumpStatus().getBatteryPercentage();
 
-        if (timeLastGoodSGV != 0) {
-            timePollExpected = timeLastGoodSGV + POLL_PERIOD_MS + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((timePollStarted - 1000L - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
-        }
+            if (timeLastGoodSGV != 0) {
+                timePollExpected = timeLastGoodSGV + POLL_PERIOD_MS + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((timePollStarted - 1000L - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
+            }
 
-        // avoid polling when too close to sensor-pump comms
-        if (((timePollExpected - timePollStarted) > 5000L) && ((timePollExpected - timePollStarted) < (POLL_GRACE_PERIOD_MS + 45000L))) {
-            sendStatus("Please wait: Poll due in " + ((timePollExpected - timePollStarted) / 1000L) + " seconds");
-            MedtronicCnlAlarmManager.setAlarm(timePollExpected);
-            MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
-            return;
-        }
+            // avoid polling when too close to sensor-pump comms
+            if (((timePollExpected - timePollStarted) > 5000L) && ((timePollExpected - timePollStarted) < (POLL_GRACE_PERIOD_MS + 45000L))) {
+                sendStatus("Please wait: Poll due in " + ((timePollExpected - timePollStarted) / 1000L) + " seconds");
+                MedtronicCnlAlarmManager.setAlarm(timePollExpected);
+                return;
+            }
 
-        long pollInterval = configurationStore.getPollInterval();
-        if ((pumpBatteryLevel > 0) && (pumpBatteryLevel <= 25)) {
-            pollInterval = configurationStore.getLowBatteryPollInterval();
-        }
+            long pollInterval = configurationStore.getPollInterval();
+            if ((pumpBatteryLevel > 0) && (pumpBatteryLevel <= 25)) {
+                pollInterval = configurationStore.getLowBatteryPollInterval();
+            }
 
-        if (!hasUsbHostFeature()) {
-            sendStatus("It appears that this device doesn't support USB OTG.");
-            Log.e(TAG, "Device does not support USB OTG");
-            MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
-            // TODO - throw, don't return
-            return;
-        }
+            if (!hasUsbHostFeature()) {
+                sendStatus("It appears that this device doesn't support USB OTG.");
+                Log.e(TAG, "Device does not support USB OTG");
+                // TODO - throw, don't return
+                return;
+            }
 
-        UsbDevice cnlStick = UsbHidDriver.getUsbDevice(mUsbManager, USB_VID, USB_PID);
-        if (cnlStick == null) {
-            sendStatus("USB connection error. Is the Contour Next Link plugged in?");
-            Log.w(TAG, "USB connection error. Is the CNL plugged in?");
+            UsbDevice cnlStick = UsbHidDriver.getUsbDevice(mUsbManager, USB_VID, USB_PID);
+            if (cnlStick == null) {
+                sendStatus("USB connection error. Is the Contour Next Link plugged in?");
+                Log.w(TAG, "USB connection error. Is the CNL plugged in?");
 
-            // TODO - set status if offline or Nightscout not reachable
-            uploadToNightscout();
-            MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
-            // TODO - throw, don't return
-            return;
-        }
+                // TODO - set status if offline or Nightscout not reachable
+                uploadToNightscout();
+                // TODO - throw, don't return
+                return;
+            }
 
-        if (!mUsbManager.hasPermission(UsbHidDriver.getUsbDevice(mUsbManager, USB_VID, USB_PID))) {
-            sendMessage(Constants.ACTION_NO_USB_PERMISSION);
-            MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
-            // TODO - throw, don't return
-            return;
-        }
-        mHidDevice = UsbHidDriver.acquire(mUsbManager, cnlStick);
+            if (!mUsbManager.hasPermission(UsbHidDriver.getUsbDevice(mUsbManager, USB_VID, USB_PID))) {
+                sendMessage(Constants.ACTION_NO_USB_PERMISSION);
+                // TODO - throw, don't return
+                return;
+            }
+            mHidDevice = UsbHidDriver.acquire(mUsbManager, cnlStick);
 
-        try {
-            mHidDevice.open();
-        } catch (Exception e) {
-            Log.e(TAG, "Unable to open serial device", e);
-            MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
-            // TODO - throw, don't return
-            return;
-        }
+            try {
+                mHidDevice.open();
+            } catch (Exception e) {
+                Log.e(TAG, "Unable to open serial device", e);
+                // TODO - throw, don't return
+                return;
+            }
 
-        DateFormat df = new SimpleDateFormat("HH:mm:ss", Locale.US);
+            DateFormat df = new SimpleDateFormat("HH:mm:ss", Locale.US);
 
-        MedtronicCnlReader cnlReader = new MedtronicCnlReader(mHidDevice);
+            MedtronicCnlReader cnlReader = new MedtronicCnlReader(mHidDevice);
 
-        Realm realm = Realm.getDefaultInstance();
-        realm.beginTransaction();
+            Realm realm = Realm.getDefaultInstance();
+            realm.beginTransaction();
 
-        try {
-            sendStatus("Connecting to Contour Next Link");
-            Log.d(TAG, "Connecting to Contour Next Link");
-            cnlReader.requestDeviceInfo();
-
-            // Is the device already configured?
-            ContourNextLinkInfo info = realm
-                    .where(ContourNextLinkInfo.class)
-                    .equalTo("serialNumber", cnlReader.getStickSerial())
-                    .findFirst();
-
-            if (info == null) {
-                info = realm.createObject(ContourNextLinkInfo.class, cnlReader.getStickSerial());
-            }
+            try {
+                sendStatus("Connecting to Contour Next Link");
+                Log.d(TAG, "Connecting to Contour Next Link");
+                cnlReader.requestDeviceInfo();
+
+                // Is the device already configured?
+                ContourNextLinkInfo info = realm
+                        .where(ContourNextLinkInfo.class)
+                        .equalTo("serialNumber", cnlReader.getStickSerial())
+                        .findFirst();
 
-            cnlReader.getPumpSession().setStickSerial(info.getSerialNumber());
+                if (info == null) {
+                    info = realm.createObject(ContourNextLinkInfo.class, cnlReader.getStickSerial());
+                }
 
-            cnlReader.enterControlMode();
+                cnlReader.getPumpSession().setStickSerial(info.getSerialNumber());
 
-            try {
-                cnlReader.enterPassthroughMode();
-                cnlReader.openConnection();
+                cnlReader.enterControlMode();
 
-                cnlReader.requestReadInfo();
+                try {
+                    cnlReader.enterPassthroughMode();
+                    cnlReader.openConnection();
 
-                String key = info.getKey();
+                    cnlReader.requestReadInfo();
 
-                if (key == null) {
-                    cnlReader.requestLinkKey();
+                    String key = info.getKey();
 
-                    info.setKey(MessageUtils.byteArrayToHexString(cnlReader.getPumpSession().getKey()));
-                    key = info.getKey();
-                }
+                    if (key == null) {
+                        cnlReader.requestLinkKey();
 
-                cnlReader.getPumpSession().setKey(MessageUtils.hexStringToByteArray(key));
+                        info.setKey(MessageUtils.byteArrayToHexString(cnlReader.getPumpSession().getKey()));
+                        key = info.getKey();
+                    }
 
-                long pumpMAC = cnlReader.getPumpSession().getPumpMAC();
-                Log.i(TAG, "PumpInfo MAC: " + (pumpMAC & 0xffffff));
-                PumpInfo activePump = realm
-                        .where(PumpInfo.class)
-                        .equalTo("pumpMac", pumpMAC)
-                        .findFirst();
+                    cnlReader.getPumpSession().setKey(MessageUtils.hexStringToByteArray(key));
 
-                if (activePump == null) {
-                    activePump = realm.createObject(PumpInfo.class, pumpMAC);
-                }
+                    long pumpMAC = cnlReader.getPumpSession().getPumpMAC();
+                    Log.i(TAG, "PumpInfo MAC: " + (pumpMAC & 0xffffff));
+                    PumpInfo activePump = realm
+                            .where(PumpInfo.class)
+                            .equalTo("pumpMac", pumpMAC)
+                            .findFirst();
 
-                activePump.updateLastQueryTS();
+                    if (activePump == null) {
+                        activePump = realm.createObject(PumpInfo.class, pumpMAC);
+                    }
+
+                    activePump.updateLastQueryTS();
 
-                byte radioChannel = cnlReader.negotiateChannel(activePump.getLastRadioChannel());
-                if (radioChannel == 0) {
-                    sendStatus("Could not communicate with the pump. Is it nearby?");
-                    Log.i(TAG, "Could not communicate with the pump. Is it nearby?");
-                    pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L); // reduce polling interval to half until pump is available
-                } else {
-                    dataStore.setActivePumpMac(pumpMAC);
+                    byte radioChannel = cnlReader.negotiateChannel(activePump.getLastRadioChannel());
+                    if (radioChannel == 0) {
+                        sendStatus("Could not communicate with the pump. Is it nearby?");
+                        Log.i(TAG, "Could not communicate with the pump. Is it nearby?");
+                        pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L); // reduce polling interval to half until pump is available
+                    } else {
+                        dataStore.setActivePumpMac(pumpMAC);
 
-                    activePump.setLastRadioChannel(radioChannel);
-                    sendStatus(String.format(Locale.getDefault(), "Connected on channel %d  RSSI: %d%%", (int) radioChannel, cnlReader.getPumpSession().getRadioRSSIpercentage()));
-                    Log.d(TAG, String.format("Connected to Contour Next Link on channel %d.", (int) radioChannel));
+                        activePump.setLastRadioChannel(radioChannel);
+                        sendStatus(String.format(Locale.getDefault(), "Connected on channel %d  RSSI: %d%%", (int) radioChannel, cnlReader.getPumpSession().getRadioRSSIpercentage()));
+                        Log.d(TAG, String.format("Connected to Contour Next Link on channel %d.", (int) radioChannel));
 
-                    // read pump status
-                    PumpStatusEvent pumpRecord = realm.createObject(PumpStatusEvent.class);
+                        // read pump status
+                        PumpStatusEvent pumpRecord = realm.createObject(PumpStatusEvent.class);
 
-                    String deviceName = String.format("medtronic-600://%s", cnlReader.getStickSerial());
-                    activePump.setDeviceName(deviceName);
+                        String deviceName = String.format("medtronic-600://%s", cnlReader.getStickSerial());
+                        activePump.setDeviceName(deviceName);
 
-                    // TODO - this should not be necessary. We should reverse lookup the device name from PumpInfo
-                    pumpRecord.setDeviceName(deviceName);
+                        // TODO - this should not be necessary. We should reverse lookup the device name from PumpInfo
+                        pumpRecord.setDeviceName(deviceName);
 
-                    long pumpTime = cnlReader.getPumpTime().getTime();
-                    long pumpOffset = pumpTime - System.currentTimeMillis();
-                    Log.d(TAG, "Time offset between pump and device: " + pumpOffset + " millis.");
+                        long pumpTime = cnlReader.getPumpTime().getTime();
+                        long pumpOffset = pumpTime - System.currentTimeMillis();
+                        Log.d(TAG, "Time offset between pump and device: " + pumpOffset + " millis.");
 
-                    // TODO - send ACTION to MainActivity to show offset between pump and uploader.
-                    pumpRecord.setPumpTimeOffset(pumpOffset);
-                    pumpRecord.setPumpDate(new Date(pumpTime - pumpOffset));
-                    cnlReader.updatePumpStatus(pumpRecord);
+                        // TODO - send ACTION to MainActivity to show offset between pump and uploader.
+                        pumpRecord.setPumpTimeOffset(pumpOffset);
+                        pumpRecord.setPumpDate(new Date(pumpTime - pumpOffset));
+                        cnlReader.updatePumpStatus(pumpRecord);
 
                     if (pumpRecord.getSgv() != 0) {
                         String offsetSign = "";
@@ -290,81 +286,82 @@ public class MedtronicCnlIntentService extends IntentService {
                         dataStore.incUnavailableSGVCount(); // poll clash detection
                     }
 
-                    realm.commitTransaction();
-                    // Tell the Main Activity we have new data
-                    sendMessage(Constants.ACTION_UPDATE_PUMP);
-                }
+                        realm.commitTransaction();
+                        // Tell the Main Activity we have new data
+                        sendMessage(Constants.ACTION_UPDATE_PUMP);
+                    }
 
-            } catch (UnexpectedMessageException e) {
-                Log.e(TAG, "Unexpected Message", e);
-                sendStatus("Communication Error: " + e.getMessage());
-                pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L);
+                } catch (UnexpectedMessageException e) {
+                    Log.e(TAG, "Unexpected Message", e);
+                    sendStatus("Communication Error: " + e.getMessage());
+                    pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L);
+                } catch (TimeoutException e) {
+                    Log.e(TAG, "Timeout communicating with the Contour Next Link.", e);
+                    sendStatus("Timeout communicating with the Contour Next Link.");
+                    pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L);
+                } catch (NoSuchAlgorithmException e) {
+                    Log.e(TAG, "Could not determine CNL HMAC", e);
+                    sendStatus("Error connecting to Contour Next Link: Hashing error.");
+                } finally {
+                    try {
+                        cnlReader.closeConnection();
+                        cnlReader.endPassthroughMode();
+                        cnlReader.endControlMode();
+                    } catch (NoSuchAlgorithmException e) {
+                    }
+
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error connecting to Contour Next Link.", e);
+                sendStatus("Error connecting to Contour Next Link.");
+            } catch (ChecksumException e) {
+                Log.e(TAG, "Checksum error getting message from the Contour Next Link.", e);
+                sendStatus("Checksum error getting message from the Contour Next Link.");
+            } catch (EncryptionException e) {
+                Log.e(TAG, "Error decrypting messages from Contour Next Link.", e);
+                sendStatus("Error decrypting messages from Contour Next Link.");
             } catch (TimeoutException e) {
                 Log.e(TAG, "Timeout communicating with the Contour Next Link.", e);
                 sendStatus("Timeout communicating with the Contour Next Link.");
-                pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway() ? 2L : 1L);
-            } catch (NoSuchAlgorithmException e) {
-                Log.e(TAG, "Could not determine CNL HMAC", e);
-                sendStatus("Error connecting to Contour Next Link: Hashing error.");
+            } catch (UnexpectedMessageException e) {
+                Log.e(TAG, "Could not close connection.", e);
+                sendStatus("Could not close connection: " + e.getMessage());
             } finally {
-                try {
-                    cnlReader.closeConnection();
-                    cnlReader.endPassthroughMode();
-                    cnlReader.endControlMode();
-                } catch (NoSuchAlgorithmException e) {
+                if (!realm.isClosed()) {
+                    if (realm.isInTransaction()) {
+                        // If we didn't commit the transaction, we've run into an error. Let's roll it back
+                        realm.cancelTransaction();
+                    }
+                    realm.close();
                 }
-
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error connecting to Contour Next Link.", e);
-            sendStatus("Error connecting to Contour Next Link.");
-        } catch (ChecksumException e) {
-            Log.e(TAG, "Checksum error getting message from the Contour Next Link.", e);
-            sendStatus("Checksum error getting message from the Contour Next Link.");
-        } catch (EncryptionException e) {
-            Log.e(TAG, "Error decrypting messages from Contour Next Link.", e);
-            sendStatus("Error decrypting messages from Contour Next Link.");
-        } catch (TimeoutException e) {
-            Log.e(TAG, "Timeout communicating with the Contour Next Link.", e);
-            sendStatus("Timeout communicating with the Contour Next Link.");
-        } catch (UnexpectedMessageException e) {
-            Log.e(TAG, "Could not close connection.", e);
-            sendStatus("Could not close connection: " + e.getMessage());
-        } finally {
-            if (!realm.isClosed()) {
-                if (realm.isInTransaction()) {
-                    // If we didn't commit the transaction, we've run into an error. Let's roll it back
-                    realm.cancelTransaction();
+                // TODO - set status if offline or Nightscout not reachable
+                sendToXDrip();
+                uploadToNightscout();
+
+                // smart polling and pump-sensor poll clash detection
+                long lastActualPollTime = timePollStarted;
+                if (timeLastGoodSGV > 0) {
+                    lastActualPollTime = timeLastGoodSGV + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((System.currentTimeMillis() - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
                 }
-                realm.close();
-            }
-            // TODO - set status if offline or Nightscout not reachable
-            sendToXDrip();
-            uploadToNightscout();
-
-            // smart polling and pump-sensor poll clash detection
-            long lastActualPollTime = timePollStarted;
-            if (timeLastGoodSGV > 0) {
-                lastActualPollTime = timeLastGoodSGV + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((System.currentTimeMillis() - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
-            }
-            long nextActualPollTime = lastActualPollTime + POLL_PERIOD_MS;
-            long nextRequestedPollTime = lastActualPollTime + pollInterval;
-            if ((nextRequestedPollTime - System.currentTimeMillis()) < 10000L) {
-                nextRequestedPollTime = nextActualPollTime;
-            }
-            // extended unavailable SGV may be due to clash with the current polling time
-            // while we wait for a good SGV event, polling is auto adjusted by offsetting the next poll based on miss count
-            if (dataStore.getUnavailableSGVCount() > 0) {
-                if (timeLastGoodSGV == 0) {
-                    nextRequestedPollTime += POLL_PERIOD_MS / 5L; // if there is a uploader/sensor poll clash on startup then this will push the next attempt out by 60 seconds
-                } else if (dataStore.getUnavailableSGVCount() > 2) {
-                    sendStatus("Warning: No SGV available from pump for " + dataStore.getUnavailableSGVCount() + " attempts");
-                    nextRequestedPollTime += ((long) ((dataStore.getUnavailableSGVCount() - 2) % 5)) * (POLL_PERIOD_MS / 10L); // adjust poll time in 1/10 steps to avoid potential poll clash (max adjustment at 5/10)
+                long nextActualPollTime = lastActualPollTime + POLL_PERIOD_MS;
+                long nextRequestedPollTime = lastActualPollTime + pollInterval;
+                if ((nextRequestedPollTime - System.currentTimeMillis()) < 10000L) {
+                    nextRequestedPollTime = nextActualPollTime;
                 }
+                // extended unavailable SGV may be due to clash with the current polling time
+                // while we wait for a good SGV event, polling is auto adjusted by offsetting the next poll based on miss count
+                if (dataStore.getUnavailableSGVCount() > 0) {
+                    if (timeLastGoodSGV == 0) {
+                        nextRequestedPollTime += POLL_PERIOD_MS / 5L; // if there is a uploader/sensor poll clash on startup then this will push the next attempt out by 60 seconds
+                    } else if (dataStore.getUnavailableSGVCount() > 2) {
+                        sendStatus("Warning: No SGV available from pump for " + dataStore.getUnavailableSGVCount() + " attempts");
+                        nextRequestedPollTime += ((long) ((dataStore.getUnavailableSGVCount() - 2) % 5)) * (POLL_PERIOD_MS / 10L); // adjust poll time in 1/10 steps to avoid potential poll clash (max adjustment at 5/10)
+                    }
+                }
+                MedtronicCnlAlarmManager.setAlarm(nextRequestedPollTime);
+                sendStatus("Next poll due at: " + df.format(nextRequestedPollTime));
             }
-            MedtronicCnlAlarmManager.setAlarm(nextRequestedPollTime);
-            sendStatus("Next poll due at: " + df.format(nextRequestedPollTime));
-
+        } finally {
             MedtronicCnlAlarmReceiver.completeWakefulIntent(intent);
         }
     }