From 2770a4986998fc61164ebb81ad4eabea3cf605fd Mon Sep 17 00:00:00 2001 From: TebbeUbben Date: Fri, 18 Jan 2019 22:40:08 +0100 Subject: [PATCH 01/26] Local Insight driver --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 23 +- .../info/nightscout/androidaps/MainApp.java | 2 + .../androidaps/db/DatabaseHelper.java | 100 +- .../Overview/notifications/Notification.java | 1 + .../EventLocalInsightUpdateGUI.java | 6 + .../PumpInsightLocal/InsightAlertService.java | 226 +++ .../LocalInsightFragment.java | 284 ++++ .../PumpInsightLocal/LocalInsightPlugin.java | 1308 +++++++++++++++++ .../activities/InsightAlertActivity.java | 256 ++++ .../activities/InsightPairingActivity.java | 255 ++++ .../InsightPairingInformationActivity.java | 88 ++ .../app_layer/AppLayerMessage.java | 91 ++ .../app_layer/ReadParameterBlockMessage.java | 48 + .../PumpInsightLocal/app_layer/Service.java | 31 + ...CloseConfigurationWriteSessionMessage.java | 12 + .../OpenConfigurationWriteSessionMessage.java | 12 + .../WriteConfigurationBlockMessage.java | 41 + .../connection/ActivateServiceMessage.java | 51 + .../app_layer/connection/BindMessage.java | 20 + .../app_layer/connection/ConnectMessage.java | 20 + .../connection/DisconnectMessage.java | 20 + .../connection/ServiceChallengeMessage.java | 42 + .../history/HistoryReadingDirection.java | 8 + .../history/ReadHistoryEventsMessage.java | 34 + .../history/StartReadingHistoryMessage.java | 34 + .../history/StopReadingHistoryMessage.java | 13 + .../BasalDeliveryChangedEvent.java | 23 + .../history_events/BolusDeliveredEvent.java | 64 + .../history_events/BolusProgrammedEvent.java | 45 + .../history_events/CannulaFilledEvent.java | 17 + .../CartridgeInsertedEvent.java | 4 + .../history_events/CartridgeRemovedEvent.java | 4 + .../history_events/DateTimeChangedEvent.java | 49 + .../DefaultDateTimeSetEvent.java | 4 + .../history/history_events/EndOfTBREvent.java | 43 + .../history/history_events/HistoryEvent.java | 83 ++ .../OccurrenceOfAlertEvent.java | 25 + .../OccurrenceOfErrorEvent.java | 4 + .../OccurrenceOfMaintenanceEvent.java | 4 + .../OccurrenceOfWarningEvent.java | 4 + .../OperatingModeChangedEvent.java | 26 + .../history_events/PowerDownEvent.java | 4 + .../history/history_events/PowerUpEvent.java | 4 + .../history_events/SniffingDoneEvent.java | 18 + .../history_events/StartOfTBREvent.java | 23 + .../history_events/TotalDailyDoseEvent.java | 42 + .../history_events/TubeFilledEvent.java | 17 + .../ActiveBRProfileBlock.java | 30 + .../parameter_blocks/BRProfile1Block.java | 4 + .../parameter_blocks/BRProfile1NameBlock.java | 4 + .../parameter_blocks/BRProfile2Block.java | 4 + .../parameter_blocks/BRProfile2NameBlock.java | 4 + .../parameter_blocks/BRProfile3Block.java | 4 + .../parameter_blocks/BRProfile3NameBlock.java | 4 + .../parameter_blocks/BRProfile4Block.java | 4 + .../parameter_blocks/BRProfile4NameBlock.java | 4 + .../parameter_blocks/BRProfile5Block.java | 4 + .../parameter_blocks/BRProfile5NameBlock.java | 4 + .../parameter_blocks/BRProfileBlock.java | 50 + .../FactoryMaxBasalAmountBlock.java | 4 + .../FactoryMaxBolusAmountBlock.java | 4 + .../FactoryMinBasalAmountBlock.java | 4 + .../FactoryMinBolusAmountBlock.java | 4 + .../InsulinAmountLimitationBlock.java | 28 + .../parameter_blocks/MaxBasalAmountBlock.java | 4 + .../parameter_blocks/MaxBolusAmountBlock.java | 4 + .../app_layer/parameter_blocks/NameBlock.java | 28 + .../parameter_blocks/ParameterBlock.java | 10 + .../SystemIdentificationBlock.java | 26 + .../TBROverNotificationBlock.java | 31 + .../remote_control/CancelBolusMessage.java | 26 + .../remote_control/CancelTBRMessage.java | 12 + .../remote_control/ChangeTBRMessage.java | 33 + .../remote_control/ConfirmAlertMessage.java | 26 + .../remote_control/DeliverBolusMessage.java | 63 + .../GetAvailableBolusTypesMessage.java | 28 + .../remote_control/SetDateTimeMessage.java | 32 + .../SetOperatingModeMessage.java | 28 + .../remote_control/SetTBRMessage.java | 33 + .../remote_control/SnoozeAlertMessage.java | 26 + .../status/GetActiveAlertMessage.java | 54 + .../status/GetActiveBasalRateMessage.java | 30 + .../status/GetActiveBolusesMessage.java | 40 + .../app_layer/status/GetActiveTBRMessage.java | 29 + .../status/GetBatteryStatusMessage.java | 30 + .../status/GetCartridgeStatusMessage.java | 31 + .../app_layer/status/GetDateTimeMessage.java | 31 + .../status/GetFirmwareVersionsMessage.java | 39 + .../status/GetOperatingModeMessage.java | 26 + .../status/GetPumpStatusRegisterMessage.java | 60 + .../status/GetTotalDailyDoseMessage.java | 28 + .../ResetPumpStatusRegisterMessage.java | 63 + .../ConfigurationMessageRequest.java | 33 + .../InsightConnectionService.java | 775 ++++++++++ .../connection_service/MessageQueue.java | 66 + .../connection_service/MessageRequest.java | 47 + .../database/InsightBolusID.java | 29 + .../database/InsightHistoryOffset.java | 16 + .../database/InsightPumpID.java | 26 + .../descriptors/ActiveBasalRate.java | 32 + .../descriptors/ActiveBolus.java | 50 + .../descriptors/ActiveTBR.java | 32 + .../PumpInsightLocal/descriptors/Alert.java | 86 ++ .../descriptors/AlertCategory.java | 9 + .../descriptors/AlertStatus.java | 7 + .../descriptors/AlertType.java | 31 + .../descriptors/AvailableBolusTypes.java | 45 + .../descriptors/BasalProfile.java | 10 + .../descriptors/BasalProfileBlock.java | 23 + .../descriptors/BatteryStatus.java | 32 + .../descriptors/BatteryType.java | 8 + .../descriptors/BolusType.java | 8 + .../descriptors/CartridgeStatus.java | 41 + .../descriptors/CartridgeType.java | 7 + .../descriptors/FirmwareVersions.java | 95 ++ .../descriptors/InsightState.java | 22 + .../descriptors/MessagePriority.java | 8 + .../descriptors/OperatingMode.java | 8 + .../descriptors/PumpTime.java | 59 + .../descriptors/SymbolStatus.java | 8 + .../descriptors/SystemIdentification.java | 32 + .../descriptors/TotalDailyDose.java | 32 + .../exceptions/AppLayerException.java | 5 + .../CommandNotSupportedException.java | 5 + .../exceptions/ConnectionFailedException.java | 5 + .../exceptions/ConnectionLostException.java | 5 + .../exceptions/DisconnectedException.java | 5 + .../IncompatibleAppVersionException.java | 5 + .../IncompatibleSatlVersionException.java | 5 + .../exceptions/InsightException.java | 4 + .../exceptions/InvalidAppCRCException.java | 5 + .../InvalidMacTrailerException.java | 5 + .../exceptions/InvalidNonceException.java | 5 + .../InvalidPacketLengthsException.java | 5 + .../exceptions/InvalidPreambleException.java | 5 + .../exceptions/InvalidSatlCRCException.java | 5 + .../InvalidSatlCommandException.java | 5 + ...ReceivedPacketInInvalidStateException.java | 5 + .../exceptions/SatlException.java | 5 + .../SecondChannelFailedException.java | 5 + .../SocketCreationFailedException.java | 5 + .../exceptions/TimeoutException.java | 5 + .../exceptions/TooChattyPumpException.java | 4 + .../UnknownAppCommandException.java | 5 + .../exceptions/UnknownServiceException.java | 5 + .../AlreadyConnectedException.java | 8 + .../AppLayerErrorException.java | 17 + .../BolusAmountNotInRangeException.java | 8 + .../BolusDurationNotInRangeException.java | 8 + .../BolusLagTimeFeatureDisabledException.java | 8 + ...olusTypeAndParameterMismatchException.java | 8 + .../CommandExecutionFailedException.java | 8 + .../ConfigMemoryAccessException.java | 8 + .../CustomBolusNotConfiguredException.java | 8 + ...mplausiblePortionLengthValueException.java | 8 + .../IncompatibleVersionException.java | 8 + .../InvalidAlertInstanceIdException.java | 8 + .../InvalidConfigBlockCRCException.java | 8 + .../InvalidConfigBlockIdException.java | 8 + .../InvalidConfigBlockLengthException.java | 8 + .../InvalidDateParameterException.java | 8 + .../InvalidDurationPresetException.java | 8 + .../InvalidLagTimeException.java | 8 + .../InvalidParameterTypeException.java | 8 + .../InvalidPayloadCRCException.java | 8 + .../InvalidPayloadException.java | 8 + .../InvalidPayloadLengthException.java | 8 + .../InvalidServicePasswordException.java | 8 + .../InvalidTBRDurationException.java | 8 + .../InvalidTBRFactorException.java | 8 + .../InvalidTBRTemplateException.java | 8 + .../InvalidTimeParameterException.java | 8 + ...InvalidValuesOfTwoChannelTransmission.java | 8 + ...berOfBolusTypeAlreadyRunningException.java | 8 + .../NoActiveTBRToCanceLException.java | 8 + .../NoActiveTBRToChangeException.java | 8 + .../NoConfigBlockDataException.java | 8 + .../NoServicePasswordNeededException.java | 8 + .../NoSuchBolusToCancelException.java | 8 + ...tAllowedToAccessPositionZeroException.java | 8 + .../NotConnectedException.java | 8 + .../NotReferencedException.java | 8 + .../PauseModeNotAllowedException.java | 8 + .../PositionProtectedException.java | 8 + .../PumpAlreadyInThatStateException.java | 8 + .../app_layer_errors/PumpBusyException.java | 8 + .../PumpStoppedException.java | 8 + ...ReadingHistoryAlreadyStartedException.java | 8 + .../ReadingHistoryNotStartedException.java | 8 + .../RunModeNotAllowedException.java | 8 + .../ServiceAlreadyActivatedException.java | 8 + .../ServiceCommandNotAvailableException.java | 8 + .../ServiceIncompatibleException.java | 8 + .../ServiceNotActivatedException.java | 8 + .../StepCountOutOfRangeException.java | 8 + .../UnknownAppLayerErrorCodeException.java | 8 + .../UnknownCommandException.java | 8 + .../UnknownServiceException.java | 8 + .../WriteSessionAlreadyOpenException.java | 8 + .../WriteSessionClosedException.java | 8 + .../app_layer_errors/WrongStateException.java | 8 + .../SatlCompatibleStateErrorException.java | 5 + ...SatlDecryptVerifyFailedErrorException.java | 5 + .../satl_errors/SatlErrorException.java | 7 + ...SatlIncompatibleVersionErrorException.java | 5 + .../SatlInvalidCRCErrorException.java | 5 + .../SatlInvalidCommIdErrorException.java | 5 + .../SatlInvalidMacErrorException.java | 5 + .../SatlInvalidMessageTypeErrorException.java | 5 + .../SatlInvalidNonceErrorException.java | 5 + .../SatlInvalidPacketErrorException.java | 5 + ...atlInvalidPayloadLengthErrorException.java | 5 + .../satl_errors/SatlNoneErrorException.java | 5 + .../SatlPairingRejectedException.java | 5 + .../SatlUndefinedErrorException.java | 5 + .../satl_errors/SatlWrongStateException.java | 5 + .../ids/ActiveBasalProfileIDs.java | 18 + .../ids/ActiveBolusTypeIDs.java | 16 + .../ids/AlertCategoryIDs.java | 17 + .../PumpInsightLocal/ids/AlertStatusIDs.java | 15 + .../PumpInsightLocal/ids/AlertTypeIDs.java | 39 + .../ids/AlertTypeIncrementalIDs.java | 39 + .../PumpInsightLocal/ids/AppCommandIDs.java | 81 + .../PumpInsightLocal/ids/AppErrorIDs.java | 121 ++ .../PumpInsightLocal/ids/BatteryTypeIDs.java | 16 + .../PumpInsightLocal/ids/BolusTypeIDs.java | 16 + .../ids/CartridgeTypeIDs.java | 15 + .../PumpInsightLocal/ids/HistoryEventIDs.java | 51 + .../ids/HistoryReadingDirectionIDs.java | 15 + .../ids/OperatingModeIDs.java | 16 + .../ids/PairingStatusIDs.java | 16 + .../ids/ParameterBlockIDs.java | 51 + .../PumpInsightLocal/ids/SatlCommandIDs.java | 39 + .../PumpInsightLocal/ids/SatlErrorIDs.java | 26 + .../PumpInsightLocal/ids/ServiceIDs.java | 18 + .../PumpInsightLocal/ids/SymbolStatusIDs.java | 16 + .../satl/ConnectionRequest.java | 4 + .../satl/ConnectionResponse.java | 4 + .../PumpInsightLocal/satl/DataMessage.java | 21 + .../satl/DisconnectMessage.java | 4 + .../PumpInsightLocal/satl/ErrorMessage.java | 18 + .../PumpInsightLocal/satl/KeyRequest.java | 39 + .../PumpInsightLocal/satl/KeyResponse.java | 24 + .../PumpInsightLocal/satl/PairingStatus.java | 8 + .../PumpInsightLocal/satl/SatlError.java | 18 + .../PumpInsightLocal/satl/SatlMessage.java | 182 +++ .../PumpInsightLocal/satl/SynAckResponse.java | 4 + .../PumpInsightLocal/satl/SynRequest.java | 4 + .../satl/VerifyConfirmRequest.java | 14 + .../satl/VerifyConfirmResponse.java | 18 + .../satl/VerifyDisplayRequest.java | 4 + .../satl/VerifyDisplayResponse.java | 4 + .../PumpInsightLocal/utils/BOCUtil.java | 8 + .../PumpInsightLocal/utils/ByteBuf.java | 384 +++++ .../utils/ConnectionEstablisher.java | 78 + .../utils/DelayedActionThread.java | 28 + .../utils/ExceptionTranslator.java | 55 + .../PumpInsightLocal/utils/IDStorage.java | 24 + .../utils/InputStreamReader.java | 51 + .../plugins/PumpInsightLocal/utils/Nonce.java | 47 + .../utils/OutputStreamWriter.java | 74 + .../utils/PairingDataStorage.java | 210 +++ .../utils/ParameterBlockUtil.java | 25 + .../PumpInsightLocal/utils/crypto/CRC.java | 44 + .../utils/crypto/Cryptograph.java | 215 +++ .../utils/crypto/DerivedKeys.java | 32 + .../utils/crypto/KeyPair.java | 28 + .../utils/crypto/VerificationString.java | 15 + .../androidaps/queue/CommandQueue.java | 18 + .../androidaps/queue/commands/Command.java | 5 +- .../CommandInsightSetTBROverNotification.java | 32 + .../queue/commands/CommandStartPump.java | 34 + .../queue/commands/CommandStopPump.java | 33 + app/src/main/res/drawable-hdpi/ic_error.png | Bin 0 -> 543 bytes .../main/res/drawable-hdpi/ic_maintenance.png | Bin 0 -> 509 bytes .../main/res/drawable-hdpi/ic_reminder.png | Bin 0 -> 1112 bytes app/src/main/res/drawable-hdpi/ic_warning.png | Bin 0 -> 483 bytes app/src/main/res/drawable-mdpi/ic_error.png | Bin 0 -> 374 bytes .../main/res/drawable-mdpi/ic_maintenance.png | Bin 0 -> 413 bytes .../main/res/drawable-mdpi/ic_reminder.png | Bin 0 -> 733 bytes app/src/main/res/drawable-mdpi/ic_warning.png | Bin 0 -> 336 bytes app/src/main/res/drawable-xhdpi/ic_error.png | Bin 0 -> 725 bytes .../res/drawable-xhdpi/ic_maintenance.png | Bin 0 -> 670 bytes .../main/res/drawable-xhdpi/ic_reminder.png | Bin 0 -> 1473 bytes .../main/res/drawable-xhdpi/ic_warning.png | Bin 0 -> 543 bytes app/src/main/res/drawable-xxhdpi/ic_error.png | Bin 0 -> 1099 bytes .../res/drawable-xxhdpi/ic_maintenance.png | Bin 0 -> 946 bytes .../main/res/drawable-xxhdpi/ic_reminder.png | Bin 0 -> 2238 bytes .../main/res/drawable-xxhdpi/ic_warning.png | Bin 0 -> 776 bytes .../main/res/drawable-xxxhdpi/ic_error.png | Bin 0 -> 1477 bytes .../res/drawable-xxxhdpi/ic_maintenance.png | Bin 0 -> 1260 bytes .../main/res/drawable-xxxhdpi/ic_reminder.png | Bin 0 -> 3012 bytes .../main/res/drawable-xxxhdpi/ic_warning.png | Bin 0 -> 977 bytes .../res/layout/activity_insight_alert.xml | 68 + .../res/layout/activity_insight_pairing.xml | 105 ++ .../activity_insight_pairing_information.xml | 168 +++ app/src/main/res/layout/bluetooth_device.xml | 11 + .../res/layout/local_insight_fragment.xml | 41 + .../local_insight_status_delimitter.xml | 7 + .../res/layout/local_insight_status_item.xml | 35 + .../main/res/values/insight_alert_codes.xml | 32 + .../res/values/insight_alert_descriptions.xml | 27 + .../main/res/values/insight_alert_titles.xml | 32 + .../main/res/values/insight_exceptions.xml | 14 + app/src/main/res/values/strings.xml | 55 + app/src/main/res/values/styles.xml | 8 + app/src/main/res/xml/pref_insight_local.xml | 51 + 308 files changed, 9992 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/EventLocalInsightUpdateGUI.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/InsightAlertService.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightFragment.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightPlugin.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightAlertActivity.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingActivity.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingInformationActivity.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/AppLayerMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/ReadParameterBlockMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/Service.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/CloseConfigurationWriteSessionMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/OpenConfigurationWriteSessionMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/WriteConfigurationBlockMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ActivateServiceMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/BindMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ConnectMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/DisconnectMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ServiceChallengeMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/HistoryReadingDirection.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/ReadHistoryEventsMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StartReadingHistoryMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StopReadingHistoryMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BasalDeliveryChangedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusDeliveredEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusProgrammedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CannulaFilledEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeInsertedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeRemovedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DateTimeChangedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DefaultDateTimeSetEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/EndOfTBREvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/HistoryEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfAlertEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfErrorEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfMaintenanceEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfWarningEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OperatingModeChangedEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerDownEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerUpEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/SniffingDoneEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/StartOfTBREvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TotalDailyDoseEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TubeFilledEvent.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ActiveBRProfileBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1Block.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2Block.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3Block.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4Block.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5Block.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfileBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBasalAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBolusAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBasalAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBolusAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/InsulinAmountLimitationBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBasalAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBolusAmountBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/NameBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ParameterBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/SystemIdentificationBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/TBROverNotificationBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelBolusMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelTBRMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ChangeTBRMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ConfirmAlertMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/DeliverBolusMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/GetAvailableBolusTypesMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetDateTimeMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetOperatingModeMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetTBRMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SnoozeAlertMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveAlertMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBasalRateMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBolusesMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveTBRMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetBatteryStatusMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetCartridgeStatusMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetDateTimeMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetFirmwareVersionsMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetOperatingModeMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetPumpStatusRegisterMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetTotalDailyDoseMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/ResetPumpStatusRegisterMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/ConfigurationMessageRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/InsightConnectionService.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageQueue.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightBolusID.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightHistoryOffset.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightPumpID.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBasalRate.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBolus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveTBR.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/Alert.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertCategory.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertType.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AvailableBolusTypes.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfile.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfileBlock.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryType.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BolusType.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeType.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/FirmwareVersions.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/InsightState.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/MessagePriority.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/OperatingMode.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/PumpTime.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SymbolStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SystemIdentification.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/TotalDailyDose.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/AppLayerException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/CommandNotSupportedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionFailedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionLostException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/DisconnectedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleAppVersionException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleSatlVersionException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InsightException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidAppCRCException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidMacTrailerException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidNonceException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPacketLengthsException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPreambleException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCRCException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCommandException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ReceivedPacketInInvalidStateException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SatlException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SecondChannelFailedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SocketCreationFailedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TimeoutException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TooChattyPumpException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownAppCommandException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownServiceException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AlreadyConnectedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AppLayerErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusAmountNotInRangeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusDurationNotInRangeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusLagTimeFeatureDisabledException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusTypeAndParameterMismatchException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CommandExecutionFailedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ConfigMemoryAccessException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CustomBolusNotConfiguredException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ImplausiblePortionLengthValueException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/IncompatibleVersionException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidAlertInstanceIdException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockCRCException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockIdException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockLengthException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDateParameterException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDurationPresetException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidLagTimeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidParameterTypeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadCRCException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadLengthException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidServicePasswordException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRDurationException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRFactorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRTemplateException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTimeParameterException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidValuesOfTwoChannelTransmission.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/MaximumNumberOfBolusTypeAlreadyRunningException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToCanceLException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToChangeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoConfigBlockDataException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoServicePasswordNeededException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoSuchBolusToCancelException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotAllowedToAccessPositionZeroException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotConnectedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotReferencedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PauseModeNotAllowedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PositionProtectedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpAlreadyInThatStateException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpBusyException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpStoppedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryAlreadyStartedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryNotStartedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/RunModeNotAllowedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceAlreadyActivatedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceCommandNotAvailableException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceIncompatibleException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceNotActivatedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/StepCountOutOfRangeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownAppLayerErrorCodeException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownCommandException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownServiceException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionAlreadyOpenException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionClosedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WrongStateException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlCompatibleStateErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlDecryptVerifyFailedErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlIncompatibleVersionErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCRCErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCommIdErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMacErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMessageTypeErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidNonceErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPacketErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPayloadLengthErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlNoneErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlPairingRejectedException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlUndefinedErrorException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlWrongStateException.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBasalProfileIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBolusTypeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertCategoryIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertStatusIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIncrementalIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppCommandIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppErrorIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BatteryTypeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BolusTypeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/CartridgeTypeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryEventIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryReadingDirectionIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/OperatingModeIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/PairingStatusIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ParameterBlockIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlCommandIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlErrorIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ServiceIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SymbolStatusIDs.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionResponse.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DataMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DisconnectMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ErrorMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyResponse.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/PairingStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlError.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlMessage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynAckResponse.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmResponse.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayRequest.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayResponse.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/BOCUtil.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ByteBuf.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ConnectionEstablisher.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/DelayedActionThread.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ExceptionTranslator.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/IDStorage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/InputStreamReader.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/Nonce.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/OutputStreamWriter.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/PairingDataStorage.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ParameterBlockUtil.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/CRC.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/Cryptograph.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/DerivedKeys.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/KeyPair.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/VerificationString.java create mode 100644 app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.java create mode 100644 app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.java create mode 100644 app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.java create mode 100644 app/src/main/res/drawable-hdpi/ic_error.png create mode 100644 app/src/main/res/drawable-hdpi/ic_maintenance.png create mode 100644 app/src/main/res/drawable-hdpi/ic_reminder.png create mode 100644 app/src/main/res/drawable-hdpi/ic_warning.png create mode 100644 app/src/main/res/drawable-mdpi/ic_error.png create mode 100644 app/src/main/res/drawable-mdpi/ic_maintenance.png create mode 100644 app/src/main/res/drawable-mdpi/ic_reminder.png create mode 100644 app/src/main/res/drawable-mdpi/ic_warning.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_error.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_maintenance.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_reminder.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_warning.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_error.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_maintenance.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_reminder.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_warning.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_error.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_maintenance.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_reminder.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_warning.png create mode 100644 app/src/main/res/layout/activity_insight_alert.xml create mode 100644 app/src/main/res/layout/activity_insight_pairing.xml create mode 100644 app/src/main/res/layout/activity_insight_pairing_information.xml create mode 100644 app/src/main/res/layout/bluetooth_device.xml create mode 100644 app/src/main/res/layout/local_insight_fragment.xml create mode 100644 app/src/main/res/layout/local_insight_status_delimitter.xml create mode 100644 app/src/main/res/layout/local_insight_status_item.xml create mode 100644 app/src/main/res/values/insight_alert_codes.xml create mode 100644 app/src/main/res/values/insight_alert_descriptions.xml create mode 100644 app/src/main/res/values/insight_alert_titles.xml create mode 100644 app/src/main/res/values/insight_exceptions.xml create mode 100644 app/src/main/res/xml/pref_insight_local.xml diff --git a/app/build.gradle b/app/build.gradle index bb01bf19d8..41992fb804 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -197,6 +197,7 @@ dependencies { implementation "com.google.android.gms:play-services-wearable:7.5.0" implementation(name: "android-edittext-validator-v1.3.4-mod", ext: "aar") implementation(name: "sightparser-release", ext: "aar") + implementation 'com.madgag.spongycastle:core:1.58.0.0' implementation("com.google.android:flexbox:0.3.0") { exclude group: "com.android.support" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 264132de25..f2df5688b7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,8 +30,8 @@ android:name=".MainApp" android:allowBackup="true" android:icon="${appIcon}" - android:roundIcon="${appIconRound}" android:label="@string/app_name" + android:roundIcon="${appIconRound}" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"> @@ -177,6 +177,8 @@ android:exported="false" /> + + + android:label="@string/title_activity_setup_wizard" + android:theme="@style/AppTheme.NoActionBar" /> - + + + \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 327e451225..2f38b5891d 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -59,6 +59,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; +import info.nightscout.androidaps.plugins.PumpInsightLocal.LocalInsightPlugin; import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.Sensitivity.SensitivityAAPSPlugin; @@ -157,6 +158,7 @@ public class MainApp extends Application { if (Config.PUMPDRIVERS) pluginsList.add(DanaRKoreanPlugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(DanaRv2Plugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin()); + if (Config.PUMPDRIVERS) pluginsList.add(LocalInsightPlugin.getInstance()); pluginsList.add(CareportalPlugin.getPlugin()); if (Config.PUMPDRIVERS && engineeringMode) pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 831e5bcc0d..f9011bc271 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -50,6 +50,9 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistor import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightBolusID; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightHistoryOffset; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightPumpID; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.utils.JsonHelper; import info.nightscout.utils.PercentageSplitter; @@ -76,8 +79,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_CAREPORTALEVENTS = "CareportalEvents"; public static final String DATABASE_PROFILESWITCHES = "ProfileSwitches"; public static final String DATABASE_TDDS = "TDDs"; + public static final String DATABASE_INSIGHT_HISTORY_OFFSETS = "InsightHistoryOffsets"; + public static final String DATABASE_INSIGHT_BOLUS_IDS = "InsightBolusIDs"; + public static final String DATABASE_INSIGHT_PUMP_IDS = "InsightPumpIDs"; - private static final int DATABASE_VERSION = 9; + private static final int DATABASE_VERSION = 10; public static Long earliestDataChange = null; @@ -122,6 +128,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { TableUtils.createTableIfNotExists(connectionSource, CareportalEvent.class); TableUtils.createTableIfNotExists(connectionSource, ProfileSwitch.class); TableUtils.createTableIfNotExists(connectionSource, TDD.class); + TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); + TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); + TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); } catch (SQLException e) { log.error("Can't create database", e); throw new RuntimeException(e); @@ -138,6 +147,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { log.debug("Upgrading database from v7 to v8"); } else if (oldVersion == 8 && newVersion == 9) { log.debug("Upgrading database from v8 to v9"); + } else if (oldVersion == 9 && newVersion == 10) { + TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); + TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); + TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); } else { log.info(DatabaseHelper.class.getName(), "onUpgrade"); TableUtils.dropTable(connectionSource, TempTarget.class, true); @@ -321,6 +334,18 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return getDao(ProfileSwitch.class); } + private Dao getDaoInsightPumpID() throws SQLException { + return getDao(InsightPumpID.class); + } + + private Dao getDaoInsightBolusID() throws SQLException { + return getDao(InsightBolusID.class); + } + + private Dao getDaoInsightHistoryOffset() throws SQLException { + return getDao(InsightHistoryOffset.class); + } + public static long roundDateToSec(long date) { long rounded = date - date % 1000; if (rounded != date) @@ -1143,6 +1168,17 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return false; } + public ExtendedBolus getExtendedBolusByPumpId(long pumpId) { + try { + return getDaoExtendedBolus().queryBuilder() + .where().eq("pumpId", pumpId) + .queryForFirst(); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return null; + } + public void delete(ExtendedBolus extendedBolus) { try { getDaoExtendedBolus().delete(extendedBolus); @@ -1650,5 +1686,67 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return null; } + // ---------------- Insight history handling --------------- + + public void createOrUpdate(InsightHistoryOffset offset) { + try { + getDaoInsightHistoryOffset().createOrUpdate(offset); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + } + + public InsightHistoryOffset getInsightHistoryOffset(String pumpSerial) { + try { + return getDaoInsightHistoryOffset().queryForId(pumpSerial); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return null; + } + + public void createOrUpdate(InsightBolusID bolusID) { + try { + getDaoInsightBolusID().createOrUpdate(bolusID); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + } + + public InsightBolusID getInsightBolusID(String pumpSerial, int bolusID, long timestamp) { + try { + return getDaoInsightBolusID().queryBuilder() + .where().eq("pumpSerial", pumpSerial) + .and().eq("bolusID", bolusID) + .and().between("timestamp", timestamp - 259200000, timestamp + 259200000) + .queryForFirst(); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return null; + } + + public void createOrUpdate(InsightPumpID pumpID) { + try { + getDaoInsightPumpID().createOrUpdate(pumpID); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + } + + public InsightPumpID getPumpStoppedEvent(String pumpSerial, long before) { + try { + return getDaoInsightPumpID().queryBuilder() + .orderBy("timestamp", false) + .where().eq("pumpSerial", pumpSerial) + .and().eq("eventType", "PumpStopped") + .and().lt("timestamp", before) + .queryForFirst(); + } catch (SQLException e) { + log.error("Unhandled exception", e); + } + return null; + } + // ---------------- Food handling --------------- } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java index f6f291ddc2..195b6c0eaa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java @@ -71,6 +71,7 @@ public class Notification { public static final int DEVICENOTPAIRED = 43; public static final int MEDTRONIC_PUMP_ALARM = 44; public static final int RILEYLINK_CONNECTION = 45; + public static final int INSIGHT_DATE_TIME_UPDATED = 46; public int id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/EventLocalInsightUpdateGUI.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/EventLocalInsightUpdateGUI.java new file mode 100644 index 0000000000..cc2fc15f86 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/EventLocalInsightUpdateGUI.java @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal; + +import info.nightscout.androidaps.events.EventUpdateGui; + +public class EventLocalInsightUpdateGUI extends EventUpdateGui { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/InsightAlertService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/InsightAlertService.java new file mode 100644 index 0000000000..e1799fcfab --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/InsightAlertService.java @@ -0,0 +1,226 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal; + +import android.app.Service; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Binder; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Vibrator; +import android.support.annotation.Nullable; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.activities.InsightAlertActivity; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.ConfirmAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SnoozeAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service.InsightConnectionService; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.Alert; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.InsightState; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ExceptionTranslator; + +public class InsightAlertService extends Service implements InsightConnectionService.StateCallback { + + private LocalBinder localBinder = new LocalBinder(); + private boolean connectionRequested; + private final Object $alertLock = new Object[0]; + private Alert alert; + private Thread thread; + private InsightAlertActivity alertActivity; + private Ringtone ringtone; + private Vibrator vibrator; + private boolean vibrating; + private InsightConnectionService connectionService; + private long ignoreTimestamp; + private AlertType ignoreType; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + connectionService = ((InsightConnectionService.LocalBinder) binder).getService(); + connectionService.registerStateCallback(InsightAlertService.this); + stateChanged(connectionService.getState()); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + connectionService = null; + } + }; + + private void retrieveRingtone() { + Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); + ringtone = RingtoneManager.getRingtone(this, uri); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ringtone.setAudioAttributes(new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) + .setLegacyStreamType(AudioManager.STREAM_RING).build()); + } else ringtone.setStreamType(AudioManager.STREAM_RING); + } + + public Alert getAlert() { + synchronized ($alertLock) { + return alert; + } + } + + public void setAlertActivity(InsightAlertActivity alertActivity) { + this.alertActivity = alertActivity; + } + + public void ignore(AlertType alertType) { + ignoreTimestamp = System.currentTimeMillis(); + ignoreType = alertType; + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return localBinder; + } + + @Override + public void onCreate() { + vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); + bindService(new Intent(this, InsightConnectionService.class), serviceConnection, BIND_AUTO_CREATE); + } + + @Override + public void onDestroy() { + if (thread != null) thread.interrupt(); + unbindService(serviceConnection); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + @Override + public void stateChanged(InsightState state) { + if (state == InsightState.CONNECTED) { + thread = new Thread(this::queryActiveAlert); + thread.start(); + + } else if (thread != null) thread.interrupt(); + } + + private void queryActiveAlert() { + while (!Thread.currentThread().isInterrupted()) { + try { + Alert alert = connectionService.requestMessage(new GetActiveAlertMessage()).await().getAlert(); + if (Thread.currentThread().isInterrupted()) { + connectionService.withdrawConnectionRequest(thread); + break; + } + synchronized ($alertLock) { + if ((this.alert == null && alert != null) + || (this.alert != null && alert == null) + || (this.alert != null && alert != null && !this.alert.equals(alert))) { + if (this.alert != null && (alert == null || this.alert.getAlertId() != alert.getAlertId())) stopAlerting(); + this.alert = alert; + if (alertActivity != null && alert != null) + new Handler(Looper.getMainLooper()).post(() -> alertActivity.update(alert)); + } + } + if (alert == null) { + stopAlerting(); + if (connectionRequested) { + connectionService.withdrawConnectionRequest(this); + connectionRequested = false; + } + if (alertActivity != null) + new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish()); + } else if (!(alert.getAlertType() == ignoreType && System.currentTimeMillis() - ignoreTimestamp < 10000)) { + if (alert.getAlertStatus() == AlertStatus.ACTIVE) alert(); + else stopAlerting(); + if (!connectionRequested) { + connectionService.requestConnection(this); + connectionRequested = true; + } + if (alertActivity == null) { + Intent intent = new Intent(InsightAlertService.this, InsightAlertActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + new Handler(Looper.getMainLooper()).post(() -> startActivity(intent)); + } + } + } catch (InterruptedException ignored) { + connectionService.withdrawConnectionRequest(thread); + break; + } catch (Exception ignored) { + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + break; + } + } + if (connectionRequested) { + connectionService.withdrawConnectionRequest(thread); + connectionRequested = false; + } + if (alertActivity != null) + new Handler(Looper.getMainLooper()).post(() -> alertActivity.finish()); + stopAlerting(); + thread = null; + } + + private void alert() { + if (!vibrating) { + vibrator.vibrate(new long[] {0, 1000, 1000}, 0); + vibrating = true; + } + if (ringtone == null || !ringtone.isPlaying()) { + retrieveRingtone(); + ringtone.play(); + } + } + + private void stopAlerting() { + if (vibrating) { + vibrator.cancel(); + vibrating = false; + } + if (ringtone != null && ringtone.isPlaying()) ringtone.stop(); + } + + public void mute() { + new Thread(() -> { + try { + SnoozeAlertMessage snoozeAlertMessage = new SnoozeAlertMessage(); + snoozeAlertMessage.setAlertID(alert.getAlertId()); + connectionService.requestMessage(snoozeAlertMessage).await(); + } catch (Exception e) { + ExceptionTranslator.makeToast(InsightAlertService.this, e); + } + }).start(); + } + + public void confirm() { + new Thread(() -> { + try { + ConfirmAlertMessage confirmAlertMessage = new ConfirmAlertMessage(); + confirmAlertMessage.setAlertID(alert.getAlertId()); + connectionService.requestMessage(confirmAlertMessage).await(); + } catch (Exception e) { + ExceptionTranslator.makeToast(InsightAlertService.this, e); + } + }).start(); + } + + public class LocalBinder extends Binder { + public InsightAlertService getService() { + return InsightAlertService.this; + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightFragment.java new file mode 100644 index 0000000000..ce29e208ad --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightFragment.java @@ -0,0 +1,284 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.squareup.otto.Subscribe; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.TBROverNotificationBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBasalRate; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBolus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveTBR; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.TotalDailyDose; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; + +public class LocalInsightFragment extends SubscriberFragment implements View.OnClickListener { + + private boolean viewsCreated; + private Button operatingMode; + private Button tbrOverNotification; + private LinearLayout statusItemContainer = null; + private Button refresh; + + private Callback operatingModeCallback; + private Callback tbrOverNotificationCallback; + private Callback refreshCallback; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.local_insight_fragment, container, false); + statusItemContainer = view.findViewById(R.id.status_item_container); + tbrOverNotification = view.findViewById(R.id.tbr_over_notification); + tbrOverNotification.setOnClickListener(this); + operatingMode = view.findViewById(R.id.operating_mode); + operatingMode.setOnClickListener(this); + refresh = view.findViewById(R.id.refresh); + refresh.setOnClickListener(this); + viewsCreated = true; + return view; + } + + @Override + public void onClick(View v) { + if (v == operatingMode) { + if (LocalInsightPlugin.getInstance().getOperatingMode() != null) { + operatingMode.setEnabled(false); + operatingModeCallback = new Callback() { + @Override + public void run() { + new Handler(Looper.getMainLooper()).post(() -> { + operatingModeCallback = null; + updateGUI(); + }); + } + }; + switch (LocalInsightPlugin.getInstance().getOperatingMode()) { + case PAUSED: + case STOPPED: + ConfigBuilderPlugin.getPlugin().getCommandQueue().startPump(operatingModeCallback); + break; + case STARTED: + ConfigBuilderPlugin.getPlugin().getCommandQueue().stopPump(operatingModeCallback); + } + } + } else if (v == tbrOverNotification) { + TBROverNotificationBlock notificationBlock = LocalInsightPlugin.getInstance().getTBROverNotificationBlock(); + if (notificationBlock != null) { + tbrOverNotification.setEnabled(false); + tbrOverNotificationCallback = new Callback() { + @Override + public void run() { + new Handler(Looper.getMainLooper()).post(() -> { + tbrOverNotificationCallback = null; + updateGUI(); + }); + } + }; + ConfigBuilderPlugin.getPlugin().getCommandQueue() + .setTBROverNotification(tbrOverNotificationCallback, !notificationBlock.isEnabled()); + } + } else if (v == refresh) { + refresh.setEnabled(false); + refreshCallback = new Callback() { + @Override + public void run() { + new Handler(Looper.getMainLooper()).post(() -> { + refreshCallback = null; + updateGUI(); + }); + } + }; + ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("InsightRefreshButton", refreshCallback); + } + } + + @Subscribe + public void onUpdateGUIEvent(EventLocalInsightUpdateGUI event) { + updateGUI(); + } + + @Override + protected void updateGUI() { + if (!viewsCreated) return; + statusItemContainer.removeAllViews(); + if (!LocalInsightPlugin.getInstance().isInitialized()) { + operatingMode.setVisibility(View.GONE); + tbrOverNotification.setVisibility(View.GONE); + refresh.setVisibility(View.GONE); + return; + } + refresh.setVisibility(View.VISIBLE); + refresh.setEnabled(refreshCallback == null); + TBROverNotificationBlock notificationBlock = LocalInsightPlugin.getInstance().getTBROverNotificationBlock(); + tbrOverNotification.setVisibility(notificationBlock == null ? View.GONE : View.VISIBLE); + if (notificationBlock != null) + tbrOverNotification.setText(notificationBlock.isEnabled() ? R.string.disable_tbr_over_notification : R.string.enable_tbr_over_notification); + tbrOverNotification.setEnabled(tbrOverNotificationCallback == null); + List statusItems = new ArrayList<>(); + getConnectionStatusItem(statusItems); + getLastConnectedItem(statusItems); + getOperatingModeItem(statusItems); + getBatteryStatusItem(statusItems); + getCartridgeStatusItem(statusItems); + getTDDItems(statusItems); + getBaseBasalRateItem(statusItems); + getTBRItem(statusItems); + getBolusItems(statusItems); + for (int i = 0; i < statusItems.size(); i++) { + statusItemContainer.addView(statusItems.get(i)); + if (i != statusItems.size() - 1) + getLayoutInflater().inflate(R.layout.local_insight_status_delimitter, statusItemContainer); + } + } + + private View getStatusItem(String label, String value) { + View statusItem = getLayoutInflater().inflate(R.layout.local_insight_status_item, null); + ((TextView) statusItem.findViewById(R.id.label)).setText(label); + ((TextView) statusItem.findViewById(R.id.value)).setText(value); + return statusItem; + } + + private void getConnectionStatusItem(List statusItems) { + int string = 0; + switch (LocalInsightPlugin.getInstance().getConnectionService().getState()) { + case NOT_PAIRED: + string = R.string.not_paired; + break; + case DISCONNECTED: + string = R.string.disconnected; + break; + case CONNECTING: + case SATL_CONNECTION_REQUEST: + case SATL_KEY_REQUEST: + case SATL_SYN_REQUEST: + case SATL_VERIFY_CONFIRM_REQUEST: + case SATL_VERIFY_DISPLAY_REQUEST: + case APP_ACTIVATE_PARAMETER_SERVICE: + case APP_ACTIVATE_STATUS_SERVICE: + case APP_BIND_MESSAGE: + case APP_CONNECT_MESSAGE: + case APP_FIRMWARE_VERSIONS: + case APP_SYSTEM_IDENTIFICATION: + case AWAITING_CODE_CONFIRMATION: + string = R.string.connecting; + break; + case CONNECTED: + string = R.string.connected; + break; + case RECOVERING: + string = R.string.recovering; + break; + } + statusItems.add(getStatusItem(MainApp.gs(R.string.insight_status), MainApp.gs(string))); + } + + private void getLastConnectedItem(List statusItems) { + switch (LocalInsightPlugin.getInstance().getConnectionService().getState()) { + case CONNECTED: + case NOT_PAIRED: + return; + default: + long lastConnection = LocalInsightPlugin.getInstance().getConnectionService().getLastConnected(); + if (lastConnection == 0) return; + int min = (int) ((System.currentTimeMillis() - lastConnection) / 60000); + statusItems.add(getStatusItem(MainApp.gs(R.string.last_connected), DateUtil.timeString(lastConnection))); + } + } + + private void getOperatingModeItem(List statusItems) { + if (LocalInsightPlugin.getInstance().getOperatingMode() == null) { + operatingMode.setVisibility(View.GONE); + return; + } + int string = 0; + operatingMode.setVisibility(View.VISIBLE); + operatingMode.setEnabled(operatingModeCallback == null); + switch (LocalInsightPlugin.getInstance().getOperatingMode()) { + case STARTED: + operatingMode.setText(R.string.stop_pump); + string = R.string.started; + break; + case STOPPED: + operatingMode.setText(R.string.start_pump); + string = R.string.stopped; + break; + case PAUSED: + operatingMode.setText(R.string.start_pump); + string = R.string.paused; + break; + } + statusItems.add(getStatusItem(MainApp.gs(R.string.operating_mode), MainApp.gs(string))); + } + + private void getBatteryStatusItem(List statusItems) { + if (LocalInsightPlugin.getInstance().getBatteryStatus() == null) return; + statusItems.add(getStatusItem(MainApp.gs(R.string.pump_battery_label), + LocalInsightPlugin.getInstance().getBatteryStatus().getBatteryAmount() + "%")); + } + + private void getCartridgeStatusItem(List statusItems) { + if (LocalInsightPlugin.getInstance().getCartridgeStatus() == null) return; + statusItems.add(getStatusItem(MainApp.gs(R.string.pump_reservoir_label), + DecimalFormatter.to2Decimal(LocalInsightPlugin.getInstance().getCartridgeStatus().getRemainingAmount()) + "U")); + } + + private void getTDDItems(List statusItems) { + if (LocalInsightPlugin.getInstance().getTotalDailyDose() == null) return; + TotalDailyDose tdd = LocalInsightPlugin.getInstance().getTotalDailyDose(); + statusItems.add(getStatusItem(MainApp.gs(R.string.tdd_bolus), DecimalFormatter.to2Decimal(tdd.getBolus()))); + statusItems.add(getStatusItem(MainApp.gs(R.string.tdd_basal), DecimalFormatter.to2Decimal(tdd.getBasal()))); + statusItems.add(getStatusItem(MainApp.gs(R.string.tdd_total), DecimalFormatter.to2Decimal(tdd.getBolusAndBasal()))); + } + + private void getBaseBasalRateItem(List statusItems) { + if (LocalInsightPlugin.getInstance().getActiveBasalRate() == null) return; + ActiveBasalRate activeBasalRate = LocalInsightPlugin.getInstance().getActiveBasalRate(); + statusItems.add(getStatusItem(MainApp.gs(R.string.pump_basebasalrate_label), + DecimalFormatter.to2Decimal(activeBasalRate.getActiveBasalRate()) + " U/h (" + activeBasalRate.getActiveBasalProfileName() + ")")); + } + + private void getTBRItem(List statusItems) { + if (LocalInsightPlugin.getInstance().getActiveTBR() == null) return; + ActiveTBR activeTBR = LocalInsightPlugin.getInstance().getActiveTBR(); + statusItems.add(getStatusItem(MainApp.gs(R.string.pump_tempbasal_label), + MainApp.gs(R.string.tbr_formatter, activeTBR.getPercentage(), activeTBR.getRemainingDuration(), activeTBR.getInitialDuration()))); + } + + private void getBolusItems(List statusItems) { + if (LocalInsightPlugin.getInstance().getActiveBoluses() == null) return; + for (ActiveBolus activeBolus : LocalInsightPlugin.getInstance().getActiveBoluses()) { + String label; + switch (activeBolus.getBolusType()) { + case MULTIWAVE: + label = MainApp.gs(R.string.multiwave_bolus); + break; + case EXTENDED: + label = MainApp.gs(R.string.extended_bolus); + break; + default: + continue; + } + statusItems.add(getStatusItem(label, MainApp.gs(R.string.eb_formatter, activeBolus.getRemainingAmount(), activeBolus.getInitialAmount(), activeBolus.getRemainingDuration()))); + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightPlugin.java new file mode 100644 index 0000000000..2c6268856d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/LocalInsightPlugin.java @@ -0,0 +1,1308 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TDD; +import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.events.EventInitializationChanged; +import info.nightscout.androidaps.events.EventRefreshOverview; +import info.nightscout.androidaps.interfaces.Constraint; +import info.nightscout.androidaps.interfaces.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginDescription; +import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; +import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.plugins.PumpCommon.defs.PumpType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.HistoryReadingDirection; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.ReadHistoryEventsMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.StartReadingHistoryMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.StopReadingHistoryMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.BolusDeliveredEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.BolusProgrammedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.CannulaFilledEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.DateTimeChangedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.DefaultDateTimeSetEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.EndOfTBREvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.HistoryEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OccurrenceOfAlertEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OperatingModeChangedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.PowerUpEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.SniffingDoneEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.StartOfTBREvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.TotalDailyDoseEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.TubeFilledEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile1Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile2Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile3Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile4Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile5Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfileBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.FactoryMinBolusAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.MaxBasalAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.MaxBolusAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.TBROverNotificationBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.CancelBolusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.CancelTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.ChangeTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.ConfirmAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.DeliverBolusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetDateTimeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetOperatingModeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveBasalRateMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveBolusesMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetBatteryStatusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetCartridgeStatusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetDateTimeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetOperatingModeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetPumpStatusRegisterMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetTotalDailyDoseMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.ResetPumpStatusRegisterMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service.InsightConnectionService; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightBolusID; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightHistoryOffset; +import info.nightscout.androidaps.plugins.PumpInsightLocal.database.InsightPumpID; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBasalRate; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBolus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveTBR; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BasalProfileBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BatteryStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.CartridgeStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.InsightState; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.OperatingMode; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.PumpTime; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.TotalDailyDose; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoActiveTBRToCanceLException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ExceptionTranslator; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ParameterBlockUtil; +import info.nightscout.androidaps.plugins.Treatments.Treatment; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.SP; + +public class LocalInsightPlugin extends PluginBase implements PumpInterface, ConstraintsInterface, InsightConnectionService.StateCallback { + + private static LocalInsightPlugin instance = null; + + private Logger log = LoggerFactory.getLogger(L.PUMP); + + private PumpDescription pumpDescription; + private InsightAlertService alertService; + private InsightConnectionService connectionService; + private List temporaryBasals; + private List pumpStartedEvents; + private long timeOffset; + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + if (binder instanceof InsightConnectionService.LocalBinder) { + connectionService = ((InsightConnectionService.LocalBinder) binder).getService(); + connectionService.registerStateCallback(LocalInsightPlugin.this); + } else if (binder instanceof InsightAlertService.LocalBinder) { + alertService = ((InsightAlertService.LocalBinder) binder).getService(); + } + if (connectionService != null && alertService != null) MainApp.bus().post(new EventInitializationChanged()); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + connectionService = null; + } + }; + + private int bolusID = -1; + private List profileBlocks; + private boolean limitsFetched; + private double maximumBolusAmount; + private double maximumBasalAmount; + private double minimumBolusAmount; + private double minimumBasalAmount; + private long lastUpdated = -1; + private OperatingMode operatingMode; + private BatteryStatus batteryStatus; + private CartridgeStatus cartridgeStatus; + private TotalDailyDose totalDailyDose; + private ActiveBasalRate activeBasalRate; + private ActiveTBR activeTBR; + private List activeBoluses; + private boolean statusLoaded; + private TBROverNotificationBlock tbrOverNotificationBlock; + + public static LocalInsightPlugin getInstance() { + if (instance == null) instance = new LocalInsightPlugin(); + return instance; + } + + public LocalInsightPlugin() { + super(new PluginDescription() + .pluginName(R.string.insight_local) + .shortName(R.string.insightpump_shortname) + .mainType(PluginType.PUMP) + .description(R.string.description_pump_insight_local) + .fragmentClass(LocalInsightFragment.class.getName()) + .preferencesId(R.xml.pref_insight_local)); + + pumpDescription = new PumpDescription(); + pumpDescription.setPumpDescription(PumpType.AccuChekInsight); + } + + public TBROverNotificationBlock getTBROverNotificationBlock() { + return tbrOverNotificationBlock; + } + + public long getLastUpdated() { + return lastUpdated; + } + + public InsightConnectionService getConnectionService() { + return connectionService; + } + + public OperatingMode getOperatingMode() { + return operatingMode; + } + + public BatteryStatus getBatteryStatus() { + return batteryStatus; + } + + public CartridgeStatus getCartridgeStatus() { + return cartridgeStatus; + } + + public TotalDailyDose getTotalDailyDose() { + return totalDailyDose; + } + + public ActiveBasalRate getActiveBasalRate() { + return activeBasalRate; + } + + public ActiveTBR getActiveTBR() { + return activeTBR; + } + + public List getActiveBoluses() { + return activeBoluses; + } + + @Override + protected void onStart() { + super.onStart(); + MainApp.instance().bindService(new Intent(MainApp.instance(), InsightConnectionService.class), serviceConnection, Context.BIND_AUTO_CREATE); + MainApp.instance().bindService(new Intent(MainApp.instance(), InsightAlertService.class), serviceConnection, Context.BIND_AUTO_CREATE); + } + + @Override + protected void onStop() { + super.onStop(); + MainApp.instance().unbindService(serviceConnection); + } + + @Override + public boolean isInitialized() { + return connectionService != null && alertService != null && connectionService.isPaired(); + } + + @Override + public boolean isSuspended() { + return operatingMode != null && operatingMode != OperatingMode.STARTED; + } + + @Override + public boolean isBusy() { + return false; + } + + @Override + public boolean isConnected() { + if (connectionService == null || alertService == null) return false; + return connectionService.getState() == InsightState.CONNECTED; + } + + @Override + public boolean isConnecting() { + if (connectionService == null || alertService == null) return false; + InsightState state = connectionService.getState(); + return state == InsightState.CONNECTING + || state == InsightState.APP_CONNECT_MESSAGE + || state == InsightState.RECOVERING; + } + + @Override + public boolean isHandshakeInProgress() { + return false; + } + + @Override + public void finishHandshaking() { + + } + + @Override + public void connect(String reason) { + if (connectionService != null && alertService != null) connectionService.requestConnection(this); + } + + @Override + public void disconnect(String reason) { + if (connectionService != null && alertService != null) connectionService.withdrawConnectionRequest(this); + } + + @Override + public void stopConnecting() { + if (connectionService != null && alertService != null) connectionService.withdrawConnectionRequest(this); + } + + @Override + public void getPumpStatus() { + try { + tbrOverNotificationBlock = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, TBROverNotificationBlock.class); + fetchStatus(); + fetchBasalProfile(); + fetchLimitations(); + updatePumpTimeIfNeeded(); + readHistory(); + } catch (Exception e) { + log.info("Error while fetching status: " + e.getClass().getCanonicalName()); + } + } + + private void updatePumpTimeIfNeeded() throws Exception { + PumpTime pumpTime = connectionService.requestMessage(new GetDateTimeMessage()).await().getPumpTime(); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, pumpTime.getYear()); + calendar.set(Calendar.MONTH, pumpTime.getMonth() - 1); + calendar.set(Calendar.DAY_OF_MONTH, pumpTime.getDay()); + calendar.set(Calendar.HOUR_OF_DAY, pumpTime.getHour()); + calendar.set(Calendar.MINUTE, pumpTime.getMinute()); + calendar.set(Calendar.SECOND, pumpTime.getSecond()); + if (Math.abs(calendar.getTimeInMillis() - System.currentTimeMillis()) > 10000) { + calendar.setTime(new Date()); + pumpTime.setYear(calendar.get(Calendar.YEAR)); + pumpTime.setMonth(calendar.get(Calendar.MONTH) + 1); + pumpTime.setDay(calendar.get(Calendar.DAY_OF_MONTH)); + pumpTime.setHour(calendar.get(Calendar.HOUR_OF_DAY)); + pumpTime.setMinute(calendar.get(Calendar.MINUTE)); + pumpTime.setSecond(calendar.get(Calendar.SECOND)); + SetDateTimeMessage setDateTimeMessage = new SetDateTimeMessage(); + setDateTimeMessage.setPumpTime(pumpTime); + connectionService.requestMessage(setDateTimeMessage).await(); + Notification notification = new Notification(Notification.INSIGHT_DATE_TIME_UPDATED, MainApp.gs(R.string.pump_time_updated), Notification.INFO, 60); + MainApp.bus().post(new EventNewNotification(notification)); + } + } + + private void fetchBasalProfile() throws Exception { + Class parameterBlock = null; + switch (activeBasalRate.getActiveBasalProfile()) { + case PROFILE_1: + parameterBlock = BRProfile1Block.class; + break; + case PROFILE_2: + parameterBlock = BRProfile2Block.class; + break; + case PROFILE_3: + parameterBlock = BRProfile3Block.class; + break; + case PROFILE_4: + parameterBlock = BRProfile4Block.class; + break; + case PROFILE_5: + parameterBlock = BRProfile5Block.class; + break; + } + profileBlocks = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, parameterBlock).getProfileBlocks(); + } + + private void fetchStatus() throws Exception { + if (statusLoaded) { + GetPumpStatusRegisterMessage registerMessage = connectionService.requestMessage(new GetPumpStatusRegisterMessage()).await(); + ResetPumpStatusRegisterMessage resetMessage = new ResetPumpStatusRegisterMessage(); + resetMessage.setOperatingModeChanged(registerMessage.isOperatingModeChanged()); + resetMessage.setBatteryStatusChanged(registerMessage.isBatteryStatusChanged()); + resetMessage.setCartridgeStatusChanged(registerMessage.isCartridgeStatusChanged()); + resetMessage.setTotalDailyDoseChanged(registerMessage.isTotalDailyDoseChanged()); + resetMessage.setActiveTBRChanged(registerMessage.isActiveTBRChanged()); + resetMessage.setActiveBolusesChanged(registerMessage.isActiveBolusesChanged()); + connectionService.requestMessage(resetMessage).await(); + if (registerMessage.isOperatingModeChanged()) + operatingMode = connectionService.requestMessage(new GetOperatingModeMessage()).await().getOperatingMode(); + if (registerMessage.isBatteryStatusChanged()) + batteryStatus = connectionService.requestMessage(new GetBatteryStatusMessage()).await().getBatteryStatus(); + if (registerMessage.isCartridgeStatusChanged()) + cartridgeStatus = connectionService.requestMessage(new GetCartridgeStatusMessage()).await().getCartridgeStatus(); + if (registerMessage.isTotalDailyDoseChanged()) + totalDailyDose = connectionService.requestMessage(new GetTotalDailyDoseMessage()).await().getTDD(); + if (registerMessage.isActiveBasalRateChanged()) + activeBasalRate = connectionService.requestMessage(new GetActiveBasalRateMessage()).await().getActiveBasalRate(); + if (registerMessage.isActiveTBRChanged()) + activeTBR = connectionService.requestMessage(new GetActiveTBRMessage()).await().getActiveTBR(); + if (registerMessage.isActiveBolusesChanged()) + activeBoluses = connectionService.requestMessage(new GetActiveBolusesMessage()).await().getActiveBoluses(); + + } else { + ResetPumpStatusRegisterMessage resetMessage = new ResetPumpStatusRegisterMessage(); + resetMessage.setOperatingModeChanged(true); + resetMessage.setBatteryStatusChanged(true); + resetMessage.setCartridgeStatusChanged(true); + resetMessage.setTotalDailyDoseChanged(true); + resetMessage.setActiveBasalRateChanged(true); + resetMessage.setActiveTBRChanged(true); + resetMessage.setActiveBolusesChanged(true); + connectionService.requestMessage(resetMessage).await(); + operatingMode = connectionService.requestMessage(new GetOperatingModeMessage()).await().getOperatingMode(); + batteryStatus = connectionService.requestMessage(new GetBatteryStatusMessage()).await().getBatteryStatus(); + cartridgeStatus = connectionService.requestMessage(new GetCartridgeStatusMessage()).await().getCartridgeStatus(); + totalDailyDose = connectionService.requestMessage(new GetTotalDailyDoseMessage()).await().getTDD(); + activeBasalRate = connectionService.requestMessage(new GetActiveBasalRateMessage()).await().getActiveBasalRate(); + activeTBR = connectionService.requestMessage(new GetActiveTBRMessage()).await().getActiveTBR(); + activeBoluses = connectionService.requestMessage(new GetActiveBolusesMessage()).await().getActiveBoluses(); + statusLoaded = true; + } + lastUpdated = System.currentTimeMillis(); + new Handler(Looper.getMainLooper()).post(() -> { + MainApp.bus().post(new EventLocalInsightUpdateGUI()); + MainApp.bus().post(new EventRefreshOverview("LocalInsightPlugin::fetchStatus")); + }); + } + + private void fetchLimitations() throws Exception { + maximumBolusAmount = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, MaxBolusAmountBlock.class).getAmountLimitation(); + maximumBasalAmount = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, MaxBasalAmountBlock.class).getAmountLimitation(); + minimumBolusAmount = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, FactoryMinBolusAmountBlock.class).getAmountLimitation(); + minimumBasalAmount = ParameterBlockUtil.readParameterBlock(connectionService, Service.CONFIGURATION, FactoryMinBolusAmountBlock.class).getAmountLimitation(); + this.pumpDescription.basalMaximumRate = maximumBasalAmount; + this.pumpDescription.basalMinimumRate = minimumBasalAmount; + limitsFetched = true; + } + + @Override + public PumpEnactResult setNewBasalProfile(Profile profile) { + PumpEnactResult result = new PumpEnactResult(); + MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); + List profileBlocks = new ArrayList<>(); + for (int i = 0; i < profile.getBasalValues().length; i++) { + Profile.BasalValue basalValue = profile.getBasalValues()[i]; + Profile.BasalValue nextValue = null; + if (profile.getBasalValues().length > i + 1) + nextValue = profile.getBasalValues()[i + 1]; + BasalProfileBlock profileBlock = new BasalProfileBlock(); + profileBlock.setBasalAmount(basalValue.value); + profileBlock.setDuration((((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60)); + profileBlocks.add(profileBlock); + } + try { + BRProfileBlock profileBlock = null; + switch(activeBasalRate.getActiveBasalProfile()) { + case PROFILE_1: + profileBlock = new BRProfile1Block(); + break; + case PROFILE_2: + profileBlock = new BRProfile2Block(); + break; + case PROFILE_3: + profileBlock = new BRProfile3Block(); + break; + case PROFILE_4: + profileBlock = new BRProfile4Block(); + break; + case PROFILE_5: + profileBlock = new BRProfile5Block(); + break; + } + profileBlock.setProfileBlocks(profileBlocks); + ParameterBlockUtil.writeConfigurationBlock(connectionService, profileBlock); + MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); + Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); + MainApp.bus().post(new EventNewNotification(notification)); + result.success = true; + result.enacted = true; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + this.profileBlocks = profileBlocks; + try { + fetchStatus(); + } catch (Exception ignored) { + } + } catch (Exception e) { + Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.gs(R.string.failedupdatebasalprofile), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public boolean isThisProfileSet(Profile profile) { + if (!isInitialized() || profileBlocks == null) return true; + if (profile.getBasalValues().length != profileBlocks.size()) return false; + for (int i = 0; i < profileBlocks.size(); i++) { + BasalProfileBlock profileBlock = profileBlocks.get(i); + Profile.BasalValue basalValue = profile.getBasalValues()[i]; + Profile.BasalValue nextValue = null; + if (profile.getBasalValues().length > i + 1) + nextValue = profile.getBasalValues()[i + 1]; + if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) + return false; + if (Math.abs(profileBlock.getBasalAmount() - basalValue.value) > 0.01D) + return false; + } + return true; + } + + @Override + public long lastDataTime() { + if (connectionService == null || alertService == null) return System.currentTimeMillis(); + return connectionService.getLastDataTime(); + } + + @Override + public double getBaseBasalRate() { + if (connectionService == null || alertService == null) return 0; + if (activeBasalRate != null) return activeBasalRate.getActiveBasalRate(); + else return 0; + } + + @Override + public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { + PumpEnactResult result = new PumpEnactResult(); + if (detailedBolusInfo.insulin > 0) { + try { + DeliverBolusMessage bolusMessage = new DeliverBolusMessage(); + bolusMessage.setBolusType(BolusType.STANDARD); + bolusMessage.setDuration(0); + bolusMessage.setExtendedAmount(0); + bolusMessage.setImmediateAmount(detailedBolusInfo.insulin); + bolusID = connectionService.requestMessage(bolusMessage).await().getBolusId(); + result.success = true; + result.enacted = true; + Treatment t = new Treatment(); + t.isSMB = detailedBolusInfo.isSMB; + final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); + bolusingEvent.t = t; + bolusingEvent.status = MainApp.gs(R.string.insight_delivered, 0d, 0d); + bolusingEvent.percent = 0; + MainApp.bus().post(bolusingEvent); + int trials = 0; + InsightBolusID insightBolusID = new InsightBolusID(); + insightBolusID.bolusID = bolusID; + insightBolusID.timestamp = System.currentTimeMillis(); + insightBolusID.pumpSerial = connectionService.getPumpSystemIdentification().getSerialNumber(); + MainApp.getDbHelper().createOrUpdate(insightBolusID); + detailedBolusInfo.date = insightBolusID.timestamp; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = insightBolusID.id; + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); + while (true) { + List activeBoluses = connectionService.requestMessage(new GetActiveBolusesMessage()).await().getActiveBoluses(); + ActiveBolus activeBolus = null; + for (ActiveBolus bolus : activeBoluses) { + if (bolus.getBolusID() == bolusID) activeBolus = bolus; + } + if (activeBolus != null) { + trials = -1; + int percentBefore = bolusingEvent.percent; + bolusingEvent.percent = (int) (100D / activeBolus.getInitialAmount() * (activeBolus.getInitialAmount() - activeBolus.getRemainingAmount())); + bolusingEvent.status = MainApp.gs(R.string.insight_delivered, activeBolus.getInitialAmount() - activeBolus.getRemainingAmount(), activeBolus.getInitialAmount()); + if (percentBefore != bolusingEvent.percent) MainApp.bus().post(bolusingEvent); + } else if (trials == -1 || trials++ >=5) break; + Thread.sleep(200); + } + readHistory(); + fetchStatus(); + } catch (Exception e) { + e.printStackTrace(); + log.info("Exception while delivering bolus: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + } else if (detailedBolusInfo.carbs > 0) { + result.success = true; + result.enacted = true; + } + result.carbsDelivered = detailedBolusInfo.carbs; + return result; + } + + @Override + public void stopBolusDelivering() { + new Thread(() -> { + try { + alertService.ignore(AlertType.WARNING_38); + CancelBolusMessage cancelBolusMessage = new CancelBolusMessage(); + cancelBolusMessage.setBolusID(bolusID); + connectionService.requestMessage(cancelBolusMessage).await(); + confirmAlert(AlertType.WARNING_38); + } catch (Exception e) { + log.info("Exception while canceling bolus: " + e.getClass().getCanonicalName()); + } + }).start(); + } + + @Override + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { + PumpEnactResult result = new PumpEnactResult(); + if (activeBasalRate == null) return result; + double percent = 100D / activeBasalRate.getActiveBasalRate() * absoluteRate; + try { + if (isFakingTempsByExtendedBoluses()) { + PumpEnactResult cancelResult = cancelTempBasal(true); + if (cancelResult.success) { + if (percent > 250) { + PumpEnactResult ebResult = setExtendedBolus((absoluteRate - getBaseBasalRate()) / 60D * ((double) durationInMinutes), durationInMinutes); + if (ebResult.success) { + result.success = true; + result.enacted = true; + result.isPercent = false; + result.absolute = absoluteRate; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + } else result.comment = ebResult.comment; + } else return setTempBasalPercent((int) percent, durationInMinutes, profile, enforceNew); + } else result.comment = cancelResult.comment; + } else return setTempBasalPercent((int) percent, durationInMinutes, profile, enforceNew); + } catch (Exception e) { + log.info("Error while setting TBR: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { + PumpEnactResult result = new PumpEnactResult(); + percent = (int) Math.round(((double) percent) / 10d) * 10; + if (percent == 100) return cancelTempBasal(true); + else if (percent > 250) percent = 250; + try { + if (activeTBR != null) { + ChangeTBRMessage message = new ChangeTBRMessage(); + message.setDuration(durationInMinutes); + message.setPercentage(percent); + connectionService.requestMessage(message); + } else { + SetTBRMessage message = new SetTBRMessage(); + message.setDuration(durationInMinutes); + message.setPercentage(percent); + connectionService.requestMessage(message); + } + result.isPercent = true; + result.percent = percent; + result.success = true; + result.enacted = true; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + readHistory(); + fetchStatus(); + } catch (Exception e) { + log.info("Error while setting TBR: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { + PumpEnactResult result = new PumpEnactResult(); + try { + DeliverBolusMessage bolusMessage = new DeliverBolusMessage(); + bolusMessage.setBolusType(BolusType.EXTENDED); + bolusMessage.setDuration(durationInMinutes); + bolusMessage.setExtendedAmount(insulin); + bolusMessage.setImmediateAmount(0); + int bolusID = connectionService.requestMessage(bolusMessage).await().getBolusId(); + InsightBolusID insightBolusID = new InsightBolusID(); + insightBolusID.bolusID = bolusID; + insightBolusID.timestamp = System.currentTimeMillis(); + insightBolusID.pumpSerial = connectionService.getPumpSystemIdentification().getSerialNumber(); + MainApp.getDbHelper().createOrUpdate(insightBolusID); + ExtendedBolus extendedBolus = new ExtendedBolus(); + extendedBolus.date = insightBolusID.timestamp; + extendedBolus.source = Source.PUMP; + extendedBolus.durationInMinutes = durationInMinutes; + extendedBolus.insulin = insulin; + extendedBolus.pumpId = insightBolusID.id; + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + result.success = true; + result.enacted = true; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + readHistory(); + fetchStatus(); + } catch (Exception e) { + log.info("Exception while delivering extended bolus: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public PumpEnactResult cancelTempBasal(boolean enforceNew) { + PumpEnactResult result = new PumpEnactResult(); + try { + PumpEnactResult cancelEBResult = null; + if (isFakingTempsByExtendedBoluses()) cancelEBResult = cancelExtendedBolus(); + connectionService.requestMessage(new CancelTBRMessage()).await(); + result.success = true; + result.enacted = true; + result.isTempCancel = true; + confirmAlert(AlertType.WARNING_36); + result.comment = MainApp.gs(R.string.virtualpump_resultok); + if (isFakingTempsByExtendedBoluses() && !cancelEBResult.success) { + result.success = false; + result.enacted = false; + } + readHistory(); + fetchStatus(); + } catch (NoActiveTBRToCanceLException e) { + result.success = true; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + } catch (Exception e) { + log.info("Exception while canceling TBR: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public PumpEnactResult cancelExtendedBolus() { + PumpEnactResult result = new PumpEnactResult(); + try { + for (ActiveBolus activeBolus : activeBoluses) { + if (activeBolus.getBolusType() == BolusType.EXTENDED || activeBolus.getBolusType() == BolusType.MULTIWAVE) { + alertService.ignore(AlertType.WARNING_38); + CancelBolusMessage cancelBolusMessage = new CancelBolusMessage(); + cancelBolusMessage.setBolusID(activeBolus.getBolusID()); + connectionService.requestMessage(cancelBolusMessage).await(); + confirmAlert(AlertType.WARNING_38); + InsightBolusID insightBolusID = MainApp.getDbHelper().getInsightBolusID(connectionService.getPumpSystemIdentification().getSerialNumber(), + activeBolus.getBolusID(), System.currentTimeMillis()); + if (insightBolusID != null) { + ExtendedBolus extendedBolus = MainApp.getDbHelper().getExtendedBolusByPumpId(insightBolusID.id); + if (extendedBolus != null) { + extendedBolus.durationInMinutes = (int) ((System.currentTimeMillis() - extendedBolus.date) / 60000); + if (extendedBolus.durationInMinutes <= 0) {; + final String _id = extendedBolus._id; + if (NSUpload.isIdValid(_id)) NSUpload.removeCareportalEntryFromNS(_id); + else UploadQueue.removeID("dbAdd", _id); + MainApp.getDbHelper().delete(extendedBolus); + } else TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + } + result.enacted = true; + result.success = true; + } + } + } + result.success = true; + result.comment = MainApp.gs(R.string.virtualpump_resultok); + readHistory(); + fetchStatus(); + } catch (Exception e) { + log.info("Exception while canceling bolus: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + private void confirmAlert(AlertType alertType) { + try { + long started = System.currentTimeMillis(); + while (System.currentTimeMillis() - started < 10000) { + GetActiveAlertMessage activeAlertMessage = connectionService.requestMessage(new GetActiveAlertMessage()).await(); + if (activeAlertMessage.getAlert() != null) { + if (activeAlertMessage.getAlert().getAlertType() == alertType) { + ConfirmAlertMessage confirmMessage = new ConfirmAlertMessage(); + confirmMessage.setAlertID(activeAlertMessage.getAlert().getAlertId()); + connectionService.requestMessage(confirmMessage).await(); + } else break; + } + } + } catch (Exception e) { + log.info("Error while confirming alert: " + e.getClass().getCanonicalName()); + } + } + + @Override + public JSONObject getJSONStatus(Profile profile, String profileName) { + return new JSONObject(); + } + + @Override + public String deviceID() { + if (connectionService == null || alertService == null) return null; + return connectionService.getPumpSystemIdentification().getSerialNumber(); + } + + public PumpEnactResult stopPump() { + PumpEnactResult result = new PumpEnactResult(); + try { + SetOperatingModeMessage operatingModeMessage = new SetOperatingModeMessage(); + operatingModeMessage.setOperatingMode(OperatingMode.STOPPED); + connectionService.requestMessage(operatingModeMessage).await(); + result.success = true; + result.enacted = true; + fetchStatus(); + readHistory(); + } catch (Exception e) { + log.info("Error while stopping pump: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + public PumpEnactResult startPump() { + PumpEnactResult result = new PumpEnactResult(); + try { + SetOperatingModeMessage operatingModeMessage = new SetOperatingModeMessage(); + operatingModeMessage.setOperatingMode(OperatingMode.STARTED); + connectionService.requestMessage(operatingModeMessage).await(); + result.success = true; + result.enacted = true; + fetchStatus(); + readHistory(); + } catch (Exception e) { + log.info("Error while starting pump: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + public PumpEnactResult setTBROverNotification(boolean enabled) { + PumpEnactResult result = new PumpEnactResult(); + boolean valueBefore = tbrOverNotificationBlock.isEnabled(); + tbrOverNotificationBlock.setEnabled(enabled); + try { + ParameterBlockUtil.writeConfigurationBlock(connectionService, tbrOverNotificationBlock); + result.success = true; + result.enacted = true; + } catch (Exception e) { + tbrOverNotificationBlock.setEnabled(valueBefore); + log.info("Error while starting pump: " + e.getClass().getCanonicalName()); + result.comment = ExceptionTranslator.getString(e); + } + return result; + } + + @Override + public PumpDescription getPumpDescription() { + return pumpDescription; + } + + @Override + public String shortStatus(boolean veryShort) { + return ""; + } + + @Override + public boolean isFakingTempsByExtendedBoluses() { + return true; + } + + @Override + public PumpEnactResult loadTDDs() { + return new PumpEnactResult().success(true); + } + + private void readHistory() { + try { + PumpTime pumpTime = connectionService.requestMessage(new GetDateTimeMessage()).await().getPumpTime(); + String pumpSerial = connectionService.getPumpSystemIdentification().getSerialNumber(); + timeOffset = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() - parseDate(pumpTime.getYear(), + pumpTime.getMonth(), pumpTime.getDay(), pumpTime.getHour(), pumpTime.getMinute(), pumpTime.getSecond()); + InsightHistoryOffset historyOffset = MainApp.getDbHelper().getInsightHistoryOffset(pumpSerial); + try { + List historyEvents = new ArrayList<>(); + if (historyOffset == null) { + StartReadingHistoryMessage startMessage = new StartReadingHistoryMessage(); + startMessage.setDirection(HistoryReadingDirection.BACKWARD); + startMessage.setOffset(0xFFFFFFFF); + connectionService.requestMessage(startMessage).await(); + for (int i = 0; i < 50; i++) { + List newEvents = connectionService.requestMessage(new ReadHistoryEventsMessage()).await().getHistoryEvents(); + if (newEvents.size() == 0) break; + historyEvents.addAll(newEvents); + } + } else { + StartReadingHistoryMessage startMessage = new StartReadingHistoryMessage(); + startMessage.setDirection(HistoryReadingDirection.FORWARD); + startMessage.setOffset(historyOffset.offset + 1); + connectionService.requestMessage(startMessage).await(); + while (true) { + List newEvents = connectionService.requestMessage(new ReadHistoryEventsMessage()).await().getHistoryEvents(); + if (newEvents.size() == 0) break; + historyEvents.addAll(newEvents); + } + } + processHistoryEvents(pumpSerial, historyEvents); + } catch (Exception e) { + e.printStackTrace(); + log.info("Error while reading history: " + e.getClass().getSimpleName()); + } finally { + try { + connectionService.requestMessage(new StopReadingHistoryMessage()).await(); + } catch (Exception ignored) { + } + } + } catch (Exception e) { + log.info("Error while reading history: " + e.getClass().getSimpleName()); + } + new Handler(Looper.getMainLooper()).post(() -> MainApp.bus().post(new EventRefreshOverview("LocalInsightPlugin::readHistory"))); + } + + private void processHistoryEvents(String serial, List historyEvents) { + Collections.sort(historyEvents); + Collections.reverse(historyEvents); + temporaryBasals = new ArrayList<>(); + pumpStartedEvents = new ArrayList<>(); + for (HistoryEvent historyEvent : historyEvents) + if (!processHistoryEvent(serial, historyEvent)) break; + Collections.reverse(temporaryBasals); + for (TemporaryBasal temporaryBasal : temporaryBasals) TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); + for (InsightPumpID pumpID : pumpStartedEvents) { + long tbrStart = MainApp.getDbHelper().getPumpStoppedEvent(pumpID.pumpSerial, pumpID.timestamp).timestamp + 10000; + TemporaryBasal temporaryBasal = new TemporaryBasal(); + temporaryBasal.durationInMinutes = (int) ((pumpID.timestamp - tbrStart) / 60000); + temporaryBasal.date = tbrStart; + temporaryBasal.source = Source.PUMP; + temporaryBasal.pumpId = pumpID.id; + temporaryBasal.percentRate = 0; + temporaryBasal.isAbsolute = false; + TreatmentsPlugin.getPlugin().addToHistoryTempBasal(temporaryBasal); + } + temporaryBasals = null; + pumpStartedEvents = null; + if (historyEvents.size() > 0) { + InsightHistoryOffset historyOffset = new InsightHistoryOffset(); + historyOffset.pumpSerial = serial; + historyOffset.offset = historyEvents.get(0).getEventPosition(); + MainApp.getDbHelper().createOrUpdate(historyOffset); + } + } + + private boolean processHistoryEvent(String serial, HistoryEvent event) { + if (event instanceof DefaultDateTimeSetEvent) return false; + else if (event instanceof DateTimeChangedEvent) processDateTimeChangedEvent((DateTimeChangedEvent) event); + else if (event instanceof CannulaFilledEvent) processCannulaFilledEvent((CannulaFilledEvent) event); + else if (event instanceof TotalDailyDoseEvent) processTotalDailyDoseEvent((TotalDailyDoseEvent) event); + else if (event instanceof TubeFilledEvent) processTubeFilledEvent((TubeFilledEvent) event); + else if (event instanceof SniffingDoneEvent) processSniffingDoneEvent((SniffingDoneEvent) event); + else if (event instanceof PowerUpEvent) processPowerUpEvent((PowerUpEvent) event); + else if (event instanceof OperatingModeChangedEvent) processOperatingModeChangedEvent(serial, (OperatingModeChangedEvent) event); + else if (event instanceof StartOfTBREvent) processStartOfTBREvent(serial, (StartOfTBREvent) event); + else if (event instanceof EndOfTBREvent) processEndOfTBREvent(serial, (EndOfTBREvent) event); + else if (event instanceof BolusProgrammedEvent) processBolusProgrammedEvent(serial, (BolusProgrammedEvent) event); + else if (event instanceof BolusDeliveredEvent) processBolusDeliveredEvent(serial, (BolusDeliveredEvent) event); + else if (event instanceof OccurrenceOfAlertEvent) processOccurrenceOfAlertEvent((OccurrenceOfAlertEvent) event); + return true; + } + + private void processDateTimeChangedEvent(DateTimeChangedEvent event) { + long timeAfter = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), event.getEventHour(), event.getEventMinute(), event.getEventSecond()); + long timeBefore = parseDate(event.getBeforeYear(), event.getBeforeMonth(), event.getBeforeDay(), event.getBeforeHour(), event.getBeforeMinute(), event.getBeforeSecond()); + timeOffset -= timeAfter - timeBefore; + } + + private void processCannulaFilledEvent(CannulaFilledEvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + uploadCareportalEvent(timestamp, CareportalEvent.SITECHANGE); + } + + private void processTotalDailyDoseEvent(TotalDailyDoseEvent event) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date(0)); + calendar.set(Calendar.YEAR, event.getTotalYear()); + calendar.set(Calendar.MONTH, event.getTotalMonth() - 1); + calendar.set(Calendar.DAY_OF_MONTH, event.getTotalDay()); + TDD tdd = new TDD(); + tdd.basal = event.getBasalTotal(); + tdd.bolus = event.getBolusTotal(); + tdd.total = tdd.basal + tdd.bolus; + tdd.date = calendar.getTimeInMillis(); + MainApp.getDbHelper().createOrUpdateTDD(tdd); + } + + private void processTubeFilledEvent(TubeFilledEvent event) { + if (!SP.getBoolean("insight_log_tube_changes", false)) return; + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + logNote(timestamp, MainApp.gs(R.string.tube_changed)); + } + + private void processSniffingDoneEvent(SniffingDoneEvent event) { + if (!SP.getBoolean("insight_log_site_changes", false)) return; + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + uploadCareportalEvent(timestamp, CareportalEvent.INSULINCHANGE); + } + + private void processPowerUpEvent(PowerUpEvent event) { + if (!SP.getBoolean("insight_log_battery_changes", false)) return; + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + uploadCareportalEvent(timestamp, CareportalEvent.PUMPBATTERYCHANGE); + } + + private void processOperatingModeChangedEvent(String serial, OperatingModeChangedEvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + InsightPumpID pumpID = new InsightPumpID(); + pumpID.eventID = event.getEventPosition(); + pumpID.pumpSerial = serial; + pumpID.timestamp = timestamp; + switch (event.getNewValue()) { + case STARTED: + pumpID.eventType = "PumpStarted"; + MainApp.getDbHelper().createOrUpdate(pumpID); + pumpStartedEvents.add(pumpID); + if (SP.getBoolean("insight_log_operating_mode_changes", false)) + logNote(timestamp, MainApp.gs(R.string.pump_started)); + break; + case STOPPED: + if (SP.getBoolean("insight_log_operating_mode_changes", false)) + pumpID.eventType = "PumpStopped"; + MainApp.getDbHelper().createOrUpdate(pumpID); + logNote(timestamp, MainApp.gs(R.string.pump_stopped)); + break; + case PAUSED: + if (SP.getBoolean("insight_log_operating_mode_changes", false)) + logNote(timestamp, MainApp.gs(R.string.pump_paused)); + break; + } + } + + private void processStartOfTBREvent(String serial, StartOfTBREvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + InsightPumpID pumpID = new InsightPumpID(); + pumpID.eventID = event.getEventPosition(); + pumpID.pumpSerial = serial; + pumpID.timestamp = timestamp; + pumpID.eventType = "StartOfTBR"; + MainApp.getDbHelper().createOrUpdate(pumpID); + TemporaryBasal temporaryBasal = new TemporaryBasal(); + temporaryBasal.durationInMinutes = event.getDuration(); + temporaryBasal.source = Source.PUMP; + temporaryBasal.pumpId = pumpID.id; + temporaryBasal.percentRate = event.getAmount(); + temporaryBasal.isAbsolute = false; + temporaryBasal.date = timestamp; + temporaryBasals.add(temporaryBasal); + } + + private void processEndOfTBREvent(String serial, EndOfTBREvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + InsightPumpID pumpID = new InsightPumpID(); + pumpID.eventID = event.getEventPosition(); + pumpID.pumpSerial = serial; + pumpID.eventType = "EndOfTBR"; + pumpID.timestamp = timestamp; + MainApp.getDbHelper().createOrUpdate(pumpID); + TemporaryBasal temporaryBasal = new TemporaryBasal(); + temporaryBasal.durationInMinutes = 0; + temporaryBasal.source = Source.PUMP; + temporaryBasal.pumpId = pumpID.id; + temporaryBasal.date = timestamp; + temporaryBasals.add(temporaryBasal); + } + + private void processBolusProgrammedEvent(String serial, BolusProgrammedEvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + InsightBolusID bolusID = MainApp.getDbHelper().getInsightBolusID(serial, event.getBolusID(), timestamp); + if (bolusID != null && bolusID.endID != null) { + bolusID.startID = event.getEventPosition(); + MainApp.getDbHelper().createOrUpdate(bolusID); + return; + } + if (bolusID == null || bolusID.startID != null) { + bolusID = new InsightBolusID(); + bolusID.timestamp = timestamp; + bolusID.bolusID = event.getBolusID(); + bolusID.pumpSerial = serial; + } + bolusID.startID = event.getEventPosition(); + MainApp.getDbHelper().createOrUpdate(bolusID); + if (event.getBolusType() == BolusType.STANDARD || event.getBolusType() == BolusType.MULTIWAVE) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.date = bolusID.timestamp; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = bolusID.id; + detailedBolusInfo.insulin = event.getImmediateAmount(); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); + } + if ((event.getBolusType() == BolusType.EXTENDED || event.getBolusType() == BolusType.MULTIWAVE)) { + ExtendedBolus extendedBolus = new ExtendedBolus(); + extendedBolus.date = bolusID.timestamp; + extendedBolus.source = Source.PUMP; + extendedBolus.durationInMinutes = event.getDuration(); + extendedBolus.insulin = event.getExtendedAmount(); + extendedBolus.pumpId = bolusID.id; + if (ProfileFunctions.getInstance().getProfile(extendedBolus.date) != null) + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + } + } + + private void processBolusDeliveredEvent(String serial, BolusDeliveredEvent event) { + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + long startTimestamp = parseRelativeDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), event.getEventHour(), + event.getEventMinute(), event.getEventSecond(), event.getStartHour(), event.getStartMinute(), event.getStartSecond()) + timeOffset; + InsightBolusID bolusID = MainApp.getDbHelper().getInsightBolusID(serial, event.getBolusID(), timestamp); + if (bolusID == null || bolusID.endID != null) { + bolusID = new InsightBolusID(); + bolusID.timestamp = startTimestamp; + bolusID.bolusID = event.getBolusID(); + bolusID.pumpSerial = serial; + } + bolusID.endID = event.getEventPosition(); + MainApp.getDbHelper().createOrUpdate(bolusID); + if (event.getBolusType() == BolusType.STANDARD || event.getBolusType() == BolusType.MULTIWAVE) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.date = bolusID.timestamp; + detailedBolusInfo.source = Source.PUMP; + detailedBolusInfo.pumpId = bolusID.id; + detailedBolusInfo.insulin = event.getImmediateAmount(); + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); + } + if (event.getBolusType() == BolusType.EXTENDED || event.getBolusType() == BolusType.MULTIWAVE) { + if (event.getDuration() == 0) { + ExtendedBolus extendedBolus = MainApp.getDbHelper().getExtendedBolusByPumpId(bolusID.id); + if (extendedBolus != null) { + final String _id = extendedBolus._id; + if (NSUpload.isIdValid(_id)) NSUpload.removeCareportalEntryFromNS(_id); + else UploadQueue.removeID("dbAdd", _id); + MainApp.getDbHelper().delete(extendedBolus); + } + } else { + ExtendedBolus extendedBolus = new ExtendedBolus(); + extendedBolus.date = bolusID.timestamp; + extendedBolus.source = Source.PUMP; + extendedBolus.durationInMinutes = event.getDuration(); + extendedBolus.insulin = event.getExtendedAmount(); + extendedBolus.pumpId = bolusID.id; + if (ProfileFunctions.getInstance().getProfile(extendedBolus.date) != null) + TreatmentsPlugin.getPlugin().addToHistoryExtendedBolus(extendedBolus); + } + } + } + + private void processOccurrenceOfAlertEvent(OccurrenceOfAlertEvent event) { + if (!SP.getBoolean("insight_log_alerts", false)) return; + long timestamp = parseDate(event.getEventYear(), event.getEventMonth(), event.getEventDay(), + event.getEventHour(), event.getEventMinute(), event.getEventSecond()) + timeOffset; + Integer code = null; + Integer title = null; + switch (event.getAlertType()) { + case ERROR_6: + code = R.string.alert_e6_code; + title = R.string.alert_e6_title; + break; + case ERROR_10: + code = R.string.alert_e10_code; + title = R.string.alert_e10_title; + break; + case ERROR_13: + code = R.string.alert_e13_code; + title = R.string.alert_e13_title; + break; + case MAINTENANCE_20: + code = R.string.alert_m20_code; + title = R.string.alert_m20_title; + break; + case MAINTENANCE_21: + code = R.string.alert_m21_code; + title = R.string.alert_m21_title; + break; + case MAINTENANCE_22: + code = R.string.alert_m22_code; + title = R.string.alert_m22_title; + break; + case MAINTENANCE_23: + code = R.string.alert_m23_code; + title = R.string.alert_m23_title; + break; + case MAINTENANCE_24: + code = R.string.alert_m24_code; + title = R.string.alert_m24_title; + break; + case MAINTENANCE_25: + code = R.string.alert_m25_code; + title = R.string.alert_m25_title; + break; + case MAINTENANCE_26: + code = R.string.alert_m26_code; + title = R.string.alert_m26_title; + break; + case MAINTENANCE_27: + code = R.string.alert_m27_code; + title = R.string.alert_m27_title; + break; + case MAINTENANCE_28: + code = R.string.alert_m28_code; + title = R.string.alert_m28_title; + break; + case MAINTENANCE_29: + code = R.string.alert_m29_code; + title = R.string.alert_m29_title; + break; + case MAINTENANCE_30: + code = R.string.alert_m30_code; + title = R.string.alert_m30_title; + break; + case WARNING_31: + code = R.string.alert_w31_code; + title = R.string.alert_w31_title; + break; + case WARNING_32: + code = R.string.alert_w32_code; + title = R.string.alert_w32_title; + break; + case WARNING_33: + code = R.string.alert_w33_code; + title = R.string.alert_w33_title; + break; + case WARNING_34: + code = R.string.alert_w34_code; + title = R.string.alert_w34_title; + break; + case WARNING_39: + code = R.string.alert_w39_code; + title = R.string.alert_w39_title; + break; + } + if (code != null) logNote(timestamp, MainApp.gs(R.string.insight_alert_formatter, MainApp.gs(code), MainApp.gs(title))); + } + + private long parseDate(int year, int month, int day, int hour, int minute, int second) { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month - 1); + calendar.set(Calendar.DAY_OF_MONTH, day); + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, second); + return calendar.getTimeInMillis(); + } + + private void logNote(long date, String note) { + try { + if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date) != null) + return; + JSONObject data = new JSONObject(); + String enteredBy = SP.getString("careportal_enteredby", ""); + if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); + data.put("created_at", DateUtil.toISOString(date)); + data.put("eventType", CareportalEvent.NOTE); + data.put("notes", note); + NSUpload.uploadCareportalEntryToNS(data); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private long parseRelativeDate(int year, int month, int day, int hour, int minute, int second, int relativeHour, int relativeMinute, int relativeSecond) { + if (relativeHour * 60 * 60 + relativeMinute * 60 + relativeSecond >= hour * 60 * 60 * minute * 60 + second) + day--; + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month - 1); + calendar.set(Calendar.DAY_OF_MONTH, day); + calendar.set(Calendar.HOUR_OF_DAY, relativeHour); + calendar.set(Calendar.MINUTE, relativeMinute); + calendar.set(Calendar.SECOND, relativeSecond); + return calendar.getTimeInMillis(); + } + + private void uploadCareportalEvent(long date, String event) { + if (MainApp.getDbHelper().getCareportalEventFromTimestamp(date) != null) + return; + try { + JSONObject data = new JSONObject(); + String enteredBy = SP.getString("careportal_enteredby", ""); + if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); + data.put("created_at", DateUtil.toISOString(date)); + data.put("eventType", event); + NSUpload.uploadCareportalEntryToNS(data); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); + percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); + return percentRate; + } + + @Override + public Constraint applyBolusConstraints(Constraint insulin) { + if (!limitsFetched) return insulin; + insulin.setIfSmaller(maximumBolusAmount, String.format(MainApp.gs(R.string.limitingbolus), maximumBolusAmount, MainApp.gs(R.string.pumplimit)), this); + if (insulin.value() < minimumBolusAmount) { + + //TODO: Add function to Constraints or use different approach + // This only works if the interface of the InsightPlugin is called last. + // If not, another constraint could theoretically set the value between 0 and minimumBolusAmount + + insulin.set(0d, String.format(MainApp.gs(R.string.limitingbolus), minimumBolusAmount, MainApp.gs(R.string.pumplimit)), this); + } + return insulin; + } + + @Override + public void stateChanged(InsightState state) { + if (state == InsightState.CONNECTED) statusLoaded = false; + else if (state == InsightState.NOT_PAIRED) { + statusLoaded = false; + profileBlocks = null; + operatingMode = null; + batteryStatus = null; + cartridgeStatus = null; + totalDailyDose = null; + activeBasalRate = null; + activeTBR = null; + activeBoluses = null; + tbrOverNotificationBlock = null; + } + new Handler(Looper.getMainLooper()).post(() -> MainApp.bus().post(new EventLocalInsightUpdateGUI())); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightAlertActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightAlertActivity.java new file mode 100644 index 0000000000..bdae55ad23 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightAlertActivity.java @@ -0,0 +1,256 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.activities; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.text.Html; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import java.text.DecimalFormat; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.PumpInsightLocal.InsightAlertService; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.Alert; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertStatus; + +public class InsightAlertActivity extends AppCompatActivity { + + private Alert alert; + private InsightAlertService alertService; + + private ImageView icon; + private TextView errorCode; + private TextView errorTitle; + private TextView errorDescription; + private Button mute; + private Button confirm; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + alertService = ((InsightAlertService.LocalBinder) binder).getService(); + alertService.setAlertActivity(InsightAlertActivity.this); + alert = alertService.getAlert(); + if (alert == null) finish(); + update(alert); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + alertService = null; + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_insight_alert); + + bindService(new Intent(this, InsightAlertService.class), serviceConnection, BIND_AUTO_CREATE); + + icon = findViewById(R.id.icon); + errorCode = findViewById(R.id.error_code); + errorTitle = findViewById(R.id.error_title); + errorDescription = findViewById(R.id.error_description); + mute = findViewById(R.id.mute); + confirm = findViewById(R.id.confirm); + + setFinishOnTouchOutside(false); + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); + WindowManager.LayoutParams layoutParams = getWindow().getAttributes(); + layoutParams.screenBrightness = 1.0F; + getWindow().setAttributes(layoutParams); + } + + @Override + protected void onDestroy() { + unbindService(serviceConnection); + super.onDestroy(); + } + + public void update(Alert alert) { + this.alert = alert; + mute.setEnabled(true); + mute.setVisibility(alert.getAlertStatus() == AlertStatus.SNOOZED ? View.GONE : View.VISIBLE); + confirm.setEnabled(true); + int icon = 0; + int code = 0; + int title = 0; + String description = null; + switch (alert.getAlertCategory()) { + case ERROR: + icon = R.drawable.ic_error; + break; + case MAINTENANCE: + icon = R.drawable.ic_maintenance; + break; + case WARNING: + icon = R.drawable.ic_warning; + break; + case REMINDER: + icon = R.drawable.ic_reminder; + break; + } + DecimalFormat decimalFormat = new DecimalFormat("##0.00"); + int hours = alert.getTBRDuration() / 60; + int minutes = alert.getTBRDuration() - hours * 60; + switch (alert.getAlertType()) { + case REMINDER_01: + code = R.string.alert_r1_code; + title = R.string.alert_r1_title; + break; + case REMINDER_02: + code = R.string.alert_r2_code; + title = R.string.alert_r2_title; + break; + case REMINDER_03: + code = R.string.alert_r3_code; + title = R.string.alert_r3_title; + break; + case REMINDER_04: + code = R.string.alert_r4_code; + title = R.string.alert_r4_title; + break; + case REMINDER_07: + code = R.string.alert_r7_code; + title = R.string.alert_r7_title; + description = getString(R.string.alert_r7_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes)); + break; + case WARNING_31: + code = R.string.alert_w31_code; + title = R.string.alert_w31_title; + description = getString(R.string.alert_w31_description, decimalFormat.format(alert.getCartridgeAmount())); + break; + case WARNING_32: + code = R.string.alert_w32_code; + title = R.string.alert_w32_title; + description = getString(R.string.alert_w32_description); + break; + case WARNING_33: + code = R.string.alert_w33_code; + title = R.string.alert_w33_title; + description = getString(R.string.alert_w33_description); + break; + case WARNING_34: + code = R.string.alert_w34_code; + title = R.string.alert_w34_title; + description = getString(R.string.alert_w34_description); + break; + case WARNING_36: + code = R.string.alert_w36_code; + title = R.string.alert_w36_title; + description = getString(R.string.alert_w36_description, alert.getTBRAmount(), new DecimalFormat("#0").format(hours) + ":" + new DecimalFormat("00").format(minutes)); + break; + case WARNING_38: + code = R.string.alert_w38_code; + title = R.string.alert_w38_title; + description = getString(R.string.alert_w38_description, decimalFormat.format(alert.getProgrammedBolusAmount()), decimalFormat.format(alert.getDeliveredBolusAmount())); + break; + case WARNING_39: + code = R.string.alert_w39_code; + title = R.string.alert_w39_title; + break; + case MAINTENANCE_20: + code = R.string.alert_m20_code; + title = R.string.alert_m20_title; + description = getString(R.string.alert_m20_description); + break; + case MAINTENANCE_21: + code = R.string.alert_m21_code; + title = R.string.alert_m21_title; + description = getString(R.string.alert_m21_description); + break; + case MAINTENANCE_22: + code = R.string.alert_m22_code; + title = R.string.alert_m22_title; + description = getString(R.string.alert_m22_description); + break; + case MAINTENANCE_23: + code = R.string.alert_m23_code; + title = R.string.alert_m23_title; + description = getString(R.string.alert_m23_description); + break; + case MAINTENANCE_24: + code = R.string.alert_m24_code; + title = R.string.alert_m24_title; + description = getString(R.string.alert_m24_description); + break; + case MAINTENANCE_25: + code = R.string.alert_m25_code; + title = R.string.alert_m25_title; + description = getString(R.string.alert_m25_description); + break; + case MAINTENANCE_26: + code = R.string.alert_m26_code; + title = R.string.alert_m26_title; + description = getString(R.string.alert_m26_description); + break; + case MAINTENANCE_27: + code = R.string.alert_m27_code; + title = R.string.alert_m27_title; + description = getString(R.string.alert_m27_description); + break; + case MAINTENANCE_28: + code = R.string.alert_m28_code; + title = R.string.alert_m28_title; + description = getString(R.string.alert_m28_description); + break; + case MAINTENANCE_29: + code = R.string.alert_m29_code; + title = R.string.alert_m29_title; + description = getString(R.string.alert_m29_description); + break; + case MAINTENANCE_30: + code = R.string.alert_m30_code; + title = R.string.alert_m30_title; + description = getString(R.string.alert_m30_description); + break; + case ERROR_6: + code = R.string.alert_e6_code; + title = R.string.alert_e6_title; + description = getString(R.string.alert_e6_description); + break; + case ERROR_10: + code = R.string.alert_e10_code; + title = R.string.alert_e10_title; + description = getString(R.string.alert_e10_description); + break; + case ERROR_13: + code = R.string.alert_e13_code; + title = R.string.alert_e13_title; + description = getString(R.string.alert_e13_description); + break; + } + this.icon.setImageDrawable(ContextCompat.getDrawable(this, icon)); + this.errorCode.setText(code); + this.errorTitle.setText(title); + if (description == null) this.errorDescription.setVisibility(View.GONE); + else { + this.errorDescription.setVisibility(View.VISIBLE); + this.errorDescription.setText(Html.fromHtml(description)); + } + } + + public void muteClicked(View view) { + mute.setEnabled(false); + alertService.mute(); + } + + public void confirmClicked(View view) { + mute.setEnabled(false); + confirm.setEnabled(false); + alertService.confirm(); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingActivity.java new file mode 100644 index 0000000000..390e9a233e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingActivity.java @@ -0,0 +1,255 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.activities; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service.InsightConnectionService; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.InsightState; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ExceptionTranslator; + +public class InsightPairingActivity extends AppCompatActivity implements InsightConnectionService.StateCallback, View.OnClickListener, InsightConnectionService.ExceptionCallback { + + private boolean scanning; + private LinearLayout deviceSearchSection; + private TextView pleaseWaitSection; + private LinearLayout codeCompareSection; + private LinearLayout pairingCompletedSection; + private Button yes; + private Button no; + private TextView code; + private Button exit; + private RecyclerView deviceList; + private DeviceAdapter deviceAdapter = new DeviceAdapter(); + + private InsightConnectionService service; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + service = ((InsightConnectionService.LocalBinder) binder).getService(); + if (service.isPaired()) return; + else { + service.requestConnection(InsightPairingActivity.this); + service.registerStateCallback(InsightPairingActivity.this); + service.registerExceptionCallback(InsightPairingActivity.this); + stateChanged(service.getState()); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_insight_pairing); + + deviceSearchSection = findViewById(R.id.device_search_section); + pleaseWaitSection = findViewById(R.id.please_wait_section); + codeCompareSection = findViewById(R.id.code_compare_section); + pairingCompletedSection = findViewById(R.id.pairing_completed_section); + yes = findViewById(R.id.yes); + no = findViewById(R.id.no); + code = findViewById(R.id.code); + exit = findViewById(R.id.exit); + deviceList = findViewById(R.id.device_list); + + yes.setOnClickListener(this); + no.setOnClickListener(this); + exit.setOnClickListener(this); + + deviceList.setLayoutManager(new LinearLayoutManager(this)); + deviceList.setAdapter(deviceAdapter); + + + bindService(new Intent(this, InsightConnectionService.class), serviceConnection, BIND_AUTO_CREATE); +} + + @Override + protected void onDestroy() { + if (service != null) { + service.withdrawConnectionRequest(InsightPairingActivity.this); + service.unregisterStateCallback(InsightPairingActivity.this); + service.unregisterExceptionCallback(InsightPairingActivity.this); + } + unbindService(serviceConnection); + super.onDestroy(); + } + + @Override + protected void onStart() { + super.onStart(); + if (service != null && service.getState() == InsightState.NOT_PAIRED) startBLScan(); + } + + @Override + protected void onStop() { + stopBLScan(); + super.onStop(); + } + + @Override + public void stateChanged(InsightState state) { + runOnUiThread(() -> { + switch (state) { + case NOT_PAIRED: + startBLScan(); + deviceSearchSection.setVisibility(View.VISIBLE); + pleaseWaitSection.setVisibility(View.GONE); + codeCompareSection.setVisibility(View.GONE); + pairingCompletedSection.setVisibility(View.GONE); + break; + case CONNECTING: + case SATL_CONNECTION_REQUEST: + case SATL_KEY_REQUEST: + case SATL_VERIFY_DISPLAY_REQUEST: + case SATL_VERIFY_CONFIRM_REQUEST: + case APP_BIND_MESSAGE: + stopBLScan(); + deviceSearchSection.setVisibility(View.GONE); + pleaseWaitSection.setVisibility(View.VISIBLE); + codeCompareSection.setVisibility(View.GONE); + pairingCompletedSection.setVisibility(View.GONE); + break; + case AWAITING_CODE_CONFIRMATION: + stopBLScan(); + deviceSearchSection.setVisibility(View.GONE); + pleaseWaitSection.setVisibility(View.GONE); + codeCompareSection.setVisibility(View.VISIBLE); + pairingCompletedSection.setVisibility(View.GONE); + code.setText(service.getVerificationString()); + break; + case DISCONNECTED: + case CONNECTED: + stopBLScan(); + deviceSearchSection.setVisibility(View.GONE); + pleaseWaitSection.setVisibility(View.GONE); + codeCompareSection.setVisibility(View.GONE); + pairingCompletedSection.setVisibility(View.VISIBLE); + break; + } + }); + } + + private void startBLScan() { + if (!scanning) { + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (!bluetoothAdapter.isEnabled()) bluetoothAdapter.enable(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); + intentFilter.addAction(BluetoothDevice.ACTION_FOUND); + registerReceiver(broadcastReceiver, intentFilter); + bluetoothAdapter.startDiscovery(); + scanning = true; + } + } + + private void stopBLScan() { + if (scanning) { + unregisterReceiver(broadcastReceiver); + BluetoothAdapter.getDefaultAdapter().cancelDiscovery(); + scanning = false; + } + } + @Override + public void onClick(View v) { + if (v == exit) finish(); + else if (v == yes) service.confirmVerificationString(); + else if (v == no) service.rejectVerificationString(); + } + + @Override + public void onExceptionOccur(Exception e) { + ExceptionTranslator.makeToast(this, e); + } + + private void deviceSelected(BluetoothDevice device) { + service.pair(device.getAddress()); + } + + private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) + BluetoothAdapter.getDefaultAdapter().startDiscovery(); + else if (action.equals(BluetoothDevice.ACTION_FOUND)) { + BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + deviceAdapter.addDevice(bluetoothDevice); + } + } + }; + + private class DeviceAdapter extends RecyclerView.Adapter { + + private List bluetoothDevices = new ArrayList<>(); + + public void addDevice(BluetoothDevice bluetoothDevice) { + if (!bluetoothDevices.contains(bluetoothDevice)) { + bluetoothDevices.add(bluetoothDevice); + notifyDataSetChanged(); + } + } + + public void clear() { + bluetoothDevices.clear(); + notifyDataSetChanged(); + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.bluetooth_device, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + BluetoothDevice bluetoothDevice = bluetoothDevices.get(position); + holder.deviceName.setText(bluetoothDevice.getName() == null ? bluetoothDevice.getAddress() : bluetoothDevice.getName()); + holder.deviceName.setOnClickListener((v) -> deviceSelected(bluetoothDevice)); + } + + @Override + public int getItemCount() { + return bluetoothDevices.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + + private TextView deviceName; + + public ViewHolder(View itemView) { + super(itemView); + deviceName = (TextView) itemView; + } + } + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingInformationActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingInformationActivity.java new file mode 100644 index 0000000000..27528cfeab --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/activities/InsightPairingInformationActivity.java @@ -0,0 +1,88 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.activities; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.TextView; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service.InsightConnectionService; + +public class InsightPairingInformationActivity extends AppCompatActivity { + + private InsightConnectionService connectionService; + + private TextView serialNumber; + private TextView releaseSWVersion; + private TextView uiProcSWVersion; + private TextView pcProcSWVersion; + private TextView mdTelSWVersion; + private TextView safetyProcSWVersion; + private TextView btInfoPageVersion; + private TextView bluetoothAddress; + private TextView systemIdAppendix; + private TextView manufacturingDate; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + connectionService = ((InsightConnectionService.LocalBinder) binder).getService(); + if (!connectionService.isPaired()) { + overridePendingTransition(0, 0); + finish(); + startActivity(new Intent(InsightPairingInformationActivity.this, InsightPairingActivity.class)); + } else { + serialNumber.setText(connectionService.getPumpSystemIdentification().getSerialNumber()); + manufacturingDate.setText(connectionService.getPumpSystemIdentification().getManufacturingDate()); + systemIdAppendix.setText(connectionService.getPumpSystemIdentification().getSystemIdAppendix() + ""); + releaseSWVersion.setText(connectionService.getPumpFirmwareVersions().getReleaseSWVersion()); + uiProcSWVersion.setText(connectionService.getPumpFirmwareVersions().getUiProcSWVersion()); + pcProcSWVersion.setText(connectionService.getPumpFirmwareVersions().getPcProcSWVersion()); + mdTelSWVersion.setText(connectionService.getPumpFirmwareVersions().getMdTelProcSWVersion()); + safetyProcSWVersion.setText(connectionService.getPumpFirmwareVersions().getSafetyProcSWVersion()); + btInfoPageVersion.setText(connectionService.getPumpFirmwareVersions().getBtInfoPageVersion()); + bluetoothAddress.setText(connectionService.getBluetoothAddress()); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + connectionService = null; + } + }; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_insight_pairing_information); + serialNumber = findViewById(R.id.serial_number); + releaseSWVersion = findViewById(R.id.release_sw_version); + uiProcSWVersion = findViewById(R.id.ui_proc_sw_version); + pcProcSWVersion = findViewById(R.id.pc_proc_sw_version); + mdTelSWVersion = findViewById(R.id.md_tel_sw_version); + safetyProcSWVersion = findViewById(R.id.safety_proc_sw_version); + btInfoPageVersion = findViewById(R.id.bt_info_page_version); + bluetoothAddress = findViewById(R.id.bluetooth_address); + systemIdAppendix = findViewById(R.id.system_id_appendix); + manufacturingDate = findViewById(R.id.manufacturing_date); + bindService(new Intent(this, InsightConnectionService.class), serviceConnection, BIND_AUTO_CREATE); + } + + @Override + protected void onDestroy() { + unbindService(serviceConnection); + super.onDestroy(); + } + + public void deletePairing(View view) { + if (connectionService != null) { + connectionService.reset(); + finish(); + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/AppLayerMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/AppLayerMessage.java new file mode 100644 index 0000000000..69243dde63 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/AppLayerMessage.java @@ -0,0 +1,91 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.IncompatibleAppVersionException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidAppCRCException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.UnknownAppCommandException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.UnknownServiceException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.AppLayerErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.UnknownAppLayerErrorCodeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AppCommandIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AppErrorIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ServiceIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.DataMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto.Cryptograph; + +public class AppLayerMessage implements Comparable { + + private static final byte VERSION = 0x20; + + private final MessagePriority messagePriority; + private final boolean inCRC; + private final boolean outCRC; + private final Service service; + + public AppLayerMessage(MessagePriority messagePriority, boolean inCRC, boolean outCRC, Service service) { + this.messagePriority = messagePriority; + this.inCRC = inCRC; + this.outCRC = outCRC; + this.service = service; + } + + protected ByteBuf getData() { + return new ByteBuf(0); + } + + protected void parse(ByteBuf byteBuf) throws Exception { + + } + + public ByteBuf serialize(Class clazz) { + byte[] data = getData().getBytes(); + ByteBuf byteBuf = new ByteBuf(4 + data.length + (outCRC ? 2 : 0)); + byteBuf.putByte(VERSION); + byteBuf.putByte(ServiceIDs.IDS.getID(getService())); + byteBuf.putUInt16LE(AppCommandIDs.IDS.getID(clazz)); + byteBuf.putBytes(data); + if (outCRC) byteBuf.putUInt16LE(Cryptograph.calculateCRC(data)); + return byteBuf; + } + + public static AppLayerMessage deserialize(ByteBuf byteBuf) throws Exception { + byte version = byteBuf.readByte(); + byte service = byteBuf.readByte(); + int command = byteBuf.readUInt16LE(); + int error = byteBuf.readUInt16LE(); + Class clazz = AppCommandIDs.IDS.getType(command); + if (clazz == null) throw new UnknownAppCommandException(); + if (version != VERSION) throw new IncompatibleAppVersionException(); + AppLayerMessage message = clazz.newInstance(); + if (ServiceIDs.IDS.getType(service) == null) throw new UnknownServiceException(); + if (error != 0) { + Class exceptionClass = AppErrorIDs.IDS.getType(error); + if (exceptionClass == null) throw new UnknownAppLayerErrorCodeException(error); + else throw exceptionClass.getConstructor(int.class).newInstance(error); + } + byte[] data = byteBuf.readBytes(byteBuf.getSize() - (message.inCRC ? 2 : 0)); + if (message.inCRC && Cryptograph.calculateCRC(data) != byteBuf.readUInt16LE()) throw new InvalidAppCRCException(); + message.parse(ByteBuf.from(data)); + return message; + } + + public static DataMessage wrap(AppLayerMessage message) { + DataMessage dataMessage = new DataMessage(); + dataMessage.setData(message.serialize(message.getClass())); + return dataMessage; + } + + public static AppLayerMessage unwrap(DataMessage dataMessage) throws Exception { + return deserialize(dataMessage.getData()); + } + + @Override + public int compareTo(AppLayerMessage o) { + return messagePriority.compareTo(o.messagePriority); + } + + public Service getService() { + return this.service; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/ReadParameterBlockMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/ReadParameterBlockMessage.java new file mode 100644 index 0000000000..43aae60e75 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/ReadParameterBlockMessage.java @@ -0,0 +1,48 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.ParameterBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ParameterBlockIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ReadParameterBlockMessage extends AppLayerMessage { + + private Class parameterBlockId; + private ParameterBlock parameterBlock; + private Service service; + + public ReadParameterBlockMessage() { + super(MessagePriority.NORMAL, true, false, null); + } + + @Override + public Service getService() { + return service; + } + + public void setService(Service service) { + this.service = service; + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(ParameterBlockIDs.IDS.getID(parameterBlockId)); + return byteBuf; + } + + @Override + protected void parse(ByteBuf byteBuf) throws Exception { + parameterBlock = ParameterBlockIDs.IDS.getType(byteBuf.readUInt16LE()).newInstance(); + byteBuf.shift(2); //Restriction level + parameterBlock.parse(byteBuf); + } + + public ParameterBlock getParameterBlock() { + return this.parameterBlock; + } + + public void setParameterBlockId(Class configurationBlockId) { + this.parameterBlockId = configurationBlockId; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/Service.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/Service.java new file mode 100644 index 0000000000..685dc8a52c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/Service.java @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer; + +public enum Service { + + CONNECTION((short) 0x0000, null), + STATUS((short) 0x0100, null), + HISTORY((short) 0x0200, null), + CONFIGURATION((short) 0x0200, "u+5Fhz6Gw4j1Kkas"), + PARAMETER((short) 0x0200, null), + REMOTE_CONTROL((short) 0x0100, "MAbcV2X6PVjxuz+R"); + + private short version; + private String servicePassword; + + Service(short version, String servicePassword) { + this.version = version; + this.servicePassword = servicePassword; + } + + public short getVersion() { + return this.version; + } + + public String getServicePassword() { + return this.servicePassword; + } + + public void setServicePassword(String servicePassword) { + this.servicePassword = servicePassword; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/CloseConfigurationWriteSessionMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/CloseConfigurationWriteSessionMessage.java new file mode 100644 index 0000000000..3bf10ba6c0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/CloseConfigurationWriteSessionMessage.java @@ -0,0 +1,12 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; + +public class CloseConfigurationWriteSessionMessage extends AppLayerMessage { + + public CloseConfigurationWriteSessionMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONFIGURATION); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/OpenConfigurationWriteSessionMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/OpenConfigurationWriteSessionMessage.java new file mode 100644 index 0000000000..fe7e39c013 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/OpenConfigurationWriteSessionMessage.java @@ -0,0 +1,12 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; + +public class OpenConfigurationWriteSessionMessage extends AppLayerMessage { + + public OpenConfigurationWriteSessionMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONFIGURATION); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/WriteConfigurationBlockMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/WriteConfigurationBlockMessage.java new file mode 100644 index 0000000000..e842beb69f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/configuration/WriteConfigurationBlockMessage.java @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.ParameterBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ParameterBlockIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class WriteConfigurationBlockMessage extends AppLayerMessage { + + private ParameterBlock parameterBlock; + private Class configurationBlockId; + + public WriteConfigurationBlockMessage() { + super(MessagePriority.NORMAL, false, true, Service.CONFIGURATION); + } + + @Override + protected ByteBuf getData() { + ByteBuf configBlockData = parameterBlock.getData(); + ByteBuf data = new ByteBuf(4 + configBlockData.getSize()); + data.putUInt16LE(ParameterBlockIDs.IDS.getID(parameterBlock.getClass())); + data.putUInt16LE(31); + data.putByteBuf(configBlockData); + return data; + } + + @Override + protected void parse(ByteBuf byteBuf) throws Exception { + configurationBlockId = ParameterBlockIDs.IDS.getType(byteBuf.readUInt16LE()); + } + + public Class getConfigurationBlockId() { + return this.configurationBlockId; + } + + public void setParameterBlock(ParameterBlock parameterBlock) { + this.parameterBlock = parameterBlock; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ActivateServiceMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ActivateServiceMessage.java new file mode 100644 index 0000000000..9a07ea7ecb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ActivateServiceMessage.java @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ActivateServiceMessage extends AppLayerMessage { + + private byte serviceID; + private short version; + private byte[] servicePassword; + + public ActivateServiceMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONNECTION); + } + + protected void parse(ByteBuf byteBuf) { + serviceID = byteBuf.readByte(); + version = byteBuf.readShort(); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(19); + byteBuf.putByte(serviceID); + byteBuf.putShort(version); + byteBuf.putBytes(servicePassword); + return byteBuf; + } + + public byte getServiceID() { + return this.serviceID; + } + + public short getVersion() { + return this.version; + } + + public void setServiceID(byte serviceID) { + this.serviceID = serviceID; + } + + public void setVersion(short version) { + this.version = version; + } + + public void setServicePassword(byte[] servicePassword) { + this.servicePassword = servicePassword; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/BindMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/BindMessage.java new file mode 100644 index 0000000000..94a67d25b9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/BindMessage.java @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection; + +import org.spongycastle.util.encoders.Hex; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class BindMessage extends AppLayerMessage { + + public BindMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONNECTION); + } + + @Override + protected ByteBuf getData() { + return ByteBuf.from(Hex.decode("3438310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ConnectMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ConnectMessage.java new file mode 100644 index 0000000000..5f728731d7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ConnectMessage.java @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection; + +import org.spongycastle.util.encoders.Hex; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ConnectMessage extends AppLayerMessage { + + public ConnectMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONNECTION); + } + + @Override + protected ByteBuf getData() { + return ByteBuf.from(Hex.decode("0000080100196000")); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/DisconnectMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/DisconnectMessage.java new file mode 100644 index 0000000000..992523b5b5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/DisconnectMessage.java @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection; + +import org.spongycastle.util.encoders.Hex; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class DisconnectMessage extends AppLayerMessage { + + public DisconnectMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONNECTION); + } + + @Override + protected ByteBuf getData() { + return ByteBuf.from(Hex.decode("0360")); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ServiceChallengeMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ServiceChallengeMessage.java new file mode 100644 index 0000000000..d43f523ec2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/connection/ServiceChallengeMessage.java @@ -0,0 +1,42 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ServiceChallengeMessage extends AppLayerMessage { + + private byte serviceID; + private byte[] randomData; + private short version; + + public ServiceChallengeMessage() { + super(MessagePriority.NORMAL, false, false, Service.CONNECTION); + } + + @Override + protected void parse(ByteBuf byteBuf) { + randomData = byteBuf.getBytes(16); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(3); + byteBuf.putByte(serviceID); + byteBuf.putShort(version); + return byteBuf; + } + + public byte[] getRandomData() { + return this.randomData; + } + + public void setServiceID(byte serviceID) { + this.serviceID = serviceID; + } + + public void setVersion(short version) { + this.version = version; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/HistoryReadingDirection.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/HistoryReadingDirection.java new file mode 100644 index 0000000000..77d40214d5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/HistoryReadingDirection.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history; + +public enum HistoryReadingDirection { + + FORWARD, + BACKWARD; + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/ReadHistoryEventsMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/ReadHistoryEventsMessage.java new file mode 100644 index 0000000000..324ce9d44f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/ReadHistoryEventsMessage.java @@ -0,0 +1,34 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.HistoryEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ReadHistoryEventsMessage extends AppLayerMessage { + + private List historyEvents; + + public ReadHistoryEventsMessage() { + super(MessagePriority.NORMAL, true, false, Service.HISTORY); + } + + @Override + protected void parse(ByteBuf byteBuf) throws Exception { + historyEvents = new ArrayList<>(); + byteBuf.shift(2); + int frameCount = byteBuf.readUInt16LE(); + for (int i = 0; i < frameCount; i++) { + int length = byteBuf.readUInt16LE(); + historyEvents.add(HistoryEvent.deserialize(ByteBuf.from(byteBuf.readBytes(length)))); + } + } + + public List getHistoryEvents() { + return historyEvents; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StartReadingHistoryMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StartReadingHistoryMessage.java new file mode 100644 index 0000000000..cb5779f9e7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StartReadingHistoryMessage.java @@ -0,0 +1,34 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.HistoryReadingDirectionIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class StartReadingHistoryMessage extends AppLayerMessage { + + private long offset; + private HistoryReadingDirection direction; + + public StartReadingHistoryMessage() { + super(MessagePriority.NORMAL, false, true, Service.HISTORY); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(8); + byteBuf.putUInt16LE(31); + byteBuf.putUInt16LE(HistoryReadingDirectionIDs.IDS.getID(direction)); + byteBuf.putUInt32LE(offset); + return byteBuf; + } + + public void setOffset(long offset) { + this.offset = offset; + } + + public void setDirection(HistoryReadingDirection direction) { + this.direction = direction; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StopReadingHistoryMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StopReadingHistoryMessage.java new file mode 100644 index 0000000000..16dcab7d27 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/StopReadingHistoryMessage.java @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class StopReadingHistoryMessage extends AppLayerMessage { + + public StopReadingHistoryMessage() { + super(MessagePriority.NORMAL, false, false, Service.HISTORY); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BasalDeliveryChangedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BasalDeliveryChangedEvent.java new file mode 100644 index 0000000000..9e21c54311 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BasalDeliveryChangedEvent.java @@ -0,0 +1,23 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class BasalDeliveryChangedEvent extends HistoryEvent { + + private double oldBasalRate; + private double newBasalRate; + + @Override + public void parse(ByteBuf byteBuf) { + oldBasalRate = byteBuf.readUInt32Decimal1000(); + newBasalRate = byteBuf.readUInt32Decimal1000(); + } + + public double getOldBasalRate() { + return oldBasalRate; + } + + public double getNewBasalRate() { + return newBasalRate; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusDeliveredEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusDeliveredEvent.java new file mode 100644 index 0000000000..913a576662 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusDeliveredEvent.java @@ -0,0 +1,64 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.BolusTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.BOCUtil; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class BolusDeliveredEvent extends HistoryEvent { + + private BolusType bolusType; + private int startHour; + private int startMinute; + private int startSecond; + private double immediateAmount; + private double extendedAmount; + private int duration; + private int bolusID; + + @Override + public void parse(ByteBuf byteBuf) { + bolusType = BolusTypeIDs.IDS.getType(byteBuf.readUInt16LE()); + byteBuf.shift(1); + startHour = BOCUtil.parseBOC(byteBuf.readByte()); + startMinute = BOCUtil.parseBOC(byteBuf.readByte()); + startSecond = BOCUtil.parseBOC(byteBuf.readByte()); + immediateAmount = byteBuf.readUInt16Decimal(); + extendedAmount = byteBuf.readUInt16Decimal(); + duration = byteBuf.readUInt16LE(); + byteBuf.shift(2); + bolusID = byteBuf.readUInt16LE(); + } + + public BolusType getBolusType() { + return bolusType; + } + + public int getStartHour() { + return startHour; + } + + public int getStartMinute() { + return startMinute; + } + + public int getStartSecond() { + return startSecond; + } + + public double getImmediateAmount() { + return immediateAmount; + } + + public double getExtendedAmount() { + return extendedAmount; + } + + public int getDuration() { + return duration; + } + + public int getBolusID() { + return bolusID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusProgrammedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusProgrammedEvent.java new file mode 100644 index 0000000000..9e355a0555 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/BolusProgrammedEvent.java @@ -0,0 +1,45 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.BolusTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class BolusProgrammedEvent extends HistoryEvent { + + private BolusType bolusType; + private double immediateAmount; + private double extendedAmount; + private int duration; + private int bolusID; + + @Override + public void parse(ByteBuf byteBuf) { + bolusType = BolusTypeIDs.IDS.getType(byteBuf.readUInt16LE()); + immediateAmount = byteBuf.readUInt16Decimal(); + extendedAmount = byteBuf.readUInt16Decimal(); + duration = byteBuf.readUInt16LE(); + byteBuf.shift(4); + bolusID = byteBuf.readUInt16LE(); + } + + + public BolusType getBolusType() { + return bolusType; + } + + public double getImmediateAmount() { + return immediateAmount; + } + + public double getExtendedAmount() { + return extendedAmount; + } + + public int getDuration() { + return duration; + } + + public int getBolusID() { + return bolusID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CannulaFilledEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CannulaFilledEvent.java new file mode 100644 index 0000000000..ed49da1f18 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CannulaFilledEvent.java @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class CannulaFilledEvent extends HistoryEvent { + + private double amount; + + @Override + public void parse(ByteBuf byteBuf) { + amount = byteBuf.readUInt16Decimal(); + } + + public double getAmount() { + return amount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeInsertedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeInsertedEvent.java new file mode 100644 index 0000000000..750c481116 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeInsertedEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class CartridgeInsertedEvent extends HistoryEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeRemovedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeRemovedEvent.java new file mode 100644 index 0000000000..e32e9a1c23 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/CartridgeRemovedEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class CartridgeRemovedEvent extends HistoryEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DateTimeChangedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DateTimeChangedEvent.java new file mode 100644 index 0000000000..338422832d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DateTimeChangedEvent.java @@ -0,0 +1,49 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.BOCUtil; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class DateTimeChangedEvent extends HistoryEvent { + + private int beforeYear; + private int beforeMonth; + private int beforeDay; + private int beforeHour; + private int beforeMinute; + private int beforeSecond; + + @Override + public void parse(ByteBuf byteBuf) { + beforeYear = BOCUtil.parseBOC(byteBuf.readByte()) * 100 + BOCUtil.parseBOC(byteBuf.readByte()); + beforeMonth = BOCUtil.parseBOC(byteBuf.readByte()); + beforeDay = BOCUtil.parseBOC(byteBuf.readByte()); + byteBuf.shift(1); + beforeHour = BOCUtil.parseBOC(byteBuf.readByte()); + beforeMinute = BOCUtil.parseBOC(byteBuf.readByte()); + beforeSecond = BOCUtil.parseBOC(byteBuf.readByte()); + } + + public int getBeforeYear() { + return beforeYear; + } + + public int getBeforeMonth() { + return beforeMonth; + } + + public int getBeforeDay() { + return beforeDay; + } + + public int getBeforeHour() { + return beforeHour; + } + + public int getBeforeMinute() { + return beforeMinute; + } + + public int getBeforeSecond() { + return beforeSecond; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DefaultDateTimeSetEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DefaultDateTimeSetEvent.java new file mode 100644 index 0000000000..2c0971f474 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/DefaultDateTimeSetEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class DefaultDateTimeSetEvent extends HistoryEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/EndOfTBREvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/EndOfTBREvent.java new file mode 100644 index 0000000000..9fdcb14fcf --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/EndOfTBREvent.java @@ -0,0 +1,43 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.BOCUtil; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class EndOfTBREvent extends HistoryEvent { + + private int startHour; + private int startMinute; + private int startSecond; + private int amount; + private int duration; + + @Override + public void parse(ByteBuf byteBuf) { + byteBuf.shift(1); + startHour = BOCUtil.parseBOC(byteBuf.readByte()); + startMinute = BOCUtil.parseBOC(byteBuf.readByte()); + startSecond = BOCUtil.parseBOC(byteBuf.readByte()); + amount = byteBuf.readUInt16LE(); + duration = byteBuf.readUInt16LE(); + } + + public int getStartHour() { + return startHour; + } + + public int getStartMinute() { + return startMinute; + } + + public int getStartSecond() { + return startSecond; + } + + public int getAmount() { + return amount; + } + + public int getDuration() { + return duration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/HistoryEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/HistoryEvent.java new file mode 100644 index 0000000000..44f60e62c6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/HistoryEvent.java @@ -0,0 +1,83 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.HistoryEventIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.BOCUtil; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class HistoryEvent implements Comparable { + + private int eventYear; + private int eventMonth; + private int eventDay; + private int eventHour; + private int eventMinute; + private int eventSecond; + private long eventPosition; + + public static HistoryEvent deserialize(ByteBuf byteBuf) { + int eventID = byteBuf.readUInt16LE(); + Class eventClass = HistoryEventIDs.IDS.getType(eventID); + HistoryEvent event = null; + if (eventClass == null) event = new HistoryEvent(); + else { + try { + event = eventClass.newInstance(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } + } + event.parseHeader(byteBuf); + event.parse(byteBuf); + return event; + } + + public final void parseHeader(ByteBuf byteBuf) { + eventYear = BOCUtil.parseBOC(byteBuf.readByte()) * 100 + BOCUtil.parseBOC(byteBuf.readByte()); + eventMonth = BOCUtil.parseBOC(byteBuf.readByte()); + eventDay = BOCUtil.parseBOC(byteBuf.readByte()); + byteBuf.shift(1); + eventHour = BOCUtil.parseBOC(byteBuf.readByte()); + eventMinute = BOCUtil.parseBOC(byteBuf.readByte()); + eventSecond = BOCUtil.parseBOC(byteBuf.readByte()); + eventPosition = byteBuf.readUInt32LE(); + } + + public void parse(ByteBuf byteBuf) { + + } + + public int getEventYear() { + return eventYear; + } + + public int getEventMonth() { + return eventMonth; + } + + public int getEventDay() { + return eventDay; + } + + public int getEventHour() { + return eventHour; + } + + public int getEventMinute() { + return eventMinute; + } + + public int getEventSecond() { + return eventSecond; + } + + public long getEventPosition() { + return eventPosition; + } + + @Override + public int compareTo(HistoryEvent historyEvent) { + return (int) (eventPosition - historyEvent.eventPosition); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfAlertEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfAlertEvent.java new file mode 100644 index 0000000000..fc0e732bd5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfAlertEvent.java @@ -0,0 +1,25 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AlertTypeIncrementalIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public abstract class OccurrenceOfAlertEvent extends HistoryEvent { + + private AlertType alertType; + private int alertID; + + @Override + public void parse(ByteBuf byteBuf) { + alertType = AlertTypeIncrementalIDs.IDS.getType(byteBuf.readUInt16LE()); + alertID = byteBuf.readUInt16LE(); + } + + public AlertType getAlertType() { + return alertType; + } + + public int getAlertID() { + return alertID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfErrorEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfErrorEvent.java new file mode 100644 index 0000000000..0c17f9a6be --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfErrorEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class OccurrenceOfErrorEvent extends OccurrenceOfAlertEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfMaintenanceEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfMaintenanceEvent.java new file mode 100644 index 0000000000..e18de9ab27 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfMaintenanceEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class OccurrenceOfMaintenanceEvent extends OccurrenceOfAlertEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfWarningEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfWarningEvent.java new file mode 100644 index 0000000000..95d40e36c2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OccurrenceOfWarningEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class OccurrenceOfWarningEvent extends OccurrenceOfAlertEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OperatingModeChangedEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OperatingModeChangedEvent.java new file mode 100644 index 0000000000..47f5707f97 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/OperatingModeChangedEvent.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.OperatingMode; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.OperatingModeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class OperatingModeChangedEvent extends HistoryEvent { + + private OperatingMode oldValue; + private OperatingMode newValue; + + @Override + public void parse(ByteBuf byteBuf) { + oldValue = OperatingModeIDs.IDS.getType(byteBuf.readUInt16LE()); + newValue = OperatingModeIDs.IDS.getType(byteBuf.readUInt16LE()); + } + + + public OperatingMode getOldValue() { + return oldValue; + } + + public OperatingMode getNewValue() { + return newValue; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerDownEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerDownEvent.java new file mode 100644 index 0000000000..939f028fd8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerDownEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class PowerDownEvent extends HistoryEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerUpEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerUpEvent.java new file mode 100644 index 0000000000..e5ec8184cb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/PowerUpEvent.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +public class PowerUpEvent extends HistoryEvent { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/SniffingDoneEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/SniffingDoneEvent.java new file mode 100644 index 0000000000..b176324e38 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/SniffingDoneEvent.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SniffingDoneEvent extends HistoryEvent { + + private double amount; + + @Override + public void parse(ByteBuf byteBuf) { + amount = byteBuf.readUInt16Decimal(); + } + + public double getAmount() { + return amount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/StartOfTBREvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/StartOfTBREvent.java new file mode 100644 index 0000000000..062804ff06 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/StartOfTBREvent.java @@ -0,0 +1,23 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class StartOfTBREvent extends HistoryEvent { + + private int amount; + private int duration; + + @Override + public void parse(ByteBuf byteBuf) { + amount = byteBuf.readUInt16LE(); + duration = byteBuf.readUInt16LE(); + } + + public int getAmount() { + return amount; + } + + public int getDuration() { + return duration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TotalDailyDoseEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TotalDailyDoseEvent.java new file mode 100644 index 0000000000..4c3ab74213 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TotalDailyDoseEvent.java @@ -0,0 +1,42 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.BOCUtil; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class TotalDailyDoseEvent extends HistoryEvent { + + private double basalTotal; + private double bolusTotal; + private int totalYear; + private int totalMonth; + private int totalDay; + + @Override + public void parse(ByteBuf byteBuf) { + basalTotal = byteBuf.readUInt32Decimal100(); + bolusTotal = byteBuf.readUInt32Decimal100(); + totalYear = BOCUtil.parseBOC(byteBuf.readByte()) * 100 + BOCUtil.parseBOC(byteBuf.readByte()); + totalMonth = BOCUtil.parseBOC(byteBuf.readByte()); + totalDay = BOCUtil.parseBOC(byteBuf.readByte()); + } + + public double getBasalTotal() { + return basalTotal; + } + + public double getBolusTotal() { + return bolusTotal; + } + + public int getTotalYear() { + return totalYear; + } + + public int getTotalMonth() { + return totalMonth; + } + + public int getTotalDay() { + return totalDay; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TubeFilledEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TubeFilledEvent.java new file mode 100644 index 0000000000..217d362eb5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/history/history_events/TubeFilledEvent.java @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class TubeFilledEvent extends HistoryEvent { + + private double amount; + + @Override + public void parse(ByteBuf byteBuf) { + amount = byteBuf.readUInt16Decimal(); + } + + public double getAmount() { + return amount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ActiveBRProfileBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ActiveBRProfileBlock.java new file mode 100644 index 0000000000..f40ffbe421 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ActiveBRProfileBlock.java @@ -0,0 +1,30 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BasalProfile; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ActiveBasalProfileIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ActiveBRProfileBlock extends ParameterBlock { + + private BasalProfile activeBasalProfile; + + @Override + public void parse(ByteBuf byteBuf) { + activeBasalProfile = ActiveBasalProfileIDs.IDS.getType(byteBuf.readUInt16LE()); + } + + @Override + public ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(ActiveBasalProfileIDs.IDS.getID(activeBasalProfile)); + return byteBuf; + } + + public BasalProfile getActiveBasalProfile() { + return activeBasalProfile; + } + + public void setActiveBasalProfile(BasalProfile activeBasalProfile) { + this.activeBasalProfile = activeBasalProfile; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1Block.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1Block.java new file mode 100644 index 0000000000..99c9c1bd74 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1Block.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile1Block extends BRProfileBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1NameBlock.java new file mode 100644 index 0000000000..670b889292 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile1NameBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile1NameBlock extends NameBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2Block.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2Block.java new file mode 100644 index 0000000000..11a275196f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2Block.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile2Block extends BRProfileBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2NameBlock.java new file mode 100644 index 0000000000..0da19911a9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile2NameBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile2NameBlock extends NameBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3Block.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3Block.java new file mode 100644 index 0000000000..8c9875bfea --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3Block.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile3Block extends BRProfileBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3NameBlock.java new file mode 100644 index 0000000000..1b63926131 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile3NameBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile3NameBlock extends NameBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4Block.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4Block.java new file mode 100644 index 0000000000..2a22a34e63 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4Block.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile4Block extends BRProfileBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4NameBlock.java new file mode 100644 index 0000000000..26d0a52fa3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile4NameBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile4NameBlock extends NameBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5Block.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5Block.java new file mode 100644 index 0000000000..ebb5fac320 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5Block.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile5Block extends BRProfileBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5NameBlock.java new file mode 100644 index 0000000000..15df4436b7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfile5NameBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class BRProfile5NameBlock extends NameBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfileBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfileBlock.java new file mode 100644 index 0000000000..2d6538dff3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/BRProfileBlock.java @@ -0,0 +1,50 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BasalProfileBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public abstract class BRProfileBlock extends ParameterBlock { + + private List profileBlocks; + + @Override + public void parse(ByteBuf byteBuf) { + profileBlocks = new ArrayList<>(); + for (int i = 0; i < 24; i++) { + BasalProfileBlock basalProfileBlock = new BasalProfileBlock(); + basalProfileBlock.setDuration(byteBuf.readUInt16LE()); + profileBlocks.add(basalProfileBlock); + } + for (int i = 0; i < 24; i++) profileBlocks.get(i).setBasalAmount(byteBuf.readUInt16Decimal()); + Iterator iterator = profileBlocks.iterator(); + while (iterator.hasNext()) + if (iterator.next().getDuration() == 0) + iterator.remove(); + } + + @Override + public ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(96); + for (int i = 0; i < 24; i++) { + if (profileBlocks.size() > i) byteBuf.putUInt16LE(profileBlocks.get(i).getDuration()); + else byteBuf.putUInt16LE(0); + } + for (int i = 0; i < 24; i++) { + if (profileBlocks.size() > i) byteBuf.putUInt16Decimal(profileBlocks.get(i).getBasalAmount()); + else byteBuf.putUInt16Decimal(0); + } + return byteBuf; + } + + public List getProfileBlocks() { + return profileBlocks; + } + + public void setProfileBlocks(List profileBlocks) { + this.profileBlocks = profileBlocks; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBasalAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBasalAmountBlock.java new file mode 100644 index 0000000000..638470a159 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBasalAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class FactoryMaxBasalAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBolusAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBolusAmountBlock.java new file mode 100644 index 0000000000..7626546f71 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMaxBolusAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class FactoryMaxBolusAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBasalAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBasalAmountBlock.java new file mode 100644 index 0000000000..15da6dee8b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBasalAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class FactoryMinBasalAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBolusAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBolusAmountBlock.java new file mode 100644 index 0000000000..43daa70db5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/FactoryMinBolusAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class FactoryMinBolusAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/InsulinAmountLimitationBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/InsulinAmountLimitationBlock.java new file mode 100644 index 0000000000..837e8f561d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/InsulinAmountLimitationBlock.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public abstract class InsulinAmountLimitationBlock extends ParameterBlock { + + private double amountLimitation; + + @Override + public void parse(ByteBuf byteBuf) { + amountLimitation = byteBuf.readUInt16Decimal(); + } + + @Override + public ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16Decimal(amountLimitation); + return byteBuf; + } + + public double getAmountLimitation() { + return this.amountLimitation; + } + + public void setAmountLimitation(double amountLimitation) { + this.amountLimitation = amountLimitation; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBasalAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBasalAmountBlock.java new file mode 100644 index 0000000000..e7c4f5a089 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBasalAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class MaxBasalAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBolusAmountBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBolusAmountBlock.java new file mode 100644 index 0000000000..eae1404127 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/MaxBolusAmountBlock.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +public class MaxBolusAmountBlock extends InsulinAmountLimitationBlock { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/NameBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/NameBlock.java new file mode 100644 index 0000000000..af019bbbff --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/NameBlock.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public abstract class NameBlock extends ParameterBlock { + + private String name; + + @Override + public void parse(ByteBuf byteBuf) { + name = byteBuf.readUTF16(40); + } + + @Override + public ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(42); + byteBuf.putUTF16(name, 40); + return byteBuf; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ParameterBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ParameterBlock.java new file mode 100644 index 0000000000..1a64f0776e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/ParameterBlock.java @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public abstract class ParameterBlock { + + public abstract void parse(ByteBuf byteBuf); + public abstract ByteBuf getData(); + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/SystemIdentificationBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/SystemIdentificationBlock.java new file mode 100644 index 0000000000..fcc7f75447 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/SystemIdentificationBlock.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.SystemIdentification; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SystemIdentificationBlock extends ParameterBlock { + + private SystemIdentification systemIdentification; + + @Override + public void parse(ByteBuf byteBuf) { + systemIdentification = new SystemIdentification(); + systemIdentification.setSerialNumber(byteBuf.readUTF16(18)); + systemIdentification.setSystemIdAppendix(byteBuf.readUInt32LE()); + systemIdentification.setManufacturingDate(byteBuf.readUTF16(22)); + } + + @Override + public ByteBuf getData() { + return null; + } + + public SystemIdentification getSystemIdentification() { + return systemIdentification; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/TBROverNotificationBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/TBROverNotificationBlock.java new file mode 100644 index 0000000000..26563b1d1f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/parameter_blocks/TBROverNotificationBlock.java @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class TBROverNotificationBlock extends ParameterBlock { + + private boolean enabled; + private int melody; + + @Override + public void parse(ByteBuf byteBuf) { + enabled = byteBuf.readBoolean(); + melody = byteBuf.readUInt16LE(); + } + + @Override + public ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(4); + byteBuf.putBoolean(enabled); + byteBuf.putUInt16LE(melody); + return byteBuf; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelBolusMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelBolusMessage.java new file mode 100644 index 0000000000..92e72a41bf --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelBolusMessage.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class CancelBolusMessage extends AppLayerMessage { + + private int bolusID; + + public CancelBolusMessage() { + super(MessagePriority.HIGHEST, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(bolusID); + return byteBuf; + } + + public void setBolusID(int bolusID) { + this.bolusID = bolusID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelTBRMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelTBRMessage.java new file mode 100644 index 0000000000..b331e846ac --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/CancelTBRMessage.java @@ -0,0 +1,12 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class CancelTBRMessage extends AppLayerMessage { + public CancelTBRMessage() { + super(MessagePriority.HIGHER, false, false, Service.REMOTE_CONTROL); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ChangeTBRMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ChangeTBRMessage.java new file mode 100644 index 0000000000..9dbda3ecb0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ChangeTBRMessage.java @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ChangeTBRMessage extends AppLayerMessage { + + private int percentage; + private int duration; + + public ChangeTBRMessage() { + super(MessagePriority.NORMAL, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(6); + byteBuf.putUInt16LE(percentage); + byteBuf.putUInt16LE(duration); + byteBuf.putUInt16LE(31); + return byteBuf; + } + + public void setPercentage(int percentage) { + this.percentage = percentage; + } + + public void setDuration(int duration) { + this.duration = duration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ConfirmAlertMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ConfirmAlertMessage.java new file mode 100644 index 0000000000..dd56282834 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/ConfirmAlertMessage.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ConfirmAlertMessage extends AppLayerMessage { + + private int alertID; + + public ConfirmAlertMessage() { + super(MessagePriority.NORMAL, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(alertID); + return byteBuf; + } + + public void setAlertID(int alertID) { + this.alertID = alertID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/DeliverBolusMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/DeliverBolusMessage.java new file mode 100644 index 0000000000..c2879beb96 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/DeliverBolusMessage.java @@ -0,0 +1,63 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.BolusTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class DeliverBolusMessage extends AppLayerMessage { + + private BolusType bolusType; + private double immediateAmount; + private double extendedAmount; + private int duration; + private int bolusId; + + public DeliverBolusMessage() { + super(MessagePriority.NORMAL, true, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(22); + byteBuf.putUInt16LE(805); + byteBuf.putUInt16LE(BolusTypeIDs.IDS.getID(bolusType)); + byteBuf.putUInt16LE(31); + byteBuf.putUInt16LE(0); + byteBuf.putUInt16Decimal(immediateAmount); + byteBuf.putUInt16Decimal(extendedAmount); + byteBuf.putUInt16LE(duration); + byteBuf.putUInt16LE(0); + byteBuf.putUInt16Decimal(immediateAmount); + byteBuf.putUInt16Decimal(extendedAmount); + byteBuf.putUInt16LE(duration); + return byteBuf; + } + + @Override + protected void parse(ByteBuf byteBuf) throws Exception { + bolusId = byteBuf.readUInt16LE(); + } + + public void setBolusType(BolusType bolusType) { + this.bolusType = bolusType; + } + + public void setImmediateAmount(double immediateAmount) { + this.immediateAmount = immediateAmount; + } + + public void setExtendedAmount(double extendedAmount) { + this.extendedAmount = extendedAmount; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int getBolusId() { + return bolusId; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/GetAvailableBolusTypesMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/GetAvailableBolusTypesMessage.java new file mode 100644 index 0000000000..50395edcc1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/GetAvailableBolusTypesMessage.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AvailableBolusTypes; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetAvailableBolusTypesMessage extends AppLayerMessage { + + private AvailableBolusTypes availableBolusTypes; + + public GetAvailableBolusTypesMessage() { + super(MessagePriority.NORMAL, false, false, Service.REMOTE_CONTROL); + } + + @Override + protected void parse(ByteBuf byteBuf) throws Exception { + availableBolusTypes = new AvailableBolusTypes(); + availableBolusTypes.setStandardAvailable(byteBuf.readBoolean()); + availableBolusTypes.setExtendedAvailable(byteBuf.readBoolean()); + availableBolusTypes.setMultiwaveAvailable(byteBuf.readBoolean()); + } + + public AvailableBolusTypes getAvailableBolusTypes() { + return this.availableBolusTypes; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetDateTimeMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetDateTimeMessage.java new file mode 100644 index 0000000000..5ceea4f168 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetDateTimeMessage.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.PumpTime; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SetDateTimeMessage extends AppLayerMessage { + + private PumpTime pumpTime; + + public SetDateTimeMessage() { + super(MessagePriority.NORMAL, false, true, Service.CONFIGURATION); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(7); + byteBuf.putUInt16LE(pumpTime.getYear()); + byteBuf.putUInt8((short) pumpTime.getMonth()); + byteBuf.putUInt8((short) pumpTime.getDay()); + byteBuf.putUInt8((short) pumpTime.getHour()); + byteBuf.putUInt8((short) pumpTime.getMinute()); + byteBuf.putUInt8((short) pumpTime.getSecond()); + return byteBuf; + } + + public void setPumpTime(PumpTime pumpTime) { + this.pumpTime = pumpTime; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetOperatingModeMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetOperatingModeMessage.java new file mode 100644 index 0000000000..a217ab54f7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetOperatingModeMessage.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.OperatingMode; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.OperatingModeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SetOperatingModeMessage extends AppLayerMessage { + + private OperatingMode operatingMode; + + public SetOperatingModeMessage() { + super(MessagePriority.HIGHEST, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(OperatingModeIDs.IDS.getID(operatingMode)); + return byteBuf; + } + + public void setOperatingMode(OperatingMode operatingMode) { + this.operatingMode = operatingMode; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetTBRMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetTBRMessage.java new file mode 100644 index 0000000000..76959ed025 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SetTBRMessage.java @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SetTBRMessage extends AppLayerMessage { + + private int percentage; + private int duration; + + public SetTBRMessage() { + super(MessagePriority.NORMAL, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(6); + byteBuf.putUInt16LE(percentage); + byteBuf.putUInt16LE(duration); + byteBuf.putUInt16LE(31); + return byteBuf; + } + + public void setPercentage(int percentage) { + this.percentage = percentage; + } + + public void setDuration(int duration) { + this.duration = duration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SnoozeAlertMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SnoozeAlertMessage.java new file mode 100644 index 0000000000..2278ae84e8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/remote_control/SnoozeAlertMessage.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class SnoozeAlertMessage extends AppLayerMessage { + + private int alertID; + + public SnoozeAlertMessage() { + super(MessagePriority.NORMAL, false, true, Service.REMOTE_CONTROL); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(alertID); + return byteBuf; + } + + public void setAlertID(int alertID) { + this.alertID = alertID; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveAlertMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveAlertMessage.java new file mode 100644 index 0000000000..291726d35d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveAlertMessage.java @@ -0,0 +1,54 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.Alert; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AlertCategoryIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AlertStatusIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.AlertTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetActiveAlertMessage extends AppLayerMessage { + + private Alert alert; + + public GetActiveAlertMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + Alert alert = new Alert(); + alert.setAlertId(byteBuf.readUInt16LE()); + alert.setAlertCategory(AlertCategoryIDs.IDS.getType(byteBuf.readUInt16LE())); + alert.setAlertType(AlertTypeIDs.IDS.getType(byteBuf.readUInt16LE())); + alert.setAlertStatus(AlertStatusIDs.IDS.getType(byteBuf.readUInt16LE())); + if (alert.getAlertType() != null) { + switch (alert.getAlertType()) { + case WARNING_38: + byteBuf.shift(4); + alert.setProgrammedBolusAmount(byteBuf.readUInt16Decimal()); + alert.setDeliveredBolusAmount(byteBuf.readUInt16Decimal()); + break; + case REMINDER_07: + case WARNING_36: + byteBuf.shift(2); + alert.setTBRAmount(byteBuf.readUInt16LE()); + alert.setTBRDuration(byteBuf.readUInt16LE()); + break; + case WARNING_31: + alert.setCartridgeAmount(byteBuf.readUInt16Decimal()); + break; + } + } + if (alert.getAlertCategory() != null + && alert.getAlertType() != null + && alert.getAlertStatus() != null) + this.alert = alert; + } + + public Alert getAlert() { + return this.alert; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBasalRateMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBasalRateMessage.java new file mode 100644 index 0000000000..b5aa73f2a7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBasalRateMessage.java @@ -0,0 +1,30 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBasalRate; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ActiveBasalProfileIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetActiveBasalRateMessage extends AppLayerMessage { + + private ActiveBasalRate activeBasalRate; + + public GetActiveBasalRateMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + ActiveBasalRate activeBasalRate = new ActiveBasalRate(); + activeBasalRate.setActiveBasalProfile(ActiveBasalProfileIDs.IDS.getType(byteBuf.readUInt16LE())); + activeBasalRate.setActiveBasalProfileName(byteBuf.readUTF16(30)); + activeBasalRate.setActiveBasalRate(byteBuf.readUInt16Decimal()); + if (activeBasalRate.getActiveBasalProfile() != null) this.activeBasalRate = activeBasalRate; + } + + public ActiveBasalRate getActiveBasalRate() { + return this.activeBasalRate; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBolusesMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBolusesMessage.java new file mode 100644 index 0000000000..90cd93c127 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveBolusesMessage.java @@ -0,0 +1,40 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveBolus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ActiveBolusTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetActiveBolusesMessage extends AppLayerMessage { + + private List activeBoluses; + + public GetActiveBolusesMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + activeBoluses = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + ActiveBolus activeBolus = new ActiveBolus(); + activeBolus.setBolusID(byteBuf.readUInt16LE()); + activeBolus.setBolusType(ActiveBolusTypeIDs.IDS.getType(byteBuf.readUInt16LE())); + byteBuf.shift(2); + byteBuf.shift(2); + activeBolus.setInitialAmount(byteBuf.readUInt16Decimal()); + activeBolus.setRemainingAmount(byteBuf.readUInt16Decimal()); + activeBolus.setRemainingDuration(byteBuf.readUInt16LE()); + if (activeBolus.getBolusType() != null) activeBoluses.add(activeBolus); + } + } + + public List getActiveBoluses() { + return this.activeBoluses; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveTBRMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveTBRMessage.java new file mode 100644 index 0000000000..d839a5a394 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetActiveTBRMessage.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.ActiveTBR; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetActiveTBRMessage extends AppLayerMessage { + + private ActiveTBR activeTBR; + + public GetActiveTBRMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + ActiveTBR activeTBR = new ActiveTBR(); + activeTBR.setPercentage(byteBuf.readUInt16LE()); + activeTBR.setRemainingDuration(byteBuf.readUInt16LE()); + activeTBR.setInitialDuration(byteBuf.readUInt16LE()); + if (activeTBR.getPercentage() != 100) this.activeTBR = activeTBR; + } + + public ActiveTBR getActiveTBR() { + return this.activeTBR; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetBatteryStatusMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetBatteryStatusMessage.java new file mode 100644 index 0000000000..d6d8668f56 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetBatteryStatusMessage.java @@ -0,0 +1,30 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BatteryStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.BatteryTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.SymbolStatusIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetBatteryStatusMessage extends AppLayerMessage { + + private BatteryStatus batteryStatus; + + public GetBatteryStatusMessage() { + super(MessagePriority.NORMAL, false, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + batteryStatus = new BatteryStatus(); + batteryStatus.setBatteryType(BatteryTypeIDs.IDS.getType(byteBuf.readUInt16LE())); + batteryStatus.setBatteryAmount(byteBuf.readUInt16LE()); + batteryStatus.setSymbolStatus(SymbolStatusIDs.IDS.getType(byteBuf.readUInt16LE())); + } + + public BatteryStatus getBatteryStatus() { + return this.batteryStatus; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetCartridgeStatusMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetCartridgeStatusMessage.java new file mode 100644 index 0000000000..c2c941e236 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetCartridgeStatusMessage.java @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.CartridgeStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.CartridgeTypeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.SymbolStatusIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetCartridgeStatusMessage extends AppLayerMessage { + + private CartridgeStatus cartridgeStatus; + + public GetCartridgeStatusMessage() { + super(MessagePriority.NORMAL, false, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + cartridgeStatus = new CartridgeStatus(); + cartridgeStatus.setInserted(byteBuf.readBoolean()); + cartridgeStatus.setCartridgeType(CartridgeTypeIDs.IDS.getType(byteBuf.readUInt16LE())); + cartridgeStatus.setSymbolStatus(SymbolStatusIDs.IDS.getType(byteBuf.readUInt16LE())); + cartridgeStatus.setRemainingAmount(byteBuf.readUInt16Decimal()); + } + + public CartridgeStatus getCartridgeStatus() { + return this.cartridgeStatus; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetDateTimeMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetDateTimeMessage.java new file mode 100644 index 0000000000..8d80a7e465 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetDateTimeMessage.java @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.PumpTime; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetDateTimeMessage extends AppLayerMessage { + + private PumpTime pumpTime; + + public GetDateTimeMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + pumpTime = new PumpTime(); + pumpTime.setYear(byteBuf.readUInt16LE()); + pumpTime.setMonth(byteBuf.readUInt8()); + pumpTime.setDay(byteBuf.readUInt8()); + pumpTime.setHour(byteBuf.readUInt8()); + pumpTime.setMinute(byteBuf.readUInt8()); + pumpTime.setSecond(byteBuf.readUInt8()); + } + + public PumpTime getPumpTime() { + return this.pumpTime; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetFirmwareVersionsMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetFirmwareVersionsMessage.java new file mode 100644 index 0000000000..ef97fc3861 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetFirmwareVersionsMessage.java @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import android.util.Log; + +import org.spongycastle.util.encoders.Hex; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.FirmwareVersions; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetFirmwareVersionsMessage extends AppLayerMessage { + + private FirmwareVersions firmwareVersions; + + public GetFirmwareVersionsMessage() { + super(MessagePriority.NORMAL, false, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + firmwareVersions = new FirmwareVersions(); + firmwareVersions.setReleaseSWVersion(byteBuf.readASCII(13)); + firmwareVersions.setUiProcSWVersion(byteBuf.readASCII(11)); + firmwareVersions.setPcProcSWVersion(byteBuf.readASCII(11)); + firmwareVersions.setMdTelProcSWVersion(byteBuf.readASCII(11)); + firmwareVersions.setBtInfoPageVersion(byteBuf.readASCII(11)); + firmwareVersions.setSafetyProcSWVersion(byteBuf.readASCII(11)); + firmwareVersions.setConfigIndex(byteBuf.readUInt16LE()); + firmwareVersions.setHistoryIndex(byteBuf.readUInt16LE()); + firmwareVersions.setStateIndex(byteBuf.readUInt16LE()); + firmwareVersions.setVocabularyIndex(byteBuf.readUInt16LE()); + } + + public FirmwareVersions getFirmwareVersions() { + return this.firmwareVersions; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetOperatingModeMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetOperatingModeMessage.java new file mode 100644 index 0000000000..ebf7607801 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetOperatingModeMessage.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.OperatingMode; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.OperatingModeIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetOperatingModeMessage extends AppLayerMessage { + + private OperatingMode operatingMode; + + public GetOperatingModeMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + this.operatingMode = OperatingModeIDs.IDS.getType(byteBuf.readUInt16LE()); + } + + public OperatingMode getOperatingMode() { + return this.operatingMode; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetPumpStatusRegisterMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetPumpStatusRegisterMessage.java new file mode 100644 index 0000000000..2fd63c76fe --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetPumpStatusRegisterMessage.java @@ -0,0 +1,60 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetPumpStatusRegisterMessage extends AppLayerMessage { + + private boolean operatingModeChanged; + private boolean batteryStatusChanged; + private boolean cartridgeStatusChanged; + private boolean totalDailyDoseChanged; + private boolean activeBasalRateChanged; + private boolean activeTBRChanged; + private boolean activeBolusesChanged; + + public GetPumpStatusRegisterMessage() { + super(MessagePriority.NORMAL, false, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + operatingModeChanged = byteBuf.readBoolean(); + batteryStatusChanged = byteBuf.readBoolean(); + cartridgeStatusChanged = byteBuf.readBoolean(); + totalDailyDoseChanged = byteBuf.readBoolean(); + activeBasalRateChanged = byteBuf.readBoolean(); + activeTBRChanged = byteBuf.readBoolean(); + activeBolusesChanged = byteBuf.readBoolean(); + } + + public boolean isOperatingModeChanged() { + return this.operatingModeChanged; + } + + public boolean isBatteryStatusChanged() { + return this.batteryStatusChanged; + } + + public boolean isCartridgeStatusChanged() { + return this.cartridgeStatusChanged; + } + + public boolean isTotalDailyDoseChanged() { + return this.totalDailyDoseChanged; + } + + public boolean isActiveBasalRateChanged() { + return this.activeBasalRateChanged; + } + + public boolean isActiveTBRChanged() { + return this.activeTBRChanged; + } + + public boolean isActiveBolusesChanged() { + return this.activeBolusesChanged; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetTotalDailyDoseMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetTotalDailyDoseMessage.java new file mode 100644 index 0000000000..1f208c97e0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/GetTotalDailyDoseMessage.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.TotalDailyDose; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class GetTotalDailyDoseMessage extends AppLayerMessage { + + private TotalDailyDose tdd; + + public GetTotalDailyDoseMessage() { + super(MessagePriority.NORMAL, true, false, Service.STATUS); + } + + @Override + protected void parse(ByteBuf byteBuf) { + tdd = new TotalDailyDose(); + tdd.setBolus(byteBuf.readUInt32Decimal100()); + tdd.setBasal(byteBuf.readUInt32Decimal100()); + tdd.setBolusAndBasal(byteBuf.readUInt32Decimal100()); + } + + public TotalDailyDose getTDD() { + return this.tdd; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/ResetPumpStatusRegisterMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/ResetPumpStatusRegisterMessage.java new file mode 100644 index 0000000000..f215165be5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/app_layer/status/ResetPumpStatusRegisterMessage.java @@ -0,0 +1,63 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.MessagePriority; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ResetPumpStatusRegisterMessage extends AppLayerMessage { + + private boolean operatingModeChanged; + private boolean batteryStatusChanged; + private boolean cartridgeStatusChanged; + private boolean totalDailyDoseChanged; + private boolean activeBasalRateChanged; + private boolean activeTBRChanged; + private boolean activeBolusesChanged; + + public ResetPumpStatusRegisterMessage() { + super(MessagePriority.NORMAL, false, false, Service.STATUS); + } + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(28); + byteBuf.putBoolean(operatingModeChanged); + byteBuf.putBoolean(batteryStatusChanged); + byteBuf.putBoolean(cartridgeStatusChanged); + byteBuf.putBoolean(totalDailyDoseChanged); + byteBuf.putBoolean(activeBasalRateChanged); + byteBuf.putBoolean(activeTBRChanged); + byteBuf.putBoolean(activeBolusesChanged); + for (int i = 0; i < 7; i++) byteBuf.putBoolean(false); + return byteBuf; + } + + public void setOperatingModeChanged(boolean operatingModeChanged) { + this.operatingModeChanged = operatingModeChanged; + } + + public void setBatteryStatusChanged(boolean batteryStatusChanged) { + this.batteryStatusChanged = batteryStatusChanged; + } + + public void setCartridgeStatusChanged(boolean cartridgeStatusChanged) { + this.cartridgeStatusChanged = cartridgeStatusChanged; + } + + public void setTotalDailyDoseChanged(boolean totalDailyDoseChanged) { + this.totalDailyDoseChanged = totalDailyDoseChanged; + } + + public void setActiveBasalRateChanged(boolean activeBasalRateChanged) { + this.activeBasalRateChanged = activeBasalRateChanged; + } + + public void setActiveTBRChanged(boolean activeTBRChanged) { + this.activeTBRChanged = activeTBRChanged; + } + + public void setActiveBolusesChanged(boolean activeBolusesChanged) { + this.activeBolusesChanged = activeBolusesChanged; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/ConfigurationMessageRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/ConfigurationMessageRequest.java new file mode 100644 index 0000000000..cb2703e3c7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/ConfigurationMessageRequest.java @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.CloseConfigurationWriteSessionMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.OpenConfigurationWriteSessionMessage; + +public class ConfigurationMessageRequest extends MessageRequest { + + private MessageRequest openRequest; + private MessageRequest closeRequest; + + public ConfigurationMessageRequest(T request, MessageRequest openRequest, MessageRequest closeRequest) { + super(request); + this.openRequest = openRequest; + this.closeRequest = closeRequest; + } + + @Override + public T await() throws Exception { + openRequest.await(); + T response = super.await(); + closeRequest.await(); + return response; + } + + @Override + public T await(long timeout) throws Exception { + openRequest.await(timeout); + T response = super.await(timeout); + closeRequest.await(timeout); + return response; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/InsightConnectionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/InsightConnectionService.java new file mode 100644 index 0000000000..1106be20a0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/InsightConnectionService.java @@ -0,0 +1,775 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service; + +import android.app.Service; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; +import android.os.PowerManager; +import android.support.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spongycastle.crypto.InvalidCipherTextException; + +import java.io.IOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.ReadParameterBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.CloseConfigurationWriteSessionMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.OpenConfigurationWriteSessionMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.WriteConfigurationBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ActivateServiceMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.BindMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ConnectMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.DisconnectMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ServiceChallengeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.SystemIdentificationBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetFirmwareVersionsMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.FirmwareVersions; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.InsightState; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.SystemIdentification; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.ConnectionFailedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.ConnectionLostException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.DisconnectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InsightException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidNonceException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidSatlCommandException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.ReceivedPacketInInvalidStateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.TimeoutException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.TooChattyPumpException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlCompatibleStateErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlDecryptVerifyFailedErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlIncompatibleVersionErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidCRCErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidCommIdErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidMacErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidMessageTypeErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidNonceErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidPacketErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlInvalidPayloadLengthErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlNoneErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlPairingRejectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlUndefinedErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlWrongStateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.ServiceIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ConnectionRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ConnectionResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.DataMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ErrorMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.KeyRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.KeyResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SatlMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SynAckResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SynRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyConfirmRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyConfirmResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyDisplayRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyDisplayResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ConnectionEstablisher; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.DelayedActionThread; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.InputStreamReader; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.Nonce; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.OutputStreamWriter; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.PairingDataStorage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto.Cryptograph; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto.DerivedKeys; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto.KeyPair; +import info.nightscout.utils.SP; + +public class InsightConnectionService extends Service implements ConnectionEstablisher.Callback, InputStreamReader.Callback, OutputStreamWriter.Callback { + + private static Logger log = LoggerFactory.getLogger(L.PUMPCOMM); + + private static final int BUFFER_SIZE = 1024; + private static final long RESPONSE_TIMEOUT = 6000; + + private List stateCallbacks = new ArrayList<>(); + private final List connectionRequests = new ArrayList<>(); + private List exceptionCallbacks = new ArrayList<>(); + private LocalBinder localBinder = new LocalBinder(); + private PairingDataStorage pairingDataStorage; + private InsightState state; + private PowerManager.WakeLock wakeLock; + private DelayedActionThread disconnectTimer; + private DelayedActionThread recoveryTimer; + private DelayedActionThread timeoutTimer; + private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + private BluetoothDevice bluetoothDevice; + private BluetoothSocket bluetoothSocket; + private ConnectionEstablisher connectionEstablisher; + private InputStreamReader inputStreamReader; + private OutputStreamWriter outputStreamWriter; + private KeyRequest keyRequest; + private ByteBuf buffer = new ByteBuf(BUFFER_SIZE); + private String verificationString; + private KeyPair keyPair; + private byte[] randomBytes; + private MessageQueue messageQueue = new MessageQueue(); + private List activatedServices = new ArrayList<>(); + private long lastDataTime; + private long lastConnected; + + KeyPair getKeyPair() { + if (keyPair == null) keyPair = Cryptograph.generateRSAKey(); + return keyPair; + } + + byte[] getRandomBytes() { + if (randomBytes == null) { + randomBytes = new byte[28]; + new SecureRandom().nextBytes(randomBytes); + } + return randomBytes; + } + + public long getLastConnected() { + return lastConnected; + } + + public long getLastDataTime() { + return lastDataTime; + } + + public FirmwareVersions getPumpFirmwareVersions() { + return pairingDataStorage.getFirmwareVersions(); + } + + public SystemIdentification getPumpSystemIdentification() { + return pairingDataStorage.getSystemIdentification(); + } + + public String getBluetoothAddress() { + return pairingDataStorage.getMacAddress(); + } + + public synchronized String getVerificationString() { + return verificationString; + } + + public synchronized void registerStateCallback(StateCallback stateCallback) { + stateCallbacks.add(stateCallback); + } + + public synchronized void unregisterStateCallback(StateCallback stateCallback) { + stateCallbacks.remove(stateCallback); + } + + public synchronized void registerExceptionCallback(ExceptionCallback exceptionCallback) { + exceptionCallbacks.add(exceptionCallback); + } + + public synchronized void unregisterExceptionCallback(ExceptionCallback exceptionCallback) { + exceptionCallbacks.remove(exceptionCallback); + } + + public synchronized void confirmVerificationString() { + setState(InsightState.SATL_VERIFY_CONFIRM_REQUEST); + sendSatlMessage(new VerifyConfirmRequest()); + } + + public synchronized void rejectVerificationString() { + handleException(new SatlPairingRejectedException()); + } + + public synchronized boolean isPaired() { + return pairingDataStorage.isPaired(); + } + + public synchronized MessageRequest requestMessage(T message) { + MessageRequest messageRequest; + if (getState() != InsightState.CONNECTED) { + messageRequest = new MessageRequest<>(message); + messageRequest.exception = new DisconnectedException(); + return messageRequest; + } + if (message instanceof WriteConfigurationBlockMessage) { + MessageRequest openRequest = new MessageRequest<>(new OpenConfigurationWriteSessionMessage()); + MessageRequest closeRequest = new MessageRequest<>(new CloseConfigurationWriteSessionMessage()); + messageRequest = new ConfigurationMessageRequest<>(message, openRequest, closeRequest); + messageQueue.enqueueRequest(openRequest); + messageQueue.enqueueRequest(messageRequest); + messageQueue.enqueueRequest(closeRequest); + } else { + messageRequest = new MessageRequest<>(message); + messageQueue.enqueueRequest(messageRequest); + } + requestNextMessage(); + return messageRequest; + } + + private void requestNextMessage() { + while (messageQueue.getActiveRequest() == null && messageQueue.hasPendingMessages()) { + messageQueue.nextRequest(); + info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service service = messageQueue.getActiveRequest().request.getService(); + if (service != info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.CONNECTION && !activatedServices.contains(service)) { + if (service.getServicePassword() == null) { + ActivateServiceMessage activateServiceMessage = new ActivateServiceMessage(); + activateServiceMessage.setServiceID(ServiceIDs.IDS.getID(service)); + activateServiceMessage.setVersion(service.getVersion()); + activateServiceMessage.setServicePassword(new byte[16]); + sendAppLayerMessage(activateServiceMessage); + } else { + ServiceChallengeMessage serviceChallengeMessage = new ServiceChallengeMessage(); + serviceChallengeMessage.setServiceID(ServiceIDs.IDS.getID(service)); + serviceChallengeMessage.setVersion(service.getVersion()); + sendAppLayerMessage(serviceChallengeMessage); + } + } else sendAppLayerMessage(messageQueue.getActiveRequest().request); + } + } + + public synchronized InsightState getState() { + return state; + } + + @Override + public synchronized void onCreate() { + pairingDataStorage = new PairingDataStorage(this); + state = pairingDataStorage.isPaired() ? InsightState.DISCONNECTED : InsightState.NOT_PAIRED; + wakeLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:InsightConnectionService"); + } + + private void setState(InsightState state) { + if (this.state == state) return; + if (this.state == InsightState.CONNECTED) lastConnected = System.currentTimeMillis(); + if ((state == InsightState.DISCONNECTED || state == InsightState.NOT_PAIRED) && wakeLock.isHeld()) + wakeLock.release(); + else if (!wakeLock.isHeld()) wakeLock.acquire(); + this.state = state; + for (StateCallback stateCallback : stateCallbacks) stateCallback.stateChanged(state); + log.info("Insight state changed: " + state.name()); + } + + public synchronized void requestConnection(Object lock) { + if (connectionRequests.contains(lock)) return; + connectionRequests.add(lock); + if (disconnectTimer != null) { + disconnectTimer.interrupt(); + disconnectTimer = null; + } + if (state == InsightState.DISCONNECTED && pairingDataStorage.isPaired()) connect(); + } + + public synchronized void withdrawConnectionRequest(Object lock) { + if (!connectionRequests.contains(lock)) return; + connectionRequests.remove(lock); + if (connectionRequests.size() == 0) { + //TODO: Make adjustable + log.info("Last connection lock released, will disconnect in 5 seconds"); + if (recoveryTimer != null) { + recoveryTimer.interrupt(); + recoveryTimer = null; + setState(InsightState.DISCONNECTED); + } else { + long disconnectTimeout = SP.getInt("insight_disconnect_delay", 5); + disconnectTimeout = Math.min(disconnectTimeout, 15); + disconnectTimeout = Math.max(disconnectTimeout, 0); + disconnectTimer = DelayedActionThread.runDelayed("Disconnect Timer", disconnectTimeout * 1000, this::disconnect); + } + } + } + + private void cleanup() { + messageQueue.completeActiveRequest(new ConnectionLostException()); + messageQueue.completePendingRequests(new ConnectionLostException()); + if (recoveryTimer != null) { + recoveryTimer.interrupt(); + recoveryTimer = null; + } + if (disconnectTimer != null) { + disconnectTimer.interrupt(); + disconnectTimer = null; + } + if (inputStreamReader != null) { + inputStreamReader.close(); + inputStreamReader = null; + } + if (outputStreamWriter != null) { + outputStreamWriter.close(); + outputStreamWriter = null; + } + if (connectionEstablisher != null) { + connectionEstablisher.close(); + connectionEstablisher = null; + } + bluetoothSocket = null; + if (timeoutTimer != null) { + timeoutTimer.interrupt(); + timeoutTimer = null; + } + buffer.clear(); + verificationString = null; + keyPair = null; + randomBytes = null; + activatedServices.clear(); + if (!pairingDataStorage.isPaired()) { + bluetoothSocket = null; + bluetoothDevice = null; + pairingDataStorage.reset(); + } + } + + private synchronized void handleException(Exception e) { + switch (state) { + case NOT_PAIRED: + case DISCONNECTED: + case RECOVERING: + return; + } + log.info("Exception occurred: " + e.getClass().getSimpleName()); + if (pairingDataStorage.isPaired()) { + setState(InsightState.RECOVERING); + cleanup(); + messageQueue.completeActiveRequest(e); + messageQueue.completePendingRequests(e); + if (!(e instanceof ConnectionFailedException)) { + connect(); + } else { + int recoveryDuration = SP.getInt("insight_recovery_duration", 5); + recoveryDuration = Math.min(recoveryDuration, 20); + recoveryDuration = Math.max(recoveryDuration, 0); + recoveryTimer = DelayedActionThread.runDelayed("RecoveryTimer", recoveryDuration * 1000, () -> { + recoveryTimer = null; + connect(); + }); + } + } else { + setState(InsightState.NOT_PAIRED); + cleanup(); + } + for (ExceptionCallback exceptionCallback : exceptionCallbacks) + exceptionCallback.onExceptionOccur(e); + } + + private synchronized void disconnect() { + if (state == InsightState.CONNECTED) { + sendAppLayerMessage(new DisconnectMessage()); + sendSatlMessageAndWait(new info.nightscout.androidaps.plugins.PumpInsightLocal.satl.DisconnectMessage()); + } + cleanup(); + setState(pairingDataStorage.isPaired() ? InsightState.DISCONNECTED : InsightState.NOT_PAIRED); + } + + public synchronized void reset() { + pairingDataStorage.reset(); + disconnect(); + } + + public synchronized void pair(String macAddress) { + if (pairingDataStorage.isPaired()) + throw new IllegalStateException("Pump must be unbonded first."); + if (connectionRequests.size() == 0) + throw new IllegalStateException("A connection lock must be hold for pairing"); + log.info("Pairing initiated"); + cleanup(); + pairingDataStorage.setMacAddress(macAddress); + connect(); + } + + private synchronized void connect() { + if (bluetoothDevice == null) + bluetoothDevice = bluetoothAdapter.getRemoteDevice(pairingDataStorage.getMacAddress()); + setState(InsightState.CONNECTING); + connectionEstablisher = new ConnectionEstablisher(this, !pairingDataStorage.isPaired(), bluetoothAdapter, bluetoothDevice, bluetoothSocket); + connectionEstablisher.start(); + } + + @Override + public synchronized void onSocketCreated(BluetoothSocket bluetoothSocket) { + this.bluetoothSocket = bluetoothSocket; + } + + @Override + public synchronized void onConnectionSucceed() { + try { + inputStreamReader = new InputStreamReader(bluetoothSocket.getInputStream(), this); + outputStreamWriter = new OutputStreamWriter(bluetoothSocket.getOutputStream(), this); + inputStreamReader.start(); + outputStreamWriter.start(); + if (pairingDataStorage.isPaired()) { + setState(InsightState.SATL_SYN_REQUEST); + sendSatlMessage(new SynRequest()); + } else { + setState(InsightState.SATL_CONNECTION_REQUEST); + sendSatlMessage(new ConnectionRequest()); + } + } catch (IOException e) { + handleException(e); + } + } + + @Override + public synchronized void onReceiveBytes(byte[] buffer, int bytesRead) { + this.buffer.putBytes(buffer, bytesRead); + try { + while (SatlMessage.hasCompletePacket(this.buffer)) { + SatlMessage satlMessage = SatlMessage.deserialize(this.buffer, pairingDataStorage.getLastNonceReceived(), pairingDataStorage.getIncomingKey()); + if (pairingDataStorage.getIncomingKey() != null + && pairingDataStorage.getLastNonceReceived() != null + && !pairingDataStorage.getLastNonceReceived().isSmallerThan(satlMessage.getNonce())) { + throw new InvalidNonceException(); + } else processSatlMessage(satlMessage); + } + } catch (InsightException e) { + handleException(e); + } + } + + private byte[] prepareSatlMessage(SatlMessage satlMessage) { + satlMessage.setCommID(pairingDataStorage.getCommId()); + Nonce nonce = pairingDataStorage.getLastNonceSent(); + if (nonce != null) { + nonce.increment(); + pairingDataStorage.setLastNonceSent(nonce); + satlMessage.setNonce(nonce); + } + ByteBuf serialized = satlMessage.serialize(satlMessage.getClass(), pairingDataStorage.getOutgoingKey()); + if (timeoutTimer != null) timeoutTimer.interrupt(); + timeoutTimer = DelayedActionThread.runDelayed("TimeoutTimer", RESPONSE_TIMEOUT, () -> { + timeoutTimer = null; + handleException(new TimeoutException()); + }); + return serialized.getBytes(); + } + + private void sendSatlMessage(SatlMessage satlMessage) { + if (outputStreamWriter == null) return; + outputStreamWriter.write(prepareSatlMessage(satlMessage)); + } + + private void sendSatlMessageAndWait(SatlMessage satlMessage) { + if (outputStreamWriter == null) return; + outputStreamWriter.writeAndWait(prepareSatlMessage(satlMessage)); + } + + private void processSatlMessage(SatlMessage satlMessage) { + if (timeoutTimer != null) { + timeoutTimer.interrupt(); + timeoutTimer = null; + } + pairingDataStorage.setLastNonceReceived(satlMessage.getNonce()); + if (satlMessage instanceof ConnectionResponse) processConnectionResponse(); + else if (satlMessage instanceof KeyResponse) processKeyResponse((KeyResponse) satlMessage); + else if (satlMessage instanceof VerifyDisplayResponse) processVerifyDisplayResponse(); + else if (satlMessage instanceof VerifyConfirmResponse) + processVerifyConfirmResponse((VerifyConfirmResponse) satlMessage); + else if (satlMessage instanceof DataMessage) processDataMessage((DataMessage) satlMessage); + else if (satlMessage instanceof SynAckResponse) processSynAckResponse(); + else if (satlMessage instanceof ErrorMessage) + processErrorMessage((ErrorMessage) satlMessage); + else handleException(new InvalidSatlCommandException()); + } + + private void processConnectionResponse() { + if (state != InsightState.SATL_CONNECTION_REQUEST) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + keyRequest = new KeyRequest(); + keyRequest.setPreMasterKey(getKeyPair().getPublicKeyBytes()); + keyRequest.setRandomBytes(getRandomBytes()); + setState(InsightState.SATL_KEY_REQUEST); + sendSatlMessage(keyRequest); + } + + private void processKeyResponse(KeyResponse keyResponse) { + if (state != InsightState.SATL_KEY_REQUEST) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + try { + DerivedKeys derivedKeys = Cryptograph.deriveKeys(Cryptograph.combine(keyRequest.getSatlContent(), keyResponse.getSatlContent()), + Cryptograph.decryptRSA(getKeyPair().getPrivateKey(), keyResponse.getPreMasterSecret()), + getRandomBytes(), + keyResponse.getRandomData()); + pairingDataStorage.setCommId(keyResponse.getCommID()); + keyRequest = null; + randomBytes = null; + keyPair = null; + verificationString = derivedKeys.getVerificationString(); + pairingDataStorage.setOutgoingKey(derivedKeys.getOutgoingKey()); + pairingDataStorage.setIncomingKey(derivedKeys.getIncomingKey()); + pairingDataStorage.setLastNonceSent(new Nonce()); + setState(InsightState.SATL_VERIFY_DISPLAY_REQUEST); + sendSatlMessage(new VerifyDisplayRequest()); + } catch (InvalidCipherTextException e) { + handleException(e); + } + } + + private void processVerifyDisplayResponse() { + if (state != InsightState.SATL_VERIFY_DISPLAY_REQUEST) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + setState(InsightState.AWAITING_CODE_CONFIRMATION); + } + + private void processVerifyConfirmResponse(VerifyConfirmResponse verifyConfirmResponse) { + if (state != InsightState.SATL_VERIFY_CONFIRM_REQUEST) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + switch (verifyConfirmResponse.getPairingStatus()) { + case CONFIRMED: + verificationString = null; + setState(InsightState.APP_BIND_MESSAGE); + sendAppLayerMessage(new BindMessage()); + break; + case PENDING: + try { + Thread.sleep(200); + sendSatlMessage(new VerifyConfirmRequest()); + } catch (InterruptedException e) { + //Redirect interrupt flag + Thread.currentThread().interrupt(); + } + break; + case REJECTED: + handleException(new SatlPairingRejectedException()); + break; + } + } + + private void processSynAckResponse() { + if (state != InsightState.SATL_SYN_REQUEST) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + setState(InsightState.APP_CONNECT_MESSAGE); + sendAppLayerMessage(new ConnectMessage()); + } + + private void processErrorMessage(ErrorMessage errorMessage) { + switch (errorMessage.getError()) { + case INVALID_NONCE: + handleException(new SatlInvalidNonceErrorException()); + break; + case INVALID_CRC: + handleException(new SatlInvalidCRCErrorException()); + break; + case INVALID_MAC_TRAILER: + handleException(new SatlInvalidMacErrorException()); + break; + case DECRYPT_VERIFY_FAILED: + handleException(new SatlDecryptVerifyFailedErrorException()); + break; + case INVALID_PAYLOAD_LENGTH: + handleException(new SatlInvalidPayloadLengthErrorException()); + break; + case INVALID_MESSAGE_TYPE: + handleException(new SatlInvalidMessageTypeErrorException()); + break; + case INCOMPATIBLE_VERSION: + handleException(new SatlIncompatibleVersionErrorException()); + break; + case COMPATIBLE_STATE: + handleException(new SatlCompatibleStateErrorException()); + break; + case INVALID_COMM_ID: + handleException(new SatlInvalidCommIdErrorException()); + break; + case INVALID_PACKET: + handleException(new SatlInvalidPacketErrorException()); + break; + case WRONG_STATE: + handleException(new SatlWrongStateException()); + break; + case UNDEFINED: + handleException(new SatlUndefinedErrorException()); + break; + case NONE: + handleException(new SatlNoneErrorException()); + break; + } + } + + private void processDataMessage(DataMessage dataMessage) { + switch (state) { + case CONNECTED: + case APP_BIND_MESSAGE: + case APP_CONNECT_MESSAGE: + case APP_ACTIVATE_PARAMETER_SERVICE: + case APP_ACTIVATE_STATUS_SERVICE: + case APP_FIRMWARE_VERSIONS: + case APP_SYSTEM_IDENTIFICATION: + break; + default: + handleException(new ReceivedPacketInInvalidStateException()); + } + try { + AppLayerMessage appLayerMessage = AppLayerMessage.unwrap(dataMessage); + if (appLayerMessage instanceof BindMessage) processBindMessage(); + else if (appLayerMessage instanceof ConnectMessage) processConnectMessage(); + else if (appLayerMessage instanceof ActivateServiceMessage) + processActivateServiceMessage(); + else if (appLayerMessage instanceof DisconnectMessage) ; + else if (appLayerMessage instanceof ServiceChallengeMessage) + processServiceChallengeMessage((ServiceChallengeMessage) appLayerMessage); + else if (appLayerMessage instanceof GetFirmwareVersionsMessage) + processFirmwareVersionsMessage((GetFirmwareVersionsMessage) appLayerMessage); + else if (appLayerMessage instanceof ReadParameterBlockMessage) + processReadParameterBlockMessage((ReadParameterBlockMessage) appLayerMessage); + else processGenericAppLayerMessage(appLayerMessage); + } catch (Exception e) { + if (state != InsightState.CONNECTED) { + handleException(e); + } else { + if (messageQueue.getActiveRequest() == null) { + handleException(new TooChattyPumpException()); + } else { + messageQueue.completeActiveRequest(e); + requestNextMessage(); + } + } + } + } + + private void processBindMessage() { + if (state != InsightState.APP_BIND_MESSAGE) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + setState(InsightState.APP_ACTIVATE_STATUS_SERVICE); + ActivateServiceMessage activateServiceMessage = new ActivateServiceMessage(); + activateServiceMessage.setServiceID(ServiceIDs.IDS.getID(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.STATUS)); + activateServiceMessage.setServicePassword(new byte[16]); + activateServiceMessage.setVersion(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.STATUS.getVersion()); + sendAppLayerMessage(activateServiceMessage); + } + + private void processFirmwareVersionsMessage(GetFirmwareVersionsMessage message) { + if (state != InsightState.APP_FIRMWARE_VERSIONS) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + pairingDataStorage.setFirmwareVersions(message.getFirmwareVersions()); + setState(InsightState.APP_ACTIVATE_PARAMETER_SERVICE); + ActivateServiceMessage activateServiceMessage = new ActivateServiceMessage(); + activateServiceMessage.setServiceID(ServiceIDs.IDS.getID(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.PARAMETER)); + activateServiceMessage.setServicePassword(new byte[16]); + activateServiceMessage.setVersion(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.PARAMETER.getVersion()); + sendAppLayerMessage(activateServiceMessage); + } + + private void processConnectMessage() { + if (state != InsightState.APP_CONNECT_MESSAGE) { + handleException(new ReceivedPacketInInvalidStateException()); + return; + } + setState(InsightState.CONNECTED); + } + + private void processActivateServiceMessage() { + if (state == InsightState.APP_ACTIVATE_PARAMETER_SERVICE) { + activatedServices.add(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.PARAMETER); + setState(InsightState.APP_SYSTEM_IDENTIFICATION); + ReadParameterBlockMessage message = new ReadParameterBlockMessage(); + message.setParameterBlockId(SystemIdentificationBlock.class); + message.setService(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.PARAMETER); + sendAppLayerMessage(message); + } else if (state == InsightState.APP_ACTIVATE_STATUS_SERVICE) { + activatedServices.add(info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service.STATUS); + setState(InsightState.APP_FIRMWARE_VERSIONS); + sendAppLayerMessage(new GetFirmwareVersionsMessage()); + } else { + if (messageQueue.getActiveRequest() == null) { + handleException(new TooChattyPumpException()); + } else { + activatedServices.add(messageQueue.getActiveRequest().request.getService()); + sendAppLayerMessage(messageQueue.getActiveRequest().request); + } + } + } + + private void processReadParameterBlockMessage(ReadParameterBlockMessage message) { + if (state == InsightState.APP_SYSTEM_IDENTIFICATION) { + if (!(message.getParameterBlock() instanceof SystemIdentificationBlock)) handleException(new TooChattyPumpException()); + else { + SystemIdentification systemIdentification = ((SystemIdentificationBlock) message.getParameterBlock()).getSystemIdentification(); + pairingDataStorage.setSystemIdentification(systemIdentification); + pairingDataStorage.setPaired(true); + log.info("Pairing completed YEE-HAW ♪ ┏(・o・)┛ ♪ ┗( ・o・)┓ ♪"); + setState(InsightState.CONNECTED); + } + } else processGenericAppLayerMessage(message); + } + + private void processServiceChallengeMessage(ServiceChallengeMessage serviceChallengeMessage) { + if (messageQueue.getActiveRequest() == null) { + handleException(new TooChattyPumpException()); + } else { + info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service service = messageQueue.getActiveRequest().request.getService(); + ActivateServiceMessage activateServiceMessage = new ActivateServiceMessage(); + activateServiceMessage.setServiceID(ServiceIDs.IDS.getID(service)); + activateServiceMessage.setVersion(service.getVersion()); + activateServiceMessage.setServicePassword(Cryptograph.getServicePasswordHash(service.getServicePassword(), serviceChallengeMessage.getRandomData())); + sendAppLayerMessage(activateServiceMessage); + } + } + + private void processGenericAppLayerMessage(AppLayerMessage appLayerMessage) { + if (messageQueue.getActiveRequest() == null) handleException(new TooChattyPumpException()); + else { + try { + messageQueue.completeActiveRequest(appLayerMessage); + lastDataTime = System.currentTimeMillis(); + } catch (Exception e) { + messageQueue.completeActiveRequest(e); + } + requestNextMessage(); + } + } + + void sendAppLayerMessage(AppLayerMessage appLayerMessage) { + sendSatlMessage(AppLayerMessage.wrap(appLayerMessage)); + } + + @Override + public synchronized void onConnectionFail(Exception e) { + handleException(new ConnectionFailedException()); + } + + @Override + public synchronized void onErrorWhileReading(Exception e) { + handleException(new ConnectionLostException()); + } + + @Override + public synchronized void onErrorWhileWriting(Exception e) { + handleException(new ConnectionLostException()); + } + + @Override + public void onDestroy() { + disconnect(); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return localBinder; + } + + public class LocalBinder extends Binder { + public InsightConnectionService getService() { + return InsightConnectionService.this; + } + } + + public interface StateCallback { + void stateChanged(InsightState state); + } + + public interface ExceptionCallback { + void onExceptionOccur(Exception e); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageQueue.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageQueue.java new file mode 100644 index 0000000000..74b557d8a0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageQueue.java @@ -0,0 +1,66 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; + +public class MessageQueue { + + MessageRequest activeRequest; + final List messageRequests = new ArrayList<>(); + + public MessageRequest getActiveRequest() { + return activeRequest; + } + + public void completeActiveRequest(AppLayerMessage response) { + if (activeRequest == null) return; + synchronized (activeRequest) { + activeRequest.response = response; + activeRequest.notifyAll(); + } + activeRequest = null; + } + + public void completeActiveRequest(Exception exception) { + if (activeRequest == null) return; + synchronized (activeRequest) { + activeRequest.exception = exception; + activeRequest.notifyAll(); + } + activeRequest = null; + } + + public void completePendingRequests(Exception exception) { + for (MessageRequest messageRequest : messageRequests) { + synchronized (messageRequest) { + messageRequest.exception = exception; + messageRequest.notifyAll(); + } + } + messageRequests.clear(); + } + + public void enqueueRequest(MessageRequest messageRequest) { + messageRequests.add(messageRequest); + Collections.sort(messageRequests); + } + + public void nextRequest() { + if (messageRequests.size() != 0) { + activeRequest = messageRequests.get(0); + messageRequests.remove(0); + } + } + + public boolean hasPendingMessages() { + return messageRequests.size() != 0; + } + + public void reset() { + activeRequest = null; + messageRequests.clear(); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageRequest.java new file mode 100644 index 0000000000..1d5c4f1b02 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/connection_service/MessageRequest.java @@ -0,0 +1,47 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; + +public class MessageRequest implements Comparable { + + T request; + T response; + Exception exception; + + MessageRequest(T request) { + this.request = request; + } + + public T await() throws Exception { + synchronized (this) { + while (exception == null && response == null) wait(); + if (exception != null) throw exception; + return response; + } + } + + public T await(long timeout) throws Exception { + synchronized (this) { + while (exception == null && response == null) wait(timeout); + if (exception != null) throw exception; + return response; + } + } + + @Override + public int compareTo(MessageRequest messageRequest) { + return request.compareTo(messageRequest.request); + } + + public T getRequest() { + return this.request; + } + + public T getResponse() { + return this.response; + } + + public Exception getException() { + return this.exception; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightBolusID.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightBolusID.java new file mode 100644 index 0000000000..44ad0ec582 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightBolusID.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.database; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import info.nightscout.androidaps.db.DatabaseHelper; + +@DatabaseTable(tableName = DatabaseHelper.DATABASE_INSIGHT_BOLUS_IDS) +public class InsightBolusID { + + @DatabaseField(generatedId = true) + public Long id; + + @DatabaseField + public String pumpSerial; + + @DatabaseField + public Long timestamp; + + @DatabaseField + public Integer bolusID; + + @DatabaseField + public Long startID; + + @DatabaseField + public Long endID; + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightHistoryOffset.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightHistoryOffset.java new file mode 100644 index 0000000000..4608fd8d46 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightHistoryOffset.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.database; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import info.nightscout.androidaps.db.DatabaseHelper; + +@DatabaseTable(tableName = DatabaseHelper.DATABASE_INSIGHT_HISTORY_OFFSETS) +public class InsightHistoryOffset { + + @DatabaseField(id = true, canBeNull = false) + public String pumpSerial; + + @DatabaseField + public long offset; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightPumpID.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightPumpID.java new file mode 100644 index 0000000000..0eae421655 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/database/InsightPumpID.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.database; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import info.nightscout.androidaps.db.DatabaseHelper; + +@DatabaseTable(tableName = DatabaseHelper.DATABASE_INSIGHT_PUMP_IDS) +public class InsightPumpID { + + @DatabaseField(generatedId = true) + public Long id; + + @DatabaseField + public long timestamp; + + @DatabaseField + public String eventType; + + @DatabaseField + public String pumpSerial; + + @DatabaseField + public long eventID; + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBasalRate.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBasalRate.java new file mode 100644 index 0000000000..8ea2c2ac02 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBasalRate.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class ActiveBasalRate { + + private BasalProfile activeBasalProfile; + private String activeBasalProfileName; + private double activeBasalRate; + + public BasalProfile getActiveBasalProfile() { + return this.activeBasalProfile; + } + + public String getActiveBasalProfileName() { + return this.activeBasalProfileName; + } + + public double getActiveBasalRate() { + return this.activeBasalRate; + } + + public void setActiveBasalProfile(BasalProfile activeBasalProfile) { + this.activeBasalProfile = activeBasalProfile; + } + + public void setActiveBasalProfileName(String activeBasalProfileName) { + this.activeBasalProfileName = activeBasalProfileName; + } + + public void setActiveBasalRate(double activeBasalRate) { + this.activeBasalRate = activeBasalRate; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBolus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBolus.java new file mode 100644 index 0000000000..6af521ab1d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveBolus.java @@ -0,0 +1,50 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class ActiveBolus { + + private int bolusID; + private BolusType bolusType; + private double initialAmount; + private double remainingAmount; + private int remainingDuration; + + public int getBolusID() { + return this.bolusID; + } + + public BolusType getBolusType() { + return this.bolusType; + } + + public double getInitialAmount() { + return this.initialAmount; + } + + public double getRemainingAmount() { + return this.remainingAmount; + } + + public int getRemainingDuration() { + return this.remainingDuration; + } + + public void setBolusID(int bolusID) { + this.bolusID = bolusID; + } + + public void setBolusType(BolusType bolusType) { + this.bolusType = bolusType; + } + + public void setInitialAmount(double initialAmount) { + this.initialAmount = initialAmount; + } + + public void setRemainingAmount(double remainingAmount) { + this.remainingAmount = remainingAmount; + } + + public void setRemainingDuration(int remainingDuration) { + this.remainingDuration = remainingDuration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveTBR.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveTBR.java new file mode 100644 index 0000000000..7ebbeec49b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/ActiveTBR.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class ActiveTBR { + + private int percentage; + private int remainingDuration; + private int initialDuration; + + public int getPercentage() { + return this.percentage; + } + + public int getRemainingDuration() { + return this.remainingDuration; + } + + public int getInitialDuration() { + return this.initialDuration; + } + + public void setPercentage(int percentage) { + this.percentage = percentage; + } + + public void setRemainingDuration(int remainingDuration) { + this.remainingDuration = remainingDuration; + } + + public void setInitialDuration(int initialDuration) { + this.initialDuration = initialDuration; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/Alert.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/Alert.java new file mode 100644 index 0000000000..ad6f71f95c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/Alert.java @@ -0,0 +1,86 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class Alert { + + private int alertId; + private AlertCategory alertCategory; + private AlertType alertType; + private AlertStatus alertStatus; + private int tbrAmount; + private int tbrDuration; + private double programmedBolusAmount; + private double deliveredBolusAmount; + private double cartridgeAmount; + + public int getAlertId() { + return this.alertId; + } + + public AlertCategory getAlertCategory() { + return this.alertCategory; + } + + public AlertType getAlertType() { + return this.alertType; + } + + public AlertStatus getAlertStatus() { + return this.alertStatus; + } + + public void setAlertId(int alertId) { + this.alertId = alertId; + } + + public void setAlertCategory(AlertCategory alertCategory) { + this.alertCategory = alertCategory; + } + + public void setAlertType(AlertType alertType) { + this.alertType = alertType; + } + + public void setAlertStatus(AlertStatus alertStatus) { + this.alertStatus = alertStatus; + } + + public int getTBRAmount() { + return tbrAmount; + } + + public void setTBRAmount(int tbrAmount) { + this.tbrAmount = tbrAmount; + } + + public int getTBRDuration() { + return tbrDuration; + } + + public void setTBRDuration(int tbrDuration) { + this.tbrDuration = tbrDuration; + } + + public double getProgrammedBolusAmount() { + return programmedBolusAmount; + } + + public void setProgrammedBolusAmount(double programmedBolusAmount) { + this.programmedBolusAmount = programmedBolusAmount; + } + + public double getDeliveredBolusAmount() { + return deliveredBolusAmount; + } + + public void setDeliveredBolusAmount(double deliveredBolusAmount) { + this.deliveredBolusAmount = deliveredBolusAmount; + } + + public void setCartridgeAmount(double cartridgeAmount) { + this.cartridgeAmount = cartridgeAmount; + } + + public double getCartridgeAmount() { + return cartridgeAmount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertCategory.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertCategory.java new file mode 100644 index 0000000000..9b69ab556b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertCategory.java @@ -0,0 +1,9 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum AlertCategory { + + REMINDER, + MAINTENANCE, + WARNING, + ERROR; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertStatus.java new file mode 100644 index 0000000000..0920e0b1a8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertStatus.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum AlertStatus { + + ACTIVE, + SNOOZED; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertType.java new file mode 100644 index 0000000000..3a8402f27f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AlertType.java @@ -0,0 +1,31 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum AlertType { + + REMINDER_01, + REMINDER_02, + REMINDER_03, + REMINDER_04, + REMINDER_07, + WARNING_31, + WARNING_32, + WARNING_33, + WARNING_34, + WARNING_36, + WARNING_38, + WARNING_39, + MAINTENANCE_20, + MAINTENANCE_21, + MAINTENANCE_22, + MAINTENANCE_23, + MAINTENANCE_24, + MAINTENANCE_25, + MAINTENANCE_26, + MAINTENANCE_27, + MAINTENANCE_28, + MAINTENANCE_29, + MAINTENANCE_30, + ERROR_6, + ERROR_10, + ERROR_13; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AvailableBolusTypes.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AvailableBolusTypes.java new file mode 100644 index 0000000000..d332c28ff0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/AvailableBolusTypes.java @@ -0,0 +1,45 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class AvailableBolusTypes { + + private boolean standardAvailable; + private boolean extendedAvailable; + private boolean multiwaveAvailable; + + public boolean isStandardAvailable() { + return this.standardAvailable; + } + + public void setStandardAvailable(boolean standardAvailable) { + this.standardAvailable = standardAvailable; + } + + public boolean isExtendedAvailable() { + return this.extendedAvailable; + } + + public void setExtendedAvailable(boolean extendedAvailable) { + this.extendedAvailable = extendedAvailable; + } + + public boolean isMultiwaveAvailable() { + return this.multiwaveAvailable; + } + + public void setMultiwaveAvailable(boolean multiwaveAvailable) { + this.multiwaveAvailable = multiwaveAvailable; + } + + public boolean isBolusTypeAvailable(BolusType bolusType) { + switch (bolusType) { + case STANDARD: + return standardAvailable; + case EXTENDED: + return extendedAvailable; + case MULTIWAVE: + return multiwaveAvailable; + default: + return false; + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfile.java new file mode 100644 index 0000000000..45a113ece4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfile.java @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum BasalProfile { + + PROFILE_1, + PROFILE_2, + PROFILE_3, + PROFILE_4, + PROFILE_5; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfileBlock.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfileBlock.java new file mode 100644 index 0000000000..ff42fa4282 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BasalProfileBlock.java @@ -0,0 +1,23 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class BasalProfileBlock { + + private int duration; + private double basalAmount; + + public int getDuration() { + return this.duration; + } + + public double getBasalAmount() { + return this.basalAmount; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public void setBasalAmount(double basalAmount) { + this.basalAmount = basalAmount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryStatus.java new file mode 100644 index 0000000000..36c5fc82fb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryStatus.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class BatteryStatus { + + private BatteryType batteryType; + private int batteryAmount; + private SymbolStatus symbolStatus; + + public BatteryType getBatteryType() { + return this.batteryType; + } + + public int getBatteryAmount() { + return this.batteryAmount; + } + + public SymbolStatus getSymbolStatus() { + return this.symbolStatus; + } + + public void setBatteryType(BatteryType batteryType) { + this.batteryType = batteryType; + } + + public void setBatteryAmount(int batteryAmount) { + this.batteryAmount = batteryAmount; + } + + public void setSymbolStatus(SymbolStatus symbolStatus) { + this.symbolStatus = symbolStatus; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryType.java new file mode 100644 index 0000000000..d161d1eafa --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BatteryType.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum BatteryType { + + ALKALI, + LITHIUM, + NI_MH; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BolusType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BolusType.java new file mode 100644 index 0000000000..89b8c883fc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/BolusType.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum BolusType { + + STANDARD, + EXTENDED, + MULTIWAVE; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeStatus.java new file mode 100644 index 0000000000..7d01968f51 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeStatus.java @@ -0,0 +1,41 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class CartridgeStatus { + + private boolean inserted; + private CartridgeType cartridgeType; + private SymbolStatus symbolStatus; + private double remainingAmount; + + public boolean isInserted() { + return this.inserted; + } + + public CartridgeType getCartridgeType() { + return this.cartridgeType; + } + + public SymbolStatus getSymbolStatus() { + return this.symbolStatus; + } + + public double getRemainingAmount() { + return this.remainingAmount; + } + + public void setInserted(boolean inserted) { + this.inserted = inserted; + } + + public void setCartridgeType(CartridgeType cartridgeType) { + this.cartridgeType = cartridgeType; + } + + public void setSymbolStatus(SymbolStatus symbolStatus) { + this.symbolStatus = symbolStatus; + } + + public void setRemainingAmount(double remainingAmount) { + this.remainingAmount = remainingAmount; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeType.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeType.java new file mode 100644 index 0000000000..399296e033 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/CartridgeType.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum CartridgeType { + + PREFILLED, + SELF_FILLED; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/FirmwareVersions.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/FirmwareVersions.java new file mode 100644 index 0000000000..4c3afe0512 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/FirmwareVersions.java @@ -0,0 +1,95 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class FirmwareVersions { + + private String releaseSWVersion; + private String uiProcSWVersion; + private String pcProcSWVersion; + private String mdTelProcSWVersion; + private String btInfoPageVersion; + private String safetyProcSWVersion; + private int configIndex; + private int historyIndex; + private int stateIndex; + private int vocabularyIndex; + + public String getReleaseSWVersion() { + return this.releaseSWVersion; + } + + public String getUiProcSWVersion() { + return this.uiProcSWVersion; + } + + public String getPcProcSWVersion() { + return this.pcProcSWVersion; + } + + public String getMdTelProcSWVersion() { + return this.mdTelProcSWVersion; + } + + public String getBtInfoPageVersion() { + return this.btInfoPageVersion; + } + + public String getSafetyProcSWVersion() { + return this.safetyProcSWVersion; + } + + public int getConfigIndex() { + return this.configIndex; + } + + public int getHistoryIndex() { + return this.historyIndex; + } + + public int getStateIndex() { + return this.stateIndex; + } + + public int getVocabularyIndex() { + return this.vocabularyIndex; + } + + public void setReleaseSWVersion(String releaseSWVersion) { + this.releaseSWVersion = releaseSWVersion; + } + + public void setUiProcSWVersion(String uiProcSWVersion) { + this.uiProcSWVersion = uiProcSWVersion; + } + + public void setPcProcSWVersion(String pcProcSWVersion) { + this.pcProcSWVersion = pcProcSWVersion; + } + + public void setMdTelProcSWVersion(String mdTelProcSWVersion) { + this.mdTelProcSWVersion = mdTelProcSWVersion; + } + + public void setBtInfoPageVersion(String btInfoPageVersion) { + this.btInfoPageVersion = btInfoPageVersion; + } + + public void setSafetyProcSWVersion(String safetyProcSWVersion) { + this.safetyProcSWVersion = safetyProcSWVersion; + } + + public void setConfigIndex(int configIndex) { + this.configIndex = configIndex; + } + + public void setHistoryIndex(int historyIndex) { + this.historyIndex = historyIndex; + } + + public void setStateIndex(int stateIndex) { + this.stateIndex = stateIndex; + } + + public void setVocabularyIndex(int vocabularyIndex) { + this.vocabularyIndex = vocabularyIndex; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/InsightState.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/InsightState.java new file mode 100644 index 0000000000..5d9bc22e78 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/InsightState.java @@ -0,0 +1,22 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum InsightState { + + NOT_PAIRED, + DISCONNECTED, + RECOVERING, + CONNECTING, + SATL_CONNECTION_REQUEST, + SATL_KEY_REQUEST, + SATL_VERIFY_DISPLAY_REQUEST, + AWAITING_CODE_CONFIRMATION, + SATL_VERIFY_CONFIRM_REQUEST, + SATL_SYN_REQUEST, + APP_CONNECT_MESSAGE, + APP_BIND_MESSAGE, + APP_ACTIVATE_STATUS_SERVICE, + APP_FIRMWARE_VERSIONS, + APP_ACTIVATE_PARAMETER_SERVICE, + APP_SYSTEM_IDENTIFICATION, + CONNECTED, +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/MessagePriority.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/MessagePriority.java new file mode 100644 index 0000000000..7dd8159737 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/MessagePriority.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum MessagePriority { + + NORMAL, + HIGHER, + HIGHEST; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/OperatingMode.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/OperatingMode.java new file mode 100644 index 0000000000..17c6ca01a1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/OperatingMode.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum OperatingMode { + + STARTED, + STOPPED, + PAUSED; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/PumpTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/PumpTime.java new file mode 100644 index 0000000000..4b72f3ec54 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/PumpTime.java @@ -0,0 +1,59 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class PumpTime { + + private int year; + private int month; + private int day; + private int hour; + private int minute; + private int second; + + public int getYear() { + return this.year; + } + + public int getMonth() { + return this.month; + } + + public int getDay() { + return this.day; + } + + public int getHour() { + return this.hour; + } + + public int getMinute() { + return this.minute; + } + + public int getSecond() { + return this.second; + } + + public void setYear(int year) { + this.year = year; + } + + public void setMonth(int month) { + this.month = month; + } + + public void setDay(int day) { + this.day = day; + } + + public void setHour(int hour) { + this.hour = hour; + } + + public void setMinute(int minute) { + this.minute = minute; + } + + public void setSecond(int second) { + this.second = second; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SymbolStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SymbolStatus.java new file mode 100644 index 0000000000..529f408e42 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SymbolStatus.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public enum SymbolStatus { + + FULL, + LOW, + EMPTY; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SystemIdentification.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SystemIdentification.java new file mode 100644 index 0000000000..5024534a08 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/SystemIdentification.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class SystemIdentification { + + private String serialNumber; + private long systemIdAppendix; + private String manufacturingDate; + + public String getSerialNumber() { + return this.serialNumber; + } + + public long getSystemIdAppendix() { + return this.systemIdAppendix; + } + + public String getManufacturingDate() { + return this.manufacturingDate; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public void setSystemIdAppendix(long systemIdAppendix) { + this.systemIdAppendix = systemIdAppendix; + } + + public void setManufacturingDate(String manufacturingDate) { + this.manufacturingDate = manufacturingDate; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/TotalDailyDose.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/TotalDailyDose.java new file mode 100644 index 0000000000..8b0f0f8054 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/descriptors/TotalDailyDose.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors; + +public class TotalDailyDose { + + private double bolus; + private double basal; + private double bolusAndBasal; + + public double getBolus() { + return this.bolus; + } + + public double getBasal() { + return this.basal; + } + + public double getBolusAndBasal() { + return this.bolusAndBasal; + } + + public void setBolus(double bolus) { + this.bolus = bolus; + } + + public void setBasal(double basal) { + this.basal = basal; + } + + public void setBolusAndBasal(double bolusAndBasal) { + this.bolusAndBasal = bolusAndBasal; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/AppLayerException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/AppLayerException.java new file mode 100644 index 0000000000..4fb957d64d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/AppLayerException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public abstract class AppLayerException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/CommandNotSupportedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/CommandNotSupportedException.java new file mode 100644 index 0000000000..f626a8e8aa --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/CommandNotSupportedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class CommandNotSupportedException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionFailedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionFailedException.java new file mode 100644 index 0000000000..9c50fee053 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionFailedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class ConnectionFailedException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionLostException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionLostException.java new file mode 100644 index 0000000000..7068a25e98 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ConnectionLostException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class ConnectionLostException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/DisconnectedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/DisconnectedException.java new file mode 100644 index 0000000000..2f5d59c54a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/DisconnectedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class DisconnectedException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleAppVersionException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleAppVersionException.java new file mode 100644 index 0000000000..4c7a89dd9f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleAppVersionException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class IncompatibleAppVersionException extends AppLayerException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleSatlVersionException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleSatlVersionException.java new file mode 100644 index 0000000000..dc0f40d0f7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/IncompatibleSatlVersionException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class IncompatibleSatlVersionException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InsightException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InsightException.java new file mode 100644 index 0000000000..1db85c723d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InsightException.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public abstract class InsightException extends Exception { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidAppCRCException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidAppCRCException.java new file mode 100644 index 0000000000..b1253b26b9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidAppCRCException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidAppCRCException extends AppLayerException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidMacTrailerException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidMacTrailerException.java new file mode 100644 index 0000000000..3a80494762 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidMacTrailerException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidMacTrailerException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidNonceException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidNonceException.java new file mode 100644 index 0000000000..53dc504cf3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidNonceException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidNonceException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPacketLengthsException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPacketLengthsException.java new file mode 100644 index 0000000000..d5eaff3a81 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPacketLengthsException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidPacketLengthsException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPreambleException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPreambleException.java new file mode 100644 index 0000000000..dabf025d87 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidPreambleException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidPreambleException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCRCException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCRCException.java new file mode 100644 index 0000000000..21c61d5379 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCRCException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidSatlCRCException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCommandException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCommandException.java new file mode 100644 index 0000000000..d720eab1c3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/InvalidSatlCommandException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class InvalidSatlCommandException extends SatlException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ReceivedPacketInInvalidStateException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ReceivedPacketInInvalidStateException.java new file mode 100644 index 0000000000..244ffe1637 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/ReceivedPacketInInvalidStateException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class ReceivedPacketInInvalidStateException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SatlException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SatlException.java new file mode 100644 index 0000000000..0dc295fd8d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SatlException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public abstract class SatlException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SecondChannelFailedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SecondChannelFailedException.java new file mode 100644 index 0000000000..ca98f47992 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SecondChannelFailedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class SecondChannelFailedException extends AppLayerException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SocketCreationFailedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SocketCreationFailedException.java new file mode 100644 index 0000000000..9b04a25ce9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/SocketCreationFailedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class SocketCreationFailedException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TimeoutException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TimeoutException.java new file mode 100644 index 0000000000..2c03b9d8cc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TimeoutException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class TimeoutException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TooChattyPumpException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TooChattyPumpException.java new file mode 100644 index 0000000000..f46862846c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/TooChattyPumpException.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class TooChattyPumpException extends InsightException { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownAppCommandException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownAppCommandException.java new file mode 100644 index 0000000000..994af8f222 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownAppCommandException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class UnknownAppCommandException extends AppLayerException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownServiceException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownServiceException.java new file mode 100644 index 0000000000..f4d54ed5ce --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/UnknownServiceException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions; + +public class UnknownServiceException extends AppLayerException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AlreadyConnectedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AlreadyConnectedException.java new file mode 100644 index 0000000000..eed505b624 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AlreadyConnectedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class AlreadyConnectedException extends AppLayerErrorException { + + public AlreadyConnectedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AppLayerErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AppLayerErrorException.java new file mode 100644 index 0000000000..25ba383983 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/AppLayerErrorException.java @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.AppLayerException; + +public abstract class AppLayerErrorException extends AppLayerException { + + private int errorCode; + + public AppLayerErrorException(int errorCode) { + this.errorCode = errorCode; + } + + @Override + public String getMessage() { + return "Error code: " + errorCode; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusAmountNotInRangeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusAmountNotInRangeException.java new file mode 100644 index 0000000000..e01252fc02 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusAmountNotInRangeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class BolusAmountNotInRangeException extends AppLayerErrorException { + + public BolusAmountNotInRangeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusDurationNotInRangeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusDurationNotInRangeException.java new file mode 100644 index 0000000000..70414af4a5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusDurationNotInRangeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class BolusDurationNotInRangeException extends AppLayerErrorException { + + public BolusDurationNotInRangeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusLagTimeFeatureDisabledException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusLagTimeFeatureDisabledException.java new file mode 100644 index 0000000000..2c4f75be14 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusLagTimeFeatureDisabledException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class BolusLagTimeFeatureDisabledException extends AppLayerErrorException { + + public BolusLagTimeFeatureDisabledException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusTypeAndParameterMismatchException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusTypeAndParameterMismatchException.java new file mode 100644 index 0000000000..5f183cacc3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/BolusTypeAndParameterMismatchException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class BolusTypeAndParameterMismatchException extends AppLayerErrorException { + + public BolusTypeAndParameterMismatchException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CommandExecutionFailedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CommandExecutionFailedException.java new file mode 100644 index 0000000000..4dbaf35017 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CommandExecutionFailedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class CommandExecutionFailedException extends AppLayerErrorException { + + public CommandExecutionFailedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ConfigMemoryAccessException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ConfigMemoryAccessException.java new file mode 100644 index 0000000000..f71b355ef9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ConfigMemoryAccessException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ConfigMemoryAccessException extends AppLayerErrorException { + + public ConfigMemoryAccessException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CustomBolusNotConfiguredException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CustomBolusNotConfiguredException.java new file mode 100644 index 0000000000..5e2692991d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/CustomBolusNotConfiguredException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class CustomBolusNotConfiguredException extends AppLayerErrorException { + + public CustomBolusNotConfiguredException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ImplausiblePortionLengthValueException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ImplausiblePortionLengthValueException.java new file mode 100644 index 0000000000..ff2bb5ea2e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ImplausiblePortionLengthValueException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ImplausiblePortionLengthValueException extends AppLayerErrorException { + + public ImplausiblePortionLengthValueException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/IncompatibleVersionException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/IncompatibleVersionException.java new file mode 100644 index 0000000000..96ce856d2f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/IncompatibleVersionException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class IncompatibleVersionException extends AppLayerErrorException { + + public IncompatibleVersionException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidAlertInstanceIdException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidAlertInstanceIdException.java new file mode 100644 index 0000000000..080e811297 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidAlertInstanceIdException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidAlertInstanceIdException extends AppLayerErrorException { + + public InvalidAlertInstanceIdException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockCRCException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockCRCException.java new file mode 100644 index 0000000000..3c99a53f35 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockCRCException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidConfigBlockCRCException extends AppLayerErrorException { + + public InvalidConfigBlockCRCException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockIdException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockIdException.java new file mode 100644 index 0000000000..35d5ffc005 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockIdException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidConfigBlockIdException extends AppLayerErrorException { + + public InvalidConfigBlockIdException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockLengthException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockLengthException.java new file mode 100644 index 0000000000..6905d02d95 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidConfigBlockLengthException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidConfigBlockLengthException extends AppLayerErrorException { + + public InvalidConfigBlockLengthException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDateParameterException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDateParameterException.java new file mode 100644 index 0000000000..bf54da11b9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDateParameterException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidDateParameterException extends AppLayerErrorException { + + public InvalidDateParameterException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDurationPresetException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDurationPresetException.java new file mode 100644 index 0000000000..e839cedfb7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidDurationPresetException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidDurationPresetException extends AppLayerErrorException { + + public InvalidDurationPresetException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidLagTimeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidLagTimeException.java new file mode 100644 index 0000000000..658c9f4168 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidLagTimeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidLagTimeException extends AppLayerErrorException { + + public InvalidLagTimeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidParameterTypeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidParameterTypeException.java new file mode 100644 index 0000000000..3ac94ae973 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidParameterTypeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidParameterTypeException extends AppLayerErrorException { + + public InvalidParameterTypeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadCRCException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadCRCException.java new file mode 100644 index 0000000000..b8711780e1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadCRCException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidPayloadCRCException extends AppLayerErrorException { + + public InvalidPayloadCRCException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadException.java new file mode 100644 index 0000000000..5313098c74 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidPayloadException extends AppLayerErrorException { + + public InvalidPayloadException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadLengthException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadLengthException.java new file mode 100644 index 0000000000..9f7dac63f0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidPayloadLengthException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidPayloadLengthException extends AppLayerErrorException { + + public InvalidPayloadLengthException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidServicePasswordException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidServicePasswordException.java new file mode 100644 index 0000000000..de17537d35 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidServicePasswordException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidServicePasswordException extends AppLayerErrorException { + + public InvalidServicePasswordException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRDurationException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRDurationException.java new file mode 100644 index 0000000000..45fa556b0a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRDurationException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidTBRDurationException extends AppLayerErrorException { + + public InvalidTBRDurationException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRFactorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRFactorException.java new file mode 100644 index 0000000000..d90cd21aee --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRFactorException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidTBRFactorException extends AppLayerErrorException { + + public InvalidTBRFactorException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRTemplateException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRTemplateException.java new file mode 100644 index 0000000000..a975f33883 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTBRTemplateException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidTBRTemplateException extends AppLayerErrorException { + + public InvalidTBRTemplateException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTimeParameterException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTimeParameterException.java new file mode 100644 index 0000000000..58f22094f3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidTimeParameterException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidTimeParameterException extends AppLayerErrorException { + + public InvalidTimeParameterException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidValuesOfTwoChannelTransmission.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidValuesOfTwoChannelTransmission.java new file mode 100644 index 0000000000..98a64f5cab --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/InvalidValuesOfTwoChannelTransmission.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class InvalidValuesOfTwoChannelTransmission extends AppLayerErrorException { + + public InvalidValuesOfTwoChannelTransmission(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/MaximumNumberOfBolusTypeAlreadyRunningException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/MaximumNumberOfBolusTypeAlreadyRunningException.java new file mode 100644 index 0000000000..72cd3e9dc4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/MaximumNumberOfBolusTypeAlreadyRunningException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class MaximumNumberOfBolusTypeAlreadyRunningException extends AppLayerErrorException { + + public MaximumNumberOfBolusTypeAlreadyRunningException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToCanceLException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToCanceLException.java new file mode 100644 index 0000000000..dae8b3ca8e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToCanceLException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NoActiveTBRToCanceLException extends AppLayerErrorException { + + public NoActiveTBRToCanceLException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToChangeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToChangeException.java new file mode 100644 index 0000000000..faf8752c56 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoActiveTBRToChangeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NoActiveTBRToChangeException extends AppLayerErrorException { + + public NoActiveTBRToChangeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoConfigBlockDataException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoConfigBlockDataException.java new file mode 100644 index 0000000000..602faa3594 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoConfigBlockDataException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NoConfigBlockDataException extends AppLayerErrorException { + + public NoConfigBlockDataException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoServicePasswordNeededException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoServicePasswordNeededException.java new file mode 100644 index 0000000000..d6df477abc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoServicePasswordNeededException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NoServicePasswordNeededException extends AppLayerErrorException { + + public NoServicePasswordNeededException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoSuchBolusToCancelException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoSuchBolusToCancelException.java new file mode 100644 index 0000000000..923c1365b6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NoSuchBolusToCancelException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NoSuchBolusToCancelException extends AppLayerErrorException { + + public NoSuchBolusToCancelException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotAllowedToAccessPositionZeroException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotAllowedToAccessPositionZeroException.java new file mode 100644 index 0000000000..8ce2c1258e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotAllowedToAccessPositionZeroException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NotAllowedToAccessPositionZeroException extends AppLayerErrorException { + + public NotAllowedToAccessPositionZeroException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotConnectedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotConnectedException.java new file mode 100644 index 0000000000..f0ddab4b8f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotConnectedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NotConnectedException extends AppLayerErrorException { + + public NotConnectedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotReferencedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotReferencedException.java new file mode 100644 index 0000000000..c3eb98fd2a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/NotReferencedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class NotReferencedException extends AppLayerErrorException { + + public NotReferencedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PauseModeNotAllowedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PauseModeNotAllowedException.java new file mode 100644 index 0000000000..03939e9346 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PauseModeNotAllowedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class PauseModeNotAllowedException extends AppLayerErrorException { + + public PauseModeNotAllowedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PositionProtectedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PositionProtectedException.java new file mode 100644 index 0000000000..e1171ecfa8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PositionProtectedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class PositionProtectedException extends AppLayerErrorException { + + public PositionProtectedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpAlreadyInThatStateException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpAlreadyInThatStateException.java new file mode 100644 index 0000000000..cfac26d3a2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpAlreadyInThatStateException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class PumpAlreadyInThatStateException extends AppLayerErrorException { + + public PumpAlreadyInThatStateException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpBusyException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpBusyException.java new file mode 100644 index 0000000000..d7deee7eea --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpBusyException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class PumpBusyException extends AppLayerErrorException { + + public PumpBusyException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpStoppedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpStoppedException.java new file mode 100644 index 0000000000..a7f42a5713 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/PumpStoppedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class PumpStoppedException extends AppLayerErrorException { + + public PumpStoppedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryAlreadyStartedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryAlreadyStartedException.java new file mode 100644 index 0000000000..e6629515fa --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryAlreadyStartedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ReadingHistoryAlreadyStartedException extends AppLayerErrorException { + + public ReadingHistoryAlreadyStartedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryNotStartedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryNotStartedException.java new file mode 100644 index 0000000000..e2328f10e6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ReadingHistoryNotStartedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ReadingHistoryNotStartedException extends AppLayerErrorException { + + public ReadingHistoryNotStartedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/RunModeNotAllowedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/RunModeNotAllowedException.java new file mode 100644 index 0000000000..da704e415e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/RunModeNotAllowedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class RunModeNotAllowedException extends AppLayerErrorException { + + public RunModeNotAllowedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceAlreadyActivatedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceAlreadyActivatedException.java new file mode 100644 index 0000000000..dca8277218 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceAlreadyActivatedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ServiceAlreadyActivatedException extends AppLayerErrorException { + + public ServiceAlreadyActivatedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceCommandNotAvailableException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceCommandNotAvailableException.java new file mode 100644 index 0000000000..b847a1d8f3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceCommandNotAvailableException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ServiceCommandNotAvailableException extends AppLayerErrorException { + + public ServiceCommandNotAvailableException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceIncompatibleException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceIncompatibleException.java new file mode 100644 index 0000000000..13b2784213 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceIncompatibleException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ServiceIncompatibleException extends AppLayerErrorException { + + public ServiceIncompatibleException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceNotActivatedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceNotActivatedException.java new file mode 100644 index 0000000000..ec2b117550 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/ServiceNotActivatedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class ServiceNotActivatedException extends AppLayerErrorException { + + public ServiceNotActivatedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/StepCountOutOfRangeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/StepCountOutOfRangeException.java new file mode 100644 index 0000000000..5c1548403c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/StepCountOutOfRangeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class StepCountOutOfRangeException extends AppLayerErrorException { + + public StepCountOutOfRangeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownAppLayerErrorCodeException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownAppLayerErrorCodeException.java new file mode 100644 index 0000000000..8487e84039 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownAppLayerErrorCodeException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class UnknownAppLayerErrorCodeException extends AppLayerErrorException { + + public UnknownAppLayerErrorCodeException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownCommandException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownCommandException.java new file mode 100644 index 0000000000..790a03802c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownCommandException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class UnknownCommandException extends AppLayerErrorException { + + public UnknownCommandException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownServiceException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownServiceException.java new file mode 100644 index 0000000000..a6c0a771f7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/UnknownServiceException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class UnknownServiceException extends AppLayerErrorException { + + public UnknownServiceException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionAlreadyOpenException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionAlreadyOpenException.java new file mode 100644 index 0000000000..c02e36f394 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionAlreadyOpenException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class WriteSessionAlreadyOpenException extends AppLayerErrorException { + + public WriteSessionAlreadyOpenException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionClosedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionClosedException.java new file mode 100644 index 0000000000..84427621bf --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WriteSessionClosedException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class WriteSessionClosedException extends AppLayerErrorException { + + public WriteSessionClosedException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WrongStateException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WrongStateException.java new file mode 100644 index 0000000000..939be56495 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/app_layer_errors/WrongStateException.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors; + +public class WrongStateException extends AppLayerErrorException { + + public WrongStateException(int errorCode) { + super(errorCode); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlCompatibleStateErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlCompatibleStateErrorException.java new file mode 100644 index 0000000000..703bb7cccc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlCompatibleStateErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlCompatibleStateErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlDecryptVerifyFailedErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlDecryptVerifyFailedErrorException.java new file mode 100644 index 0000000000..d0ad555a20 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlDecryptVerifyFailedErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlDecryptVerifyFailedErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlErrorException.java new file mode 100644 index 0000000000..eb3ee0a703 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlErrorException.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InsightException; + +public abstract class SatlErrorException extends InsightException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlIncompatibleVersionErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlIncompatibleVersionErrorException.java new file mode 100644 index 0000000000..de69d3bb6f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlIncompatibleVersionErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlIncompatibleVersionErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCRCErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCRCErrorException.java new file mode 100644 index 0000000000..d96a5920e6 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCRCErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidCRCErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCommIdErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCommIdErrorException.java new file mode 100644 index 0000000000..9fa4e095aa --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidCommIdErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidCommIdErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMacErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMacErrorException.java new file mode 100644 index 0000000000..c207dc20a4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMacErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidMacErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMessageTypeErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMessageTypeErrorException.java new file mode 100644 index 0000000000..d52a81a168 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidMessageTypeErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidMessageTypeErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidNonceErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidNonceErrorException.java new file mode 100644 index 0000000000..309fa6916b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidNonceErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidNonceErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPacketErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPacketErrorException.java new file mode 100644 index 0000000000..dd5e611d66 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPacketErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidPacketErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPayloadLengthErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPayloadLengthErrorException.java new file mode 100644 index 0000000000..4651328d8d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlInvalidPayloadLengthErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlInvalidPayloadLengthErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlNoneErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlNoneErrorException.java new file mode 100644 index 0000000000..d55280118b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlNoneErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlNoneErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlPairingRejectedException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlPairingRejectedException.java new file mode 100644 index 0000000000..2e5be0efe0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlPairingRejectedException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlPairingRejectedException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlUndefinedErrorException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlUndefinedErrorException.java new file mode 100644 index 0000000000..a905fa2e31 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlUndefinedErrorException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlUndefinedErrorException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlWrongStateException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlWrongStateException.java new file mode 100644 index 0000000000..2f75c664cf --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/exceptions/satl_errors/SatlWrongStateException.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors; + +public class SatlWrongStateException extends SatlErrorException { + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBasalProfileIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBasalProfileIDs.java new file mode 100644 index 0000000000..96b86a7a39 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBasalProfileIDs.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BasalProfile; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class ActiveBasalProfileIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(BasalProfile.PROFILE_1, 31); + IDS.put(BasalProfile.PROFILE_2, 227); + IDS.put(BasalProfile.PROFILE_3, 252); + IDS.put(BasalProfile.PROFILE_4, 805); + IDS.put(BasalProfile.PROFILE_5, 826); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBolusTypeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBolusTypeIDs.java new file mode 100644 index 0000000000..479371c3c5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ActiveBolusTypeIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class ActiveBolusTypeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(BolusType.STANDARD, 227); + IDS.put(BolusType.EXTENDED, 252); + IDS.put(BolusType.MULTIWAVE, 805); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertCategoryIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertCategoryIDs.java new file mode 100644 index 0000000000..67a8e4ebe7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertCategoryIDs.java @@ -0,0 +1,17 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertCategory; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class AlertCategoryIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(AlertCategory.REMINDER, 227); + IDS.put(AlertCategory.MAINTENANCE, 252); + IDS.put(AlertCategory.WARNING, 805); + IDS.put(AlertCategory.ERROR, 826); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertStatusIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertStatusIDs.java new file mode 100644 index 0000000000..626ebb93c0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertStatusIDs.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class AlertStatusIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(AlertStatus.ACTIVE, 31); + IDS.put(AlertStatus.SNOOZED, 227); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIDs.java new file mode 100644 index 0000000000..31627993a7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIDs.java @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class AlertTypeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(AlertType.REMINDER_01, 31); + IDS.put(AlertType.REMINDER_02, 227); + IDS.put(AlertType.REMINDER_03, 252); + IDS.put(AlertType.REMINDER_04, 805); + IDS.put(AlertType.REMINDER_07, 826); + IDS.put(AlertType.WARNING_31, 966); + IDS.put(AlertType.WARNING_32, 985); + IDS.put(AlertType.WARNING_33, 1354); + IDS.put(AlertType.WARNING_34, 1365); + IDS.put(AlertType.WARNING_36, 1449); + IDS.put(AlertType.WARNING_38, 1462); + IDS.put(AlertType.WARNING_39, 1647); + IDS.put(AlertType.MAINTENANCE_20, 1648); + IDS.put(AlertType.MAINTENANCE_21, 1676); + IDS.put(AlertType.MAINTENANCE_22, 1683); + IDS.put(AlertType.MAINTENANCE_23, 6182); + IDS.put(AlertType.MAINTENANCE_24, 6201); + IDS.put(AlertType.MAINTENANCE_25, 6341); + IDS.put(AlertType.MAINTENANCE_26, 6362); + IDS.put(AlertType.MAINTENANCE_27, 6915); + IDS.put(AlertType.MAINTENANCE_28, 6940); + IDS.put(AlertType.MAINTENANCE_29, 7136); + IDS.put(AlertType.MAINTENANCE_30, 7167); + IDS.put(AlertType.ERROR_6, 7532); + IDS.put(AlertType.ERROR_10, 7539); + IDS.put(AlertType.ERROR_13, 7567); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIncrementalIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIncrementalIDs.java new file mode 100644 index 0000000000..cccb2bcef9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AlertTypeIncrementalIDs.java @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.AlertType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class AlertTypeIncrementalIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(AlertType.REMINDER_01, 1); + IDS.put(AlertType.REMINDER_02, 2); + IDS.put(AlertType.REMINDER_03, 3); + IDS.put(AlertType.REMINDER_04, 4); + IDS.put(AlertType.REMINDER_07, 7); + IDS.put(AlertType.WARNING_31, 31); + IDS.put(AlertType.WARNING_32, 32); + IDS.put(AlertType.WARNING_33, 33); + IDS.put(AlertType.WARNING_34, 34); + IDS.put(AlertType.WARNING_36, 36); + IDS.put(AlertType.WARNING_38, 38); + IDS.put(AlertType.WARNING_39, 39); + IDS.put(AlertType.MAINTENANCE_20, 20); + IDS.put(AlertType.MAINTENANCE_21, 21); + IDS.put(AlertType.MAINTENANCE_22, 22); + IDS.put(AlertType.MAINTENANCE_23, 23); + IDS.put(AlertType.MAINTENANCE_24, 24); + IDS.put(AlertType.MAINTENANCE_25, 25); + IDS.put(AlertType.MAINTENANCE_26, 26); + IDS.put(AlertType.MAINTENANCE_27, 27); + IDS.put(AlertType.MAINTENANCE_28, 28); + IDS.put(AlertType.MAINTENANCE_29, 29); + IDS.put(AlertType.MAINTENANCE_30, 30); + IDS.put(AlertType.ERROR_6, 6); + IDS.put(AlertType.ERROR_10, 10); + IDS.put(AlertType.ERROR_13, 13); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppCommandIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppCommandIDs.java new file mode 100644 index 0000000000..e13870517b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppCommandIDs.java @@ -0,0 +1,81 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.AppLayerMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetDateTimeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.ReadParameterBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.CloseConfigurationWriteSessionMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.OpenConfigurationWriteSessionMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.WriteConfigurationBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ActivateServiceMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.BindMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ConnectMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.DisconnectMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.connection.ServiceChallengeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.ReadHistoryEventsMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.StartReadingHistoryMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.StopReadingHistoryMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.CancelBolusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.CancelTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.ChangeTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.ConfirmAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.DeliverBolusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.GetAvailableBolusTypesMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetOperatingModeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SetTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.remote_control.SnoozeAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveAlertMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveBasalRateMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveBolusesMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetActiveTBRMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetBatteryStatusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetCartridgeStatusMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetDateTimeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetFirmwareVersionsMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetOperatingModeMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetPumpStatusRegisterMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.GetTotalDailyDoseMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.status.ResetPumpStatusRegisterMessage; + +public class AppCommandIDs { + + public static final IDStorage, Integer> IDS = new IDStorage<>(); + + static { + IDS.put(ConnectMessage.class, 61451); + IDS.put(BindMessage.class, 62413); + IDS.put(DisconnectMessage.class, 61460); + IDS.put(ActivateServiceMessage.class, 61687); + IDS.put(ServiceChallengeMessage.class, 62418); + IDS.put(GetActiveAlertMessage.class, 985); + IDS.put(GetActiveBolusesMessage.class, 1647); + IDS.put(GetActiveTBRMessage.class, 1462); + IDS.put(GetAvailableBolusTypesMessage.class, 6362); + IDS.put(GetBatteryStatusMessage.class, 805); + IDS.put(GetCartridgeStatusMessage.class, 826); + IDS.put(GetDateTimeMessage.class, 227); + IDS.put(GetFirmwareVersionsMessage.class, 11992); + IDS.put(GetOperatingModeMessage.class, 252); + IDS.put(GetPumpStatusRegisterMessage.class, 31); + IDS.put(ResetPumpStatusRegisterMessage.class, 35476); + IDS.put(GetActiveBasalRateMessage.class, 1449); + IDS.put(GetTotalDailyDoseMessage.class, 966); + IDS.put(CancelTBRMessage.class, 6201); + IDS.put(CancelBolusMessage.class, 7136); + IDS.put(SetOperatingModeMessage.class, 6182); + IDS.put(ReadParameterBlockMessage.class, 7766); + IDS.put(WriteConfigurationBlockMessage.class, 7850); + IDS.put(CloseConfigurationWriteSessionMessage.class, 7861); + IDS.put(OpenConfigurationWriteSessionMessage.class, 7753); + IDS.put(DeliverBolusMessage.class, 6915); + IDS.put(SetTBRMessage.class, 6341); + IDS.put(ChangeTBRMessage.class, 42067); + IDS.put(ReadHistoryEventsMessage.class, 10408); + IDS.put(StartReadingHistoryMessage.class, 10324); + IDS.put(StopReadingHistoryMessage.class, 38887); + IDS.put(ConfirmAlertMessage.class, 1683); + IDS.put(SnoozeAlertMessage.class, 1676); + IDS.put(SetDateTimeMessage.class, 7167); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppErrorIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppErrorIDs.java new file mode 100644 index 0000000000..7ab4804109 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/AppErrorIDs.java @@ -0,0 +1,121 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.AlreadyConnectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.AppLayerErrorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.BolusAmountNotInRangeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.BolusDurationNotInRangeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.BolusLagTimeFeatureDisabledException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.BolusTypeAndParameterMismatchException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.CommandExecutionFailedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ConfigMemoryAccessException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.CustomBolusNotConfiguredException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ImplausiblePortionLengthValueException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.IncompatibleVersionException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidAlertInstanceIdException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidConfigBlockCRCException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidConfigBlockIdException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidConfigBlockLengthException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidDateParameterException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidDurationPresetException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidLagTimeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidParameterTypeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidPayloadCRCException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidPayloadException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidPayloadLengthException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidServicePasswordException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidTBRDurationException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidTBRFactorException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidTBRTemplateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidTimeParameterException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.InvalidValuesOfTwoChannelTransmission; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.MaximumNumberOfBolusTypeAlreadyRunningException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoActiveTBRToCanceLException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoActiveTBRToChangeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoConfigBlockDataException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoServicePasswordNeededException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoSuchBolusToCancelException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NotAllowedToAccessPositionZeroException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NotConnectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NotReferencedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PauseModeNotAllowedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PositionProtectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PumpAlreadyInThatStateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PumpBusyException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PumpStoppedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ReadingHistoryAlreadyStartedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ReadingHistoryNotStartedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.RunModeNotAllowedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ServiceAlreadyActivatedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ServiceCommandNotAvailableException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ServiceIncompatibleException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.ServiceNotActivatedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.StepCountOutOfRangeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.UnknownCommandException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.UnknownServiceException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.WriteSessionAlreadyOpenException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.WriteSessionClosedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.WrongStateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class AppErrorIDs { + + public static final IDStorage, Integer> IDS = new IDStorage<>(); + + static { + IDS.put(PumpStoppedException.class, 3178); + IDS.put(BolusAmountNotInRangeException.class, 6017); + IDS.put(PumpAlreadyInThatStateException.class, 3324); + IDS.put(InvalidServicePasswordException.class, 61593); + IDS.put(UnknownCommandException.class, 61455); + IDS.put(AlreadyConnectedException.class, 61530); + IDS.put(WrongStateException.class, 61680); + IDS.put(ServiceIncompatibleException.class, 61542); + IDS.put(UnknownServiceException.class, 61545); + IDS.put(NoServicePasswordNeededException.class, 61695); + IDS.put(ServiceAlreadyActivatedException.class, 61644); + IDS.put(IncompatibleVersionException.class, 61491); + IDS.put(InvalidPayloadLengthException.class, 61500); + IDS.put(NotConnectedException.class, 61525); + IDS.put(ServiceCommandNotAvailableException.class, 61605); + IDS.put(ServiceNotActivatedException.class, 61610); + IDS.put(PumpBusyException.class, 61635); + IDS.put(NotReferencedException.class, 5335); + IDS.put(StepCountOutOfRangeException.class, 5348); + IDS.put(InvalidPayloadCRCException.class, 2805); + IDS.put(InvalidParameterTypeException.class, 2810); + IDS.put(CommandExecutionFailedException.class, 22796); + IDS.put(InvalidAlertInstanceIdException.class, 3238); + IDS.put(InvalidTBRFactorException.class, 3241); + IDS.put(InvalidTBRDurationException.class, 3264); + IDS.put(InvalidTBRTemplateException.class, 6363); + IDS.put(PauseModeNotAllowedException.class, 3315); + IDS.put(RunModeNotAllowedException.class, 3279); + IDS.put(NoActiveTBRToCanceLException.class, 3840); + IDS.put(BolusTypeAndParameterMismatchException.class, 3925); + IDS.put(InvalidDurationPresetException.class, 5924); + IDS.put(BolusLagTimeFeatureDisabledException.class, 90); + IDS.put(BolusDurationNotInRangeException.class, 6014); + IDS.put(InvalidValuesOfTwoChannelTransmission.class, 0x0F96); + IDS.put(NoSuchBolusToCancelException.class, 4005); + IDS.put(MaximumNumberOfBolusTypeAlreadyRunningException.class, 4010); + IDS.put(CustomBolusNotConfiguredException.class, 6270); + IDS.put(InvalidDateParameterException.class, 4044); + IDS.put(InvalidTimeParameterException.class, 4080); + IDS.put(NoConfigBlockDataException.class, 4471); + IDS.put(InvalidConfigBlockIdException.class, 4472); + IDS.put(InvalidConfigBlockCRCException.class, 4487); + IDS.put(InvalidConfigBlockLengthException.class, 6286); + IDS.put(WriteSessionAlreadyOpenException.class, 4539); + IDS.put(WriteSessionClosedException.class, 4562); + IDS.put(ConfigMemoryAccessException.class, 4573); + IDS.put(ReadingHistoryAlreadyStartedException.class, 11794); + IDS.put(ReadingHistoryNotStartedException.class, 4680); + IDS.put(InvalidPayloadException.class, 6210); + IDS.put(ImplausiblePortionLengthValueException.class, 4824); + IDS.put(NotAllowedToAccessPositionZeroException.class, 4830); + IDS.put(PositionProtectedException.class, 4845); + IDS.put(InvalidLagTimeException.class, 3891); + IDS.put(NoActiveTBRToChangeException.class, 6322); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BatteryTypeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BatteryTypeIDs.java new file mode 100644 index 0000000000..45a4912213 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BatteryTypeIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BatteryType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class BatteryTypeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(BatteryType.ALKALI, 31); + IDS.put(BatteryType.LITHIUM, 227); + IDS.put(BatteryType.NI_MH, 252); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BolusTypeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BolusTypeIDs.java new file mode 100644 index 0000000000..0665455e0e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/BolusTypeIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.BolusType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class BolusTypeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(BolusType.STANDARD, 31); + IDS.put(BolusType.EXTENDED, 227); + IDS.put(BolusType.MULTIWAVE, 252); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/CartridgeTypeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/CartridgeTypeIDs.java new file mode 100644 index 0000000000..2ddd69b600 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/CartridgeTypeIDs.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.CartridgeType; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class CartridgeTypeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(CartridgeType.PREFILLED, 31); + IDS.put(CartridgeType.SELF_FILLED, 227); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryEventIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryEventIDs.java new file mode 100644 index 0000000000..4604ffccb8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryEventIDs.java @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.BasalDeliveryChangedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.BolusDeliveredEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.BolusProgrammedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.CannulaFilledEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.CartridgeInsertedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.CartridgeRemovedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.DateTimeChangedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.DefaultDateTimeSetEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.EndOfTBREvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.HistoryEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OccurrenceOfErrorEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OccurrenceOfMaintenanceEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OccurrenceOfWarningEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.OperatingModeChangedEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.PowerDownEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.PowerUpEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.SniffingDoneEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.StartOfTBREvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.TotalDailyDoseEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.history_events.TubeFilledEvent; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class HistoryEventIDs { + + public static final IDStorage, Integer> IDS = new IDStorage<>(); + + static { + IDS.put(BolusDeliveredEvent.class, 917); + IDS.put(BolusProgrammedEvent.class, 874); + IDS.put(CannulaFilledEvent.class, 3264); + IDS.put(DateTimeChangedEvent.class, 165); + IDS.put(DefaultDateTimeSetEvent.class, 170); + IDS.put(EndOfTBREvent.class, 771); + IDS.put(OccurrenceOfErrorEvent.class, 1011); + IDS.put(OccurrenceOfMaintenanceEvent.class, 1290); + IDS.put(OccurrenceOfWarningEvent.class, 1360); + IDS.put(OperatingModeChangedEvent.class, 195); + IDS.put(PowerUpEvent.class, 15); + IDS.put(PowerDownEvent.class, 51); + IDS.put(SniffingDoneEvent.class, 102); + IDS.put(StartOfTBREvent.class, 240); + IDS.put(TotalDailyDoseEvent.class, 960); + IDS.put(TubeFilledEvent.class, 105); + IDS.put(CartridgeInsertedEvent.class, 60); + IDS.put(CartridgeRemovedEvent.class, 85); + IDS.put(BasalDeliveryChangedEvent.class, 204); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryReadingDirectionIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryReadingDirectionIDs.java new file mode 100644 index 0000000000..5b2737d1f0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/HistoryReadingDirectionIDs.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.history.HistoryReadingDirection; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class HistoryReadingDirectionIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(HistoryReadingDirection.FORWARD, 31); + IDS.put(HistoryReadingDirection.BACKWARD, 227); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/OperatingModeIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/OperatingModeIDs.java new file mode 100644 index 0000000000..2e6597e494 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/OperatingModeIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.OperatingMode; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class OperatingModeIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(OperatingMode.STOPPED, 31); + IDS.put(OperatingMode.STARTED, 227); + IDS.put(OperatingMode.PAUSED, 252); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/PairingStatusIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/PairingStatusIDs.java new file mode 100644 index 0000000000..7b34e9375f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/PairingStatusIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.PairingStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class PairingStatusIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(PairingStatus.PENDING, 1683); + IDS.put(PairingStatus.REJECTED, 7850); + IDS.put(PairingStatus.CONFIRMED, 11835); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ParameterBlockIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ParameterBlockIDs.java new file mode 100644 index 0000000000..9dbcfe90cc --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ParameterBlockIDs.java @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.FactoryMaxBasalAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.FactoryMinBasalAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.MaxBasalAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.ParameterBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.TBROverNotificationBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.ActiveBRProfileBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile1Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile1NameBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile2Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile2NameBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile3Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile3NameBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile4Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile4NameBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile5Block; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.BRProfile5NameBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.FactoryMaxBolusAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.FactoryMinBolusAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.MaxBolusAmountBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.SystemIdentificationBlock; + +public class ParameterBlockIDs { + + public static final IDStorage, Integer> IDS = new IDStorage<>(); + + static { + IDS.put(FactoryMaxBolusAmountBlock.class, 41222); + IDS.put(MaxBolusAmountBlock.class, 31); + IDS.put(FactoryMinBolusAmountBlock.class, 60183); + IDS.put(SystemIdentificationBlock.class, 35476); + IDS.put(BRProfile1Block.class, 7136); + IDS.put(BRProfile2Block.class, 7167); + IDS.put(BRProfile3Block.class, 7532); + IDS.put(BRProfile4Block.class, 7539); + IDS.put(BRProfile5Block.class, 7567); + IDS.put(BRProfile1NameBlock.class, 48265); + IDS.put(BRProfile2NameBlock.class, 48278); + IDS.put(BRProfile3NameBlock.class, 48975); + IDS.put(BRProfile4NameBlock.class, 48976); + IDS.put(BRProfile5NameBlock.class, 49068); + IDS.put(ActiveBRProfileBlock.class, 7568); + IDS.put(MaxBasalAmountBlock.class, 6940); + IDS.put(FactoryMinBasalAmountBlock.class, 60395); + IDS.put(FactoryMaxBasalAmountBlock.class, 41241); + IDS.put(TBROverNotificationBlock.class, 25814); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlCommandIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlCommandIDs.java new file mode 100644 index 0000000000..268573293e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlCommandIDs.java @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SatlMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ConnectionRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ConnectionResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.DataMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.DisconnectMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.ErrorMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.KeyRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.KeyResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SynAckResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SynRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyConfirmRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyConfirmResponse; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyDisplayRequest; +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.VerifyDisplayResponse; + +public class SatlCommandIDs { + + public static final IDStorage, Byte> IDS = new IDStorage<>(); + + static { + IDS.put(DataMessage.class, (byte) 3); + IDS.put(ErrorMessage.class, (byte) 6); + IDS.put(ConnectionRequest.class, (byte) 9); + IDS.put(ConnectionResponse.class, (byte) 10); + IDS.put(KeyRequest.class, (byte) 12); + IDS.put(VerifyConfirmRequest.class, (byte) 14); + IDS.put(KeyResponse.class, (byte) 17); + IDS.put(VerifyDisplayRequest.class, (byte) 18); + IDS.put(VerifyDisplayResponse.class, (byte) 20); + IDS.put(SynRequest.class, (byte) 23); + IDS.put(SynAckResponse.class, (byte) 24); + IDS.put(DisconnectMessage.class, (byte) 27); + IDS.put(VerifyConfirmResponse.class, (byte) 30); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlErrorIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlErrorIDs.java new file mode 100644 index 0000000000..941305ee24 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SatlErrorIDs.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.satl.SatlError; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class SatlErrorIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(SatlError.UNDEFINED, (byte) 0); + IDS.put(SatlError.INCOMPATIBLE_VERSION, (byte) 1); + IDS.put(SatlError.INVALID_COMM_ID, (byte) 2); + IDS.put(SatlError.INVALID_MAC_TRAILER, (byte) 3); + IDS.put(SatlError.INVALID_CRC, (byte) 4); + IDS.put(SatlError.INVALID_PACKET, (byte) 5); + IDS.put(SatlError.INVALID_NONCE, (byte) 6); + IDS.put(SatlError.DECRYPT_VERIFY_FAILED, (byte) 7); + IDS.put(SatlError.COMPATIBLE_STATE, (byte) 8); + IDS.put(SatlError.WRONG_STATE, (byte) 0x0F); + IDS.put(SatlError.INVALID_MESSAGE_TYPE, (byte) 51); + IDS.put(SatlError.INVALID_PAYLOAD_LENGTH, (byte) 60); + IDS.put(SatlError.NONE, (byte) 255); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ServiceIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ServiceIDs.java new file mode 100644 index 0000000000..c4d62c1088 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/ServiceIDs.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class ServiceIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(Service.CONNECTION, (byte) 0); + IDS.put(Service.STATUS, (byte) 15); + IDS.put(Service.HISTORY, (byte) 60); + IDS.put(Service.CONFIGURATION, (byte) 85); + IDS.put(Service.REMOTE_CONTROL, (byte) 102); + IDS.put(Service.PARAMETER, (byte) 51); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SymbolStatusIDs.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SymbolStatusIDs.java new file mode 100644 index 0000000000..d3cdebdcc3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/ids/SymbolStatusIDs.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.ids; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.SymbolStatus; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.IDStorage; + +public class SymbolStatusIDs { + + public static final IDStorage IDS = new IDStorage<>(); + + static { + IDS.put(SymbolStatus.FULL, 31); + IDS.put(SymbolStatus.LOW, 227); + IDS.put(SymbolStatus.EMPTY, 252); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionRequest.java new file mode 100644 index 0000000000..534d2361ea --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionRequest.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class ConnectionRequest extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionResponse.java new file mode 100644 index 0000000000..3685935fca --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ConnectionResponse.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class ConnectionResponse extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DataMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DataMessage.java new file mode 100644 index 0000000000..61f2281d01 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DataMessage.java @@ -0,0 +1,21 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class DataMessage extends SatlMessage { + + private ByteBuf data; + + @Override + protected void parse(ByteBuf byteBuf) { + data = byteBuf; + } + + public ByteBuf getData() { + return this.data; + } + + public void setData(ByteBuf data) { + this.data = data; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DisconnectMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DisconnectMessage.java new file mode 100644 index 0000000000..897c719480 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/DisconnectMessage.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class DisconnectMessage extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ErrorMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ErrorMessage.java new file mode 100644 index 0000000000..f871fe34eb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/ErrorMessage.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.SatlErrorIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class ErrorMessage extends SatlMessage { + + private SatlError error; + + @Override + protected void parse(ByteBuf byteBuf) { + error = SatlErrorIDs.IDS.getType(byteBuf.readByte()); + } + + public SatlError getError() { + return this.error; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyRequest.java new file mode 100644 index 0000000000..5b5435b188 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyRequest.java @@ -0,0 +1,39 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import java.util.Calendar; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class KeyRequest extends SatlMessage { + + private byte[] randomBytes; + private byte[] preMasterKey; + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(288); + byteBuf.putBytes(randomBytes); + byteBuf.putUInt32LE(translateDate()); + byteBuf.putBytes(preMasterKey); + return byteBuf; + } + + private static int translateDate() { + Calendar calendar = Calendar.getInstance(); + int second = calendar.get(Calendar.SECOND); + int minute = calendar.get(Calendar.MINUTE); + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int day = calendar.get(Calendar.DAY_OF_MONTH); + int month = calendar.get(Calendar.MONTH); + int year = calendar.get(Calendar.YEAR); + return (year % 100 & 0x3f) << 26 | (month & 0x0f) << 22 | (day & 0x1f) << 17 | (hour & 0x1f) << 12 | (minute & 0x3f) << 6 | (second & 0x3f); + } + + public void setRandomBytes(byte[] randomBytes) { + this.randomBytes = randomBytes; + } + + public void setPreMasterKey(byte[] preMasterKey) { + this.preMasterKey = preMasterKey; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyResponse.java new file mode 100644 index 0000000000..9f8abac101 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/KeyResponse.java @@ -0,0 +1,24 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class KeyResponse extends SatlMessage { + + private byte[] randomData; + private byte[] preMasterSecret; + + @Override + protected void parse(ByteBuf byteBuf) { + randomData = byteBuf.readBytes(28); + byteBuf.shift(4); + preMasterSecret = byteBuf.getBytes(256); + } + + public byte[] getRandomData() { + return this.randomData; + } + + public byte[] getPreMasterSecret() { + return this.preMasterSecret; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/PairingStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/PairingStatus.java new file mode 100644 index 0000000000..9bea5b5b10 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/PairingStatus.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public enum PairingStatus { + + CONFIRMED, + REJECTED, + PENDING; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlError.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlError.java new file mode 100644 index 0000000000..7e9396c34d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlError.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public enum SatlError { + + UNDEFINED, + INCOMPATIBLE_VERSION, + INVALID_COMM_ID, + INVALID_MAC_TRAILER, + INVALID_CRC, + INVALID_PACKET, + INVALID_NONCE, + DECRYPT_VERIFY_FAILED, + COMPATIBLE_STATE, + WRONG_STATE, + INVALID_MESSAGE_TYPE, + INVALID_PAYLOAD_LENGTH, + NONE; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlMessage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlMessage.java new file mode 100644 index 0000000000..77f846c434 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SatlMessage.java @@ -0,0 +1,182 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import android.util.Log; + +import org.spongycastle.util.encoders.Hex; + +import java.util.Arrays; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.IncompatibleSatlVersionException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidMacTrailerException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidNonceException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidPacketLengthsException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidPreambleException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidSatlCRCException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.InvalidSatlCommandException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.SatlCommandIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.Nonce; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto.Cryptograph; + +public abstract class SatlMessage { + + private static final long PREAMBLE = 4293840008L; + private static final byte VERSION = 0x20; + + private Nonce nonce; + private long commID = 0; + private byte[] satlContent; + + protected ByteBuf getData() { + return new ByteBuf(0); + } + + protected void parse(ByteBuf byteBuf) { + + } + + public ByteBuf serialize(Class clazz, byte[] key) { + ByteBuf byteBuf; + if (nonce == null || key == null) byteBuf = serializeCRC(clazz); + else byteBuf = serializeCTR(nonce.getProductionalBytes(), key, SatlCommandIDs.IDS.getID(clazz)); + satlContent = byteBuf.getBytes(8, byteBuf.getSize() - 16); + return byteBuf; + } + + private ByteBuf serializeCRC(Class clazz) { + ByteBuf data = getData(); + int length = data.getSize() + 31; + ByteBuf byteBuf = new ByteBuf(length + 8); + byteBuf.putUInt32LE(PREAMBLE); + byteBuf.putUInt16LE(length); + byteBuf.putUInt16LE(~length); + byteBuf.putByte(VERSION); + byteBuf.putByte(SatlCommandIDs.IDS.getID(clazz)); + byteBuf.putUInt16LE(data.getSize() + 2); + byteBuf.putUInt32LE(clazz == KeyRequest.class ? 1 : commID); + byteBuf.putBytes((byte) 0x00, 13); + byteBuf.putByteBuf(data); + byteBuf.putUInt16LE(Cryptograph.calculateCRC(byteBuf.getBytes(8, length - 10))); + byteBuf.putBytes((byte) 0x00, 8); + return byteBuf; + } + + private ByteBuf serializeCTR(ByteBuf nonce, byte[] key, byte commandId) { + ByteBuf data = getData(); + ByteBuf encryptedData = ByteBuf.from(Cryptograph.encryptDataCTR(data.getBytes(), key, nonce.getBytes())); + int length = 29 + encryptedData.getSize(); + ByteBuf byteBuf = new ByteBuf(length + 8); + byteBuf.putUInt32LE(PREAMBLE); + byteBuf.putUInt16LE(length); + byteBuf.putUInt16LE(~length); + byteBuf.putByte(VERSION); + byteBuf.putByte(commandId); + byteBuf.putUInt16LE(encryptedData.getSize()); + byteBuf.putUInt32LE(commID); + byteBuf.putByteBuf(nonce); + byteBuf.putByteBuf(encryptedData); + byteBuf.putBytes(Cryptograph.produceCCMTag(byteBuf.getBytes(16, 13), data.getBytes(), byteBuf.getBytes(8, 21), key)); + return byteBuf; + } + + public static SatlMessage deserialize(ByteBuf data, Nonce lastNonce, byte[] key) throws InvalidMacTrailerException, InvalidSatlCRCException, InvalidNonceException, InvalidPreambleException, InvalidPacketLengthsException, IncompatibleSatlVersionException, InvalidSatlCommandException { + SatlMessage satlMessage; + byte[] satlContent = data.getBytes(8, data.getSize() - 16); + if (key == null) satlMessage = deserializeCRC(data); + else satlMessage = deserializeCTR(data, lastNonce, key); + satlMessage.setSatlContent(satlContent); + return satlMessage; + } + + private static SatlMessage deserializeCTR(ByteBuf data, Nonce lastNonce, byte[] key) throws InvalidMacTrailerException, InvalidNonceException, InvalidPreambleException, InvalidPacketLengthsException, IncompatibleSatlVersionException, InvalidSatlCommandException { + long preamble = data.readUInt32LE(); + int packetLength = data.readUInt16LE(); + int packetLengthXOR = data.readUInt16LE() ^ 65535; + byte[] header = data.getBytes(21); + byte version = data.readByte(); + byte commandId = data.readByte(); + Class clazz = SatlCommandIDs.IDS.getType(commandId); + int dataLength = data.readUInt16LE(); + long commId = data.readUInt32LE(); + byte[] nonce = data.readBytes(13); + byte[] payload = data.readBytes(dataLength); + byte[] trailer = data.readBytes(8); + Nonce parsedNonce = Nonce.fromProductionalBytes(nonce); + payload = Cryptograph.encryptDataCTR(payload, key, nonce); + if (!Arrays.equals(trailer, Cryptograph.produceCCMTag(nonce, payload, header, key))) throw new InvalidMacTrailerException(); + if (!lastNonce.isSmallerThan(parsedNonce)) throw new InvalidNonceException(); + if (preamble != PREAMBLE) throw new InvalidPreambleException(); + if (packetLength != packetLengthXOR) throw new InvalidPacketLengthsException(); + if (version != VERSION) throw new IncompatibleSatlVersionException(); + if (clazz == null) throw new InvalidSatlCommandException(); + SatlMessage message = null; + try { + message = clazz.newInstance(); + } catch (Exception ignored) { + } + message.parse(ByteBuf.from(payload)); + message.setNonce(parsedNonce); + message.setCommID(commId); + return message; + } + + private static SatlMessage deserializeCRC(ByteBuf data) throws InvalidSatlCRCException, InvalidPreambleException, InvalidPacketLengthsException, IncompatibleSatlVersionException, InvalidSatlCommandException { + long preamble = data.readUInt32LE(); + int packetLength = data.readUInt16LE(); + int packetLengthXOR = data.readUInt16LE() ^ 65535; + byte[] crcContent = data.getBytes(packetLength - 10); + byte version = data.readByte(); + byte commandId = data.readByte(); + Class clazz = SatlCommandIDs.IDS.getType(commandId); + int dataLength = data.readUInt16LE(); + long commId = data.readUInt32LE(); + byte[] nonce = data.readBytes(13); + byte[] payload = data.readBytes(dataLength - 2); + int crc = data.readUInt16LE(); + data.shift(8); + if (crc != Cryptograph.calculateCRC(crcContent)) throw new InvalidSatlCRCException(); + if (preamble != PREAMBLE) throw new InvalidPreambleException(); + if (packetLength != packetLengthXOR) throw new InvalidPacketLengthsException(); + if (version != VERSION) throw new IncompatibleSatlVersionException(); + if (clazz == null) throw new InvalidSatlCommandException(); + SatlMessage message = null; + try { + message = clazz.newInstance(); + } catch (Exception ignored) { + } + message.parse(ByteBuf.from(payload)); + message.setNonce(Nonce.fromProductionalBytes(nonce)); + message.setCommID(commId); + return message; + } + + public static boolean hasCompletePacket(ByteBuf byteBuf) { + if (byteBuf.getSize() < 37) return false; + if (byteBuf.getSize() < byteBuf.getUInt16LE(4) + 8) return false; + return true; + } + + public Nonce getNonce() { + return this.nonce; + } + + public long getCommID() { + return this.commID; + } + + public byte[] getSatlContent() { + return this.satlContent; + } + + public void setNonce(Nonce nonce) { + this.nonce = nonce; + } + + public void setCommID(long commID) { + this.commID = commID; + } + + public void setSatlContent(byte[] satlContent) { + this.satlContent = satlContent; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynAckResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynAckResponse.java new file mode 100644 index 0000000000..c28cb1101f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynAckResponse.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class SynAckResponse extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynRequest.java new file mode 100644 index 0000000000..7c2f04439e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/SynRequest.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class SynRequest extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmRequest.java new file mode 100644 index 0000000000..9df12e8b27 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmRequest.java @@ -0,0 +1,14 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.PairingStatusIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class VerifyConfirmRequest extends SatlMessage { + + @Override + protected ByteBuf getData() { + ByteBuf byteBuf = new ByteBuf(2); + byteBuf.putUInt16LE(PairingStatusIDs.IDS.getID(PairingStatus.CONFIRMED)); + return byteBuf; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmResponse.java new file mode 100644 index 0000000000..7afae3bd91 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyConfirmResponse.java @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.ids.PairingStatusIDs; +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class VerifyConfirmResponse extends SatlMessage { + + private PairingStatus pairingStatus; + + @Override + protected void parse(ByteBuf byteBuf) { + pairingStatus = PairingStatusIDs.IDS.getType(byteBuf.readUInt16LE()); + } + + public PairingStatus getPairingStatus() { + return this.pairingStatus; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayRequest.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayRequest.java new file mode 100644 index 0000000000..5c9499840e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayRequest.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class VerifyDisplayRequest extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayResponse.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayResponse.java new file mode 100644 index 0000000000..32e014764f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/satl/VerifyDisplayResponse.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.satl; + +public class VerifyDisplayResponse extends SatlMessage { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/BOCUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/BOCUtil.java new file mode 100644 index 0000000000..73daff3005 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/BOCUtil.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +public final class BOCUtil { + + public static int parseBOC(byte b) { + return ((b & 0xF0) >> 4) * 10 + (b & 0x0F); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ByteBuf.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ByteBuf.java new file mode 100644 index 0000000000..c9f1fcf790 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ByteBuf.java @@ -0,0 +1,384 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class ByteBuf { + + private byte[] bytes; + private int size = 0; + + public ByteBuf(int length) { + bytes = new byte[length]; + } + + + public byte[] getBytes() { + byte[] bytes = new byte[size]; + System.arraycopy(this.bytes, 0, bytes, 0, size); + return bytes; + } + + public void shift(int offset) { + System.arraycopy(bytes, offset, bytes, 0, bytes.length - offset); + size -= offset; + } + + public byte getByte(int position) { + return bytes[position]; + } + + public byte getByte() { + return bytes[0]; + } + + public byte readByte() { + byte b = getByte(); + shift(1); + return b; + } + + public void putByte(byte b) { + bytes[size] = b; + size += 1; + } + + + + public void putBytes(byte b, int count) { + for (int i = 0; i < count; i++) bytes[size++] = b; + } + + + + public byte[] getBytes(int position, int length) { + byte[] copy = new byte[length]; + System.arraycopy(bytes, position, copy, 0, length); + return copy; + } + + public byte[] getBytes(int length) { + return getBytes(0, length); + } + + public byte[] readBytes(int length) { + byte[] copy = getBytes(length); + shift(length); + return copy; + } + + public byte[] readBytes() { + return readBytes(size); + } + + public void putBytes(byte[] bytes, int length) { + System.arraycopy(bytes, 0, this.bytes, size, length); + size += length; + } + + public void putBytes(byte[] bytes) { + putBytes(bytes, bytes.length); + } + + + + public byte[] getBytesLE(int position, int length) { + byte[] copy = new byte[length]; + for (int i = 0; i < length; i++) + copy[i] = bytes[length - 1 - i + position]; + return copy; + } + + public byte[] getBytesLE(int length) { + return getBytesLE(0, length); + } + + public byte[] readBytesLE(int length) { + byte[] copy = getBytesLE(length); + shift(length); + return copy; + } + + public void putBytesLE(byte[] bytes, int length) { + for (int i = 0; i < length; i++) + this.bytes[size + length - 1 - i] = bytes[i]; + size += length; + } + + public void putBytesLE(byte[] bytes) { + putBytesLE(bytes, bytes.length); + } + + + public void putByteBuf(ByteBuf byteBuf) { + putBytes(byteBuf.getBytes(), byteBuf.getSize()); + } + + + + public short getUInt8(int position) { + return (short) (bytes[position] & 0xFF); + } + + public short getUInt8() { + return getUInt8(0); + } + + public short readUInt8() { + short value = getUInt8(); + shift(1); + return value; + } + + public void putUInt8(short value) { + putByte((byte) (value & 0xFF)); + } + + + + public int getUInt16LE(int position) { + return (bytes[position++] & 0xFF | + (bytes[position] & 0xFF) << 8); + } + + public int getUInt16LE() { + return getUInt16LE(0); + } + + public int readUInt16LE() { + int i = getUInt16LE(); + shift(2); + return i; + } + + public void putUInt16LE(int i) { + putByte((byte) (i & 0xFF)); + putByte((byte) ((i >> 8) & 0xFF)); + } + + + + public double getUInt16Decimal(int position) { + return new BigDecimal(getUInt16LE(position)) + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP) + .doubleValue(); + } + + public double getUInt16Decimal() { + return getUInt16Decimal(0); + } + + public double readUInt16Decimal() { + double d = getUInt16Decimal(); + shift(2); + return d; + } + + public void putUInt16Decimal(double d) { + putUInt16LE(new BigDecimal(d) + .multiply(new BigDecimal(100)) + .setScale(0, RoundingMode.HALF_UP) + .intValue()); + } + + + + public double getUInt32Decimal100(int position) { + return new BigDecimal(getUInt32LE(position)) + .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP) + .doubleValue(); + } + + public double getUInt32Decimal100() { + return getUInt32Decimal100(0); + } + + public double readUInt32Decimal100() { + double d = getUInt32Decimal100(); + shift(4); + return d; + } + + public void putUInt32Decimal100(double d) { + putUInt32LE(new BigDecimal(d) + .multiply(new BigDecimal(100)) + .setScale(0, RoundingMode.HALF_UP) + .longValue()); + } + + + + public double getUInt32Decimal1000(int position) { + return new BigDecimal(getUInt32LE(position)) + .divide(new BigDecimal(1000), 3, RoundingMode.HALF_UP) + .doubleValue(); + } + + public double getUInt32Decimal1000() { + return getUInt32Decimal1000(0); + } + + public double readUInt32Decimal1000() { + double d = getUInt32Decimal1000(); + shift(4); + return d; + } + + public void putUInt32Decimal1000(double d) { + putUInt32LE(new BigDecimal(d) + .multiply(new BigDecimal(1000)) + .setScale(0, RoundingMode.HALF_UP) + .longValue()); + } + + + + public short getShort(int position) { + return (short) (bytes[position++] << 8 | + bytes[position] & 0xFF); + } + + public short getShort() { + return getShort(0); + } + + public short readShort() { + short s = getShort(); + shift(2); + return s; + } + + public void putShort(short s) { + putByte((byte) (s >> 8)); + putByte((byte) s); + } + + + + public long getUInt32LE(int position) { + return ((long) bytes[position++] & 0xFF) | + ((long) bytes[position++] & 0xFF) << 8 | + ((long) bytes[position++] & 0xFF) << 16 | + ((long) bytes[position] & 0xFF) << 24; + } + + public long getUInt32LE() { + return getUInt32LE(0); + } + + public long readUInt32LE() { + long l = getUInt32LE(); + shift(4); + return l; + } + + public void putUInt32LE(long l) { + putByte((byte) (l & 0xFF)); + putByte((byte) ((l >> 8) & 0xFF)); + putByte((byte) ((l >> 16) & 0xFF)); + putByte((byte) ((l >> 24) & 0xFF)); + } + + + + public String getUTF16(int position, int stringLength) { + try { + String string = new String(getBytes(position, stringLength * 2 + 2), "UTF-16LE"); + return string.substring(0, string.indexOf(new String(new char[] {0, 0}))); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } + + public String getUTF16(int stringLength) { + return getUTF16(0, stringLength); + } + + public String readUTF16(int stringLength) { + String string = getUTF16(stringLength); + shift(stringLength * 2 + 2); + return string; + } + + public void putUTF16(String string, int stringLength) { + try { + putBytes(string.getBytes("UTF-16LE"), stringLength * 2); + putBytes((byte) 0, 2); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + + + public String getASCII(int position, int stringLength) { + try { + String string = new String(getBytes(position, stringLength + 1), "US-ASCII"); + return string.substring(0, string.indexOf(0)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } + + public String getASCII(int stringLength) { + return getASCII(0, stringLength); + } + + public String readASCII(int stringLength) { + String string = getASCII(stringLength); + shift(stringLength + 1); + return string; + } + + public void putASCII(String string, int stringLength) { + try { + putBytes(string.getBytes("UTF-16LE"), stringLength * 2); + putBytes((byte) 0, 1); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + + + public boolean getBoolean(int position) { + return getUInt16LE(position) == 75; + } + + public boolean getBoolean() { + return getBoolean(0); + } + + public boolean readBoolean() { + boolean bool = getBoolean(); + shift(2); + return bool; + } + + public void putBoolean(boolean bool) { + putUInt16LE(bool ? 75 : 180); + } + + + + public static ByteBuf from(byte[] bytes, int length) { + ByteBuf byteBuf = new ByteBuf(length); + byteBuf.putBytes(bytes, length); + return byteBuf; + } + + public static ByteBuf from(byte[] bytes) { + return from(bytes, bytes.length); + } + + public int getSize() { + return this.size; + } + + public void clear() { + shift(size); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ConnectionEstablisher.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ConnectionEstablisher.java new file mode 100644 index 0000000000..0257cc04f3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ConnectionEstablisher.java @@ -0,0 +1,78 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.UUID; + +public class ConnectionEstablisher extends Thread { + + private Callback callback; + private boolean forPairing; + private BluetoothAdapter bluetoothAdapter; + private BluetoothDevice bluetoothDevice; + private BluetoothSocket socket; + + public ConnectionEstablisher(Callback callback, boolean forPairing, BluetoothAdapter bluetoothAdapter, BluetoothDevice bluetoothDevice, BluetoothSocket socket) { + this.callback = callback; + this.forPairing = forPairing; + this.bluetoothAdapter = bluetoothAdapter; + this.bluetoothDevice = bluetoothDevice; + this.socket = socket; + } + + @Override + public void run() { + try { + if (!bluetoothAdapter.isEnabled()) { + bluetoothAdapter.enable(); + Thread.sleep(2000); + } + } catch (InterruptedException ignored) { + return; + } + if (forPairing && bluetoothDevice.getBondState() != BluetoothDevice.BOND_NONE) { + try { + Method removeBond = bluetoothDevice.getClass().getMethod("removeBond", (Class[]) null); + removeBond.invoke(bluetoothDevice, (Object[]) null); + } catch (ReflectiveOperationException e) { + if (!isInterrupted()) callback.onConnectionFail(e); + return; + } + } + try { + if (socket == null) { + socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")); + callback.onSocketCreated(socket); + } + } catch (IOException e) { + if (!isInterrupted()) callback.onConnectionFail(e); + return; + } + try { + socket.connect(); + if (!isInterrupted()) callback.onConnectionSucceed(); + } catch (IOException e) { + if (!isInterrupted()) callback.onConnectionFail(e); + } + } + + public void close() { + try { + interrupt(); + if (socket.isConnected()) socket.close(); + } catch (IOException ignored) { + } + } + + public interface Callback { + void onSocketCreated(BluetoothSocket bluetoothSocket); + + void onConnectionSucceed(); + + void onConnectionFail(Exception e); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/DelayedActionThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/DelayedActionThread.java new file mode 100644 index 0000000000..6f1c48732f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/DelayedActionThread.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +public class DelayedActionThread extends Thread { + + private long duration; + private Runnable runnable; + + private DelayedActionThread(String name, long duration, Runnable runnable) { + setName(name); + this.duration = duration; + this.runnable = runnable; + } + + @Override + public void run() { + try { + Thread.sleep(duration); + runnable.run(); + } catch (InterruptedException e) { + } + } + + public static DelayedActionThread runDelayed(String name, long duration, Runnable runnable) { + DelayedActionThread delayedActionThread = new DelayedActionThread(name, duration, runnable); + delayedActionThread.start(); + return delayedActionThread; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ExceptionTranslator.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ExceptionTranslator.java new file mode 100644 index 0000000000..3b90bf5e13 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ExceptionTranslator.java @@ -0,0 +1,55 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; + +import java.util.HashMap; +import java.util.Map; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.ConnectionFailedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.ConnectionLostException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.DisconnectedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.SocketCreationFailedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.TimeoutException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.MaximumNumberOfBolusTypeAlreadyRunningException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoActiveTBRToCanceLException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoActiveTBRToChangeException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.NoSuchBolusToCancelException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PumpAlreadyInThatStateException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.PumpStoppedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.app_layer_errors.RunModeNotAllowedException; +import info.nightscout.androidaps.plugins.PumpInsightLocal.exceptions.satl_errors.SatlPairingRejectedException; + +public class ExceptionTranslator { + + private static final Map, Integer> TABLE = new HashMap<>(); + + static { + TABLE.put(ConnectionFailedException.class, R.string.connection_failed); + TABLE.put(ConnectionLostException.class, R.string.connection_lost); + TABLE.put(DisconnectedException.class, R.string.disconnected); + TABLE.put(SatlPairingRejectedException.class, R.string.pairing_rejected); + TABLE.put(SocketCreationFailedException.class, R.string.socket_creation_failed); + TABLE.put(TimeoutException.class, R.string.timeout); + TABLE.put(MaximumNumberOfBolusTypeAlreadyRunningException.class, R.string.maximum_number_of_bolus_type_already_running); + TABLE.put(NoActiveTBRToCanceLException.class, R.string.no_active_tbr_to_cancel); + TABLE.put(NoActiveTBRToChangeException.class, R.string.no_active_tbr_to_change); + TABLE.put(NoSuchBolusToCancelException.class, R.string.no_such_bolus_to_cancel); + TABLE.put(PumpAlreadyInThatStateException.class, R.string.pump_already_in_that_state_exception); + TABLE.put(PumpStoppedException.class, R.string.pump_stopped); + TABLE.put(RunModeNotAllowedException.class, R.string.run_mode_not_allowed); + } + + public static String getString(Exception exception) { + Integer res = TABLE.get(exception.getClass()); + return res == null ? exception.getClass().getSimpleName() : MainApp.gs(res); + } + + public static void makeToast(Context context, Exception exception) { + new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(context, getString(exception), Toast.LENGTH_LONG).show()); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/IDStorage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/IDStorage.java new file mode 100644 index 0000000000..da463845a8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/IDStorage.java @@ -0,0 +1,24 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import java.util.HashMap; +import java.util.Map; + +public class IDStorage { + + private Map types = new HashMap<>(); + private Map ids = new HashMap<>(); + + public void put(T type, I id) { + types.put(type, id); + ids.put(id, type); + } + + public T getType(I type) { + return ids.get(type); + } + + public I getID(T id) { + return types.get(id); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/InputStreamReader.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/InputStreamReader.java new file mode 100644 index 0000000000..d357fdeccb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/InputStreamReader.java @@ -0,0 +1,51 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import java.io.IOException; +import java.io.InputStream; + +public class InputStreamReader extends Thread { + + private static final int BUFFER_SIZE = 1024; + + private InputStream inputStream; + private Callback callback; + + public InputStreamReader(InputStream inputStream, Callback callback) { + setName(getClass().getSimpleName()); + this.inputStream = inputStream; + this.callback = callback; + } + + @Override + public void run() { + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead; + try { + while (!isInterrupted()) { + bytesRead = inputStream.read(buffer); + if (bytesRead == -1) callback.onErrorWhileReading(new IOException("Stream closed")); + else callback.onReceiveBytes(buffer, bytesRead); + } + } catch (IOException e) { + if (!isInterrupted()) callback.onErrorWhileReading(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + + public void close() { + interrupt(); + try { + inputStream.close(); + } catch (IOException e) { + } + } + + public interface Callback { + void onReceiveBytes(byte[] buffer, int bytesRead); + void onErrorWhileReading(Exception e); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/Nonce.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/Nonce.java new file mode 100644 index 0000000000..332de4ec05 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/Nonce.java @@ -0,0 +1,47 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import java.math.BigInteger; + +public class Nonce { + + private BigInteger bigInteger; + + public Nonce() { + bigInteger = BigInteger.ZERO; + } + + public Nonce(byte[] storageValue) { + bigInteger = new BigInteger(storageValue); + } + + public byte[] getStorageValue() { + return bigInteger.toByteArray(); + } + + public ByteBuf getProductionalBytes() { + ByteBuf byteBuf = new ByteBuf(13); + byteBuf.putBytesLE(bigInteger.toByteArray()); + byteBuf.putBytes((byte) 0x00, 13 - byteBuf.getSize()); + return byteBuf; + } + + public static Nonce fromProductionalBytes(byte[] bytes) { + ByteBuf byteBuf = new ByteBuf(14); + byteBuf.putByte((byte) 0x00); + byteBuf.putBytesLE(bytes); + return new Nonce(byteBuf.getBytes()); + } + + public void increment() { + bigInteger = bigInteger.add(BigInteger.ONE); + } + + public void increment(int count) { + bigInteger = bigInteger.add(BigInteger.valueOf(count)); + } + + public boolean isSmallerThan(Nonce greater) { + return bigInteger.compareTo(greater.bigInteger) < 0; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/OutputStreamWriter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/OutputStreamWriter.java new file mode 100644 index 0000000000..9f84ad067a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/OutputStreamWriter.java @@ -0,0 +1,74 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import java.io.IOException; +import java.io.OutputStream; + +public class OutputStreamWriter extends Thread { + + private static final int BUFFER_SIZE = 1024; + + private OutputStream outputStream; + private Callback callback; + private final ByteBuf buffer = new ByteBuf(BUFFER_SIZE); + + public OutputStreamWriter(OutputStream outputStream, Callback callback) { + setName(getClass().getSimpleName()); + this.outputStream = outputStream; + this.callback = callback; + } + + @Override + public void run() { + try { + while (!isInterrupted()) { + synchronized (buffer) { + if (buffer.getSize() != 0) { + outputStream.write(buffer.readBytes()); + outputStream.flush(); + buffer.notifyAll(); + } + buffer.wait(); + } + } + } catch (IOException e) { + if (!isInterrupted()) callback.onErrorWhileWriting(e); + } catch (InterruptedException ignored) { + } finally { + try { + outputStream.close(); + } catch (IOException e) { + } + } + } + + public void write(byte[] bytes) { + synchronized (buffer) { + buffer.putBytes(bytes); + buffer.notifyAll(); + } + } + + public void writeAndWait(byte[] bytes) { + synchronized (buffer) { + buffer.putBytes(bytes); + buffer.notifyAll(); + try { + buffer.wait(); + } catch (InterruptedException e) { + } + } + } + + public void close() { + interrupt(); + try { + outputStream.close(); + } catch (IOException e) { + } + } + + public interface Callback { + void onErrorWhileWriting(Exception e); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/PairingDataStorage.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/PairingDataStorage.java new file mode 100644 index 0000000000..83cec09d09 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/PairingDataStorage.java @@ -0,0 +1,210 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +import org.spongycastle.util.encoders.Hex; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.FirmwareVersions; +import info.nightscout.androidaps.plugins.PumpInsightLocal.descriptors.SystemIdentification; + +public class PairingDataStorage { + + private SharedPreferences preferences; + + private boolean paired; + private String macAddress; + private Nonce lastNonceSent; + private Nonce lastNonceReceived; + private long commId; + private byte[] incomingKey; + private byte[] outgoingKey; + private FirmwareVersions firmwareVersions; + private SystemIdentification systemIdentification; + + public PairingDataStorage(Context context) { + this.preferences = context.getSharedPreferences(context.getPackageName() + ".PAIRING_DATA_STORAGE", Context.MODE_PRIVATE); + paired = preferences.getBoolean("paired", false); + macAddress = preferences.getString("macAddress", null); + String lastNonceSentHex = preferences.getString("lastNonceSent", null); + if (lastNonceSentHex != null) lastNonceSent = new Nonce(Hex.decode(lastNonceSentHex)); + String lastNonceReceivedHex = preferences.getString("lastNonceReceived", null); + if (lastNonceReceivedHex != null) lastNonceReceived = new Nonce(Hex.decode(lastNonceReceivedHex)); + commId = preferences.getLong("commId", 0); + String incomingKeyHex = preferences.getString("incomingKey", null); + incomingKey = incomingKeyHex == null ? null : Hex.decode(incomingKeyHex); + String outgoingKeyHex = preferences.getString("outgoingKey", null); + outgoingKey = outgoingKeyHex == null ? null : Hex.decode(outgoingKeyHex); + + String pumpSerial = preferences.getString("pumpSerial", null); + String manufacturingDate = preferences.getString("manufacturingDate", null); + long systemIdAppendix = preferences.getLong("systemIdAppendix", 0); + + if (pumpSerial != null) { + systemIdentification = new SystemIdentification(); + systemIdentification.setSerialNumber(pumpSerial); + systemIdentification.setManufacturingDate(manufacturingDate); + systemIdentification.setSystemIdAppendix(systemIdAppendix); + } + + String releaseSWVersion = preferences.getString("releaseSWVersion", null); + String uiProcSWVersion = preferences.getString("uiProcSWVersion", null); + String pcProcSWVersion = preferences.getString("pcProcSWVersion", null); + String mdTelProcSWVersion = preferences.getString("mdTelProcSWVersion", null); + String btInfoPageVersion = preferences.getString("btInfoPageVersion", null); + String safetyProcSWVersion = preferences.getString("safetyProcSWVersion", null); + int configIndex = preferences.getInt("configIndex", 0); + int historyIndex = preferences.getInt("historyIndex", 0); + int stateIndex = preferences.getInt("stateIndex", 0); + int vocabularyIndex = preferences.getInt("vocabularyIndex", 0); + if (releaseSWVersion != null) { + firmwareVersions = new FirmwareVersions(); + firmwareVersions.setReleaseSWVersion(releaseSWVersion); + firmwareVersions.setUiProcSWVersion(uiProcSWVersion); + firmwareVersions.setPcProcSWVersion(pcProcSWVersion); + firmwareVersions.setMdTelProcSWVersion(mdTelProcSWVersion); + firmwareVersions.setBtInfoPageVersion(btInfoPageVersion); + firmwareVersions.setSafetyProcSWVersion(safetyProcSWVersion); + firmwareVersions.setConfigIndex(configIndex); + firmwareVersions.setHistoryIndex(historyIndex); + firmwareVersions.setStateIndex(stateIndex); + firmwareVersions.setVocabularyIndex(vocabularyIndex); + } + } + + public void setPaired(boolean paired) { + this.paired = paired; + preferences.edit().putBoolean("paired", paired).apply(); + } + + public void setMacAddress(String macAddress) { + this.macAddress = macAddress; + preferences.edit().putString("macAddress", macAddress).apply(); + } + + public void setLastNonceSent(Nonce lastNonceSent) { + this.lastNonceSent = lastNonceSent; + preferences.edit().putString("lastNonceSent", lastNonceSent == null ? null : Hex.toHexString(lastNonceSent.getStorageValue())).apply(); + } + + public void setLastNonceReceived(Nonce lastNonceReceived) { + this.lastNonceReceived = lastNonceReceived; + preferences.edit().putString("lastNonceReceived", lastNonceReceived == null ? null : Hex.toHexString(lastNonceReceived.getStorageValue())).apply(); + } + + public void setCommId(long commId) { + this.commId = commId; + preferences.edit().putLong("commId", commId).apply(); + } + + public void setIncomingKey(byte[] incomingKey) { + this.incomingKey = incomingKey; + preferences.edit().putString("incomingKey", incomingKey == null ? null : Hex.toHexString(incomingKey)).apply(); + } + + public void setOutgoingKey(byte[] outgoingKey) { + this.outgoingKey = outgoingKey; + preferences.edit().putString("outgoingKey", outgoingKey == null ? null : Hex.toHexString(outgoingKey)).apply(); + } + + public SharedPreferences getPreferences() { + return this.preferences; + } + + public boolean isPaired() { + return this.paired; + } + + public String getMacAddress() { + return this.macAddress; + } + + public Nonce getLastNonceSent() { + return this.lastNonceSent; + } + + public Nonce getLastNonceReceived() { + return this.lastNonceReceived; + } + + public long getCommId() { + return this.commId; + } + + public byte[] getIncomingKey() { + return this.incomingKey; + } + + public byte[] getOutgoingKey() { + return this.outgoingKey; + } + + public FirmwareVersions getFirmwareVersions() { + return firmwareVersions; + } + + public void setFirmwareVersions(FirmwareVersions firmwareVersions) { + this.firmwareVersions = firmwareVersions; + if (firmwareVersions == null) { + preferences.edit() + .putString("releaseSWVersion", null) + .putString("uiProcSWVersion", null) + .putString("pcProcSWVersion", null) + .putString("mdTelProcSWVersion", null) + .putString("btInfoPageVersion", null) + .putString("safetyProcSWVersion", null) + .putInt("configIndex", 0) + .putInt("historyIndex", 0) + .putInt("stateIndex", 0) + .putInt("vocabularyIndex", 0) + .apply(); + } else { + preferences.edit() + .putString("releaseSWVersion", firmwareVersions.getReleaseSWVersion()) + .putString("uiProcSWVersion", firmwareVersions.getUiProcSWVersion()) + .putString("pcProcSWVersion", firmwareVersions.getPcProcSWVersion()) + .putString("mdTelProcSWVersion", firmwareVersions.getMdTelProcSWVersion()) + .putString("btInfoPageVersion", firmwareVersions.getBtInfoPageVersion()) + .putString("safetyProcSWVersion", firmwareVersions.getSafetyProcSWVersion()) + .putInt("configIndex", firmwareVersions.getConfigIndex()) + .putInt("historyIndex", firmwareVersions.getHistoryIndex()) + .putInt("stateIndex", firmwareVersions.getStateIndex()) + .putInt("vocabularyIndex", firmwareVersions.getVocabularyIndex()) + .apply(); + } + } + + public SystemIdentification getSystemIdentification() { + return systemIdentification; + } + + public void setSystemIdentification(SystemIdentification systemIdentification) { + this.systemIdentification = systemIdentification; + if (systemIdentification == null) { + preferences.edit() + .putString("pumpSerial", null) + .putString("manufacturingDate", null) + .putLong("systemIdAppendix", 0) + .apply(); + } else { + preferences.edit() + .putString("pumpSerial", systemIdentification.getSerialNumber()) + .putString("manufacturingDate", systemIdentification.getManufacturingDate()) + .putLong("systemIdAppendix", systemIdentification.getSystemIdAppendix()) + .apply(); + } + } + + public void reset() { + setPaired(false); + setMacAddress(null); + setCommId(0); + setIncomingKey(null); + setOutgoingKey(null); + setLastNonceReceived(null); + setLastNonceSent(null); + setFirmwareVersions(null); + setSystemIdentification(null); + setMacAddress(null); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ParameterBlockUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ParameterBlockUtil.java new file mode 100644 index 0000000000..44936f5c10 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/ParameterBlockUtil.java @@ -0,0 +1,25 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.ReadParameterBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.Service; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.configuration.WriteConfigurationBlockMessage; +import info.nightscout.androidaps.plugins.PumpInsightLocal.app_layer.parameter_blocks.ParameterBlock; +import info.nightscout.androidaps.plugins.PumpInsightLocal.connection_service.InsightConnectionService; +import sugar.free.sightparser.applayer.descriptors.configuration_blocks.ConfigurationBlock; + +public class ParameterBlockUtil { + + public static T readParameterBlock(InsightConnectionService connectionService, Service service, Class parameterBlock) throws Exception { + ReadParameterBlockMessage readMessage = new ReadParameterBlockMessage(); + readMessage.setService(service); + readMessage.setParameterBlockId(parameterBlock); + return (T) connectionService.requestMessage(readMessage).await().getParameterBlock(); + } + + public static void writeConfigurationBlock(InsightConnectionService connectionService, ParameterBlock parameterBlock) throws Exception { + WriteConfigurationBlockMessage writeMessage = new WriteConfigurationBlockMessage(); + writeMessage.setParameterBlock(parameterBlock); + connectionService.requestMessage(writeMessage).await(); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/CRC.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/CRC.java new file mode 100644 index 0000000000..e276cfbc04 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/CRC.java @@ -0,0 +1,44 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto; + +/* + * Based on: http://introcs.cs.princeton.edu/java/61data/CRC16.java + * Table generated using: http://pycrc.org/ + * Command used: python pycrc.py --width 16 --poly 0x1021 --reflect-in True --reflect-out True --xor-in 0xffff --xor-out=0x0000 --generate TABLE + */ +class CRC { + + protected static final int[] TABLE = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 + }; +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/Cryptograph.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/Cryptograph.java new file mode 100644 index 0000000000..2a4405a2c3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/Cryptograph.java @@ -0,0 +1,215 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto; + +import org.spongycastle.crypto.AsymmetricCipherKeyPair; +import org.spongycastle.crypto.Digest; +import org.spongycastle.crypto.InvalidCipherTextException; +import org.spongycastle.crypto.digests.MD5Digest; +import org.spongycastle.crypto.digests.SHA1Digest; +import org.spongycastle.crypto.encodings.OAEPEncoding; +import org.spongycastle.crypto.engines.RSAEngine; +import org.spongycastle.crypto.engines.TwofishEngine; +import org.spongycastle.crypto.generators.RSAKeyPairGenerator; +import org.spongycastle.crypto.macs.HMac; +import org.spongycastle.crypto.modes.CBCBlockCipher; +import org.spongycastle.crypto.params.AsymmetricKeyParameter; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.crypto.params.ParametersWithIV; +import org.spongycastle.crypto.params.RSAKeyGenerationParameters; +import org.spongycastle.crypto.params.RSAKeyParameters; +import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import info.nightscout.androidaps.plugins.PumpInsightLocal.utils.ByteBuf; + +public class Cryptograph { + + private static final String keySeed = "master secret"; + private static final String verificationSeed = "finished"; + + private static byte[] getHmac(byte[] secret, byte[] data, Digest algorithm) { + HMac hmac = new HMac(algorithm); + hmac.init(new KeyParameter(secret)); + byte[] result = new byte[hmac.getMacSize()]; + hmac.update(data, 0, data.length); + hmac.doFinal(result, 0); + return result; + } + + private static byte[] getMultiHmac(byte[] secret, byte[] data, int bytes, Digest algorithm) { + byte[] nuData = data; + byte[] output = new byte[bytes]; + int size = 0; + while (size < bytes) { + nuData = getHmac(secret, nuData, algorithm); + byte[] preOutput = getHmac(secret, combine(nuData, data), algorithm); + System.arraycopy(preOutput, 0, output, size, Math.min(bytes - size, preOutput.length)); + size += preOutput.length; + } + return output; + } + + private static byte[] sha1MultiHmac(byte[] secret, byte[] data, int bytes) { + return getMultiHmac(secret, data, bytes, new SHA1Digest()); + } + + private static byte[] md5MultiHmac(byte[] secret, byte[] data, int bytes) { + return getMultiHmac(secret, data, bytes, new MD5Digest()); + } + + public static byte[] getServicePasswordHash(String servicePassword, byte[] salt) { + return multiHashXOR(servicePassword.getBytes(), combine("service pwd".getBytes(), salt), 16); + } + + private static byte[] byteArrayXOR(byte[] array1, byte[] array2) { + int length = Math.min(array1.length, array2.length); + byte[] xor = new byte[length]; + for (int i = 0; i < length; i++) { + xor[i] = (byte) (array1[i] ^ array2[i]); + } + return xor; + } + + private static byte[] multiHashXOR(byte[] secret, byte[] seed, int bytes) { + byte[] array1 = new byte[secret.length / 2]; + byte[] array2 = new byte[array1.length]; + System.arraycopy(secret, 0, array1, 0, array1.length); + System.arraycopy(secret, array1.length, array2, 0, array2.length); + byte[] md5 = md5MultiHmac(array1, seed, bytes); + byte[] sha1 = sha1MultiHmac(array2, seed, bytes); + return byteArrayXOR(md5, sha1); + } + + public static DerivedKeys deriveKeys(byte[] verificationSeed, byte[] secret, byte[] random, byte[] peerRandom) { + byte[] result = multiHashXOR(secret, combine(combine(keySeed.getBytes(), random), peerRandom), 32); + DerivedKeys derivedKeys = new DerivedKeys(); + derivedKeys.incomingKey = new byte[result.length / 2]; + derivedKeys.outgoingKey = new byte[derivedKeys.incomingKey.length]; + System.arraycopy(result, 0, derivedKeys.incomingKey, 0, derivedKeys.incomingKey.length); + System.arraycopy(result, derivedKeys.incomingKey.length, derivedKeys.outgoingKey, 0, derivedKeys.outgoingKey.length); + derivedKeys.verificationString = calculateVerificationString(verificationSeed, result); + return derivedKeys; + } + + private static String calculateVerificationString(byte[] verificationSeed, byte[] key) { + byte[] verificationData = multiHashXOR(key, combine(Cryptograph.verificationSeed.getBytes(), verificationSeed), 8); + long value = 0; + for (int i = 7; i >= 0; i--) { + long byteValue = verificationData[i]; + if (byteValue < 0) byteValue += 256; + value |= byteValue << (i * 8); + } + StringBuilder stringBuilder = new StringBuilder(); + for (int index = 0; index < 10; index++) { + if (index == 3 || index == 6) stringBuilder.append(" "); + stringBuilder.append(VerificationString.TABLE[((int) value) & 63]); + value >>= 6; + } + return stringBuilder.toString(); + } + + private static byte[] processRSA(AsymmetricKeyParameter key, byte[] data, boolean encrypt) throws InvalidCipherTextException { + OAEPEncoding cipher = new OAEPEncoding(new RSAEngine()); + cipher.init(encrypt, key); + return cipher.processBlock(data, 0, data.length); + } + + public static byte[] decryptRSA(RSAPrivateCrtKeyParameters key, byte[] data) throws InvalidCipherTextException { + return processRSA(key, data, false); + } + + public static KeyPair generateRSAKey() { + RSAKeyPairGenerator generator = new RSAKeyPairGenerator(); + generator.init(new RSAKeyGenerationParameters(BigInteger.valueOf(65537), new SecureRandom(), 2048, 8)); + AsymmetricCipherKeyPair ackp = generator.generateKeyPair(); + KeyPair keyPair = new KeyPair(); + keyPair.privateKey = (RSAPrivateCrtKeyParameters) ackp.getPrivate(); + keyPair.publicKey = (RSAKeyParameters) ackp.getPublic(); + return keyPair; + } + + public static byte[] combine(byte[] array1, byte[] array2) { + byte[] combined = new byte[array1.length + array2.length]; + System.arraycopy(array1, 0, combined, 0, array1.length); + System.arraycopy(array2, 0, combined, array1.length, array2.length); + return combined; + } + + private static byte[] produceCCMPrimitive(byte headerByte, byte[] nonce, short number) { + ByteBuf byteBuf = new ByteBuf(16); + byteBuf.putByte(headerByte); + byteBuf.putBytes(nonce); + byteBuf.putShort(number); + return byteBuf.getBytes(); + } + + private static byte[] produceIV(byte[] nonce, short payloadSize) { + return produceCCMPrimitive((byte) 0x59, nonce, payloadSize); + } + + private static byte[] produceCTRBlock(byte[] nonce, short counter) { + return produceCCMPrimitive((byte) 0x01, nonce, counter); + } + + private static byte[] blockCipherZeroPad(byte[] input) { + int modulus = input.length % 16; + if (modulus == 0) return input; + byte[] append = new byte[16 - modulus]; + for (int i = 0; i < 16 - modulus; i++) { + append[i] = 0x00; + } + return combine(input, append); + } + + public static byte[] encryptDataCTR(byte[] data, byte[] key, byte[] nonce) { + byte[] padded = blockCipherZeroPad(data); + int length = padded.length >> 4; + byte[] result = new byte[length * 16]; + TwofishEngine engine = new TwofishEngine(); + engine.init(true, new KeyParameter(key)); + for (int i = 0; i < length; i++) { + engine.processBlock(produceCTRBlock(nonce, (short) (i + 1)), 0, result, i * 16); + } + byte[] xor = byteArrayXOR(padded, result); + byte[] copy = new byte[Math.min(data.length, xor.length)]; + System.arraycopy(xor, 0, copy, 0, copy.length); + return copy; + } + + private static byte[] processHeader(byte[] header) { + ByteBuf byteBuf; + byteBuf = new ByteBuf(2 + header.length); + byteBuf.putShort((short) header.length); + byteBuf.putBytes(header); + return byteBuf.getBytes(); + } + + public static byte[] produceCCMTag(byte[] nonce, byte[] payload, byte[] header, byte[] key) { + TwofishEngine engine = new TwofishEngine(); + engine.init(true, new KeyParameter(key)); + byte[] initializationVector = new byte[engine.getBlockSize()]; + engine.processBlock(produceIV(nonce, (short) payload.length), 0, initializationVector, 0); + CBCBlockCipher cbc = new CBCBlockCipher(new TwofishEngine()); + cbc.init(true, new ParametersWithIV(new KeyParameter(key), initializationVector)); + byte[] processedHeader = blockCipherZeroPad(processHeader(header)); + byte[] processedPayload = blockCipherZeroPad(payload); + byte[] combine = combine(processedHeader, blockCipherZeroPad(processedPayload)); + byte[] result = new byte[combine.length]; + for (int i = 0; i < combine.length / 16; i++) + cbc.processBlock(combine, i * 16, result, i * 16); + byte[] result2 = new byte[8]; + System.arraycopy(result, result.length - 16, result2, 0, 8); + byte[] ctr = new byte[engine.getBlockSize()]; + engine.processBlock(produceCTRBlock(nonce, (short) 0), 0, ctr, 0); + return byteArrayXOR(result2, ctr); + } + + public static int calculateCRC(byte[] bytes) { + int crc = 0xffff; + for (byte b : bytes) { + crc = (crc >>> 8) ^ CRC.TABLE[(crc ^ b) & 0xff]; + } + return crc; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/DerivedKeys.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/DerivedKeys.java new file mode 100644 index 0000000000..57be969d94 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/DerivedKeys.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto; + +public class DerivedKeys { + + byte[] incomingKey; + byte[] outgoingKey; + String verificationString; + + public byte[] getIncomingKey() { + return this.incomingKey; + } + + public byte[] getOutgoingKey() { + return this.outgoingKey; + } + + public String getVerificationString() { + return this.verificationString; + } + + public void setIncomingKey(byte[] incomingKey) { + this.incomingKey = incomingKey; + } + + public void setOutgoingKey(byte[] outgoingKey) { + this.outgoingKey = outgoingKey; + } + + public void setVerificationString(String verificationString) { + this.verificationString = verificationString; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/KeyPair.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/KeyPair.java new file mode 100644 index 0000000000..ad993fac88 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/KeyPair.java @@ -0,0 +1,28 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto; + +import org.spongycastle.crypto.params.RSAKeyParameters; +import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters; + +public class KeyPair { + + protected KeyPair() { + } + + RSAPrivateCrtKeyParameters privateKey; + RSAKeyParameters publicKey; + + public byte[] getPublicKeyBytes() { + byte[] modulus = publicKey.getModulus().toByteArray(); + byte[] bytes = new byte[256]; + System.arraycopy(modulus, 1, bytes, 0, 256); + return bytes; + } + + public RSAPrivateCrtKeyParameters getPrivateKey() { + return this.privateKey; + } + + public RSAKeyParameters getPublicKey() { + return this.publicKey; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/VerificationString.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/VerificationString.java new file mode 100644 index 0000000000..7ba8024930 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsightLocal/utils/crypto/VerificationString.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.PumpInsightLocal.utils.crypto; + +class VerificationString { + + static char[] TABLE = new char[] { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/' + }; +} diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java index 69979508fe..b32e850ff1 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java @@ -35,6 +35,7 @@ import info.nightscout.androidaps.queue.commands.CommandBolus; import info.nightscout.androidaps.queue.commands.CommandCancelExtendedBolus; import info.nightscout.androidaps.queue.commands.CommandCancelTempBasal; import info.nightscout.androidaps.queue.commands.CommandExtendedBolus; +import info.nightscout.androidaps.queue.commands.CommandInsightSetTBROverNotification; import info.nightscout.androidaps.queue.commands.CommandLoadEvents; import info.nightscout.androidaps.queue.commands.CommandLoadHistory; import info.nightscout.androidaps.queue.commands.CommandLoadTDDs; @@ -42,6 +43,8 @@ import info.nightscout.androidaps.queue.commands.CommandReadStatus; import info.nightscout.androidaps.queue.commands.CommandSMBBolus; import info.nightscout.androidaps.queue.commands.CommandSetProfile; import info.nightscout.androidaps.queue.commands.CommandSetUserSettings; +import info.nightscout.androidaps.queue.commands.CommandStartPump; +import info.nightscout.androidaps.queue.commands.CommandStopPump; import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute; import info.nightscout.androidaps.queue.commands.CommandTempBasalPercent; @@ -239,6 +242,21 @@ public class CommandQueue { return true; } + public void stopPump(Callback callback) { + add(new CommandStopPump(callback)); + notifyAboutNewCommand(); + } + + public void startPump(Callback callback) { + add(new CommandStartPump(callback)); + notifyAboutNewCommand(); + } + + public void setTBROverNotification(Callback callback, boolean enable) { + add(new CommandInsightSetTBROverNotification(callback, enable)); + notifyAboutNewCommand(); + } + public synchronized void cancelAllBoluses() { if (!isRunning(Command.CommandType.BOLUS)) { MainApp.bus().post(new EventDismissBolusprogressIfRunning(new PumpEnactResult().success(true).enacted(false))); diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java index 7207f5b8d1..97a7e68521 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/Command.java @@ -25,7 +25,10 @@ public abstract class Command { READSTATUS, LOADHISTORY, // TDDs and so far only Dana specific LOADEVENTS, // so far only Dana specific - SETUSERSETTINGS // so far only Dana specific + SETUSERSETTINGS, // so far only Dana specific, + START_PUMP, + STOP_PUMP, + INSIGHT_SET_TBR_OVER_ALARM } public CommandType commandType; diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.java new file mode 100644 index 0000000000..0e67758b07 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandInsightSetTBROverNotification.java @@ -0,0 +1,32 @@ +package info.nightscout.androidaps.queue.commands; + +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpInsightLocal.LocalInsightPlugin; +import info.nightscout.androidaps.queue.Callback; + +public class CommandInsightSetTBROverNotification extends Command { + + private boolean enabled; + + public CommandInsightSetTBROverNotification(Callback callback, boolean enabled) { + commandType = CommandType.INSIGHT_SET_TBR_OVER_ALARM; + this.callback = callback; + this.enabled = enabled; + } + + @Override + public void execute() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump instanceof LocalInsightPlugin) { + PumpEnactResult result = ((LocalInsightPlugin) pump).setTBROverNotification(enabled); + if (callback != null) callback.result(result).run(); + } + } + + @Override + public String status() { + return "INSIGHTSETTBROVERNOTIFICATION"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.java new file mode 100644 index 0000000000..b6f29014d4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.java @@ -0,0 +1,34 @@ +package info.nightscout.androidaps.queue.commands; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.DanaRInterface; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpInsightLocal.LocalInsightPlugin; +import info.nightscout.androidaps.queue.Callback; + +public class CommandStartPump extends Command { + + public CommandStartPump(Callback callback) { + commandType = CommandType.START_PUMP; + this.callback = callback; + } + + @Override + public void execute() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump instanceof LocalInsightPlugin) { + PumpEnactResult result = ((LocalInsightPlugin) pump).startPump(); + if (callback != null) callback.result(result).run(); + } + } + + @Override + public String status() { + return "STARTPUMP"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.java new file mode 100644 index 0000000000..35bf48f3a4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStopPump.java @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.queue.commands; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpInsightLocal.LocalInsightPlugin; +import info.nightscout.androidaps.queue.Callback; + +public class CommandStopPump extends Command { + + public CommandStopPump(Callback callback) { + commandType = CommandType.STOP_PUMP; + this.callback = callback; + } + + @Override + public void execute() { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump instanceof LocalInsightPlugin) { + PumpEnactResult result = ((LocalInsightPlugin) pump).stopPump(); + if (callback != null) callback.result(result).run(); + } + } + + @Override + public String status() { + return "STOPPUMP"; + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_error.png b/app/src/main/res/drawable-hdpi/ic_error.png new file mode 100644 index 0000000000000000000000000000000000000000..5b57c7458fe6e0232f0b1d39c727dc0d713b0d69 GIT binary patch literal 543 zcmV+)0^t3LP)5W7?899m9(BsleB6keoid%NSbw7Ou{Mg zLfZK(#pUFA#6(^4aX53dF;$D`?4p@;gIsLnhUKggsXxDs z)_OS5jWv)LhO+_IK(G-EYFP!fgE&h}tb!&1hg}Z9DhLjygF4u*GmW#r7~73mkU^Vh zv?+reG;(CnDH@&1APYLPzDWDKm!?c ztpd7|K_@Dp6B*>FfE*cARRL8K9X}F))hESV_}Egqjmc5RWc4^>;g-r+SdKhTDuZ)5O8BIm zPbt~*rE6jNqPCuLDWtW)dn0LYRQ}D1Q(gl1iBq4Nxi$G74@BvnJ?3*}V}%AjLHRUT hp8ZcPva+(&`vtH|z}Y7)DLfCk&++Be+6*y<<0xNES4xCH`HcRlq1Z5UP_@u||TC_DJhVYmKy% z6hV@@6S}1$)<~_bksgyHSW&n&E0E^vaLNPlAuQ4`{CYzg z4bTAiL5h=*F%G|KYk=1Cvroju_>ZP*fNsJcq^9B%z432v?3`o(exwLEa65KT4)~AM z#+Tz?+E_vPh_5zLav)2rpwz@)=cqW4Sz?VB{-lUFDC|U>$E)5Eb1q5ju^7Bb5piIn z2B;Z&_0xF_enP74E4(HME+gMLJ-NL|NWjBMk>rB$Bh+8Yv4Gt&s|I#TqFW zXRVPkF`rM?R$O^bpw&XriTWJJt2bPah@=%I>A_ac@__H%XEzh5Lpm~ZLV=`N;w3rK zVQZv}!IK=xksQg99LbToStDH*u|+y3VvE#C#1d(u=%qlKBtb_;_Tkk~Nr*`2LFz4f zDUdpgUJ9f(qLl*alLAL0(lDQgoTIk5l185a;qb$sq~JPT00000NkvXXu0mjfdy3>L literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_reminder.png b/app/src/main/res/drawable-hdpi/ic_reminder.png new file mode 100644 index 0000000000000000000000000000000000000000..b45924d4eb9018306d8a8b8995031d2ce57d7028 GIT binary patch literal 1112 zcmV-e1gHCnP)`C3&Ck+fUM&+0*tQzw6*lGFVy5 z=1?^?Y)g}M0ZnXc@o*wJ23Qv`fE*`U4AgNue>>X(aUp-ZojU6p=H^*SGHhu9*q$6E z&oZ}#V<|pEU?j_!Cst()AfK_6g<(T}A!!EtnkNn+OVTfFX#UuXDI|?%i@+T^mZT}{ z<-ZK`Bz?;Ysl~ntSJREh`G6LtGnp3NIO!92c4^>gh$=^UP~S%)^27 zV>s0erw<1*j}X$n^gYX2Wo*XqN(-6I_<>MAuvx_gKAg?05?&%{U}+(95Yy<2 zX&h8u;6q7z*(zZXh9b|Geqk<0q`=qQ%V8{LMJ&Og+{;%K5V_3$!h*bt3}q3kjFlP7 z-|j3gijT>0H%1XSRHd1t#(ZId@Z7eHWb!7(z=;x zfis;PNJjU!Um#&q zGRRQs%?Bp~a*0`JAmL&_PVy`4TaZCCLFtI;~^HRe(Z8_*yZYsy%>hT7|x|W)$GY6FIWG4 zcDi|>nX8$Cz<21!GfodEKT_B0$L5LUc?6lrGFHaN9xF)LFBi+uVxXQ&1A~wj^T8I;##r*NSTeCr&n+;FT+U*$O1d@J;(y%(t!qGjXr6-kJdV#2;A88*rHa+*@L(=-i z7;!#8XKh^1a#b#m>u9I52P_V*L!`i0+?{BgFUg_Y$Cnfkxx(V%&{(5|XxNg0g!+L^ zEj}7Ji{beCjWemYxPC}?9xWrum0000 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_warning.png b/app/src/main/res/drawable-hdpi/ic_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..d7aa344bcad6ae43f5675e9b252bcf013e90e5b1 GIT binary patch literal 483 zcmV<90UZ8`P)qzp^y`55P(eplh|CjHbmWvL zqS8bsHi^h9OLXFrSEA8FXY3J)5<7Ip9VMbLMghk}ppFPzCu54t5n<;P$&?PdV22F( zV1q8W;e*T=qAMJd5mj`hRWhK!3|;Ar0;$tN32c!vZ>&%PSGi<<{6c)?B=-8@KiG4sjxu0dNqu`)t;4H6@a)X?37M9r8I z9D{s0qKzzrMB9`S9D{s0Vt{Oe#K4detb;_wkP-}oOgW;7?1MzpkP-}o3^}5QQnKev z2@ZFZoGHQK*qag@)}1NA;hdr~B{=LjQi9?3$#cXIWim(%4JpAoNK_3e!8&M0!I=^q zwwx&;tSLwIQ3U(Wl;AL!BPJ-4lR!#{Xd{pkA{fXKT@=}FASGmMAV-W)d>N6Glamu4 ZegJZ!Wb&e5Z_NMz002ovPDHLkV1l&*$%p^| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_error.png b/app/src/main/res/drawable-mdpi/ic_error.png new file mode 100644 index 0000000000000000000000000000000000000000..68a4b0e48c18f3f79cf1a71b0a8acb55b921e17e GIT binary patch literal 374 zcmV-+0g3*JP)YhE$S|XX$e%tUGPzpP^wpJPy*Klp3RI6}A=v`$Znp{+?^y%MhL0GYr zBIB14ZrQQ_KSrCTBf<(H${WA*Z@yFB0ikghidLP#TcA!LZMw0GfFd#sLjsHf0ModJ UWiB+#xc~qF07*qoM6N<$f=t$#-v9sr literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_maintenance.png b/app/src/main/res/drawable-mdpi/ic_maintenance.png new file mode 100644 index 0000000000000000000000000000000000000000..728313d9e724f3dc2c1711b6eed8cff32d1b287f GIT binary patch literal 413 zcmV;O0b>4%P)@NB{!`MHGk#F_ZyD0TmFS0tiBgk!AoSq6D&57K3RR!zv9V zJ3&(0y{=dP4?6%jk9B8EuulfrJJVu}4;Dj-pr$oo6ZmA=0%M)db~GRdK#Nrih!ic_yU>6#gb}0( zs;U7E_#sl!d*Dq2-uYeHz9U0eFB(wcZ<&ZaJZZosv=eLt;hkx~9%>sJkVI|9w0K0T z&bS6FfNvtN6C@O1kRoa|jfhe3O$>0N6U0r4S+3El5;rZT*yV~E0I%G#MS_w}NHH8i zjQS=jZiupPA{If!d=q6iM8!8T8bJ)ZAgY8{azVr+h#}v^y&IxNc<1*2NQ4tK&HNHa zX0C`jon`4US25l}Wa%{_fspqC(EtE)%3g>Go`F;PtgHG06Zz6r>lN2600000NkvXX Hu0mjfn(~|& literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_reminder.png b/app/src/main/res/drawable-mdpi/ic_reminder.png new file mode 100644 index 0000000000000000000000000000000000000000..2c269d553030af91e807bd6d2b3f3260463158ea GIT binary patch literal 733 zcmV<30wVp1P)#a^+dW!e|#nf7HE{@OMJO1|@ z==H1LET*#|=IatA=wiMhI!Ae0Eds;UMFI7OgGE}S9D93Ra(fhTm*jPOM=@vmOfpYX z6wqXz2#xHqbtW|(iZ z=W9b8A64#?@Qj9NOCK{OUpOx|a=Q77Om|9bN#r}mAuob5X!b&b%=1|Lb)UKJs}&GFEdG&}^*a(J1Bs z$>iFL0*D&wOp+WJMa%)bswpDBfkcy60ka~XizLTJ8$ibDB^N{F~x^&qU(A|^1B~6n7fXR`^d6HwJkUiZNRgRII7x~P}3OGq_z?l<894MKj zE=o{mvgCj$=CNNL^dE^b)Ei$qZ8@_xZ7D@B>yh-gMMmQFVr}A8nr3s5d}+KJ9AQV@ zb+cne>bPli^t`hAX^dZ?T>3u4sqtGl&CtvO_}#dUfhz%j1zkC z#Edjb^v04TmR!*ruPjNSL4VkgK!FSkK4iiX86KJN5qo6Io;b`oBU{eQ2~(jbd(e{= zK~~&cfg3AAw8#|@Ede&j9T1zy9OVy~BQ@se4~Ro#j{bl>Qe%$(fT$yL^y?of9SYic z=NNbEnqyeUNK0hcgA7aG9OD6VqzwuO93w4IN&C2Y+s2xwQH^grceC@v&iOICSD8#E zlgUJfZcHMFwH)9yw|GT4#k}S=r#Zk{a+pLHSwv%Iv4h8W@ra$wpoy$t0GlYluROLe zQ0bx$GdV#RCzwSYrGXZ#;5AWr$x2!%Nz`Bw?}^e|7E?pXpf9J1!)f{|eoUf}xD+x; zaiS)<#BEha>lF^;NZSMjM{C}awl}m^Q0&8ky$Xg=STS1uQJV*Zpx+S2ed@?B zmV%i8SnB`te_<-%A+_ZP3&B(XERY}EHWzSP-Z2u)1;7Y-#a@#Ed*uy{C^i{TL?d~@ zWUQJjFIb0F>*NJjvFfVaXo+Pl<-%Aj8!H!T`j#T%f+fqZPMF!);nA8g#Tac4>d`^$}gF_ULh&syzICkoxg$ zZsZcTTxuvzOr^l|0)!jAV_QM#oh<=*M+;UOU&C^v4zoE)7$=!c9i@wbY#~3;Dq=rb zK@(=N-TpGD_jTNZ-`8m4M66A3Tzq&Y-z z8X>!fgqtMRo$!o2x)Z#pqC3Gw7UvOO;Yp8(hqOb>qg-SL;;)P3);6)@^KvMuwLMK_kArL0)R&o&tzy`s^-*Xd6 z4p0ETBNP_72NmQ1-T1yY6c%_3y2=3-g9U=U`7limuoWy2?9GQAa)4uCfne`n4435q z*WovWycSMF4glQccfBI-Kbj90R#VI4=j-4i*UZ=EHW;&!`20z4!SV!K5toLHVLg{{0{{=%$1FONN_~hS!UXvY z;s0j{9rY*laR#A}lL&@j2!>z?hF}PWU+O2iTp z5)u+fIaCbdP<8^agaaggxP;yOVFeY% z5Gt~QKWyVHi4R^Oo7|>QL=2z^Q^+loyTvpL(-x<$5*kT##pz3u#2hLx8Fv>-NL+}! zeiRooIEEN*GPqR?;8rqlGl%LD9#^p!H(NMW4B=F^;ASHyN;tep4sI4uOI(n`soc%` zv|$W$Sw}kiSj${S(VF+Ti<8|KD{8R-H)&iiK~a>>xEn%Am!tSKV@b!$UPkko^T<+? zk+{j>O$ma^OvhavlJzalE6l^MS-eO&efDUMyUwJFKb*)q++^{fm-uG`($HMCU23f7EbRA*d6!drY)(t9(faphcQ&kb$NEiO>ObU4`?~OrRw$_ z6`m<;AXOM(~E;8AP%M%ZnC*XU3PuA zRKnpnES$1+do>|zv=u=oT!i_=An1W-5~3%d^`97?eZ zyZc3q1yFbpyImn~W!}QBgNV@p3LUU}D_lEk6Iwde;~Jm_X=s}$EJ1NEcAtwF51{Zl zc6Uoq3`5&ViMR(S!w$3|5)9SJL3>@qbO0ybK+B=J1i?#a7NsHyP>Kw+7bOV#qV*Js zTL6WgXuX5Az4xHq6k}%v^nAzE71;)G{8Y_0_Y}V&WHbO*}@G z7`Fs|jLr+ckUb{8a1Ak>h83(G#$#xG#4o-<`zAm~>0>gmv-pORz6+Ue#4jF2n-H-7 zJPfCG+~c#Ddo!|r~G6Ye+ifkWeC>@3cbIN($)>^_jNC_)UoEgUR{ zaWGqqedN=)!Rs??cvNQEzR1 z$cFwbZk71re755~cKPV~I)xNTNJvOX bNHFFn1F+K)LM65q00000NkvXXu0mjf)EBin literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_warning.png b/app/src/main/res/drawable-xhdpi/ic_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..652a1bb1d99edcf08613d38f5e64fed241e8060d GIT binary patch literal 543 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%&M7!1&D5#WAFU@y$U&o|XiO;}7pU zb{|qWKmBRdzNZuNe@=4-QoHj5_kC9AiMsH=>A|&Km)_sq_xvEkZkzL;_k6#%q2avU zfi+xjwR^f|UaV6)wnR)en&;Gw3x&#u=g9qiW4O#=Icr->&x;b3BRx{FYYdeV9mU0k zd|q6bFU$7iMOxqEIGz{J4sb7@`XaIOu#(!B0;NNdypJlI7YBtM`8-ubz4rF{WUZD) zjgCcytxP5f3S0&a{31sflon}yaXvgR`iz*h|H1YDcFuqMYx8-thwpBiUZ{1miDUlj zw7LKI!Fk4y3YWB`$@d@Ln||c62j^Kkxpr&ygUVlKF!fJxzWlLc@2iR-hHbg9LNNG)jrG4=*mfd34b_t3t;?_(O-FiEO`|SpP#FJC zZ~$Fk->~3i#TRDmOomwv?iLJIqWyp68jhzi`W{H$A1>R^=X*GLzw^f%@57EScE0@K xM*jQ97Z<*)cmwptR(+hyDKLfN(++PamyM^IUnycrSyH-vqSj3W~gV~jDz z7-NiKJ5J+4-k=xbnZ^QE(N2y3XlFGGn8tW|@)i$qI@>8E9L5uLU>=*;S~ceL6Hjrd ze8$e)$LB00i$#3Sz3eQ%(8LY=#9!p)Pk!bGn&bmc;T<+mgmt{jDRLPX(ubn;<9xY@ z>ljH{MslrO!nsVLY*RQ>E?`eSBcdK6K4W)P84Wx|3-z>-r)W?$aS&svg0UQ=>fvfy zsEQV@R+Z4i>qJyZ#2YlK8rYYSRMANGRsC@sOR1`*9Hsi=0@|sv7A{cza2x+nb^mai z>Vp@Ea6!bgDj#D_$_wdQP$`_|l zqcGYGic{lM<%!YYRUjCx{BS9F7YHs@UKr$Mph3z9XM&f3;B4iAp56xPsq8qB$lE{> zCn+o51#bhvyUK<})_Waj9ZkxDTfpl;aEr2_tM`GrC_Q%PU+)9`%N|OLM+m{AN{ep^ z!M93_b%bDz(&1=AakSFlSwiuw(x4-u=%_SUNGKL6IkqJv+bJndB_yXRDefaA_bDk} zAtbLTDLN3xUdI?rX|x%XXRwlDLQsJwC@E$J6=;T%Vrfu;mMSS)f(q24q=dh53yxI1zM)0m=#o@SxSmYK?Rzmq!<=dpkYdipMwh2K}qpaP=Q`jQrr_% zpnH@Qrvw$~6eY!WK?T}Y$+0k)Kns-y9fAqeL22-8FoB*?8XO%=pre%zYk~;0PHFL7 z5P`l^T09y=pvROJI|uP6&YhGVoxBg!Nm+1{_knIw7BsQW>p<&iw2N8dyrWolIn;@E zL0z04$^&P68|X~sgTY<~8mzoxJ8=7Qm5Y0vI!ZDn&TA1#*g+>HPFPHm7C9c zi$=w;0k-PlAjVS#W8x2EBj4{R-V~jBY`5*E5Ek0ea RJ^%m!002ovPDHLkV1gVD_UQls literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_maintenance.png b/app/src/main/res/drawable-xxhdpi/ic_maintenance.png new file mode 100644 index 0000000000000000000000000000000000000000..952e7b9ef35c47475220653d491440b752f007ef GIT binary patch literal 946 zcmV;j15NyiP)vtRH6wz=(Tfnqztcf4M&t*nhW@hcC5p$h?z9wJs5_mfX?8^+BdvV&HfB_g|ZyelF*=)#F2vRlC;=_Se|PJgGB=+0UJ#L80r!Z=ZX=h9$Ziq`ipcKg5YkJOL-EV!{PYst5`}0$uoDrliO6nz z@E4bIi6f%h{Q)&%wIia|-gu5DA6U(mPKb&))fdoL0Ki%|M5TQJje-P-HjsUDJ@H%s zkO0wj#UeV_56~yzkmw^nK&`+bQ3pRjYaupK1fU!a@xgNrfI*ZbkKN@yfS!W*L=kx4 zNgqIefI)O!(mY0A`2ebq)dqtoSstkB1E?EBAd1feoqYg}gSbT85`_oG`v95&F^RZ^ z97q$;0*F8qp9jYH09pbOh~o3WNFPA6Ap%i+9vJ2WXd+}lbW3a=qrpCa29ZfQ+!B|^ zsI3p6CXfYD@;p$=2he|z1yS-m@P-edHy|6L#ChOGA3#??c0>vDz;Ql+4x%tyqC|O? z1TQg!?ApjilB<4H+7UHee!BdpQTOarWx(078$c*Q(6A`~4B0I_< zB0DM}B0D~#NJM5lz7~ulqdL_8g!-C&e4n? zd5F`(u97C2WfS>NL?RNAh(xrH5zP{j8K;OyL?RNAh(uJ}L?ogUL}WKrL?RNAh(si! zJxVlJL}r{JA`yv5M0-0CiAY2u5|N0ebGV4?J`QFg8Wzk%lo!lIv?iE|sCNiyBU(tz z-U(@ob0QM8vAzxzQEQ7wM4c=i5p}ZON)wUEBO;SWMBObO5q0O#uqzQ|!Xu)-7LSPf zT8m>MGI>Na$l?*vAdU=bJJAyHm~l3f*cJ5U=&*Z=gLq>*(o|mJfKVb*N-3o_0c77- UK6?sHV*mgE07*qoM6N<$f=#%SKmY&$ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_reminder.png b/app/src/main/res/drawable-xxhdpi/ic_reminder.png new file mode 100644 index 0000000000000000000000000000000000000000..e918305ba092c40e2d95a761f82324aeb2f5b997 GIT binary patch literal 2238 zcmV;v2toIWP)7=l1L;Hi9{liNF)+5M^7%GSRzC*7tmAUiG}zUxL+c~{lK@3l=xvBa{++UB_f;& z0L)^X#0%Tg%ztew5nvbotC{U3E=X|!9W}9rgp4(4p`-KTQkb77Qx%I!h**j$GCdV} z!Db}iV)iS2B_s@>41>rEHshFu?k$Q#TG~HAH;YkG7iQi4p)KuR8reRI!h9b7er13- z#vp#h-??EI=BM!YRyb9NzPyFMr|2F(U%4A>%08(CGy` z^ui3aOvv)9F`6AXncI1TPx+B4RFS5cDk}MrPkD{oIEn2TMK8$$6R3p<3pOdv#a|`M z`Yy}sa|z#(i?6tVwf(-dEK4Q+&WW-xf5IS9(ThEJj9P-K<{@^byXTtriTi>byf8mP ziF(y+&Vw{yLoN3(S-YAj;i=FIHlvt@zca;%VO&ZTw$0%}28t19L5KyL?P9g2A;pOTo-2LiJ3xf#y`Xvf>*^cTnI&*OM&V_gX!3-cGeG_j|Iggt4(%REL(xG3fu zywtIlgow4M^I6Y|B~09mm${6RkTHt6c)4D}!? zafOS~%%M-L0_wvYH0Qf}yr@RAw@4HL>DU`h6@}sgTcY`eRO|vu@iUsu#RVQiv%5%C z0qNKs&7)!;y=cK~Iz_PzsEBEpwa{B^V}CSwr>B59N3Z?_+kiNK67!a5rWj zicK_OwrA`E+7q)Tv4_Rb42^w2!_h1%wor;$nMjNRQt$_6lf@Q}!0fra2w4ww1w#1=lnY(udE-Pf!sUBm{MedPX8 z<3OY8Fm#|+0E~YBfYe>PGe9yno!s0n! zKh+e78(iRX6d@!OaV+%!ToB+W!g=BfLuf#At%QmNc$i9h=sQ@72KtKw{{L`0VI*o$^b*+qu@<`?r5(7Mi?iO*45!9eNL?Xt4=xP}(?s2TovG547 zA+6{RmoQMsk3NkBBEl%@(0xN;c&$XdRI`jkfTfv>m$85D<|ZrY@kDT+MloN;4$E=nBx}Z6n9a`c(WJBhldw{N3iLO<+H6!Qagi zB?@^ZvPP5B12mcpAHDd2Y`n!Jiw7;=4A81HDvaPqvhxMoP$FGG3EKx~b{jSN^D)_~ z;Q_V{)Gm2j?x!|TyX5H6gO|xg15dM0mJPQDvlmYVXt*6O6megmmhJa+XxZM4ZVY89 z#{R2i``v+Bw%C4%DAP|DC6ywQO5tb5{X12kw_#Gi9{mtS1=||tv>qR>Hq)$ M07*qoM6N<$g1a_53IG5A literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_warning.png b/app/src/main/res/drawable-xxhdpi/ic_warning.png new file mode 100644 index 0000000000000000000000000000000000000000..7ab70f77c20c5a17d48442b1c1f79e3b3fbc8333 GIT binary patch literal 776 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q1xWh(YZ)^zFrD{waSW+od~;BdrzwEJ^eYx_*+m^=F^2>zF%gNyYwDq zNpLuU-xJ$Uuf=15h{Tjs(JR!Wr1@j2)m2sH?30Ggh#fMFw3_(6xI-N!@i1KK0{SC=i| z1G>Xe7UNokg#+?>89Oa;fB?d_v)-`vO2;RGxs%n$KU&MG919P%)sz-zgg2N ZAkexNJafUL1AnqWf}XB^F6*2UngBx>S`q*N literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_error.png b/app/src/main/res/drawable-xxxhdpi/ic_error.png new file mode 100644 index 0000000000000000000000000000000000000000..b8743474f785c4c966d093b1c1a43bb494b38ecb GIT binary patch literal 1477 zcmV;$1v>hPP)G0000GyNkl40*GZTC5us61C+qP}n=6GUWjP0y##x~aD?I&1!yH9nU!h8ROddm39L_|bH zL_|bHL_|bHqJmaz!4X_d8E-Ly8s;>K5xhk?S8^m<(#FIc8P1`Uw-`wcxth#K-lB}N z$XITK_ME~q{6tWG;2BP&tu2^P#IBSwhC&&`BkV?z%}v;ea{eL=zf-}EHl45{7chpf zjpjmD(86y=IW_oFLpkj%t>{cS4fs}1IUOx+=;(Xl&lRCVnsz%S)Dtyzl%!yHL<{bv zmZ+-XUYc7{QN*=OBgxK6StBUw^;OW8EJBvMGMD}Hpg3ZuqREVO%r=tG>~C3 zX*8MD%s-Z3BxyB>CCoP-Ce0o;zu2F&+u!`517k_Mv2^tJysIA|eJM5{xEY!1W(yzd z(uhpeNXEiNGln2D^`V)CiSv=!U0~s%B@>a^O`xTPg(vXF76N~suyC*`D8M{zW?|q1 z1(=Wbt?<|q6kxu#wnC$u0xZC%R#QYMkJUi|7TFpWG_F^G99(ZfW0(TuV3-Aq zH9-M#lCdChEs~pSElBi0a??H7v3gk~H(6G+pl}qDyCe1GV^Z!3F$T%q7z+l?k^Ho< zAaE#>pTjH&+=k@mRto~JAwC~Z@(q%ougx9HBKcd+T(JR?zxB-(2O{}9z+7<=lD`Yh z6%Qdk2R!jS`OpKIsh&4iyrTdP-Z5A7Qve73%oSfLfP*j16~8HfgI~=R;}pQbSaU_K z0ywBKSGZ6B%oS41AuV@bQQbTEH3SC<3LFCHPy9x>lof)S+ENR}}F z=t3=NR7=L9fxT%WZJOBAqJ!f}n`10mxPmmf!lH*;bmi+AC8WW9=8+PVShP{DA9N~# z|Fz#QZXk(nu=wC;8c31`j<$GVd;TUV{$hKJA3D&FBrgr;?7AR2!+of!#7rO?8bzg}?0+gb#T8NUQmN zU_RaADSW^#@ezyo<@gyU2lw)b0Yz<;+dYN%9QH`O#B$!y1t?tm1*o{7ZidCdX+W{m zG~UT-KROZ*E#b`L5LUmT+p)j+AYn7@1*b^ znMy-7hhHp{-NW86#tQk&)H@hAQMCWU)#opTY=kWhB}89zupD-G({T>B6ka1ES!lCD z$iQZa_mHpFt z=lxTA!2*_FKOcTP(e`|SEvLlpr=JgRp2)l2(OSsB?ES^5{HH&diA-^@x8Eao^MjJf zjD(!Of1cQ@9Y{8LWqT~_{QaZM6M4&>9XY>zKCC;D_qr39bu^RzxX1*cCK;id8*EMH zCVY9pw)nH$+ijUChd-ITU%QS|V(#{g{YRCgm$iW1XJ{lhNk@FDgWZ4giGuzPft*V| zAC8?UxZF9B(@pFgzq^ZDjzeLb_&NS=7q=d-bPdCRCr7+Xnyi(y`qZ&D;cXP?B-hSmUib2OOTFFo#?fbe;ogC{hVldaF>Q9W9`Q#VULXp zNqz;Zg*^<#?prpBNGm;K*$$)+e{KW{*{Z5fNGd)u=RuCu$zv0F{}!|Z1vSnC<&{77 z0hwy~){P>IKe8p&DOVlgT=JrS@mzxeJ z`1(ZG&&o5LMV(C?cZ$zg*jvFufBXxk0L5p(WM>FJ@t^STTZ3PM-vgFojzA&_%zVb;x8OO8 zmR~^<)R-IZZ=B^ka^n`~9ET&EeY}S1H*}WFd7#b4uc>}R56GG~p{S|f`4ndzho*Xk zE>PeLP(X6A^|51f|Nkj(Vt=8ZGUtIK8?U5##e~MgESxs`6&jz5t9oB4}P)&HK;W{pRWGl&nKXU9@C$l>+&*h z|2f8EbJTvS#gw{5wLNwbEuSlA=2x~bOX!0Oo-?mL8L!`QYlYdC>Q6X literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_reminder.png b/app/src/main/res/drawable-xxxhdpi/ic_reminder.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa4e934d0290ca196fdf74742fa9cd689b4b4f9 GIT binary patch literal 3012 zcmV;#3p@0QP)G0000Y%NklCLn` z=}FiBHlAMR+`pIx>4+oSr04AaML{+6>#C};Y+*neFdGR$%Q>tg*vc`}-(zS>(XtF= zQ~E@H9o7gLWC5-6`^1!?yjVnyWX;(tNlm6wvKoto@?i%#o%_LrAwyJnU*~c*3*|sR z7c0cu*(pi&^{_&mnfX9g;ZX(1R!Qpgi051pvdg4C5Fr~SsV&9$z@*s?-byjr?G-Y> z?c!9LKV*;1>B@qXR5tU}PYlB2JqPda8CfL7X4W z6$)gKMI7Q$ExN1G1NJwc{t@+Dn>feoQ~Kb&E1mVy5F5Bxvtp}vyEP3+X<@y~(9FeE ze8pfs=c$#ZpPXU#6!!GIVf@m~4E!k086&Hijb&dSD3#akX0#%9wSe!;71C!dEs}|E z4U}%>)Bkpc)VpxLsRHvZRsuXXiZ#R$MC#7QtOF2tnm9IHWZIX(jC{b ztcS(xuukIE@_PSuNJx+C3%fyOSvj$8GFvDCv$;vERttv&_V-WMhcp@Fm66{eG@B-I z-ZW2%$7x;@r^ZYnfmJjBo;N6@%Xq%V=cWw_OzcN7s_k6*F+ct6q(+QyO%M{8@sD?9 ztdKsl`kB3Z0FPu@z%cx0HanBG&8%(PzP5djZQHhO+qSK>uGfy|yVf};RW(VvySkJ2 zF@rCuo~OF-Jgp3S;#ZK1+i9(c(1zQ|#b-2CC1}el3{cca@iOj;*rHSB2UnSdvTRzy8J{ZHsk72^5hZnxD;0#Xea-W&)c{< zO&;PrT)j+6zTtFS?JrMpB(6@9Ul>dlH+!mDsDx?+d*Y^?e)5U)@N>N6a{!6sar3fY zJ0#s)E%_cm;%eOdP=25}>v8b_saOO^@c=IVNE7*hOK|ZzX~~lS7NmI{7w5+3@w2vlyE)x+w~r ziQRa~=Kyw0@N{;U6zj0LRq{Q69k*ih2l5m)=3_S~5dj8aH&xl~Rb!=W#c*szO**a2*3Sj@t zS4M%t!rbU)%Bh40YbIveSa1&zxv zJ3r9@&d2OB1&zBf+da_%cE{{a1&zlso0sSSbAum%EqDd935gCc0kc;WG(N;^aH0bY z!R$i?jn$YHCOSYNW~&r5He%K~(E-|Ewn0H7i&;UU0~BCZp`cNMSvt`H(wLPfXl%f& zRiXp5!fZpWeF*a~-92~+uU63b2(uv(1%P5srXb>vp&uz|yo%XG1q!pZd|LrxB4)2D zXgnG1i)rkhp|1kMJj|X{(6}esMXIrd#u|S?QeMhiP{;$gTFwG1$yg7-&ouv%?etx^q9SwsA1| z$_a;JRz@R*gV!;8M|RN1BL`$p|p3`VP%DQ)#ESje-|DPMwiNho59P^e4LHlczK01M^eOpZJ@D? z7?0hViUQp!b3eG%A9Up&{_O`cBA>OlmJjD#tytu-|jv-{R z+e|0<&&NxA?6?>gZ;)0@kmeO!oGTyDB>0Qm>>{|xZ9PpAc$H!FxEeP5$dAPfm zCh`Q0xD!`drpaHNiMy2ymIoNjQrsOUpOMe2xGUl}iWtA57caa+9)El zZQn}pNU;Z7$i<)OsCZxmJFu|qTL~Cr`Iy{nW02y5S(KBjyBQwR zL-#InRmLR63qPYOo@Jf_#9W@HD!!xm;g?iU6^r>b4OPQv$glZ?swm|!`ZL9Kl4=sv^=%;0QjU>VD5a#T(sNPW2S?GH0-e&T>R2 z7I7LcQbP57Onb#2EqRWbv5DuokY6!{5%i@q&8bg)n$wBCj9@Ci;sTyy3pL|0nkX5l z$7#e%1;>)7Bw;>Vh>ML(Rr1i44~c^}>7-;L!{zub%LU{s$r#J~`090rD)~sU8=LUW zpZKY24_b0575Ji*vuUK-hQZw7L4-1Hq_=7-`fx2}M5TyJ>8jd}E?h_vVcW);w9`M; zp)H58jIeyjfwa)))nPnWvW*~Z9wyvF-1VGZlpPB~?4V;yT) z%=^5?qnypp7)j=@?ZGht0002OAp57b#tvWr0000001*d0NN*nmPs4Qp0000eBBo+mIZ`q4wNR8!S?et~APd`B)b%T77j zR8iQt=|!_MhGJgU3??c0PVwz%unip=3zj4~rNl)tVllG0TAFB?ArC z1lk~>^)Q)h>IcJCuOAXX!+n6#O{XN}gVChhynf6;(hZU}1nL$6>gECJ21?%m>V5;% z{S9dNe^#yfH@6LWfsxg0@PD0pV|RAKV#j0dC)!SZ5ZtuTsAfr%m!!O+wANvSP)p7V z9=t*mxwKLt8doj|I_9pmV#-IL(9_QoU#*yO-hI{LAUpY$eO^CnmRJ!h*kYyi_VYw5 zd#&T=WJMJ@8XN_}cwL!{0~%OF7Bq-0U=Ulty!MOGk7H}hH*aPX`FA{@ui)p4MM4pF zOlS4vV?!35cHejP>Edp$lAkBazdTN^PPVuE^fBP%`cKg6|LRRM OL0nH)KbLh*2~7Ye^0Hk3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_insight_alert.xml b/app/src/main/res/layout/activity_insight_alert.xml new file mode 100644 index 0000000000..043fbaebe3 --- /dev/null +++ b/app/src/main/res/layout/activity_insight_alert.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + +