Index: denali.pro
===================================================================
diff -u -r90e68000c37bc14b0dfd5f18caf425c24cc0b5f4 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- denali.pro (.../denali.pro) (revision 90e68000c37bc14b0dfd5f18caf425c24cc0b5f4)
+++ denali.pro (.../denali.pro) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -5,6 +5,9 @@
QMAKE_CXXFLAGS += -Wall -Werror -Wextra -Wimplicit-fallthrough=3 # -save-temps # see .ii
# -Wpedantic -Wconversion -Wshadow # these can't always be used, since it gives errors in Qt library.
+TRANSLATIONS += denali.ts
+
+
#CONFIG += disable_crc
disable_crc {
message( *** IMPORTANT : DISABLED CRC CHECK *** )
Index: denali.ts
===================================================================
diff -u
--- denali.ts (revision 0)
+++ denali.ts (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -0,0 +1,5435 @@
+
+
+
+
+ AlarmListDialog
+
+
+ Alarm list
+
+
+
+
+ ApplicationController
+
+
+ %1 Initialized
+
+
+
+
+ ApplicationPost
+
+
+ The POST log file could not be read.
+
+
+
+
+ BPHREntry
+
+
+ Blood Pressure
+
+
+
+
+ mmHg
+
+
+
+
+ Heart Rate
+
+
+
+
+ BPM
+
+
+
+
+ BackButton
+
+
+ BACK
+
+
+
+
+ Bluetooth::BluetoothInterface
+
+
+ %1 Initialized
+
+
+
+
+ BCUFF Battery: %1
+
+
+
+
+ Can::CanInterface
+
+
+ Connected
+
+
+
+
+ %1 Initialized
+
+
+
+
+ Device Creation
+
+
+
+
+ Connection
+
+
+
+
+ Disconnected
+
+
+
+
+ %1 '%2[%3]', %4
+
+
+
+
+ Can::FrameInterface
+
+
+ %1 Initialized
+
+
+
+
+ Can::MessageAcknowModel
+
+
+ %1 Initialized
+
+
+
+
+ Can::MessageDispatcher
+
+
+ %1 Initialized
+
+
+
+
+ Out of Sync : %1 , %2
+
+
+
+
+ Ack Req, Sq:%1, ID:%2
+
+
+
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckReq : %1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
+ ,%1,Ack Bak, Sq:%2
+
+
+
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
+ ,%1,Ack Req, Sq:%2, ID:%3
+
+
+
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckReq : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
+ Ack Bak, Sq:%1, Dst:%2
+
+
+
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
+ Can::MessageInterpreter
+
+
+ Unhandled Message ID (HD)
+
+
+
+
+ Unknown transmit Message with ID '%1'
+
+
+
+
+ CheckListView
+
+
+ Complete!
+
+
+
+
+ CloudSyncController
+
+
+ %1 Initialized
+
+
+
+
+ CS Unknown Error
+
+
+
+
+ CS The device registration failed
+
+
+
+
+ CS Invalid Device State
+
+
+
+
+ CS The treatment report delivery failed
+
+
+
+
+ CS The device check-in failed
+
+
+
+
+ CS The device decommissioning failed
+
+
+
+
+ CS Invalid UI Message CRC
+
+
+
+
+ CS DRT device registration failed
+
+
+
+
+ CS Patient association failed
+
+
+
+
+ CS New token certification failed
+
+
+
+
+ CS Token verification failed
+
+
+
+
+ CS Cloud device validation failed
+
+
+
+
+ CS Patient ID does not exists
+
+
+
+
+ CS Temporary patient ID creation failed
+
+
+
+
+ CS Save credentials failed
+
+
+
+
+ CS Unknown device state
+
+
+
+
+ CS Config file save failed
+
+
+
+
+
+ CS Log upload failed
+
+
+
+
+ CS The device factory reset failed
+
+
+
+
+ CS The log retention failed
+
+
+
+
+ CS Out buffer file does not exist
+
+
+
+
+ CS Out buffer empty
+
+
+
+
+ CS Incorrect header
+
+
+
+
+ CS Incorrect timestamp
+
+
+
+
+ CS Incorrect sequence
+
+
+
+
+ CS Incorrect CRC
+
+
+
+
+ CS Incorrect ID
+
+
+
+
+ CS Incorrect parameter count
+
+
+
+
+ CS Invalid ID
+
+
+
+
+ CS Mismatch parameter count
+
+
+
+
+ CS Missing parameter
+
+
+
+
+ CS No history available
+
+
+
+
+ CS Duplicate data
+
+
+
+
+ CS The log folder cannot be created.
+
+
+
+
+ CS Error writing to the input file.
+
+
+
+
+ CS The credentials file does not exist.
+
+
+
+
+ CS The credentials folder is incorrect.
+
+
+
+
+ CS No credential file name provided.
+
+
+
+
+ CS The credentials folder is empty.
+
+
+
+
+ CS No Treatment Code provided.
+
+
+
+
+ CS The provided Treatment Code is empty.
+
+
+
+
+ CS No Log Name provided.
+
+
+
+
+ CS The provided Log Name is empty.
+
+
+
+
+ CS Not Sent, Device not registered.
+
+
+
+
+ CS No Log Retention summary provided.
+
+
+
+
+ ConfirmButton
+
+
+ CONFIRM
+
+
+
+
+ ConfirmDialog
+
+
+ Are you sure?
+
+
+
+
+ CANCEL
+
+
+
+
+ CONFIRM
+
+
+
+
+ ID
+
+
+
+
+ ConfirmTreatmentTable
+
+
+ New Treatment
+
+
+
+
+ PRESCRIPTION
+
+
+
+
+ OPERATING PARAMETERS
+
+
+
+
+ Blood Flow Rate
+
+
+
+
+ Dialysate Flow Rate
+
+
+
+
+ Duration
+
+
+
+
+ Heparin Dispensing Rate
+
+
+
+
+ Heparin Bolus Volume
+
+
+
+
+ Heparin Stop Time
+
+
+
+
+ Saline Bolus Volume
+
+
+
+
+ Heparin Type
+
+
+
+
+ Acid Concentrate
+
+
+
+
+ Bicarbonate Concentrate
+
+
+
+
+ Dialyzer Type
+
+
+
+
+ Dialysate Temperature
+
+
+
+
+ Blood Pressure Measure Interval
+
+
+
+
+ Device::DeviceController
+
+
+ %1 - Device or resource busy (%2)
+
+
+
+
+ %1 - %2 (%3 , %4)
+
+
+
+
+ Encrypted Partition %1 started.
+
+
+
+
+ Factory Reset started.
+
+
+
+
+ Decommissioning started.
+
+
+
+
+ USB unmount started.
+
+
+
+
+ USB mount started
+
+
+
+
+ Device::DeviceError
+
+
+ The device script abnormal exit.
+
+
+
+
+ The device script file is not found.
+
+
+
+
+ The device script file is not executable.
+
+
+
+
+ The request is already in progress.
+
+
+
+
+ The requested value is out of range.
+
+
+
+
+ The requested value is incorrect.
+
+
+
+
+ The response value is incorrect.
+
+
+
+
+ The watch file cannot be created.
+
+
+
+
+ The watch file is not found.
+
+
+
+
+ The watch file cannot be added.
+
+
+
+
+ The Bluetooth cuff pair clear error.
+
+
+
+
+ The Bluetooth cuff pair query error.
+
+
+
+
+ No paired Bluetooth cuff found.
+
+
+
+
+ The Bluetooth cuff pair invalid address.
+
+
+
+
+ The Encrypted Partition error.
+
+
+
+
+ DiagnosticsDialog
+
+
+ ROP
+
+
+
+
+ DRP
+
+
+
+
+ Prssr
+
+
+
+
+ Rsrvr
+
+
+
+
+ Heatrs
+
+
+
+
+ CANerr: %1
+
+
+
+
+ LoadCl
+
+
+
+
+ Tmprtr
+
+
+
+
+ Conduct
+
+
+
+
+ Air Status
+
+
+
+
+ DG Mode
+
+
+
+
+ BP
+
+
+
+
+ DPi
+
+
+
+
+ UF/DPo
+
+
+
+
+ Prsr Oc
+
+
+
+
+ Syringe
+
+
+
+
+ HD Mode
+
+
+
+
+ Vlv
+
+
+
+
+ BLD
+
+
+
+
+ Alarms
+
+
+
+
+ PreTx States
+
+
+
+
+ DisinfectStack
+
+
+ Disinfection
+
+
+
+
+ Water Flush
+
+
+
+
+ Heat Disinfect with Active Cool
+
+
+
+
+ Chemical Disinfect
+
+
+
+
+ Chemical Flush
+
+
+
+
+ RO Permeate Sample
+
+
+
+
+ Heat Disinfect
+
+
+
+
+ EndTreatmentAdditional
+
+
+ Saline Bolus
+
+
+
+
+ EndTreatmentEndStack
+
+
+ Treatment Complete
+
+
+
+
+ START RINSEBACK
+
+
+
+
+ Treatment Complete Paused
+
+
+
+
+ EndTreatmentRecirculateStack
+
+
+ BACK TO RECIRCULATE
+
+
+
+
+ END TREATMENT
+
+
+
+
+ RESUME TREATMENT
+
+
+
+
+ Recirculate Disconnect
+
+
+
+
+ Recirculate
+
+
+
+
+ Recirculate Stopped
+
+
+
+
+ Recirculate Reconnect
+
+
+
+
+ EndTreatmentRinseback
+
+
+ Rinseback
+
+
+
+
+ End
+
+
+
+
+ Decelerate
+
+
+
+
+ Resume
+
+
+
+
+ Pause
+
+
+
+
+ Accelerate
+
+
+
+
+ EndTreatmentRinsebackComplete
+
+
+ Rinseback Complete
+
+
+
+
+ END TREATMENT
+
+
+
+
+ RECIRCULATE
+
+
+
+
+ SALINE BOLUS
+
+
+
+
+ (50mL)
+
+
+
+
+ EndTreatmentRinsebackInit
+
+
+ Rinseback Setup
+
+
+
+
+ END TREATMENT
+
+
+
+
+ START RINSEBACK
+
+
+
+
+ EndTreatmentRinsebackReconnect
+
+
+ Rinseback Reconnect
+
+
+
+
+ END TREATMENT
+
+
+
+
+ ExportButton
+
+
+ Export
+
+
+
+
+ Gui::GuiController
+
+
+ %1 Initialized
+
+
+
+
+ MainHome
+
+
+ CREATE TREATMENT
+
+
+
+
+ MainStack
+
+
+ SERVICE MODE
+
+
+
+
+ MainTimer
+
+
+ %1 Initialized
+
+
+
+
+ ManagerStack
+
+
+ Treatment Management
+
+
+
+
+ NotificationBar
+
+
+ ID
+
+
+
+
+ NotificationDialog
+
+
+ Notification
+
+
+
+
+ RESUME
+
+
+
+
+ RINSEBACK
+
+
+
+
+ END TREATMENT
+
+
+
+
+ OK
+
+
+
+
+ ID
+
+
+
+
+ PostTreatmentBase
+
+
+ Disconnection
+
+
+
+
+ Review
+
+
+
+
+ Disposables
+
+
+
+
+ Disinfection
+
+
+
+
+ PostTreatmentReview
+
+
+ NEXT
+
+
+
+
+ Code:
+
+
+
+
+ PostTreatmentStack
+
+
+ Patient Disconnection
+
+
+
+
+ Treatment Review
+
+
+
+
+ Disposables Removal
+
+
+
+
+ PowerItem
+
+
+ Cannot shutdown during 'Treatment'
+
+
+
+
+ System is shutting down
+
+
+
+
+ PreTreatmentBase
+
+
+ Create
+
+
+
+
+ Sample
+
+
+
+
+ Consumables
+
+
+
+
+ Disposables
+
+
+
+
+ Prime
+
+
+
+
+ BP/HR
+
+
+
+
+ Ultrafiltration
+
+
+
+
+ Connection
+
+
+
+
+ Start
+
+
+
+
+ PreTreatmentConfirm
+
+
+ Code:
+
+
+
+
+ PreTreatmentConnectionStack
+
+
+ CONFIRM
+
+
+
+
+ BP/HR
+
+
+
+
+ CONNECTION
+
+
+
+
+ Press CONNECTION to pair a Bluetooth Pressure Measurement Cuff.
+
+
+
+
+ Press START on Blood Pressure Measurement Cuff to display reading or enter vitals manually
+
+
+
+
+ Bluetooth Cuff
+
+
+
+
+ Ultrafiltration Setup
+
+
+
+
+ Patient Connection
+
+
+
+
+ CONTINUE
+
+
+
+
+ Start Treatment
+
+
+
+
+ START
+
+
+
+
+ PreTreatmentConsumablesStack
+
+
+ Consumables Installation
+
+
+
+
+ Consumables Self Test
+
+
+
+
+ Self Test Complete!
+
+
+
+
+ BiCarb Pump Check
+
+
+
+
+ Acid Pump Check
+
+
+
+
+ PreTreatmentCreate
+
+
+ RESET
+
+
+
+
+ PREPOPULATE
+
+
+
+
+ PRESCRIPTION
+
+
+
+
+ Blood Flow Rate
+
+
+
+
+ Dialysate Flow Rate
+
+
+
+
+ Duration
+
+
+
+
+ Heparin Dispensing Rate
+
+
+
+
+
+
+
+
+
+ OFF
+
+
+
+
+
+
+ ON
+
+
+
+
+ Heparin Bolus Volume
+
+
+
+
+ Heparin Stop Time
+
+
+
+
+ Saline Bolus
+
+
+
+
+ OPERATING PARAMETERS
+
+
+
+
+ Heparin Type
+
+
+
+
+ Acid Concentrate
+
+
+
+
+ Bicarbonate Concentrate
+
+
+
+
+ Dialyzer Type
+
+
+
+
+ Dialysate Temperature
+
+
+
+
+ Blood Pressure Measurement Interval
+
+
+
+
+ PreTreatmentCreateStack
+
+
+ Patient ID
+
+
+
+
+
+ CONTINUE
+
+
+
+
+ SKIP
+
+
+
+
+ Create a Custom Treatment
+
+
+
+
+ Confirm Treatment
+
+
+
+
+ PreTreatmentDisposablesStack
+
+
+ System Self Test
+
+
+
+
+ Cartridge Installation
+
+
+
+
+
+
+ NEXT
+
+
+
+
+ Cartridge Connection
+
+
+
+
+ Heparin Syringe
+
+
+
+
+ Saline Bag
+
+
+
+
+ CONFIRM
+
+
+
+
+ PreTreatmentPrimeStack
+
+
+ Begin Prime
+
+
+
+
+ Self Test Complete!
+
+
+
+
+ Occlusion Sensor Check
+
+
+
+
+ Cartridge Install Checks
+
+
+
+
+ Pressure Leak Check
+
+
+
+
+ Priming Heparin Line
+
+
+
+
+ Syringe Pump Occlusion Check
+
+
+
+
+ CONTINUE
+
+
+
+
+ Priming
+
+
+
+
+ Priming Complete!
+
+
+
+
+ Start Prime
+
+
+
+
+ Blood Circuit Priming
+
+
+
+
+ Dialysate Circuit Priming
+
+
+
+
+ Wet Self Tests
+
+
+
+
+ PreTreatmentUltrafiltration
+
+
+ Ultrafiltration Volume
+
+
+
+
+ PreTreatmentWaterSampleStack
+
+
+ Flushing Carbon Filters for Water Sample
+
+
+
+
+ NEXT
+
+
+
+
+ Water Sample
+
+
+
+
+ WATER SAMPLE
+
+
+
+
+ Water Sample Result
+
+
+
+
+ FAIL
+
+
+
+
+ PASS
+
+
+
+
+ Water Sample Result Failed
+
+
+
+
+ OK
+
+
+
+
+ PressureRangeSlider
+
+
+ LOW
+
+
+
+
+ HIGH
+
+
+
+
+ QObject
+
+
+ Application terminated by SIGINT
+
+
+
+
+ Application terminated by SIGTERM
+
+
+
+
+ Unknown device error %2 [%1]
+
+
+
+
+ Device error [%1]
+
+
+
+
+ Removed previously paired device(s).
+
+
+
+
+ The Encrypt Partition Command Complete.
+
+
+
+
+ Paired BCuff Query %1 %2
+
+
+
+
+ The Factory Reset Command Complete.
+
+
+
+
+ The Decommissioning Command Complete.
+
+
+
+
+ The USB (un)mount Command Complete.
+
+
+
+
+ Indication for when no alarms is a possible situation.
+
+
+
+
+ HD stuck button POST failure.
+Stop or Off button detected to be pressed for at least 1 second during test shortly after power up.
+
+
+
+
+ HD FPGA POST failure.
+
+
+
+
+ DG FPGA POST failure.
+
+
+
+
+ HD Watchdog POST failure.
+
+
+
+
+ DG Watchdog POST failure.
+
+
+
+
+ HD UI communication POST failure.
+UI failed to communicate within a reasonable time after power up.
+
+
+
+
+ HD RTC battery low.
+
+
+
+
+ HD accelerometer failed POST.
+
+
+
+
+ DG accelerometer failed POST.
+
+
+
+
+ HD blood leak sensor setting embedded mode failure.
+
+
+
+
+ HD dialysate temperature below target temperature or below safety temp.
+
+
+
+
+ HD firmware image integrity POST test failed.
+
+
+
+
+ DG firmware image integrity POST test failed.
+
+
+
+
+ DG invalid usage record CRC.
+
+
+
+
+ HD dialysate temperature above high safety.
+
+
+
+
+ HD alarm audio failed POST.
+
+
+
+
+ HD UI POST failed.
+
+
+
+
+ HD didn't get ACK on message to DG that required acknowledgment.
+
+
+
+
+ HD dialysate temperature above target temperature.
+
+
+
+
+ DG conductivity sensors invalid calibration record.
+
+
+
+
+ DG drain line volume invalid calibration record.
+
+
+
+
+ DG reservoirs invalid calibration record.
+
+
+
+
+ DG acid concentrate calibration record.
+
+
+
+
+ DG bicarb concentrate calibration record.
+
+
+
+
+ DG accelerometer invalid calibration record.
+
+
+
+
+ HD accelerometer invalid calibration record.
+
+
+
+
+ HD blood leak sensor zero and self test sequence failed.
+
+
+
+
+ DG two wire sensors FPGA fault.
+
+
+
+
+ HD heparin force sensor invalid calibration record.
+
+
+
+
+ HD Software fault.
+Software found itself in an unexpected state.
+
+
+
+
+ HD blood pump failed motor controller current check.
+Too high when pump should be off or out of range when pump should be running.
+
+
+
+
+ HD blood pump failed motor off check.
+Measured speed while commanded off.
+
+
+
+
+ HD blood pump failed motor direction check.
+Measured vs commanded.
+
+
+
+
+ HD blood pump failed rotor speed check.
+Mismatch with rotor and motor speeds.
+
+
+
+
+ HD dialysis inlet pump failed motor controller current check.
+Too high when pump should be off or out of range when pump should be running.
+
+
+
+
+ HD dialysis inlet pump failed motor off check.
+Measured speed while commanded off.
+
+
+
+
+ HD dialysis inlet pump failed motor direction check.
+Measured vs commanded.
+
+
+
+
+ HD dialysis inlet pump failed rotor speed check.
+Mismatch with rotor and motor speeds.
+
+
+
+
+ HD dialysis outlet pump failed motor controller current check.
+Too high when pump should be off or out of range when pump should be running.
+
+
+
+
+ HD dialysis outlet pump failed motor off check.
+Measured speed while commanded off.
+
+
+
+
+ HD dialysis outlet pump failed motor direction check.
+Measured vs commanded.
+
+
+
+
+ HD dialysis outlet pump failed rotor speed check.
+Mismatch with rotor and motor speeds.
+
+
+
+
+ DG main primary heater FPGA fault.
+
+
+
+
+ HD UI communication timeout.
+
+
+
+
+ HD too many bad communications CRC.
+
+
+
+
+ HD didn't get ACK on message to UI that required acknowledgment.
+
+
+
+
+ DG maximum RO Pump PWM exceeded.
+
+
+
+
+ HD ultrafiltration volume accuracy error during treatment.
+
+
+
+
+ HD FPGA communication down for too long.
+
+
+
+
+ DG FPGA not accepting commanded valve states.
+
+
+
+
+ HD blood pump failed motor speed check.
+Measured vs commanded.
+
+
+
+
+ HD dialysate inlet pump failed motor speed check.
+Measured vs commanded.
+
+
+
+
+ HD dialysate outlet pump failed motor speed check.
+Measured vs commanded.
+
+
+
+
+ HD critical data integrity check failed.
+
+
+
+
+ DG critical data integrity check failed.
+
+
+
+
+ HD accelerometer error (no readings or FPGA reports error).
+
+
+
+
+ DG accelerometer error (no readings or FPGA reports error).
+
+
+
+
+ HD valve homing failed.
+
+
+
+
+ HD valve transition time out.
+
+
+
+
+ HD valve not functional.
+
+
+
+
+ HD valve current out of range.
+
+
+
+
+ HD valve position out of target.
+
+
+
+
+ HD syringe pump prime timeout.
+
+
+
+
+ DG barometric pressure sensor out of range.
+
+
+
+
+ HD DG requests DG command with invalid parameter fault.
+
+
+
+
+ HD blood leak sensor set point set failure.
+
+
+
+
+ HD blood pump occlusion self-test failure alarm.
+
+
+
+
+ HD active reservoir recirculation out of range.
+
+
+
+
+ HD blood leak sensor invalid calibration record.
+
+
+
+
+ HD arterial pressure self-test failure alarm.
+
+
+
+
+ HD venous pressure self-test failure alarm.
+
+
+
+
+ HD No load cell data message receive at least once every 2 seconds.
+
+
+
+
+ HD No dialysate temperature data message receive at least once every 2 seconds.
+
+
+
+
+ DG inlet UV reactor is on with no flow.
+
+
+
+
+ HD syringe pump self-test failure alarm.
+
+
+
+
+ HD monitored voltage is out of range.
+
+
+
+
+ DG monitored voltage is out of range.
+
+
+
+
+ HD syringe pump direction (from encoder) error.
+
+
+
+
+ HD syringe pump direction (from controller) error.
+
+
+
+
+ HD syringe pump fault reported by FPGA.
+
+
+
+
+ HD syringe pump over travel error.
+
+
+
+
+ HD syringe pump DAC write failure.
+
+
+
+
+ HD syringe pump is running while the BP is off.
+
+
+
+
+ DG set RTC year is invalid.
+
+
+
+
+ HD pump track latch opened alarm.
+
+
+
+
+ HD set RTC year is invalid.
+
+
+
+
+ DG heating invalid calibration record.
+
+
+
+
+ DG concentrate pumps hall sensor out of range.
+
+
+
+
+ DG outlet UV reactor on with no flow.
+
+
+
+
+
+ DG load cells A1/B1 FPGA fault.
+
+
+
+
+ HD No dialysate flow data receive in the last 3 seconds.
+
+
+
+
+ DG temperature sensors invalid calibration record.
+
+
+
+
+ DG outlet primary conductivity out of range.
+
+
+
+
+ DG pressure out of range.
+
+
+
+
+ DG watchdog expired.
+
+
+
+
+ DG inlet water temperature in high range.
+
+
+
+
+ DG fill conductivity out of range.
+
+
+
+
+ HD battery communication fault.
+
+
+
+
+ HD syringe pump stall alarm.
+
+
+
+
+ DG conductivity sensors invalid temperature compensation calibration record.
+
+
+
+
+ UI POST HD communication failure.
+
+
+
+
+ DG heat disinfect temperature gradient out of range.
+
+
+
+
+ HD invalid calibration CRC.
+
+
+
+
+ HD air trap level sensors reporting illegal combination of air/fluid.
+
+
+
+
+ DG invalid calibration CRC.
+
+
+
+
+ DG dialysate flow sensor invalid calibration record.
+
+
+
+
+ HD reports DG restarted fault.
+
+
+
+
+ HD syringe pump ADC FPGA fault.
+
+
+
+
+ HD syringe pump volume check error.
+
+
+
+
+ HD syringe pump speed check error.
+
+
+
+
+ HD syringe pump not stopped in off state error.
+
+
+
+
+ DG Drain pump current out of range.
+
+
+
+
+ HD venous air bubble detector self-test failure.
+
+
+
+
+ DG temperature sensor out of range.
+
+
+
+
+ HD UI SD card failure.
+
+
+
+
+ DG CAN message not acked.
+
+
+
+
+ DG RTC config error.
+
+
+
+
+ DG RTC battery low error.
+
+
+
+
+ HD pre-treatment mode wet self-test prime check failure.
+
+
+
+
+ DG main primary heater voltage out of range.
+
+
+
+
+ DG small primary heater voltage out of range.
+
+
+
+
+ DG trimmer heater voltage out of range.
+
+
+
+
+ HD end of treatment alarm (high priority).
+
+
+
+
+ HD blood sitting too long after treatment stopped by user alarm (>5 min).
+
+
+
+
+ HD blood leak detected alarm.
+
+
+
+
+ HD venous pressure too low during treatment.
+
+
+
+
+ HD venous air bubble detected alarm.
+
+
+
+
+ HD blood leak recovering please wait.
+
+
+
+
+ HD venous pressure too high during treatment.
+
+
+
+
+ HD arterial pressure too low during treatment.
+
+
+
+
+ HD arterial pressure too high during treatment.
+
+
+
+
+ DG fluid leak detected alarm.
+
+
+
+
+ HD fluid leak detected alarm.
+
+
+
+
+ HD experienced large acceleration.
+
+
+
+
+ DG experienced large acceleration.
+
+
+
+
+ HD tilt exceeds maximum.
+
+
+
+
+ DG tilt exceeds maximum.
+
+
+
+
+ HD AC power lost alarm.
+
+
+
+
+ HD DG communication timeout.
+
+
+
+
+ HD air trap fill timeout during treatment.
+
+
+
+
+ HD blood pump occlusion detected.
+
+
+
+
+ DG dialysate temperature sensors out of range.
+
+
+
+
+ DG cleaning mode inlet water conductivity out of high range.
+
+
+
+
+ DG concentrate conductivity after adding acid out of range alarm.
+
+
+
+
+ DG RTC or timer accuracy failure.
+
+
+
+
+ DG wait for the DG to produce dialysate.
+
+
+
+
+ DG Cleaning mode inlet water temperature too high.
+
+
+
+
+ HD watchdog expired.
+
+
+
+
+ DG inlet water conductivity in high range.
+
+
+
+
+ DG inlet water conductivity in low range.
+
+
+
+
+ DG inlet water pressure in low range.
+
+
+
+
+ HD prime completed high priority alarm.
+
+
+
+
+ DG cleaning mode inlet water conductivity out of low range.
+
+
+
+
+ HD No reservoirs data message receive at least once every 2 seconds.
+
+
+
+
+ HD No DG operation mode message receive at least once every 2 seconds.
+
+
+
+
+ DG chemical disinfect prime acid line timeout.
+
+
+
+
+ DG inlet water temperature is in the low range.
+
+
+
+
+ DG chemical disinfect flush remove acid and close the concentrate cap.
+
+
+
+
+ HD blood pump rotor speed too high.
+
+
+
+
+ DG comm too many bad CRCs.
+
+
+
+
+ DG FPGA clock speed check failure.
+
+
+
+
+ HD sees primary load cell for reservoir 1 change too much too fast.
+
+
+
+
+ HD sees primary load cell for reservoir 2 change too much too fast.
+
+
+
+
+ HD in treatment rinseback operation timeout.
+
+
+
+
+
+
+ Test alarm, clear top only.
+
+
+
+
+ HD cartridge door opened alarm.
+
+
+
+
+ DG Dialysate flow rate out of maximum range.
+
+
+
+
+ HD syringe empty alarm.
+
+
+
+
+ HD syringe pump occlusion alarm.
+
+
+
+
+ HD syringe pump not enough Heparin alarm.
+
+
+
+
+ HD RTC configuration error.
+
+
+
+
+ HD RTC or timer accuracy failure.
+
+
+
+
+ HD pump direction status error.
+
+
+
+
+ DG software fault.
+Software found itself in an unexpected state.
+
+
+
+
+ HD communication timeout.
+
+
+
+
+ DG FPGA communication down for too long.
+
+
+
+
+ DG RO flow out of maximum range.
+
+
+
+
+ DG load cells weight out of range for tare.
+
+
+
+
+ DG load cells invalid calibration.
+
+
+
+
+ DG invalid load cell value.
+
+
+
+
+ DG inlet UV reactor not healthy.
+
+
+
+
+ DG fan RPM out of range.
+
+
+
+
+ DG concentrate pump fault.
+
+
+
+
+ DG concentrate pump CP1 speed control error.
+
+
+
+
+ DG concentrate pump CP2 speed control error.
+
+
+
+
+ DG drain pump RPM out of range.
+
+
+
+
+ DG drain pump off fault.
+
+
+
+
+ DG flow rate out of upper range.
+
+
+
+
+ DG flow rate out of lower range.
+
+
+
+
+ HD blood pump partial occlusion detected.
+
+
+
+
+ DG RO pump duty cycle out of range.
+
+
+
+
+ DG RO pump pressure out of range.
+
+
+
+
+ DG CPi/CPo sensors FPGA fault.
+
+
+
+
+ DG CD1/CD2 sensors FPGA fault.
+
+
+
+
+ DG RO flow too low while primary heater is on.
+
+
+
+
+ DG Dialysate flow too low while trimmer heater is on.
+
+
+
+
+ DG thermistors/sensors temperature out of range.
+
+
+
+
+ HD pre-treatment mode wet self-test lc vs FMD failure.
+
+
+
+
+ HD pre-treatment mode dry pressure normal self-test failure.
+
+
+
+
+ DG fill conductivities acid/bicarb invalid calibration record.
+
+
+
+
+ DG RO rejection ratio out of range.
+
+
+
+
+ DG conductivity sensor fault.
+
+
+
+
+ DG dialysate fill runs out of time.
+
+
+
+
+ DG flow meter check failure alarm.
+
+
+
+
+ HD venous pressure occlusion alarm.
+
+
+
+
+ DG drain circulation line timeout.
+
+
+
+
+ HD battery pack detected an error.
+
+
+
+
+ HD blood sitting too long warning (>4 min).
+
+
+
+
+ HD end of treatment alarm (user not acting to end treatment).
+
+
+
+
+ HD prime completed medium priority alarm.
+
+
+
+
+
+
+
+
+
+ Available for use.
+
+
+
+
+ HD end treatment sub-mode timeout alarm.
+
+
+
+
+ HD syringe detected alarm.
+
+
+
+
+ HD syringe pump syringe removed alarm.
+
+
+
+
+ DG THd sensors FPGA fault.
+
+
+
+
+ HD Saline bag is empty.
+
+
+
+
+ HD occlusion sensor FPGA fault.
+
+
+
+
+ HD arterial sensor FPGA fault.
+
+
+
+
+ HD treatment stopped by user action.
+
+
+
+
+ HD end of treatment warning.
+
+
+
+
+ HD prime completed low priority alarm.
+
+
+
+
+ HD time out on prime saline purge air state.
+
+
+
+
+ HD prime dialysate dialyzer time out alarm.
+
+
+
+
+ HD prime dialysate bypass time out alarm.
+
+
+
+
+ HD pre-treatment mode dry pressure self-test failure.
+
+
+
+
+ HD pre-treatment mode wet self-test LC vs LC failure.
+
+
+
+
+ DG barometric sensor coefficients bad CRC.
+
+
+
+
+ DG inlet water pressure in high range.
+
+
+
+
+ HD in treatment stopped sub-mode after rinseback completed (no escalation).
+
+
+
+
+ HD needs new cartridge to be installed.
+
+
+
+
+ HD no cartridge loaded or installed improperly alarm.
+
+
+
+
+ HD fail to remove cartridge alarm.
+
+
+
+
+ DG bicarb conductivity out of range during bicarb pump check alarm.
+
+
+
+
+ DG reservoir drain time out.
+
+
+
+
+ DG reservoir fill time out.
+
+
+
+
+ DG reservoir leak time out.
+
+
+
+
+ DG cleaning mode temperature sensors difference out of range.
+
+
+
+
+ DG heat disinfect target temperature time out (could not reach to temperature).
+
+
+
+
+ DG cleaning mode conductivity sensors out of range.
+
+
+
+
+
+ Alarm Id available.
+
+
+
+
+ DG chemical disinfect could not reach to target temperature out of range.
+
+
+
+
+ DG chemical disinfect target conductivity out of range.
+
+
+
+
+ DG chemical disinfect insert acid and remove the concentrate cap.
+
+
+
+
+ HD invalid system record.
+
+
+
+
+ HD invalid service record.
+
+
+
+
+ DG invalid system record.
+
+
+
+
+ DG invalid service record.
+
+
+
+
+ HD and UI software builds are not compatible.
+
+
+
+
+ HD processor is in Disinfect Chemical Flush mode.
+
+
+
+
+ HD invalid institutional record.
+
+
+
+
+ HD UI POST OS version compatibility failure.
+
+
+
+
+ HD temperatures out of range.
+
+
+
+
+ HD UI POST Application Integrity (Sha256Sum) failure.
+
+
+
+
+ HD UI POST CANBus failure.
+
+
+
+
+ HD UI POST Touch failure.
+
+
+
+
+ HD UI POST SD-Card failure.
+
+
+
+
+ HD UI POST RTC failure.
+
+
+
+
+ HD UI POST WiFi failure.
+
+
+
+
+ HD UI POST Bluetooth failure.
+
+
+
+
+ HD UI POST Ethernet failure.
+
+
+
+
+ HD UI POST Sound failure.
+
+
+
+
+ HD POST Safety Shutdown failure.
+
+
+
+
+ DG POST Safety Shutdown failure.
+
+
+
+
+ HD Fan RPM out of range.
+
+
+
+
+ DG inactive reservoir weight out of range.
+
+
+
+
+ HD arterial pressure sensor is reading out of range.
+
+
+
+
+ HD venous pressure sensor is reading out of range.
+
+
+
+
+ HD BP occlusion sensor is reading out of range.
+
+
+
+
+ HD active reservoir weight out of range.
+
+
+
+
+ DG dialysate drain time out.
+
+
+
+
+ DG drain pump direction invalid.
+
+
+
+
+ Acid concentration bottle low volume alarm.
+
+
+
+
+ Bicarbonate concentration bottle low volume alarm.
+
+
+
+
+ DG load cells weight out of range.
+
+
+
+
+ DG load cells primary/back up drift out of range.
+
+
+
+
+ HD processor is in RO permeate sample mode.
+
+
+
+
+ DG concentrate cap not in proper position.
+
+
+
+
+ HD processor clock speed checks against FPGA clock failure.
+
+
+
+
+ HD load cells primary/back up drift out of range.
+
+
+
+
+ DG dialysate cap not closed.
+
+
+
+
+ HD venous pressure sensor FPGA fault.
+
+
+
+
+ HD processor is in Disinfect Flush mode.
+
+
+
+
+ HD processor is in Disinfect Heat mode.
+
+
+
+
+ HD processor is in Disinfect Chemical mode.
+
+
+
+
+ HD processor is in Disinfect active cool mode.
+
+
+
+
+ HD UI POST CloudSync failure.
+
+
+
+
+ DG TDi sensors FPGA fault.
+
+
+
+
+ DG TRo sensors FPGA fault.
+
+
+
+
+ DG baro sensor FPGA fault.
+
+
+
+
+ DG invalid serial number.
+
+
+
+
+ HD invalid serial number.
+
+
+
+
+ DG RO permeate sample remove the dialysate cap.
+
+
+
+
+ DG processor RAM error.
+
+
+
+
+ DG drain pump direction FPGA fault.
+
+
+
+
+ HD invalid usage record.
+
+
+
+
+ HD processor RAM error.
+
+
+
+
+ DG turn off inlet water valves.
+
+
+
+
+ HD AC power lost second alarm.
+
+
+
+
+ DG CPi conductivity sensor invalid character received.
+
+
+
+
+ DG CPo conductivity sensor invalid character received.
+
+
+
+
+ DG CD1 conductivity sensor invalid character received.
+
+
+
+
+ DG CD2 conductivity sensor invalid character received.
+
+
+
+
+ HD Dialysate In flow rate to too low.
+
+
+
+
+ DG cleaning mode inlet water temperature too low.
+
+
+
+
+ DG cleaning mode inlet water pressure too high.
+
+
+
+
+ DG cleaning mode inlet water pressure too low.
+
+
+
+
+
+ Alarm available.
+
+
+
+
+ Alarm available for use.
+
+
+
+
+ DG chemical disinfect flush flush sample.
+
+
+
+
+ DG chemical disinfect flush sample timeout.
+
+
+
+
+ DG outlet UV reactor not healthy.
+
+
+
+
+ HD UI POST Year check failure.
+
+
+
+
+ HD UI POST Configuration check failure.
+
+
+
+
+ Total number of alarms.
+
+
+
+
+ ALARM_ID_UNDEFINED [%1]
+
+
+
+
+ SDCProgressItem
+
+
+ SD
+
+
+
+
+ SettingsBluetoothCuff
+
+
+ Devices
+
+
+
+
+ SCAN
+
+
+
+
+ SettingsDGCleaning
+
+
+ Last Basic Flush Complete
+
+
+
+
+ Last Chemical Disinfect Start
+
+
+
+
+ Last Chemical Disinfect Complete
+
+
+
+
+ Last Chemical Disinfect Flush Complete
+
+
+
+
+ Last Heat Disinfect Complete
+
+
+
+
+ Proceed to Cleaning Mode
+
+
+
+
+ SettingsDGScheduling
+
+
+ Water Flush
+
+
+
+
+
+ Cycle (Days)
+
+
+
+
+ Heat Disinfection
+
+
+
+
+ SettingsDateTime
+
+
+ Time (HH:MM)
+
+
+
+
+ :
+
+
+
+
+ Date (MM/DD/YYYY)
+
+
+
+
+
+ /
+
+
+
+
+ SettingsDecommission
+
+
+ Do you want to perform the %1?
+
+
+
+
+ Please wait ...
+
+
+
+
+ SettingsDeviceRegistration
+
+
+ UI Version
+
+
+
+
+ HD Serial
+
+
+
+
+ DG Serial
+
+
+
+
+ Wireless
+
+
+
+
+ Ethernet
+
+
+
+
+ Registration complete
+
+
+
+
+ Cloud Service is running
+
+
+
+
+ Registering the device
+
+
+
+
+ START
+
+
+
+
+ No Network Connection
+
+
+
+
+ No device Serial
+
+
+
+
+ SettingsExportLogs
+
+
+ SD-Card
+
+
+
+
+ USB Drive
+
+
+
+
+ Application
+
+
+
+
+ Service
+
+
+
+
+ Treatment
+
+
+
+
+ log export to USB in progress ...
+
+
+
+
+ log export to USB is complete
+
+
+
+
+ SettingsFactoryReset
+
+
+ Do you want to perform the %1?
+
+
+
+
+ Please wait ...
+
+
+
+
+ SettingsHome
+
+
+ Clear Alarm Condition
+
+
+
+
+ SettingsInformation
+
+
+ Versions
+
+
+
+
+ OS Version
+
+
+
+
+ UI Version
+
+
+
+
+ HD Version
+
+
+
+
+ HD FPGA Version
+
+
+
+
+ HD Serial Number
+
+
+
+
+ DG Version
+
+
+
+
+ DG FPGA Version
+
+
+
+
+ DG Serial Number
+
+
+
+
+ Service
+
+
+
+
+ HD Last Service Date
+
+
+
+
+ HD Next Service Date
+
+
+
+
+ DG Last Service Date
+
+
+
+
+ DG Next Service Date
+
+
+
+
+ Treatment
+
+
+
+
+ Total Hours
+
+
+
+
+ Hours Since Last Service
+
+
+
+
+ Last Start
+
+
+
+
+ Last Reset
+
+
+
+
+ SettingsLocalization
+
+
+ Language
+
+
+
+
+ SettingsManufacturingSetup
+
+
+ Do you want to perform the %1?
+
+
+
+
+ Please wait ...
+
+
+
+
+ SettingsROInput
+
+
+ Pure Water Mode
+
+
+
+
+ ON
+
+
+
+
+ OFF
+
+
+
+
+ SettingsRootSSHAccess
+
+
+ Enable SSH Login
+
+
+
+
+ Enable Root Login
+
+
+
+
+ SettingsServicePassword
+
+
+ Set Service Password
+
+
+
+
+ Service Password
+
+
+
+
+ Incorrect password
+
+
+
+
+ Mismatch Passwords
+
+
+
+
+ Invalid Password
+
+
+
+
+ SettingsStack
+
+
+ Information
+
+
+
+
+ Volume And Brightness
+
+
+
+
+ Wi-Fi
+
+
+
+
+ Bluetooth Cuff
+
+
+
+
+ DG Cleaning
+
+
+
+
+ DG Scheduling
+
+
+
+
+
+ Service
+
+
+
+
+ Date and Time
+
+
+
+
+ Export Logs
+
+
+
+
+ Language
+
+
+
+
+ Water Input Mode
+
+
+
+
+ Calibration
+
+
+
+
+ Device Configuration
+
+
+
+
+ Device Registration
+
+
+
+
+
+ Software Update
+
+
+
+
+ Enable Root SSH
+
+
+
+
+ Factory Reset
+
+
+
+
+ Decommissioning
+
+
+
+
+ Institutional Configurations
+
+
+
+
+ Manufacturing Setup
+
+
+
+
+ Device Settings
+
+
+
+
+ COMPLETE
+
+
+
+
+ SHUTDOWN
+
+
+
+
+
+ Application POST Failed, please shutdown and retry
+
+
+
+
+ SettingsVolumeBrightness
+
+
+ Brightness
+
+
+
+
+ Alarm Volume
+
+
+
+
+ System Volume
+
+
+
+
+ %
+
+
+
+
+ SettingsWiFi
+
+
+ IP Address
+
+
+
+
+ Gateway
+
+
+
+
+ Subnet Mask
+
+
+
+
+ DNS
+
+
+
+
+ SSID
+
+
+
+
+ SCAN
+
+
+
+
+ Not Supported
+
+
+
+
+ Connected
+
+
+
+
+ Do you want to disconnect from `%1`?
+
+
+
+
+ Join
+
+
+
+
+ Password
+
+
+
+
+ Disconnect
+
+
+
+
+ Storage::Logger
+
+
+ %1 Initialized
+
+
+
+
+ Application %1 Started
+
+
+
+
+ The '%1' folder selected for the treatment reports
+
+
+
+
+ Initializing log clean up
+
+
+
+
+ Remove Logs Ended: %1
+
+
+
+
+ Storage::TreatmentLog
+
+
+
+ NONE
+
+
+
+
+
+
+
+ OFF
+
+
+
+
+ mL/min
+
+
+
+
+ hour
+
+
+
+
+ min
+
+
+
+
+ mEq/L
+
+
+
+
+ C
+
+
+
+
+ L
+
+
+
+
+ mL
+
+
+
+
+ IU/mL
+
+
+
+
+ mL/hr
+
+
+
+
+ mmHg
+
+
+
+
+ Patient ID
+
+
+
+
+
+
+ Blood Flow Rate
+
+
+
+
+ Dialysate Flow Rate
+
+
+
+
+ Treatment Duration
+
+
+
+
+ Actual Treatment Duration
+
+
+
+
+ Acid ConcentrateType
+
+
+
+
+ Bicarbonate Concentrate Type
+
+
+
+
+ Potassium Concentration
+
+
+
+
+ Calcium Concentration
+
+
+
+
+ Bicarbonate Concentration
+
+
+
+
+ Sodium Concentration
+
+
+
+
+ Dialysate Temperature
+
+
+
+
+ Dialyzer Type
+
+
+
+
+ Heparin Type
+
+
+
+
+ Heparin Concentration
+
+
+
+
+ Heparin Bolus Volume
+
+
+
+
+ Heparin Dispense Rate
+
+
+
+
+ Heparin Stop
+
+
+
+
+ Heparin Delivered Volume
+
+
+
+
+ Treatment Start DateTime
+
+
+
+
+ Treatment End DateTime
+
+
+
+
+ Water Sample Test Result
+
+
+
+
+ Dialysate Volume Used
+
+
+
+
+ Prescribed UF Volume
+
+
+
+
+ Target UF Volume
+
+
+
+
+ Actual UF Volume
+
+
+
+
+ Prescribed UF Rate
+
+
+
+
+ Target UF Rate
+
+
+
+
+ Actual UF Rate
+
+
+
+
+ Saline Bolus Volume
+
+
+
+
+ TimeEntry
+
+
+ Time
+
+
+
+
+ :
+
+
+
+
+ TreatmentAdjustmentDuration
+
+
+ TREATMENT DURATION
+
+
+
+
+ TreatmentAdjustmentFlow
+
+
+ FLOWS
+
+
+
+
+ Blood Flow Rate
+
+
+
+
+ Dialysate Flow Rate
+
+
+
+
+ TreatmentAdjustmentPressuresLimits
+
+
+ PRESSURES
+
+
+
+
+ Arterial Window
+
+
+
+
+ Venous Window
+
+
+
+
+ Venous Asymmetric
+
+
+
+
+ TreatmentAdjustmentUltrafiltrationConfirm
+
+
+ ULTRAFILTRATION VOLUME
+
+
+
+
+ To confirm new UF Volume (%1),
+select a treatment adjustment:
+
+
+
+
+ CONFIRM
+
+
+
+
+ %1 UF Rate
+
+
+
+
+ The rate %3 by %1 %2,
+the treatment duration remains the same.
+
+
+
+
+
+ UF Rate : %1 %2
+
+
+
+
+ %1 Treatment Duration
+
+
+
+
+ The rate remains, the treatment
+duration %2 by %1 minutes.
+
+
+
+
+ TreatmentAdjustmentUltrafiltrationEdit
+
+
+ ULTRAFILTRATION VOLUME
+
+
+
+
+ NEXT
+
+
+
+
+ TreatmentAdjustmentUltrafiltrationPaused
+
+
+ ULTRAFILTRATION VOLUME
+
+
+
+
+ EDIT ULTRAFILTRATION VOLUME
+
+
+
+
+ RESUME ULTRAFILTRATION
+
+
+
+
+ TreatmentAdjustmentUltrafiltrationStart
+
+
+ ULTRAFILTRATION VOLUME
+
+
+
+
+ PAUSE ULTRAFILTRATION
+
+
+
+
+ Note: Ultrafiltration needs to be paused to edit the volume.
+
+
+
+
+ TreatmentBloodPrime
+
+
+ Blood Priming
+
+
+
+
+ TreatmentFlowBase
+
+
+ TreatmentFlowBase
+
+
+
+
+ TreatmentFlows
+
+
+ FLOWS
+
+
+
+
+ Blood
+
+
+
+
+ Dialysate
+
+
+
+
+ TreatmentFluid
+
+
+ FLUID MANAGEMENT
+
+
+
+
+ Volume Delivered
+
+
+
+
+ (%1 %2)
+
+
+
+
+ Cumulative Delivered
+
+
+
+
+ TreatmentHeparin
+
+
+ HEPARIN DELIVERY
+
+
+
+
+
+ OFF
+
+
+
+
+ PAUSE HEPARIN
+
+
+
+
+ RESUME DELIVERY
+
+
+
+
+ Maximum Cumulative Heparin Volume Delivered
+
+
+
+
+ Bolus Active
+
+
+
+
+ Syringe Empty
+
+
+
+
+
+
+
+
+
+ Delivery Stopped
+
+
+
+
+ Delivery Paused
+
+
+
+
+ Dispensing Active
+
+
+
+
+ HEPARIN
+
+
+
+
+ TreatmentHome
+
+
+ Interval:
+
+
+
+
+ min
+
+
+
+
+ OFF
+
+
+
+
+ Last Read:
+
+
+
+
+ TreatmentPressures
+
+
+ PRESSURE
+
+
+
+
+ (mmHg)
+
+
+
+
+ Arterial
+
+
+
+
+ Venous
+
+
+
+
+ TreatmentSaline
+
+
+ START BOLUS
+
+
+
+
+ STOP BOLUS
+
+
+
+
+ Maximum cumulative saline bolus volume delivered
+
+
+
+
+ SALINE BOLUS
+
+
+
+
+ TreatmentStack
+
+
+ Ultrafiltration Paused
+
+
+
+
+ Treatment
+
+
+
+
+ Trending
+
+
+
+
+ Settings
+
+
+
+
+ VITALS
+
+
+
+
+ TreatmentTime
+
+
+ Time Remaining
+
+
+
+
+ Treatment Paused
+
+
+
+
+ TreatmentUltrafiltration
+
+
+ ULTRAFILTRATION VOLUME
+
+
+
+
+ (%1 %2)
+
+
+
+
+ TreatmentVitals
+
+
+ VITALS
+
+
+
+
+ USBProgressItem
+
+
+ USB
+
+
+
+
+ UltrafiltrationButton
+
+
+ Invalid
+
+
+
+
+ Increase
+
+
+
+
+ Decrease
+
+
+
+
+ Due to out of range adjustment, this option
+is disabled.
+
+
+
+
+ UserConfirmation
+
+
+ Current
+
+
+
+
+ New
+
+
+
+
+ Confirm
+
+
+
+
+ VAlarmStatus
+
+
+ Suppressing HD communication timeout.
+
+
+
+
+ Alarm
+
+
+
+
+ VDevice
+
+
+
+ Not enough secure information provided
+
+
+
+
+ Variables
+
+
+ CREATE
+
+
+
+
+ CONFIRM
+
+
+
+
+ PRIME
+
+
+
+
+ BEGIN
+
+
+
+
+ min
+
+
+
+
+ mL/min
+
+
+
+
+ mL/hr
+
+
+
+
+ mmHg
+
+
+
+
+ BPM
+
+
+
+
+ (L)
+
+
+
+
+ mL
+
+
+
+
+ °C
+
+
+
+
+ mEq/L
+
+
+
+
+ IU/mL
+
+
+
+
+ View::VAdjustmentAlarmVolume
+
+
+ The alarm volume change request has been rejected [%1]
+
+
+
+
+ View::VAdjustmentInstitutionalRecord
+
+
+ Enabled
+
+
+
+
+ Disabled
+
+
+
+
+ Blood Flow Rate
+
+
+
+
+ Dialysate Flow Rate
+
+
+
+
+ Treatment Duration
+
+
+
+
+ Heparin Stop
+
+
+
+
+ Saline Bolus Volume
+
+
+
+
+ Dialysate Temperature
+
+
+
+
+ Arterial Pressure Limit
+
+
+
+
+ Venous Pressure Limit
+
+
+
+
+ Venous Asym Pressure Limit
+
+
+
+
+ Prescribed UF Volume
+
+
+
+
+ Heparin Dispense Rate
+
+
+
+
+ Heparin Bolus Volume
+
+
+
+
+ Chemical Disinfect
+
+
+
+
+
+ mL/min
+
+
+
+
+
+ min
+
+
+
+
+
+ mL
+
+
+
+
+ C
+
+
+
+
+
+
+ mmHg
+
+
+
+
+ L
+
+
+
+
+ mL/hr
+
+
+
+
+ View::VAlarmActiveList
+
+
+ No Active Alarm List
+%1
+
+
+
+
+ View::VBluetooth
+
+
+ Bluetooth reconnected.
+
+
+
+
+ Bluetooth paired and connected.
+
+
+
+
+ Bluetooth paired and disconnected.
+
+
+
+
+ BluetoothInterface Closed
+
+
+
+
+ The Bluetooth Adapter Is Ready %1
+
+
+
+
+ The Bluetooth Adapter Connected
+
+
+
+
+ The Bluetooth Adapter Disconnected
+
+
+
+
+ No Valid Bluetooth Adapter
+
+
+
+
+ The Bluetooth Adapter POST Failed
+
+
+
+
+ The Bluetooth Adapter Is Off
+
+
+
+
+ The Bluetooth Adapter IO Error
+
+
+
+
+ The Bluetooth Adapter Unknown Error
+
+
+
+
+ No Valid device found
+
+
+
+
+ Scanning ...
+
+
+
+
+ Scanning Rejected
+
+
+
+
+ Device Discovering ...
+
+
+
+
+ Blood Pressure Device Found
+
+
+
+
+ Scanning Stopped
+
+
+
+
+ Scanning Finished
+
+
+
+
+ Device Initializing ...
+
+
+
+
+ Device Initialization Error
+
+
+
+
+ Device Connecting ...
+
+
+
+
+ Device Waiting For Measurement ...
+
+
+
+
+ Device Connection Error
+
+
+
+
+ Device Connected
+
+
+
+
+ Device Clean Up
+
+
+
+
+ Device In Power Saving Mode
+
+
+
+
+ Service Scanning ...
+
+
+
+
+ Service Error: %1
+
+
+
+
+ Service Invalid
+
+
+
+
+ Service Discovered
+
+
+
+
+ Service Detail Discovering ...
+
+
+
+
+ Service Detail Error
+
+
+
+
+ Service Detail Done
+
+
+
+
+ Service Clean Up
+
+
+
+
+ Service Characteristic Changed
+
+
+
+
+ Service Characteristic Read
+
+
+
+
+ Service Characteristic Write
+
+
+
+
+ Service Descriptor Read
+
+
+
+
+ Service Descriptor Write
+
+
+
+
+ View::VConfirm
+
+
+ Shutdown
+
+
+
+
+ Are you sure you want to Shutdown?
+
+
+
+
+ SHUTDOWN
+
+
+
+
+
+ CANCEL
+
+
+
+
+ Confirm
+
+
+
+
+ Are you sure?
+
+
+
+
+ CONFIRM
+
+
+
+
+ View::VDateTime
+
+
+ SetDateTime %1
+
+
+
+
+ Not Set
+
+
+
+
+ Succeed
+
+
+
+
+ Failed
+
+
+
+
+ Good Morning
+
+
+
+
+ Good Afternoon
+
+
+
+
+ Good Evening
+
+
+
+
+ View::VDuetRoWaterDG
+
+
+ The RO Water Mode change request has been rejected [%1]
+
+
+
+
+ View::VNetworkModel
+
+
+ Scanning...
+
+
+
+
+ Scan Finished
+
+
+
+
+ Connecting to %1...
+
+
+
+
+ Disconnecting from %1...
+
+
+
+
+ Connected to %1.
+
+
+
+
+ Disconnected from %1.
+
+
+
+
+ No Ethernet
+
+
+
+
+ No WiFi
+
+
+
+
+ WiFi Disconnect
+
+
+
+
+ Successfully set the IP address.
+
+
+
+
+ Successfully set the gateway.
+
+
+
+
+ Successfully set the subnet mask.
+
+
+
+
+ Successfully set the DNS.
+
+
+
+
+ View::VTreatmentCreate
+
+
+
+
+
+ OFF
+
+
+
+
+
+
+
+ NONE
+
+
+
+
+ View::VTreatmentVitals
+
+
+ Vital received,%1,%2,%3
+
+
+
+
+ Vital Confirmed,%1,%2,%3
+
+
+
+
+ Vital Skipped
+
+
+
+
+ WifiInterface
+
+
+ %1 Initialized
+
+
+
+
+ %1.Obtaining IP Address.%1
+
+
+
+
+ Failed to disconnect from %1
+
+
+
+
+ Failed to set static IP Address
+
+
+
+
+ Failed to set gateway.
+
+
+
+
+ Failed to set subnet mask.
+
+
+
+
+ Failed to set DNS.
+
+
+
+
+ main
+
+
+ Treatment
+
+
+
+
+ Manager
+
+
+
+
+ Settings
+
+
+
+
+ Show the Can Frame Output
+
+
+
+
+ Show the Message Output
+
+
+
+
+ Show the Logs Output
+
+
+
+
+ Enable send low priority, empty message on the CANBus just to keep UI board CAN driver awake
+
+
+
+
+ Test fake message interval(ms)
+
+
+
+
+ interval
+
+
+
+
+ Test fake message data
+will use default sequenced long fake message if set to 00(default)
+will used only if correct integer value assigned for interval option
+
+
+
+
+ data
+
+
+
+
+ Test fake message sequence at the beginning of the frame
+
+
+
+
+ Disable unhandled messages report as an error in the log
+
+
+
+
+ Disable the Dialin messages logged as unhandled
+
+
+
+
+ Disables HD communication timeout
+
+
+
+
+ Disables alarm no minimize
+
+
+
+
+ disable-sd-card-fail-log-stop
+
+
+
+
+ disable-cloudsync-fail-stop
+
+
+
+
+ Disables Check-In Log
+
+
+
+
+ Disables Acknowledgment Log
+
+
+
+
+ Enables Dry-Demo Mode
+
+
+
+
+ Sets the Active CANBus [Shall start with 'can' or 'vcan]
+
+
+
+
+ CANBus
+
+
+
+
+ Enables the manufacturing mode to configure the system for the first time.
+
+
+
+
+ In case the application is not in Manufacturing Setup but needs to use root home folder for configurations.
+
+
+
+
+ Enables the update mode to update only necessary files during the update and keep the rest.
+
+
+
+
+ Use the log long file name format
+<date>_<time>_<serial>_<mode>
+
+
+
+
+ Use the log cloud upload
+
+
+
+
+ Use the log compression
+
+
+
+
+ tst_acknow
+
+
+ Connected
+
+
+
+
+ Disconnected
+
+
+
+
+ tst_canbus
+
+
+ Connection
+
+
+
+
+ Connected
+
+
+
+
+ Disconnected
+
+
+
+
+ tst_models
+
+
+ ALARM_ID_UNDEFINED [-1]
+
+
+
+
+ ALARM_ID_UNDEFINED [599]
+
+
+
+
+ tst_views
+
+
+ REQUEST_REJECT_REASON_INVALID_TREATMENT_STATE
+
+
+
+
+ REQUEST_REJECT_REASON_UF_NOT_IN_PROGESS
+
+
+
+
+ REQUEST_REJECT_REASON_UF_NOT_PAUSED
+
+
+
+
Index: sources/ApplicationController.cpp
===================================================================
diff -u -ra522e6aa7a36ac696a9a956200e89d838f319e25 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision a522e6aa7a36ac696a9a956200e89d838f319e25)
+++ sources/ApplicationController.cpp (.../ApplicationController.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -49,7 +49,7 @@
_init = true;
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/MainTimer.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/MainTimer.cpp (.../MainTimer.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/MainTimer.cpp (.../MainTimer.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -44,7 +44,7 @@
}
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/bluetooth/BluetoothInterface.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/bluetooth/BluetoothInterface.cpp (.../BluetoothInterface.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/bluetooth/BluetoothInterface.cpp (.../BluetoothInterface.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -53,7 +53,7 @@
// runs in BluetoothInterface thread
// REMINDER:initConnections(); has been removed from here to the ondoStart,
// since the _local, _agent objects are created there.
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
// TODO: the same logic has to work for all the controllers
// needs more testing.
Index: sources/canbus/CanInterface.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -54,9 +54,9 @@
initConnections();
- status(tr("Connected"));
+ status(QString("Connected"));
QString logMessage = QString("UI,%1,%2")
- .arg(tr("%1 Initialized").arg(metaObject()->className()))
+ .arg(QString("%1 Initialized").arg(metaObject()->className()))
.arg(status());
LOG_DEBUG(logMessage);
@@ -246,7 +246,7 @@
else {
mError = vError;
}
- _canStatus = tr("%1 '%2[%3]', %4")
+ _canStatus = QString("%1 '%2[%3]', %4")
.arg(vDescription)
.arg(_canType)
.arg(_canInterface)
Index: sources/canbus/FrameInterface.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/canbus/FrameInterface.cpp (.../FrameInterface.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/canbus/FrameInterface.cpp (.../FrameInterface.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -47,7 +47,7 @@
startTimer(1, Qt::PreciseTimer);
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/canbus/MessageAcknowModel.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/canbus/MessageAcknowModel.cpp (.../MessageAcknowModel.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/canbus/MessageAcknowModel.cpp (.../MessageAcknowModel.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -44,7 +44,7 @@
// runs in MessageAcknowModel thread
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/canbus/MessageDispatcher.cpp
===================================================================
diff -u -r5687815256ae070a9a207107088e3f72dd464da0 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision 5687815256ae070a9a207107088e3f72dd464da0)
+++ sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -48,7 +48,7 @@
// runs in the thread
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/cloudsync/CloudSyncController.cpp
===================================================================
diff -u -r5687815256ae070a9a207107088e3f72dd464da0 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 5687815256ae070a9a207107088e3f72dd464da0)
+++ sources/cloudsync/CloudSyncController.cpp (.../CloudSyncController.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -12,1354 +12,1354 @@
* \date (original) 14-Oct-2021
*
*/
-#include "CloudSyncController.h"
-
-// Qt
-#include
-
-// Project
-#include "ApplicationController.h"
-#include "DeviceController.h"
-#include "FileHandler.h"
-#include "TreatmentLog.h"
-#include "crc.h"
-
-SINGLETON_DISABLE(CloudSyncController)
-
-/*!
- * \brief CloudSyncController::CloudSyncController
- * \details Constructor
- * \param parent - QObject parent owner object.
- * Qt handles the children destruction by their parent objects life-cycle.
- */
-CloudSyncController::CloudSyncController(QObject *parent) : QObject(parent) {
- testWatchBuffDate();
- startTimer(_interval);
-}
-
-/*!
- * \brief CloudSyncController initializer
- */
-bool CloudSyncController::init()
-{
- if ( _init ) return false;
- _init = true;
-
- initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
-
- return true;
-}
-
-/*!
- * \brief CloudSyncController::init
- * \details Initialized the Class by calling the init() method first
- * And initializes the thread vThread by calling initThread
- * on success init().
- * \param vThread - the thread
- * \return returns the return value of the init() method
- */
-bool CloudSyncController::init(QThread &vThread)
-{
- if ( ! init() ) return false;
- initThread(vThread);
- return true;
-}
-
-/*!
- * \brief CloudSyncController::quit
- * \details quits the class
- * Calls quitThread
- */
-void CloudSyncController::quit()
-{
- // disabled coco begin validated: CloudSync termination is not correctly done in coco!!!
- // it has been tested and works perfectly fine in normal run.
- quitThread(); // validated
-}
-// disabled coco end
-
-/*!
- * \brief CloudSyncController::doRegister
- * \details Send the register device command.
- */
-void CloudSyncController::doRegister()
-{
- sendDeviceRegister();
-}
-
-/*!
- * \brief CloudSyncController::initConnections
- * \details Initializes the required signal/slot connection between this class and other objects
- * to be able to communicate.
- */
-void CloudSyncController::initConnections()
-{
- if ( ! gDisableCloudSyncFailStop ) {
- SINGLETON_DISABLE_CONNECT(didPOSTCloudSync)
- }
-
- connect(&_ApplicationController , SIGNAL(didPOSTCloudSync(bool)),
- this , SLOT( onPOSTCloudSync(bool)));
- connect(&_ApplicationController , SIGNAL(didActionReceive (GuiActionType , const QVariantList &)),
- this , SLOT( onActionReceive (GuiActionType , const QVariantList &)));
-
- connect(&_DeviceController , SIGNAL(didCryptSetupMount(bool)),
- this , SLOT( onCryptSetupMount(bool)));
- connect(&_DeviceController , SIGNAL(didPendingLog (const QString &, const QString &)),
- this , SLOT( onPendingLog (const QString &, const QString &)));
- connect(&_Logger , SIGNAL(didRetentionLogCS (quint8)),
- this , SLOT( onRetentionLog (quint8)));
-
- connect(&_DeviceController , SIGNAL(didWatchFileChange (const QString &)),
- this , SLOT( onWatchFileChange (const QString &)));
- connect(&_DeviceController , SIGNAL(didFactoryReset (bool)),
- this , SLOT( onFactoryReset (bool)));
- connect(&_DeviceController , SIGNAL(didDecommissioning (bool)),
- this , SLOT( onDecommissioning (bool)));
- connect(&_TreatmentLog , SIGNAL(didPendingTxr (const QString &)),
- this , SLOT( onPendingTxr (const QString &)));
- connect(this , SIGNAL(didInitComplete ()),
- this , SLOT( onInitComplete ()),Qt::QueuedConnection); // it has to be queued connection, don't remove it.
-}
-
-/*!
- * \brief CloudSyncController::initThread
- * \details Moves this object into the thread vThread.
- * And checks that this method is called from main thread.
- * Also connects quitThread to CloudSync aboutToQuit.
- * \param vThread - the thread
- */
-void CloudSyncController::initThread(QThread &vThread)
-{
- // runs in main thread
- Q_ASSERT_X(QThread::currentThread() == qApp->thread(), __func__, "The Class initialization must be done in Main Thread" );
- _thread = &vThread;
- _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className()));
- connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit()));
- _thread->start();
- moveToThread(_thread);
-}
-
-/*!
- * \brief CloudSyncController::quitThread
- * \details Moves this object to main thread to be handled by QCloudSync
- * And to be destroyed there.
- */
-void CloudSyncController::quitThread()
-{
- // disabled coco begin validated: CloudSync termination is not correctly done in coco!!!
- // it has been tested and works perfectly fine in normal run.
-
- if ( ! _thread ) return;
-
- // runs in thread
- moveToThread(qApp->thread()); // validated
-}
-// disabled coco end
-
-/*!
- * \brief CloudSyncController::timerEvent
- * \details The timer event handler which currently is triggered on each second to check for the date change,
- * Which caused the watched file change and needs to updated the watched list.
- * The check-in (watch dog) also needs to be here.
- */
-void CloudSyncController::timerEvent(QTimerEvent *)
-{
- TIME_CALL(sendCheckIn(), _checkinIntervalSend); // call every x times/second - will be called on first call.
- TIME_CALL(testCheckIn(), _checkinIntervalTest); // call every x times/second - will be called on first call.
- testWatchBuffDate();
- testDeviceInfoWait();
-}
-
-/*!
- * \brief CloudSyncController::event
- * \details The override method of QObject event to handle the ThreadChange.
- * \param vEvent - the QObject event
- * \return true if the event e was recognized and processed
- */
-bool CloudSyncController::event(QEvent *vEvent) {
- if (vEvent->type() == QEvent::ThreadChange) {
- emit didInitComplete();
- }
- // Make sure the rest of events are handled
- return QObject::event(vEvent);
-}
-
-/*!
- * \brief CloudSyncController::onInitComplete
- * \details The slot to be called when the CloudSync initialization is complete
- * Does nothing for now
- */
-void CloudSyncController::onInitComplete() {
- /* Development testability:
- For testing if -C (gDisableCloudSyncFailStop) is used call the testReady
- which is called
- - when the encrypted partition is mounted
- - a request for credential save received
- testReady will set ok = true if -C (gDisableCloudSyncFailStop) is used.
- */
- if ( gDisableCloudSyncFailStop ) testReady();
-}
-
-/*!
- * \brief CloudSyncController::onPOSTCloudSync
- * \details This the handler for the ApplicationController::didPOSTCloudSync(bool)
- * \param vPass - will be true if the POST test of CloudSync passed and it is running.
- */
-void CloudSyncController::onPOSTCloudSync(bool vPass)
-{
- _postPass = vPass;
-}
-
-/*!
- * \brief CloudSyncController::onCryptSetupMount
- * \details This the handler for the DeviceController::onCryptSetupMount()
- */
-void CloudSyncController::onCryptSetupMount(bool vPass)
-{
- if ( vPass ) {
- testReady();
- }
-}
-
-/*!
- * \brief CloudSyncController::onFactoryReset
- * \details this slot will be called when the DeviceController is done with the Factory Reset
- * to let the UI request CS to do the Factory Reset and clean up all the Logs.
- * \param vPass - Device controller factory reset was successful.
- */
-void CloudSyncController::onFactoryReset(bool vPass)
-{
- if ( vPass ) {
- csFactoryReset();
- }
-}
-
-/*!
- * \brief CloudSyncController::onDecommissioning
- * \details this slot will be called when the DeviceController is done with the Decommissioning
- * to let the UI request CS to do the Decommissioning and clean up all the Tokens.
- * \param vPass - Device controller Decommissioning was successful.
- */
-void CloudSyncController::onDecommissioning(bool vPass)
-{
- if ( vPass ) {
- csDecommissioning();
- }
-}
-
-/*!
- * \brief CloudSyncController::onWatchFileChange
- * \details This slot will be called when the Device Controller identifies any changes in the watched files.
- * \param vFile - watched file
- * \note The DeviceController will emit the signal on any watched file update, it's up to the CloudSyncController to filter the result.
- */
-void CloudSyncController::onWatchFileChange(const QString &vFile)
-{
- // TODO: It may improve the performance of the code to make it more specific.
- // Meaning, Device controller has only one file watcher and it will call all the slots of all the classes watching for a file change.
- // then ignore what is not important, but it may effect, the call queue and the threading performance.
- // Later investigation.
- if ( vFile != _date_out_File ) return; // ignore unwanted file updates.
- QString content;
- Storage::FileHandler::read(vFile, content);
- sendUIResponse(content);
-}
-
-/*!
- * \brief CloudSyncController::addCSBuffWatch
- * \details Adds a watcher on the CloudSync Application output file.
- * \sa _out_File
- */
-bool CloudSyncController::addCSBuffWatch()
-{
- bool ok = true;
- QVariantList args {};
- Errors_Enum error = eError_Unknown;
- QString dateFormatted;
-
- // -------------------------------------------------- check the folder
- // this makeFolder function call investigated for permissions
- // during setup the folder if does not exists will be created (root)
- // the lockdown.sh script will set the permissions for it.
- // on power cycle to normal operation the folder with the correct exists.
- // *** NOTE: the makeFolder returns true if the folder already exists. ***
- ok = Storage::FileHandler::makeFolder(_location);
- if ( ! ok ) { error = eError_LogFolder; args = {{ _location }}; ok = false; goto lErr; }
-
- // -------------------------------------------------- Check the out file
- // check the date time for the file to watch
- dateFormatted = _datetime.toString(_dateFormat);
- if (_dateFormatted != dateFormatted ) {
- _dateFormatted = dateFormatted;
- _isWatching = false; // first time the date changes and CSctrl needs a new watch this flag need to be reset until the watch is added.
- }
- _date_out_File = _location + _dateFormatted + _dateSeparator + _out_File;
- // watching/wait for the cloud sync output file buffer.
- // if the file does not exists, send a check-in to the CS and wait for the response.
- // by CS sending the response it will create the out file and next time this function with start watching the file.
- // since this class has a one second timer set, next call is next second
- // TODO: during this less that 1s UI will not see messages from CS, since the file was not there to watch.
- // send device state to make the CloudSync send back a message to create the out buff with its user to own the file
- ok = QFileInfo(_date_out_File).exists();
- if ( ! ok ) {
- _isWatching = false;
- sendCheckIn();
- }
- if ( ! ok ) { error = eError_OutFileExist; args = {{ _location }}; ok = false; goto lErr; }
-
- // -------------------------------------------------- return if already watching
- if ( _isWatching ) { goto lOut; }
-
- // -------------------------------------------------- add the watch
- _DeviceController.doAddWatch(_date_out_File, false);
- _isWatching = true; // when the watch is added then the flag sets until next time the date changes.
- // since the buff files will be deleted on each power cycle, when the out buf is created it means the CloudSync is running.
- // we emit the ApplicationController to check the post.log for the CloudSync status check.
- goto lOut;
-
-lErr:
- toLog(error, args);
-
-lOut:
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::interpret
- * \details Checks the received buffer to make sure it has all the required parameters
- * \param vIndex
- * \return true if the buffer is correct.
- */
-bool CloudSyncController::interpret(const QString &vContent, Message &vMessage)
-{
- bool ok = true;
- QVariantList args {};
- Errors_Enum error = eError_Unknown;
-
- QStringList lines;
- QString buffer;
-
- int index = -1;
- quint32 count = 0;
-
- Message message;
- QStringList items;
- quint32 id;
-
- if ( vContent.trimmed().isEmpty() ) { error = eError_OutFileEmpty ; ok = false; goto lErr; }
-
- lines = vContent.split('\n',Qt::SkipEmptyParts);
- buffer = lines.last();
- // DEBUG: LOG_DEBUG(QString("CS [%1]").arg(buffer));
-
- items = buffer.split(_separator);
- count = items.count();
-
- // check the required message length
- if ( count < eMessage_Count ) { error = eError_HeaderCount ; ok = false; goto lErr; }
- index = eMessage_Timestamp ; message.timestamp = items[index].toUInt(&ok); if (!ok) { error = eError_Timestamp ; ok = false; goto lErr; }
- index = eMessage_Sequence ; message.sequence = items[index].toUInt(&ok); if (!ok) { error = eError_Sequence ; ok = false; goto lErr; }
- index = eMessage_CRC ; message.crc = items[index].toUInt(&ok); if (!ok) { error = eError_CSCRC ; ok = false; goto lErr; }
- index = eMessage_MessageID ; message.id = items[index].toInt (&ok); if (!ok) { error = eError_MessageID ; ok = false; goto lErr; }
- index = eMessage_ParamCount; message.paramCount = items[index].toUInt(&ok); if (!ok) { error = eError_ParamCount ; ok = false; goto lErr; }
-
- // check the parameters count
- if ( count - eMessage_Count != message.paramCount ) { error = eError_ParamMismatch ; ok = false; goto lErr; }
-
- // check missing parameters
- id = CS2UI(message.id);
- if ( ! paramCount.contains(id)) paramCount[id] = 0;
- if ( message.paramCount < paramCount[id] ) { error = eError_ParamMissing ; ok = false; goto lErr; }
-
- // convert the message id and check its validity
- id = message.id; // keep the original recevied message id after we are done using the id for loggging.
- message.id = CS2UI(static_cast(message.id));
- if ( eMessageID_Start > message.id || message.id > eMessageID_Count ) { error = eError_InvalidID ; ok = false; goto lErr; }
-
- // getting the parameters
- for ( quint32 i = eMessage_Count; i < eMessage_Count + message.paramCount; i++ ) {
- message.params.append( items[i] );
- }
-
- vMessage = message;
- LOG_APPED_CS(QString("%1,%2").arg(id).arg(message.params.join(',')));
-
- return true;
-
-lErr:
- // building the error info for each error
- switch (error) {
- case eError_Unknown : args = { }; break;
- case eError_OutFileExist : args = { }; break;
- case eError_OutFileEmpty : args = { }; break;
- case eError_HeaderCount : args = { count , eMessage_Count }; break;
- case eError_Timestamp : args = { items[index].trimmed() }; break;
- case eError_Sequence : args = { items[index].trimmed() }; break;
- case eError_CSCRC : args = { items[index].trimmed() }; break;
- case eError_MessageID : args = { items[index].trimmed() }; break;
- case eError_InvalidID : args = { items[index].trimmed() }; break;
- case eError_ParamCount : args = { items[index].trimmed() }; break;
- case eError_ParamMismatch : args = { count - eMessage_Count , message.paramCount }; break;
- case eError_ParamMissing : args = { paramCount[message.id] , message.paramCount }; break;
- // Interpreter function only handles the message parsing errors. So default can be used.
- default : break;
- }
- toLog(error, args);
- return false;
-}
-
-/*!
- * \brief CloudSyncController::toText
- * \details returns the error message of the error id.
- * \param vErrorID - Error id
- * \param vMessage - error message
- * \return the error message or empty string if the error is 0 (no error), or Unknown Error if not found
- */
-QString CloudSyncController::toText(CloudSyncController::Errors_Enum vErrorID)
-{
- QString text = tr( "CS Unknown Error" ) ;
- if ( vErrorID == 0 ) return text;
- switch (vErrorID) {
- case eError_Unknown : /* "CS Unknown Error" */ ; break;
- // CS Errors
- case eError_Registration : text = tr( "CS The device registration failed" ) ; break;
- case eError_DeviceState : text = tr( "CS Invalid Device State" ) ; break;
- case eError_TxReport : text = tr( "CS The treatment report delivery failed" ) ; break;
- case eError_CheckIn : text = tr( "CS The device check-in failed" ) ; break;
- case eError_Decommission : text = tr( "CS The device decommissioning failed" ) ; break;
- case eError_UICRC : text = tr( "CS Invalid UI Message CRC" ) ; break;
- case eError_DeviceValidation : text = tr( "CS DRT device registration failed" ) ; break;
- case eError_PatientAssociation : text = tr( "CS Patient association failed" ) ; break;
- case eError_GetNewTokenCert : text = tr( "CS New token certification failed" ) ; break;
- case eError_VerifyToken : text = tr( "CS Token verification failed" ) ; break;
- case eError_ValidateDevice : text = tr( "CS Cloud device validation failed" ) ; break;
- case eError_PatientIdExists : text = tr( "CS Patient ID does not exists" ) ; break;
- case eError_TemporaryPatient : text = tr( "CS Temporary patient ID creation failed" ) ; break;
- case eError_SaveCredentials : text = tr( "CS Save credentials failed" ) ; break;
- case eError_UnknownDeviceState : text = tr( "CS Unknown device state" ) ; break;
- case eError_ConfigSave : text = tr( "CS Config file save failed" ) ; break;
- case eError_DeviceLog : text = tr( "CS Log upload failed" ) ; break;
- case eError_Logging : text = tr( "CS Log upload failed" ) ; break;
- case eError_FactoryReset : text = tr( "CS The device factory reset failed" ) ; break;
- case eError_Retention : text = tr( "CS The log retention failed" ) ; break;
- // UI Errors
- case eError_OutFileExist : text = tr( "CS Out buffer file does not exist" ) ; break;
- case eError_OutFileEmpty : text = tr( "CS Out buffer empty" ) ; break;
- case eError_HeaderCount : text = tr( "CS Incorrect header" ) ; break;
- case eError_Timestamp : text = tr( "CS Incorrect timestamp" ) ; break;
- case eError_Sequence : text = tr( "CS Incorrect sequence" ) ; break;
- case eError_CSCRC : text = tr( "CS Incorrect CRC" ) ; break;
- case eError_MessageID : text = tr( "CS Incorrect ID" ) ; break;
- case eError_ParamCount : text = tr( "CS Incorrect parameter count" ) ; break;
- case eError_InvalidID : text = tr( "CS Invalid ID" ) ; break;
- case eError_ParamMismatch : text = tr( "CS Mismatch parameter count" ) ; break;
- case eError_ParamMissing : text = tr( "CS Missing parameter" ) ; break;
- case eError_NoHistory : text = tr( "CS No history available" ) ; break;
- case eError_Duplicate : text = tr( "CS Duplicate data" ) ; break;
- case eError_LogFolder : text = tr( "CS The log folder cannot be created." ) ; break;
- case eError_LogFileInp : text = tr( "CS Error writing to the input file." ) ; break;
- case eError_CredentialFile : text = tr( "CS The credentials file does not exist." ) ; break;
- case eError_CredentialPath : text = tr( "CS The credentials folder is incorrect." ) ; break;
- case eError_CredentialCount : text = tr( "CS No credential file name provided." ) ; break;
- case eError_CredentialEmpty : text = tr( "CS The credentials folder is empty." ) ; break;
- case eError_TxCodeNoParam : text = tr( "CS No Treatment Code provided." ) ; break;
- case eError_TxCodeEmpty : text = tr( "CS The provided Treatment Code is empty." ) ; break;
- case eError_LogNameNoParam : text = tr( "CS No Log Name provided." ) ; break;
- case eError_LogNameEmpty : text = tr( "CS The provided Log Name is empty." ) ; break;
- case eError_NotRegistered : text = tr( "CS Not Sent, Device not registered." ) ; break;
- case eError_LogRetentionNoParam : text = tr( "CS No Log Retention summary provided." ) ; break;
-
- }
- return text;
-}
-
-/*!
- * \brief CloudSyncController::toInfo
- * \details Provides extra information, related to each error, to be concatenated later to the error description.
- * \param vErrorID - the error id
- * \param vInfoItems - the information items to be used in creating the info.
- * \return the extra info for the error as string
- */
-QString CloudSyncController::toInfo(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems)
-{
- // IMPORTANT: Please be careful here used QVariantList::value to act as a loose list.
- // It means it is designed to not throw out of bound error and just use "~" as a missing info argument.
- auto item = [=](uint i) { return vInfoItems.value(i,"~").toString(); };
-
- QString info = QString( "[%1]" ).arg( vErrorID ) ;
- switch (vErrorID) {
- case eError_Unknown : ; break;
- // CS Errors
- case eError_Registration : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_DeviceState : ; break;
- case eError_TxReport : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_CheckIn : ; break;
- case eError_Decommission : ; break;
- case eError_UICRC : /* info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) */ ; break;
- case eError_DeviceValidation : ; break;
- case eError_PatientAssociation : ; break;
- case eError_GetNewTokenCert : ; break;
- case eError_VerifyToken : ; break;
- case eError_ValidateDevice : ; break;
- case eError_PatientIdExists : ; break;
- case eError_TemporaryPatient : ; break;
- case eError_SaveCredentials : ; break;
- case eError_UnknownDeviceState : ; break;
- case eError_ConfigSave : ; break;
- case eError_DeviceLog : ; break;
- case eError_Logging : ; break;
- case eError_FactoryReset : ; break;
- case eError_Retention : ; break;
- // UI Errors
- case eError_OutFileExist : ; break;
- case eError_OutFileEmpty : ; break;
- case eError_HeaderCount : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
- case eError_Timestamp : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_Sequence : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_CSCRC : /* info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) */ ; break;
- case eError_MessageID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_InvalidID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_ParamCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_ParamMismatch : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
- case eError_ParamMissing : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
- case eError_NoHistory : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_Duplicate : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_LogFolder : ; break;
- case eError_LogFileInp : ; break;
- case eError_CredentialFile : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_CredentialPath : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_CredentialCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_CredentialEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_TxCodeNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_TxCodeEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_LogNameNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_LogNameEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_NotRegistered : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- case eError_LogRetentionNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
- }
- return info;
-}
-
-/*!
- * \brief CloudSyncController::errorOut
- * \details the function to send out the error message to the cloudsync inp buffer.
- * \param vErrorID - the error id from CloudSyncController::Errors_Enum in range of 950 to 999
- * \param vInfoItems -
- */
-void CloudSyncController::errorOut(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems) {
- QString msg = QString::number(UI2CS(eMessageID_Error));
- QString len = QString::number(1 + vInfoItems.count());
- QString prm = QString::number(vErrorID);
- QStringList buf = { msg, len, prm };
- for (const auto &item: vInfoItems) {
- buf += item.toString();
- }
- sendUIBuff(buf);
-}
-
-/*!
- * \brief CloudSyncController::toLog
- * \details logs the error in debug mode (service log)
- * \param vErrorID - error id
- * \param vInfoItems - extra information
- */
-void CloudSyncController::toLog(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems)
-{
- errorOut(vErrorID, vInfoItems);
- LOG_DEBUG(toText(vErrorID) + " " + toInfo(vErrorID, vInfoItems));
-}
-
-/*!
- * \brief CloudSyncController::sendUIResponse
- * \details the function to be called after reading the CloudSync out file to interpret the content of the file.
- * \param vContent - the content to be interpreted.
- * \return true if the content has a meaning for the interpreter, false otherwise.
- */
-bool CloudSyncController::sendUIResponse(const QString &vContent)
-{
- // IMPORTANT:
- // please note the following in development testing it has been found out that.
- // Do not use gedit.
- // if the out.buf is edited by the "gedit" application the watch will be broken.
- // The "nano" application works fine.
- // A simple python3 code to open file and write to file works as well and that's sufficient for UI<=>CS communication.
- // TODO: messages have to have a sequence.
- // if the seq is duplicate it will be ignored.
- // seq, id, payload
- // DEBUG: qDebug() << vContent;
-
- bool ok = true;
- Message message;
- if ( ! interpret(vContent, message) ) return false; // The error handling internal to interpret method.
- ok = sendMessage(message);
-
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::testWatchBuffDate
- * \details Checks the date and updated the watched file in case the date changed.
- */
-void CloudSyncController::testWatchBuffDate()
-{
- // prepare date values for addCSBufWatch
- _datetime = QDateTime::currentDateTime().toUTC();
- _secSinceEpoch = _datetime.toSecsSinceEpoch();
- _timeFormatted = _datetime.toString(_timeFormat);
-
- addCSBuffWatch(); // bool out is not used here and error handling is internal to the addCSBuffWatch
-}
-
-/*!
- * \brief CloudSyncController::makeUIBuff
- * \details make formatted UI buffer to send out.
- * \param vMessage - The message id with destination added. 2k, 1K
- * \return the formatted buffer
- */
-QStringList CloudSyncController::makeUIBuff(const qint32 vMessageID, const QStringList &vPrm)
-{
- int count = vPrm.count();
- QStringList prm = count ? vPrm : _uiHistory[ vMessageID ];
- QString msg = QString::number(vMessageID);
- QString len = QString::number(prm.count());
-
- QStringList dataList;
- dataList += msg;
- dataList += len;
- dataList += prm;
-
- return dataList;
-}
-
-/*!
- * \brief CloudSyncController::isDuplicate
- * \param vMessage - current action/messageID received.
- * \param vData - current data to compare with the history
- * \return true if duplicate
- */
-bool CloudSyncController::isDuplicate(const qint32 vMessageID, const QStringList &vData)
-{
- return _uiHistory.contains(vMessageID) && _uiHistory[vMessageID] == vData;
-}
-
-/*!
- * \brief CloudSyncController::writeInpFile
- * \details Writes to the CS Input buffer
- * \param vBuffer - the string out buffer.
- * \return true if successful
- */
-bool CloudSyncController::writeInpFile(const QString &vInpBuff)
-{
- bool ok = true;
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
-
- _date_inp_File = _location + // The location
- _dateFormatted + _dateSeparator + _inp_File; // The file name
-
- // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // writing the message into the buffer.
- LOG_APPED_UI( vInpBuff );
- if(!QFile::exists(_date_inp_File)){
- Storage::FileHandler::makeFolder(_location);
- }
- if ( ! Storage::FileHandler::write(_date_inp_File, vInpBuff + "\n") ) { error = eError_LogFileInp; args = { _date_inp_File }; ok = false; goto lErr; }
- return ok;
-
-lErr:
- // don't send the error back to the CS
- // it calls this same function if the error is in this function
- // and creates a loop
- LOG_DEBUG(toText(error) + " " + toInfo(error, args));
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendUIBuff
- * \details Sends the UI Buffer to the UI input file.
- * \param vData - the data to be sent out.
- * \return true on successful writing to the file buffer.
- * \sa _inp_File
- */
-bool CloudSyncController::sendUIBuff(const QStringList &vDataList)
-{
- bool ok = true;
- QString inpBuff = "%1,%2,%3,%4";
-
- inpBuff = inpBuff
- .arg( _secSinceEpoch )
- .arg( Types::safeIncrement(_seq))
- .arg( generateCRC(_secSinceEpoch, _seq, vDataList))
- .arg( vDataList.join(_separator));
-
- ok = writeInpFile(inpBuff);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::saveUIHistory
- * \details stores the action data in history, if vData is provided.
- * \param vAction - the request id, which in current design is same as the Message comes to the UI.
- * \param vData - The message data
- * \return true if a message history is available, false otherwise.
- */
-bool CloudSyncController::saveUIHistory(const qint32 vAction, const QVariantList &vData)
-{
- bool ok = true;
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
-
- qint32 messageID = UI2CS(static_cast(vAction));
- QStringList data;
-
- if ( vData.isEmpty() ) { error = eError_NoHistory; args = { messageID }; ok = false; goto lErr; }
-
- data = Format::fromVariantList(vData);
-
- if ( isDuplicate(messageID, data) ) { error = eError_Duplicate; args = { messageID }; ok = false; return ok; } // TODO: goto lErr; } don't log it just ignore and return false.
-
- // store the last message data
- _uiHistory[messageID] = data;
-
- return ok;
-
-lErr:
- toLog(error, args);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendUIHistory
- * \details sends the saved history of the message as a response to the cloud sync upon request.
- * \param vAction - the request id, which in current design is same as the Message comes to the UI.
- * \return true if a message history is available, false otherwise.
- */
-bool CloudSyncController::sendUIHistory(const qint32 vAction)
-{
- bool ok = true;
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
-
- // only sends messages if device has been registered
- qint32 messageID = UI2CS(static_cast(vAction));
- if ( ! isRegistered() && vAction != eMessageID_DeviceRegister ) { error = eError_NotRegistered ; args = { messageID }; ok = false; goto lErr; }
- if ( ! _uiHistory.contains( messageID ) ) { error = eError_NoHistory ; args = { messageID }; ok = false; goto lErr; }
-
- sendUIBuff(makeUIBuff(messageID));
-
- return ok;
-
-lErr:
- toLog(error, args);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::onActionReceive
- * \details The slot which will be called when a CANBus message is received, and will be sent to CloudSync if related.
- * \param vAction - The message action
- * \param vData - The message data
- */
-void CloudSyncController::onActionReceive(GuiActionType vAction, const QVariantList &vData)
-{
- // TODO: This section is the translation/mapping section
- // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- // preparing the message
- // Same parameters will be sent for these messages for now, so data is not changed.
-
- switch (vAction) {
- case GuiActionType::ID_HDOperationModeData : {
- // ----------------------------------------------------------------------------------------
- // DEBUG : disable the HD HW message on the device on CloudSync integration testing.
- // currently it is always on fault and resets CloudSync inp log
- QVariantList varData = vData;
- QStringList strData = Format::fromVariantList(vData);
- if ( strData.length() == 2 ) {
- if ( strData[0] == "0" ) {
- if ( strData[1] == "1") { varData = {0,0}; } // use Fault, wait4Tx instead of 0,0 to send fault. to able to simulate and bypass HD.
- else { return; }
- }
- }
- // ----------------------------------------------------------------------------------------
-
- if (saveDeviceState(varData)) // if not empty, nor duplicate, and saved
- sendDeviceState();
- }
- break;
-
- case GuiActionType::ID_AdjustSerialHDRsp :
- case GuiActionType::ID_AdjustSerialDGRsp :
- // this message is not complete in one step and saves only the received info and waits for the other if complete will send.
- saveDeviceInfo(vAction, vData);
- break;
-
- default:
- break;
- }
-}
-
-void CloudSyncController::sendPendingTxr(const QString &vFileName)
-{
- bool ok = true; Q_UNUSED(ok)
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
- qint32 messageID = UI2CS(static_cast( eMessageID_TxReport ));
- // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
- if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { vFileName }; ok = false; goto lErr; }
- sendUIBuff(makeUIBuff( messageID , { vFileName } ));
-
- return;
-lErr:
- toLog(error, args);
-}
-
-void CloudSyncController::onPendingTxr(const QString &vFileName)
-{
- sendPendingTxr(vFileName);
-}
-
-/*!
- * \brief CloudSyncController::onPendingLog
- * \details The signal handler to call the function to send the CloudSync a message to upload the pending file.
- * \param vFileName - The pending file name
- * \param vChecksum - The sha256sum of the file content
- */
-void CloudSyncController::onPendingLog(const QString &vFileName, const QString vChecksum)
-{
- sendPendingLog(vFileName, vChecksum);
-}
-
-/*!
- * \brief CloudSyncController::sendPendingLog
- * \details The function to send CloudSync a message to uplaod the pending log file.
- * \param vFileName - The pending file name
- * \param vChecksum - The sha256sum of the file content
- */
-void CloudSyncController::sendPendingLog(const QString &vFileName, const QString vChecksum)
-{
- bool ok = true; Q_UNUSED(ok)
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
- qint32 messageID = UI2CS(static_cast( eMessageID_SendLogUpload ));
- // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
- if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { vFileName }; ok = false; goto lErr; }
- sendUIBuff(makeUIBuff( messageID , { vFileName, vChecksum } ));
-
- return;
-lErr:
- toLog(error, args);
-}
-
-/*!
- * \brief CloudSyncController::rcvdPendingLog
- * \details reads the received Log Name from CloudSync app and notifies with a signal.
- * \param vMessage : message containing the uploaded Log name.
- * \return true on successful extracting the Log Name.
- */
-bool CloudSyncController::rcvdPendingLog(const Message &vMessage)
-{
- bool ok = true;
- QString mLogName;
- // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
- if ( vMessage.params.isEmpty() ) { toLog(eError_LogNameNoParam , {}); ok = false; goto lOut; }
- mLogName = vMessage.params[0].trimmed();
- if ( mLogName.isEmpty() ) { toLog(eError_LogNameEmpty , {}); ok = false; goto lOut; }
- //DEBUG qDebug() << " ---------- " << mLogName;
- emit didLogUpload( mLogName );
-
- lOut:
- return ok;
-}
-
-/// -------------------------------------------------- Retention Log
-/*!
- * \brief CloudSyncController::onRetentionLog
- * \details The slot tha handles the received even to request for the log retention
- * \param vMaxUsePercent - the maximum size of the SD-Card (log storage device) cloudsync can get for the logs
- */
-void CloudSyncController::onRetentionLog(quint8 vMaxUsePercent)
-{
- sendRetentionLog(vMaxUsePercent);
-}
-
-void CloudSyncController::sendRetentionLog(quint8 vMaxUsePercent)
-{
- bool ok = true; Q_UNUSED(ok)
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
- qint32 messageID = UI2CS(static_cast( eMessageID_SendLogRetention ));
- // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
- if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { eMessageID_SendLogRetention, vMaxUsePercent }; ok = false; goto lErr; }
- sendUIBuff(makeUIBuff( messageID , { QString::number(vMaxUsePercent) } ));
-
- return;
-lErr:
- toLog(error, args);
-}
-
-bool CloudSyncController::rcvdRetentionLog(const Message &vMessage)
-{
- bool ok = true;
- QString tmp;
- quint16 mLogsCount; // number of deleted logs
- quint32 mLogsSize ; // total current logs size
- // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
- if ( vMessage.params.isEmpty() ) { toLog(eError_LogRetentionNoParam , {eMessageID_SendLogRetention }); ok = false; goto lOut; }
- if ( vMessage.params.count () < paramCount[eMessageID_SendLogRetention]) { toLog(eError_ParamCount , {eMessageID_SendLogRetention }); ok = false; goto lOut; }
-
- tmp = vMessage.params[0];
- mLogsCount = tmp.toUInt(&ok);
- if ( ! ok ) { toLog(eError_ParamMismatch , {eMessageID_SendLogRetention, 0}); ok = false; goto lOut; }
-
- tmp = vMessage.params[1];
- mLogsSize = tmp.toUInt(&ok);
- if ( ! ok ) { toLog(eError_ParamMismatch , {eMessageID_SendLogRetention, 1}); ok = false; goto lOut; }
-
- //DEBUG qDebug() << " ---------- " << mLogsCount << mLogsSize;
- emit didLogRetention( mLogsCount, mLogsSize );
-
- LOG_APPED_CS(QString("Log retention deleted %1 files of total %2 MB.").arg(mLogsCount).arg(mLogsSize));
-
- lOut:
- return ok;
-}
-/// --------------------------------------------------
-
-/*!
- * \brief CloudSyncController::sendMessage
- * \details Makes and Sends the appropriate message for the vAction.
- * Some messages are sent out upon request form the last received on the history and will not be asked from FW.
- * \return true if there is a history for that message and no error happened.
- */
-bool CloudSyncController::sendMessage(const Message &vMessage) {
- bool ok = false;
- // we are using the file system for the UI<=>CS communication,
- // and the file events are multiple during the write to the file.
- // if a write to the _out.buf trigeres the message to be sent more than once,
- // ignore the same message, with the same sequence number.
- static quint32 sequence ;
- if ( sequence == vMessage.sequence ) return ok;
- sequence = vMessage.sequence ;
-
- //DEBUG qDebug() << Q_FUNC_INFO << vMessage.id;
- // this function is used in sendUIResponse, therefore the message IDs which are responses should be implemented here.
- switch (vMessage.id) {
- case eMessageID_DeviceRegister : /* No Request/Response */ break;
- case eMessageID_CheckIn : ok = takeCheckIn ( ); break;
- case eMessageID_DeviceInfo : ok = sendDeviceInfo ( ); break;
- case eMessageID_CredentialsSave : ok = sendCredentialsSave( vMessage ); break;
- case eMessageID_UIFactoryReset : ok = sendFactoryReset ( ); break;
- case eMessageID_DeviceState : ok = sendDeviceState ( ); break;
-
- case eMessageID_TxCodeDisplay : ok = sendTxCodeDisplay ( vMessage ); break;
- case eMessageID_SendLogUpload : ok = rcvdPendingLog ( vMessage ); break;
- case eMessageID_SendLogRetention : ok = rcvdRetentionLog ( vMessage ); break;
-
- case eMessageID_TxReport : /* No Req/Rsp, it is event based */ break; // This message doesn't have the response since there is no request. UI will send when the data ready by HD.
-
- case eMessageID_Error : ok = errorHandler ( vMessage ); break;
-
- }
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::saveDeviceState
- * \details Saves the device state in the history for later request
- * \param vData - the device information
- * \return
- */
-bool CloudSyncController::saveDeviceState(const QVariantList &vData)
-{
- bool ok = false;
- ok = saveUIHistory(eMessageID_DeviceState, vData);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendDeviceState
- * \return Sends the last received device state from history to CloudSync
- */
-bool CloudSyncController::sendDeviceState()
-{
- bool ok = false;
- ok = sendUIHistory(eMessageID_DeviceState);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::csFactoryReset
- * \details This function is requesting CloudSync to remove all the logs
- * in the logs folder (/media/sd-card/cloudsync/log/)
- * during Factory Reset
- * It is a request from UI to CS since UI Linux user (denali) should not have access
- * to remove the CloudSync logs.
- */
-bool CloudSyncController::csFactoryReset()
-{
-
- bool ok = true;
- return ok; // NOT IMPLEMENTED
-
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
- qint32 messageID = UI2CS(static_cast( eMessageID_CSFactoryReset ));
-
- if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; }
- sendUIBuff(makeUIBuff( messageID , { } ));
-
- return ok;
-lErr:
- toLog(error, args);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::Decommissioning
- * \details This function is requesting CloudSync to remove all the credentials and configurations
- * in the settings partition (/var/configurations/CloudSync)
- * during decommissioning
- * which then it means the device needs to be re-registered to able to communicate with cloud.
- * It is a request from UI to CS since UI Linux user (denali) should not have access
- * to remove the CloudSync credentials.
- */
-bool CloudSyncController::csDecommissioning()
-{
- bool ok = true;
- QVariantList args ;
- Errors_Enum error = eError_Unknown;
- qint32 messageID = UI2CS(static_cast( eMessageID_CSDecommissioning ));
-
- if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; }
- sendUIBuff(makeUIBuff( messageID , { } ));
-
- return ok;
-lErr:
- toLog(error, args);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::factoryReset
- * \details does the reset factory
- * \return true on successful reset
- */
-bool CloudSyncController::uiFactoryReset()
-{
- // reset factory has not been implemented yet.
- bool ok = true;
- // TODO: call the UI Software Reset Factory here when it has implemented.
- LOG_DEBUG("CloudSync Reset factory request has not been implemented yet.");
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendFactoryReset
- * \details sends the factory reset response to CloudSync
- * \return true on successful send.
- */
-bool CloudSyncController::sendFactoryReset()
-{
- enum { eSucceed, eFailed };
- bool ok = false;
- ok = uiFactoryReset();
- // if ( ! ok ) { } /* Not defined */
- qint32 messageID = UI2CS(eMessageID_UIFactoryReset);
- // TODO : Store registration success in here
- ok = sendUIBuff({ QString("%1").arg( messageID ) ,"1", QString("%1").arg( ok ? eSucceed : eFailed ) });
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendCredentialsSave
- * \details validates the credentials files which their sent location.
- * \param vMessage - the message received from CloudSync
- * \return true on successfully validate the files.
- */
-bool CloudSyncController::sendCredentialsSave( const Message &vMessage)
-{
- bool ok = true;
- QString destination = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name;
-
- // file existence has been separated from copy remove to avoid partial copy.
- if ( ! vMessage.params.count() ) { toLog(eError_CredentialCount , { }); ok = false; goto lOut; }
- for ( auto fileName : vMessage.params ) {
- QFileInfo fileinfo(fileName);
- if ( ! fileinfo.exists() ) { toLog(eError_CredentialFile , {fileName }); ok = false; goto lOut; }
- if ( fileinfo.absolutePath() != destination ) { toLog(eError_CredentialPath , {fileName }); ok = false; goto lOut; }
- }
- // no need to call for isRegistered() function, we are testing for the count, location, and existence.
-
-lOut:
- if ( ok ) sendCredentialsResponse();
- emit didRegisterDone(ok);
- testReady();
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendCredentialsResponse
- * \return send the confirmation of the credential save on the device from UI to CS to let CS know when to delete them.
- */
-bool CloudSyncController::sendCredentialsResponse()
-{
- enum { eSucceed, eFailed };
- bool ok = false;
- qint32 messageID = UI2CS(eMessageID_CredentialsSave);
- ok = sendUIBuff({ QString("%1").arg( messageID ) ,"1", QString("%1").arg( ok ? eSucceed : eFailed ) });
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendCheckIn
- * \details Send a check-in message and expects the same check-in message from CS
- * \return
- */
-bool CloudSyncController::sendCheckIn()
-{
- _checkinRcvd = false;
- qint32 messageID = UI2CS(eMessageID_CheckIn);
- return sendUIBuff( { QString("%1").arg( messageID ) ,"0" } );
-}
-
-/*!
- * \brief CloudSyncController::testCheckIn
- * \details
- * \return
- */
-void CloudSyncController::testCheckIn()
-{
- if ( ! _checkinRcvd ) {
- LOG_APPED_UI(QString("CloudSync check-in failed"));
- }
-}
-
-/*!
- * \brief CloudSyncController::takeCheckIn
- * \details if the check-in received this method will be called
- * \return true -
- */
-bool CloudSyncController::takeCheckIn()
-{
- _checkinRcvd = true;
- emit didCheckInReceive();
- return true;
-}
-
-/*!
- * \brief CloudSyncController::sendTxCodeDisplay
- * \details reads the received Tx Code from CloudSync app and notifies with a signal.
- * \param vMessage : message containing the Tx Code.
- * \return true on successful extracting the Tc Code.
- */
-bool CloudSyncController::sendTxCodeDisplay(const CloudSyncController::Message &vMessage)
-{
- bool ok = true;
- QString mTxCode;
-
- // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
- if ( vMessage.params.isEmpty() ) { toLog(eError_TxCodeNoParam , {}); ok = false; goto lOut; }
-
- mTxCode = vMessage.params[0].trimmed();
- if ( mTxCode.isEmpty() ) { toLog(eError_TxCodeEmpty , {}); ok = false; goto lOut; }
-
- //DEBUG qDebug() << " ---------- " << mTxCode;
- emit didTxCodeReceive ( mTxCode );
-
-lOut:
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::errorHandler
- * \details nothing for now.
- * \param vMessage - the received message
- * \return always true for now.
- */
-bool CloudSyncController::errorHandler(const Message &vMessage)
-{
- qDebug() << "ERR: " << vMessage.params;
- return true;
-}
-
-/*!
- * \brief CloudSyncController::sendDeviceRegister
- * \details sends the device registration request
- * \return true on successful send.
- */
-bool CloudSyncController::sendDeviceRegister()
-{
- bool ok = false;
- ok = sendUIHistory(eMessageID_DeviceRegister);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::isRegistered
- * \details checks if the device is registered by looking for existing credentials.
- * \return true if device has been registered.
- */
-bool CloudSyncController::isRegistered()
-{
-#ifdef BUILD_FOR_DESKTOP
- return true;
-#else
- QString source = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name;
- QFileInfoList fileInfos = QDir(source).entryInfoList(QDir::NoDotAndDotDot|QDir::Files);
- return !fileInfos.isEmpty();
-#endif
-}
-
-/*!
- * \brief CloudSyncController::testReady
- * \details Checks if the CloudSync POST was passed and the device registration is complete.
- */
-void CloudSyncController::testReady()
-{
- bool ok = _postPass && isRegistered();
-#ifdef BUILD_FOR_DESKTOP
- ok = true;
-#endif
- emit didCloudSyncStatus( ok
- || gDisableCloudSyncFailStop // Development testability
- );
-}
-
-/*!
- * \brief CloudSyncController::saveDeviceInfo
- * \details keeps the received device information and set a flag to wait for the next message.
- * \param vAction - the action enum which identifies information source of HD or DG.
- * \param vData - the device information
- * \param vTimedOut - if true the missing device information will be filled by zero and will be sent anyway.
- * \return
- */
-bool CloudSyncController::saveDeviceInfo(GuiActionType vAction, const QVariantList &vData)
-{
- bool ok = false;
-
- // the messages are coming from different sources and the order of receiving could not be guessed.
- // so for each of these two we check and fill the designated variable
- // if both values received
- initDeviceInfoWait();
-
- if ( vAction == GuiActionType::ID_AdjustSerialHDRsp ) {
- if ( vData.count() ) {
- _deviceInfoHD = vData[eDeviceInfo_Ix].toString();
- } else {
- _deviceInfoHD = "";
- }
- }
- if ( vAction == GuiActionType::ID_AdjustSerialDGRsp ) {
- if ( vData.count() ) {
- _deviceInfoDG = vData[eDeviceInfo_Ix].toString();
- } else {
- _deviceInfoDG = "";
- }
- }
-
- if ( !_deviceInfoHD.isEmpty() && !_deviceInfoDG.isEmpty() ) {
- saveDeviceInfoTimeOut();
- ok = true;
- }
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::saveDeviceInfoTimeOut
- * \details send the Device information regardless of the information filled or not.
- * \return true on successful save and send.
- */
-bool CloudSyncController::saveDeviceInfoTimeOut()
-{
- bool ok = false;
- if ( _deviceInfoUI.isEmpty() ) { _deviceInfoUI = qApp->applicationVersion(); }
- saveUIHistory(eMessageID_DeviceInfo , { _deviceInfoHD, _deviceInfoDG, _deviceInfoUI } );
- saveUIHistory(eMessageID_DeviceRegister , { _deviceInfoHD, _deviceInfoDG, _deviceInfoUI } ); // the device registration request format is the same as Device info with different message id.
-
- sendDeviceInfo (); // this one may need to be removed and only will be sent on the request
-
- stopDeviceInfoWait();
-
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::sendDeviceInfo
- * \details sends the devices information if both the HD and DG information are ready otherwise will fill the missing with 0 if the vTimeout is set to true.
- * \return
- */
-bool CloudSyncController::sendDeviceInfo()
-{
- bool ok = false;
- ok = sendUIHistory(eMessageID_DeviceInfo);
- return ok;
-}
-
-/*!
- * \brief CloudSyncController::testDeviceInfoWait
- * \details tests the wait conditions if there is a wait, decrements until times out and sends the device info.
- */
-void CloudSyncController::testDeviceInfoWait()
-{
- if (_deviceInfoStop ) return;
- // DEBUG: qDebug() << _deviceInfoWait;
- if (_deviceInfoWait ){
- _deviceInfoWait -- ;
- }
- else {
- saveDeviceInfoTimeOut();
- }
-}
-
-/*!
- * \brief CloudSyncController::stopDeviceInfoWait
- * \details stops waiting for the device info.
- */
-void CloudSyncController::stopDeviceInfoWait() {
- _deviceInfoStop = true;
- // NOTE: if it is accepted to use the last received info just comment these 3 cleanup lines.
- // so the last message will update the history only and it will be sent out.
- _deviceInfoHD = "";
- _deviceInfoDG = "";
- _deviceInfoUI = "";
-}
-
-/*!
- * \brief CloudSyncController::initDeviceInfoWait
- * \details if currently not in wait, then set the wait to the secs of wait.
- */
-void CloudSyncController::initDeviceInfoWait() {
- if ( _deviceInfoStop ) { // if timer is stopped
- _deviceInfoWait = _deviceInfoSecs; // enable the timer.
- _deviceInfoStop = false;
- }
-}
-
-/*!
- * \brief CloudSyncController::generateCRC
- * \details The crc algorithm is to get
- * all the message sections including, epoch, seq, and the parameters,
- * without any separator
- * concatenate them together like a one long string
- * and run the crc on them
- * \example 1674193951,4,,1001,3,HD1234567890123,DG1234567890123,DEN-14517-UI-BN-S88.01192111.1
- * str: 1674193951410013HD1234567890123DG1234567890123DEN-14517-UI-BN-S88.01192111.1
- * out: 145
- * \note the parameters values will keep untouched, meaning, if a parameter has space it will not be removed.
- * \param vSecSinceEpoch
- * \param vSeq - the message sequence
- * \param vData - the message payload in list of strings
- * \return - quint8 crc code
- */
-quint8 CloudSyncController::generateCRC(quint64 vSecSinceEpoch, quint64 vSeq, const QStringList &vDataList)
-{
- quint8 crc = 0;
- QByteArray buf;
- buf += QByteArray::number(vSecSinceEpoch);
- buf += QByteArray::number(vSeq);
- buf += vDataList.join("").toLatin1();
- crc = crc8(buf);
- return crc;
-}
+#include "CloudSyncController.h"
+
+// Qt
+#include
+
+// Project
+#include "ApplicationController.h"
+#include "DeviceController.h"
+#include "FileHandler.h"
+#include "TreatmentLog.h"
+#include "crc.h"
+
+SINGLETON_DISABLE(CloudSyncController)
+
+/*!
+ * \brief CloudSyncController::CloudSyncController
+ * \details Constructor
+ * \param parent - QObject parent owner object.
+ * Qt handles the children destruction by their parent objects life-cycle.
+ */
+CloudSyncController::CloudSyncController(QObject *parent) : QObject(parent) {
+ testWatchBuffDate();
+ startTimer(_interval);
+}
+
+/*!
+ * \brief CloudSyncController initializer
+ */
+bool CloudSyncController::init()
+{
+ if ( _init ) return false;
+ _init = true;
+
+ initConnections();
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
+
+ return true;
+}
+
+/*!
+ * \brief CloudSyncController::init
+ * \details Initialized the Class by calling the init() method first
+ * And initializes the thread vThread by calling initThread
+ * on success init().
+ * \param vThread - the thread
+ * \return returns the return value of the init() method
+ */
+bool CloudSyncController::init(QThread &vThread)
+{
+ if ( ! init() ) return false;
+ initThread(vThread);
+ return true;
+}
+
+/*!
+ * \brief CloudSyncController::quit
+ * \details quits the class
+ * Calls quitThread
+ */
+void CloudSyncController::quit()
+{
+ // disabled coco begin validated: CloudSync termination is not correctly done in coco!!!
+ // it has been tested and works perfectly fine in normal run.
+ quitThread(); // validated
+}
+// disabled coco end
+
+/*!
+ * \brief CloudSyncController::doRegister
+ * \details Send the register device command.
+ */
+void CloudSyncController::doRegister()
+{
+ sendDeviceRegister();
+}
+
+/*!
+ * \brief CloudSyncController::initConnections
+ * \details Initializes the required signal/slot connection between this class and other objects
+ * to be able to communicate.
+ */
+void CloudSyncController::initConnections()
+{
+ if ( ! gDisableCloudSyncFailStop ) {
+ SINGLETON_DISABLE_CONNECT(didPOSTCloudSync)
+ }
+
+ connect(&_ApplicationController , SIGNAL(didPOSTCloudSync(bool)),
+ this , SLOT( onPOSTCloudSync(bool)));
+ connect(&_ApplicationController , SIGNAL(didActionReceive (GuiActionType , const QVariantList &)),
+ this , SLOT( onActionReceive (GuiActionType , const QVariantList &)));
+
+ connect(&_DeviceController , SIGNAL(didCryptSetupMount(bool)),
+ this , SLOT( onCryptSetupMount(bool)));
+ connect(&_DeviceController , SIGNAL(didPendingLog (const QString &, const QString &)),
+ this , SLOT( onPendingLog (const QString &, const QString &)));
+ connect(&_Logger , SIGNAL(didRetentionLogCS (quint8)),
+ this , SLOT( onRetentionLog (quint8)));
+
+ connect(&_DeviceController , SIGNAL(didWatchFileChange (const QString &)),
+ this , SLOT( onWatchFileChange (const QString &)));
+ connect(&_DeviceController , SIGNAL(didFactoryReset (bool)),
+ this , SLOT( onFactoryReset (bool)));
+ connect(&_DeviceController , SIGNAL(didDecommissioning (bool)),
+ this , SLOT( onDecommissioning (bool)));
+ connect(&_TreatmentLog , SIGNAL(didPendingTxr (const QString &)),
+ this , SLOT( onPendingTxr (const QString &)));
+ connect(this , SIGNAL(didInitComplete ()),
+ this , SLOT( onInitComplete ()),Qt::QueuedConnection); // it has to be queued connection, don't remove it.
+}
+
+/*!
+ * \brief CloudSyncController::initThread
+ * \details Moves this object into the thread vThread.
+ * And checks that this method is called from main thread.
+ * Also connects quitThread to CloudSync aboutToQuit.
+ * \param vThread - the thread
+ */
+void CloudSyncController::initThread(QThread &vThread)
+{
+ // runs in main thread
+ Q_ASSERT_X(QThread::currentThread() == qApp->thread(), __func__, "The Class initialization must be done in Main Thread" );
+ _thread = &vThread;
+ _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className()));
+ connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit()));
+ _thread->start();
+ moveToThread(_thread);
+}
+
+/*!
+ * \brief CloudSyncController::quitThread
+ * \details Moves this object to main thread to be handled by QCloudSync
+ * And to be destroyed there.
+ */
+void CloudSyncController::quitThread()
+{
+ // disabled coco begin validated: CloudSync termination is not correctly done in coco!!!
+ // it has been tested and works perfectly fine in normal run.
+
+ if ( ! _thread ) return;
+
+ // runs in thread
+ moveToThread(qApp->thread()); // validated
+}
+// disabled coco end
+
+/*!
+ * \brief CloudSyncController::timerEvent
+ * \details The timer event handler which currently is triggered on each second to check for the date change,
+ * Which caused the watched file change and needs to updated the watched list.
+ * The check-in (watch dog) also needs to be here.
+ */
+void CloudSyncController::timerEvent(QTimerEvent *)
+{
+ TIME_CALL(sendCheckIn(), _checkinIntervalSend); // call every x times/second - will be called on first call.
+ TIME_CALL(testCheckIn(), _checkinIntervalTest); // call every x times/second - will be called on first call.
+ testWatchBuffDate();
+ testDeviceInfoWait();
+}
+
+/*!
+ * \brief CloudSyncController::event
+ * \details The override method of QObject event to handle the ThreadChange.
+ * \param vEvent - the QObject event
+ * \return true if the event e was recognized and processed
+ */
+bool CloudSyncController::event(QEvent *vEvent) {
+ if (vEvent->type() == QEvent::ThreadChange) {
+ emit didInitComplete();
+ }
+ // Make sure the rest of events are handled
+ return QObject::event(vEvent);
+}
+
+/*!
+ * \brief CloudSyncController::onInitComplete
+ * \details The slot to be called when the CloudSync initialization is complete
+ * Does nothing for now
+ */
+void CloudSyncController::onInitComplete() {
+ /* Development testability:
+ For testing if -C (gDisableCloudSyncFailStop) is used call the testReady
+ which is called
+ - when the encrypted partition is mounted
+ - a request for credential save received
+ testReady will set ok = true if -C (gDisableCloudSyncFailStop) is used.
+ */
+ if ( gDisableCloudSyncFailStop ) testReady();
+}
+
+/*!
+ * \brief CloudSyncController::onPOSTCloudSync
+ * \details This the handler for the ApplicationController::didPOSTCloudSync(bool)
+ * \param vPass - will be true if the POST test of CloudSync passed and it is running.
+ */
+void CloudSyncController::onPOSTCloudSync(bool vPass)
+{
+ _postPass = vPass;
+}
+
+/*!
+ * \brief CloudSyncController::onCryptSetupMount
+ * \details This the handler for the DeviceController::onCryptSetupMount()
+ */
+void CloudSyncController::onCryptSetupMount(bool vPass)
+{
+ if ( vPass ) {
+ testReady();
+ }
+}
+
+/*!
+ * \brief CloudSyncController::onFactoryReset
+ * \details this slot will be called when the DeviceController is done with the Factory Reset
+ * to let the UI request CS to do the Factory Reset and clean up all the Logs.
+ * \param vPass - Device controller factory reset was successful.
+ */
+void CloudSyncController::onFactoryReset(bool vPass)
+{
+ if ( vPass ) {
+ csFactoryReset();
+ }
+}
+
+/*!
+ * \brief CloudSyncController::onDecommissioning
+ * \details this slot will be called when the DeviceController is done with the Decommissioning
+ * to let the UI request CS to do the Decommissioning and clean up all the Tokens.
+ * \param vPass - Device controller Decommissioning was successful.
+ */
+void CloudSyncController::onDecommissioning(bool vPass)
+{
+ if ( vPass ) {
+ csDecommissioning();
+ }
+}
+
+/*!
+ * \brief CloudSyncController::onWatchFileChange
+ * \details This slot will be called when the Device Controller identifies any changes in the watched files.
+ * \param vFile - watched file
+ * \note The DeviceController will emit the signal on any watched file update, it's up to the CloudSyncController to filter the result.
+ */
+void CloudSyncController::onWatchFileChange(const QString &vFile)
+{
+ // TODO: It may improve the performance of the code to make it more specific.
+ // Meaning, Device controller has only one file watcher and it will call all the slots of all the classes watching for a file change.
+ // then ignore what is not important, but it may effect, the call queue and the threading performance.
+ // Later investigation.
+ if ( vFile != _date_out_File ) return; // ignore unwanted file updates.
+ QString content;
+ Storage::FileHandler::read(vFile, content);
+ sendUIResponse(content);
+}
+
+/*!
+ * \brief CloudSyncController::addCSBuffWatch
+ * \details Adds a watcher on the CloudSync Application output file.
+ * \sa _out_File
+ */
+bool CloudSyncController::addCSBuffWatch()
+{
+ bool ok = true;
+ QVariantList args {};
+ Errors_Enum error = eError_Unknown;
+ QString dateFormatted;
+
+ // -------------------------------------------------- check the folder
+ // this makeFolder function call investigated for permissions
+ // during setup the folder if does not exists will be created (root)
+ // the lockdown.sh script will set the permissions for it.
+ // on power cycle to normal operation the folder with the correct exists.
+ // *** NOTE: the makeFolder returns true if the folder already exists. ***
+ ok = Storage::FileHandler::makeFolder(_location);
+ if ( ! ok ) { error = eError_LogFolder; args = {{ _location }}; ok = false; goto lErr; }
+
+ // -------------------------------------------------- Check the out file
+ // check the date time for the file to watch
+ dateFormatted = _datetime.toString(_dateFormat);
+ if (_dateFormatted != dateFormatted ) {
+ _dateFormatted = dateFormatted;
+ _isWatching = false; // first time the date changes and CSctrl needs a new watch this flag need to be reset until the watch is added.
+ }
+ _date_out_File = _location + _dateFormatted + _dateSeparator + _out_File;
+ // watching/wait for the cloud sync output file buffer.
+ // if the file does not exists, send a check-in to the CS and wait for the response.
+ // by CS sending the response it will create the out file and next time this function with start watching the file.
+ // since this class has a one second timer set, next call is next second
+ // TODO: during this less that 1s UI will not see messages from CS, since the file was not there to watch.
+ // send device state to make the CloudSync send back a message to create the out buff with its user to own the file
+ ok = QFileInfo(_date_out_File).exists();
+ if ( ! ok ) {
+ _isWatching = false;
+ sendCheckIn();
+ }
+ if ( ! ok ) { error = eError_OutFileExist; args = {{ _location }}; ok = false; goto lErr; }
+
+ // -------------------------------------------------- return if already watching
+ if ( _isWatching ) { goto lOut; }
+
+ // -------------------------------------------------- add the watch
+ _DeviceController.doAddWatch(_date_out_File, false);
+ _isWatching = true; // when the watch is added then the flag sets until next time the date changes.
+ // since the buff files will be deleted on each power cycle, when the out buf is created it means the CloudSync is running.
+ // we emit the ApplicationController to check the post.log for the CloudSync status check.
+ goto lOut;
+
+lErr:
+ toLog(error, args);
+
+lOut:
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::interpret
+ * \details Checks the received buffer to make sure it has all the required parameters
+ * \param vIndex
+ * \return true if the buffer is correct.
+ */
+bool CloudSyncController::interpret(const QString &vContent, Message &vMessage)
+{
+ bool ok = true;
+ QVariantList args {};
+ Errors_Enum error = eError_Unknown;
+
+ QStringList lines;
+ QString buffer;
+
+ int index = -1;
+ quint32 count = 0;
+
+ Message message;
+ QStringList items;
+ quint32 id;
+
+ if ( vContent.trimmed().isEmpty() ) { error = eError_OutFileEmpty ; ok = false; goto lErr; }
+
+ lines = vContent.split('\n',Qt::SkipEmptyParts);
+ buffer = lines.last();
+ // DEBUG: LOG_DEBUG(QString("CS [%1]").arg(buffer));
+
+ items = buffer.split(_separator);
+ count = items.count();
+
+ // check the required message length
+ if ( count < eMessage_Count ) { error = eError_HeaderCount ; ok = false; goto lErr; }
+ index = eMessage_Timestamp ; message.timestamp = items[index].toUInt(&ok); if (!ok) { error = eError_Timestamp ; ok = false; goto lErr; }
+ index = eMessage_Sequence ; message.sequence = items[index].toUInt(&ok); if (!ok) { error = eError_Sequence ; ok = false; goto lErr; }
+ index = eMessage_CRC ; message.crc = items[index].toUInt(&ok); if (!ok) { error = eError_CSCRC ; ok = false; goto lErr; }
+ index = eMessage_MessageID ; message.id = items[index].toInt (&ok); if (!ok) { error = eError_MessageID ; ok = false; goto lErr; }
+ index = eMessage_ParamCount; message.paramCount = items[index].toUInt(&ok); if (!ok) { error = eError_ParamCount ; ok = false; goto lErr; }
+
+ // check the parameters count
+ if ( count - eMessage_Count != message.paramCount ) { error = eError_ParamMismatch ; ok = false; goto lErr; }
+
+ // check missing parameters
+ id = CS2UI(message.id);
+ if ( ! paramCount.contains(id)) paramCount[id] = 0;
+ if ( message.paramCount < paramCount[id] ) { error = eError_ParamMissing ; ok = false; goto lErr; }
+
+ // convert the message id and check its validity
+ id = message.id; // keep the original recevied message id after we are done using the id for loggging.
+ message.id = CS2UI(static_cast(message.id));
+ if ( eMessageID_Start > message.id || message.id > eMessageID_Count ) { error = eError_InvalidID ; ok = false; goto lErr; }
+
+ // getting the parameters
+ for ( quint32 i = eMessage_Count; i < eMessage_Count + message.paramCount; i++ ) {
+ message.params.append( items[i] );
+ }
+
+ vMessage = message;
+ LOG_APPED_CS(QString("%1,%2").arg(id).arg(message.params.join(',')));
+
+ return true;
+
+lErr:
+ // building the error info for each error
+ switch (error) {
+ case eError_Unknown : args = { }; break;
+ case eError_OutFileExist : args = { }; break;
+ case eError_OutFileEmpty : args = { }; break;
+ case eError_HeaderCount : args = { count , eMessage_Count }; break;
+ case eError_Timestamp : args = { items[index].trimmed() }; break;
+ case eError_Sequence : args = { items[index].trimmed() }; break;
+ case eError_CSCRC : args = { items[index].trimmed() }; break;
+ case eError_MessageID : args = { items[index].trimmed() }; break;
+ case eError_InvalidID : args = { items[index].trimmed() }; break;
+ case eError_ParamCount : args = { items[index].trimmed() }; break;
+ case eError_ParamMismatch : args = { count - eMessage_Count , message.paramCount }; break;
+ case eError_ParamMissing : args = { paramCount[message.id] , message.paramCount }; break;
+ // Interpreter function only handles the message parsing errors. So default can be used.
+ default : break;
+ }
+ toLog(error, args);
+ return false;
+}
+
+/*!
+ * \brief CloudSyncController::toText
+ * \details returns the error message of the error id.
+ * \param vErrorID - Error id
+ * \param vMessage - error message
+ * \return the error message or empty string if the error is 0 (no error), or Unknown Error if not found
+ */
+QString CloudSyncController::toText(CloudSyncController::Errors_Enum vErrorID)
+{
+ QString text = tr( "CS Unknown Error" ) ;
+ if ( vErrorID == 0 ) return text;
+ switch (vErrorID) {
+ case eError_Unknown : /* "CS Unknown Error" */ ; break;
+ // CS Errors
+ case eError_Registration : text = tr( "CS The device registration failed" ) ; break;
+ case eError_DeviceState : text = tr( "CS Invalid Device State" ) ; break;
+ case eError_TxReport : text = tr( "CS The treatment report delivery failed" ) ; break;
+ case eError_CheckIn : text = tr( "CS The device check-in failed" ) ; break;
+ case eError_Decommission : text = tr( "CS The device decommissioning failed" ) ; break;
+ case eError_UICRC : text = tr( "CS Invalid UI Message CRC" ) ; break;
+ case eError_DeviceValidation : text = tr( "CS DRT device registration failed" ) ; break;
+ case eError_PatientAssociation : text = tr( "CS Patient association failed" ) ; break;
+ case eError_GetNewTokenCert : text = tr( "CS New token certification failed" ) ; break;
+ case eError_VerifyToken : text = tr( "CS Token verification failed" ) ; break;
+ case eError_ValidateDevice : text = tr( "CS Cloud device validation failed" ) ; break;
+ case eError_PatientIdExists : text = tr( "CS Patient ID does not exists" ) ; break;
+ case eError_TemporaryPatient : text = tr( "CS Temporary patient ID creation failed" ) ; break;
+ case eError_SaveCredentials : text = tr( "CS Save credentials failed" ) ; break;
+ case eError_UnknownDeviceState : text = tr( "CS Unknown device state" ) ; break;
+ case eError_ConfigSave : text = tr( "CS Config file save failed" ) ; break;
+ case eError_DeviceLog : text = tr( "CS Log upload failed" ) ; break;
+ case eError_Logging : text = tr( "CS Log upload failed" ) ; break;
+ case eError_FactoryReset : text = tr( "CS The device factory reset failed" ) ; break;
+ case eError_Retention : text = tr( "CS The log retention failed" ) ; break;
+ // UI Errors
+ case eError_OutFileExist : text = tr( "CS Out buffer file does not exist" ) ; break;
+ case eError_OutFileEmpty : text = tr( "CS Out buffer empty" ) ; break;
+ case eError_HeaderCount : text = tr( "CS Incorrect header" ) ; break;
+ case eError_Timestamp : text = tr( "CS Incorrect timestamp" ) ; break;
+ case eError_Sequence : text = tr( "CS Incorrect sequence" ) ; break;
+ case eError_CSCRC : text = tr( "CS Incorrect CRC" ) ; break;
+ case eError_MessageID : text = tr( "CS Incorrect ID" ) ; break;
+ case eError_ParamCount : text = tr( "CS Incorrect parameter count" ) ; break;
+ case eError_InvalidID : text = tr( "CS Invalid ID" ) ; break;
+ case eError_ParamMismatch : text = tr( "CS Mismatch parameter count" ) ; break;
+ case eError_ParamMissing : text = tr( "CS Missing parameter" ) ; break;
+ case eError_NoHistory : text = tr( "CS No history available" ) ; break;
+ case eError_Duplicate : text = tr( "CS Duplicate data" ) ; break;
+ case eError_LogFolder : text = tr( "CS The log folder cannot be created." ) ; break;
+ case eError_LogFileInp : text = tr( "CS Error writing to the input file." ) ; break;
+ case eError_CredentialFile : text = tr( "CS The credentials file does not exist." ) ; break;
+ case eError_CredentialPath : text = tr( "CS The credentials folder is incorrect." ) ; break;
+ case eError_CredentialCount : text = tr( "CS No credential file name provided." ) ; break;
+ case eError_CredentialEmpty : text = tr( "CS The credentials folder is empty." ) ; break;
+ case eError_TxCodeNoParam : text = tr( "CS No Treatment Code provided." ) ; break;
+ case eError_TxCodeEmpty : text = tr( "CS The provided Treatment Code is empty." ) ; break;
+ case eError_LogNameNoParam : text = tr( "CS No Log Name provided." ) ; break;
+ case eError_LogNameEmpty : text = tr( "CS The provided Log Name is empty." ) ; break;
+ case eError_NotRegistered : text = tr( "CS Not Sent, Device not registered." ) ; break;
+ case eError_LogRetentionNoParam : text = tr( "CS No Log Retention summary provided." ) ; break;
+
+ }
+ return text;
+}
+
+/*!
+ * \brief CloudSyncController::toInfo
+ * \details Provides extra information, related to each error, to be concatenated later to the error description.
+ * \param vErrorID - the error id
+ * \param vInfoItems - the information items to be used in creating the info.
+ * \return the extra info for the error as string
+ */
+QString CloudSyncController::toInfo(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems)
+{
+ // IMPORTANT: Please be careful here used QVariantList::value to act as a loose list.
+ // It means it is designed to not throw out of bound error and just use "~" as a missing info argument.
+ auto item = [=](uint i) { return vInfoItems.value(i,"~").toString(); };
+
+ QString info = QString( "[%1]" ).arg( vErrorID ) ;
+ switch (vErrorID) {
+ case eError_Unknown : ; break;
+ // CS Errors
+ case eError_Registration : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_DeviceState : ; break;
+ case eError_TxReport : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_CheckIn : ; break;
+ case eError_Decommission : ; break;
+ case eError_UICRC : /* info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) */ ; break;
+ case eError_DeviceValidation : ; break;
+ case eError_PatientAssociation : ; break;
+ case eError_GetNewTokenCert : ; break;
+ case eError_VerifyToken : ; break;
+ case eError_ValidateDevice : ; break;
+ case eError_PatientIdExists : ; break;
+ case eError_TemporaryPatient : ; break;
+ case eError_SaveCredentials : ; break;
+ case eError_UnknownDeviceState : ; break;
+ case eError_ConfigSave : ; break;
+ case eError_DeviceLog : ; break;
+ case eError_Logging : ; break;
+ case eError_FactoryReset : ; break;
+ case eError_Retention : ; break;
+ // UI Errors
+ case eError_OutFileExist : ; break;
+ case eError_OutFileEmpty : ; break;
+ case eError_HeaderCount : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
+ case eError_Timestamp : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_Sequence : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_CSCRC : /* info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) */ ; break;
+ case eError_MessageID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_InvalidID : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_ParamCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_ParamMismatch : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
+ case eError_ParamMissing : info = QString( "[%1:%2/%3]" ).arg( vErrorID ).arg( item(0) ).arg( item(1) ) ; break;
+ case eError_NoHistory : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_Duplicate : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_LogFolder : ; break;
+ case eError_LogFileInp : ; break;
+ case eError_CredentialFile : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_CredentialPath : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_CredentialCount : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_CredentialEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_TxCodeNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_TxCodeEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_LogNameNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_LogNameEmpty : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_NotRegistered : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ case eError_LogRetentionNoParam : info = QString( "[%1:%2]" ).arg( vErrorID ).arg( item(0) ) ; break;
+ }
+ return info;
+}
+
+/*!
+ * \brief CloudSyncController::errorOut
+ * \details the function to send out the error message to the cloudsync inp buffer.
+ * \param vErrorID - the error id from CloudSyncController::Errors_Enum in range of 950 to 999
+ * \param vInfoItems -
+ */
+void CloudSyncController::errorOut(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems) {
+ QString msg = QString::number(UI2CS(eMessageID_Error));
+ QString len = QString::number(1 + vInfoItems.count());
+ QString prm = QString::number(vErrorID);
+ QStringList buf = { msg, len, prm };
+ for (const auto &item: vInfoItems) {
+ buf += item.toString();
+ }
+ sendUIBuff(buf);
+}
+
+/*!
+ * \brief CloudSyncController::toLog
+ * \details logs the error in debug mode (service log)
+ * \param vErrorID - error id
+ * \param vInfoItems - extra information
+ */
+void CloudSyncController::toLog(CloudSyncController::Errors_Enum vErrorID, const QVariantList &vInfoItems)
+{
+ errorOut(vErrorID, vInfoItems);
+ LOG_DEBUG(toText(vErrorID) + " " + toInfo(vErrorID, vInfoItems));
+}
+
+/*!
+ * \brief CloudSyncController::sendUIResponse
+ * \details the function to be called after reading the CloudSync out file to interpret the content of the file.
+ * \param vContent - the content to be interpreted.
+ * \return true if the content has a meaning for the interpreter, false otherwise.
+ */
+bool CloudSyncController::sendUIResponse(const QString &vContent)
+{
+ // IMPORTANT:
+ // please note the following in development testing it has been found out that.
+ // Do not use gedit.
+ // if the out.buf is edited by the "gedit" application the watch will be broken.
+ // The "nano" application works fine.
+ // A simple python3 code to open file and write to file works as well and that's sufficient for UI<=>CS communication.
+ // TODO: messages have to have a sequence.
+ // if the seq is duplicate it will be ignored.
+ // seq, id, payload
+ // DEBUG: qDebug() << vContent;
+
+ bool ok = true;
+ Message message;
+ if ( ! interpret(vContent, message) ) return false; // The error handling internal to interpret method.
+ ok = sendMessage(message);
+
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::testWatchBuffDate
+ * \details Checks the date and updated the watched file in case the date changed.
+ */
+void CloudSyncController::testWatchBuffDate()
+{
+ // prepare date values for addCSBufWatch
+ _datetime = QDateTime::currentDateTime().toUTC();
+ _secSinceEpoch = _datetime.toSecsSinceEpoch();
+ _timeFormatted = _datetime.toString(_timeFormat);
+
+ addCSBuffWatch(); // bool out is not used here and error handling is internal to the addCSBuffWatch
+}
+
+/*!
+ * \brief CloudSyncController::makeUIBuff
+ * \details make formatted UI buffer to send out.
+ * \param vMessage - The message id with destination added. 2k, 1K
+ * \return the formatted buffer
+ */
+QStringList CloudSyncController::makeUIBuff(const qint32 vMessageID, const QStringList &vPrm)
+{
+ int count = vPrm.count();
+ QStringList prm = count ? vPrm : _uiHistory[ vMessageID ];
+ QString msg = QString::number(vMessageID);
+ QString len = QString::number(prm.count());
+
+ QStringList dataList;
+ dataList += msg;
+ dataList += len;
+ dataList += prm;
+
+ return dataList;
+}
+
+/*!
+ * \brief CloudSyncController::isDuplicate
+ * \param vMessage - current action/messageID received.
+ * \param vData - current data to compare with the history
+ * \return true if duplicate
+ */
+bool CloudSyncController::isDuplicate(const qint32 vMessageID, const QStringList &vData)
+{
+ return _uiHistory.contains(vMessageID) && _uiHistory[vMessageID] == vData;
+}
+
+/*!
+ * \brief CloudSyncController::writeInpFile
+ * \details Writes to the CS Input buffer
+ * \param vBuffer - the string out buffer.
+ * \return true if successful
+ */
+bool CloudSyncController::writeInpFile(const QString &vInpBuff)
+{
+ bool ok = true;
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+
+ _date_inp_File = _location + // The location
+ _dateFormatted + _dateSeparator + _inp_File; // The file name
+
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // writing the message into the buffer.
+ LOG_APPED_UI( vInpBuff );
+ if(!QFile::exists(_date_inp_File)){
+ Storage::FileHandler::makeFolder(_location);
+ }
+ if ( ! Storage::FileHandler::write(_date_inp_File, vInpBuff + "\n") ) { error = eError_LogFileInp; args = { _date_inp_File }; ok = false; goto lErr; }
+ return ok;
+
+lErr:
+ // don't send the error back to the CS
+ // it calls this same function if the error is in this function
+ // and creates a loop
+ LOG_DEBUG(toText(error) + " " + toInfo(error, args));
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendUIBuff
+ * \details Sends the UI Buffer to the UI input file.
+ * \param vData - the data to be sent out.
+ * \return true on successful writing to the file buffer.
+ * \sa _inp_File
+ */
+bool CloudSyncController::sendUIBuff(const QStringList &vDataList)
+{
+ bool ok = true;
+ QString inpBuff = "%1,%2,%3,%4";
+
+ inpBuff = inpBuff
+ .arg( _secSinceEpoch )
+ .arg( Types::safeIncrement(_seq))
+ .arg( generateCRC(_secSinceEpoch, _seq, vDataList))
+ .arg( vDataList.join(_separator));
+
+ ok = writeInpFile(inpBuff);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::saveUIHistory
+ * \details stores the action data in history, if vData is provided.
+ * \param vAction - the request id, which in current design is same as the Message comes to the UI.
+ * \param vData - The message data
+ * \return true if a message history is available, false otherwise.
+ */
+bool CloudSyncController::saveUIHistory(const qint32 vAction, const QVariantList &vData)
+{
+ bool ok = true;
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+
+ qint32 messageID = UI2CS(static_cast(vAction));
+ QStringList data;
+
+ if ( vData.isEmpty() ) { error = eError_NoHistory; args = { messageID }; ok = false; goto lErr; }
+
+ data = Format::fromVariantList(vData);
+
+ if ( isDuplicate(messageID, data) ) { error = eError_Duplicate; args = { messageID }; ok = false; return ok; } // TODO: goto lErr; } don't log it just ignore and return false.
+
+ // store the last message data
+ _uiHistory[messageID] = data;
+
+ return ok;
+
+lErr:
+ toLog(error, args);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendUIHistory
+ * \details sends the saved history of the message as a response to the cloud sync upon request.
+ * \param vAction - the request id, which in current design is same as the Message comes to the UI.
+ * \return true if a message history is available, false otherwise.
+ */
+bool CloudSyncController::sendUIHistory(const qint32 vAction)
+{
+ bool ok = true;
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+
+ // only sends messages if device has been registered
+ qint32 messageID = UI2CS(static_cast(vAction));
+ if ( ! isRegistered() && vAction != eMessageID_DeviceRegister ) { error = eError_NotRegistered ; args = { messageID }; ok = false; goto lErr; }
+ if ( ! _uiHistory.contains( messageID ) ) { error = eError_NoHistory ; args = { messageID }; ok = false; goto lErr; }
+
+ sendUIBuff(makeUIBuff(messageID));
+
+ return ok;
+
+lErr:
+ toLog(error, args);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::onActionReceive
+ * \details The slot which will be called when a CANBus message is received, and will be sent to CloudSync if related.
+ * \param vAction - The message action
+ * \param vData - The message data
+ */
+void CloudSyncController::onActionReceive(GuiActionType vAction, const QVariantList &vData)
+{
+ // TODO: This section is the translation/mapping section
+ // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+ // preparing the message
+ // Same parameters will be sent for these messages for now, so data is not changed.
+
+ switch (vAction) {
+ case GuiActionType::ID_HDOperationModeData : {
+ // ----------------------------------------------------------------------------------------
+ // DEBUG : disable the HD HW message on the device on CloudSync integration testing.
+ // currently it is always on fault and resets CloudSync inp log
+ QVariantList varData = vData;
+ QStringList strData = Format::fromVariantList(vData);
+ if ( strData.length() == 2 ) {
+ if ( strData[0] == "0" ) {
+ if ( strData[1] == "1") { varData = {0,0}; } // use Fault, wait4Tx instead of 0,0 to send fault. to able to simulate and bypass HD.
+ else { return; }
+ }
+ }
+ // ----------------------------------------------------------------------------------------
+
+ if (saveDeviceState(varData)) // if not empty, nor duplicate, and saved
+ sendDeviceState();
+ }
+ break;
+
+ case GuiActionType::ID_AdjustSerialHDRsp :
+ case GuiActionType::ID_AdjustSerialDGRsp :
+ // this message is not complete in one step and saves only the received info and waits for the other if complete will send.
+ saveDeviceInfo(vAction, vData);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void CloudSyncController::sendPendingTxr(const QString &vFileName)
+{
+ bool ok = true; Q_UNUSED(ok)
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+ qint32 messageID = UI2CS(static_cast( eMessageID_TxReport ));
+ // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
+ if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { vFileName }; ok = false; goto lErr; }
+ sendUIBuff(makeUIBuff( messageID , { vFileName } ));
+
+ return;
+lErr:
+ toLog(error, args);
+}
+
+void CloudSyncController::onPendingTxr(const QString &vFileName)
+{
+ sendPendingTxr(vFileName);
+}
+
+/*!
+ * \brief CloudSyncController::onPendingLog
+ * \details The signal handler to call the function to send the CloudSync a message to upload the pending file.
+ * \param vFileName - The pending file name
+ * \param vChecksum - The sha256sum of the file content
+ */
+void CloudSyncController::onPendingLog(const QString &vFileName, const QString vChecksum)
+{
+ sendPendingLog(vFileName, vChecksum);
+}
+
+/*!
+ * \brief CloudSyncController::sendPendingLog
+ * \details The function to send CloudSync a message to uplaod the pending log file.
+ * \param vFileName - The pending file name
+ * \param vChecksum - The sha256sum of the file content
+ */
+void CloudSyncController::sendPendingLog(const QString &vFileName, const QString vChecksum)
+{
+ bool ok = true; Q_UNUSED(ok)
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+ qint32 messageID = UI2CS(static_cast( eMessageID_SendLogUpload ));
+ // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
+ if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { vFileName }; ok = false; goto lErr; }
+ sendUIBuff(makeUIBuff( messageID , { vFileName, vChecksum } ));
+
+ return;
+lErr:
+ toLog(error, args);
+}
+
+/*!
+ * \brief CloudSyncController::rcvdPendingLog
+ * \details reads the received Log Name from CloudSync app and notifies with a signal.
+ * \param vMessage : message containing the uploaded Log name.
+ * \return true on successful extracting the Log Name.
+ */
+bool CloudSyncController::rcvdPendingLog(const Message &vMessage)
+{
+ bool ok = true;
+ QString mLogName;
+ // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
+ if ( vMessage.params.isEmpty() ) { toLog(eError_LogNameNoParam , {}); ok = false; goto lOut; }
+ mLogName = vMessage.params[0].trimmed();
+ if ( mLogName.isEmpty() ) { toLog(eError_LogNameEmpty , {}); ok = false; goto lOut; }
+ //DEBUG qDebug() << " ---------- " << mLogName;
+ emit didLogUpload( mLogName );
+
+ lOut:
+ return ok;
+}
+
+/// -------------------------------------------------- Retention Log
+/*!
+ * \brief CloudSyncController::onRetentionLog
+ * \details The slot tha handles the received even to request for the log retention
+ * \param vMaxUsePercent - the maximum size of the SD-Card (log storage device) cloudsync can get for the logs
+ */
+void CloudSyncController::onRetentionLog(quint8 vMaxUsePercent)
+{
+ sendRetentionLog(vMaxUsePercent);
+}
+
+void CloudSyncController::sendRetentionLog(quint8 vMaxUsePercent)
+{
+ bool ok = true; Q_UNUSED(ok)
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+ qint32 messageID = UI2CS(static_cast( eMessageID_SendLogRetention ));
+ // DEBUG ok = false; // using the ok bool which is true as the debug flag to bypass the registration on debug testing.
+ if ( ok && ! isRegistered() ) { error = eError_NotRegistered ; args = { eMessageID_SendLogRetention, vMaxUsePercent }; ok = false; goto lErr; }
+ sendUIBuff(makeUIBuff( messageID , { QString::number(vMaxUsePercent) } ));
+
+ return;
+lErr:
+ toLog(error, args);
+}
+
+bool CloudSyncController::rcvdRetentionLog(const Message &vMessage)
+{
+ bool ok = true;
+ QString tmp;
+ quint16 mLogsCount; // number of deleted logs
+ quint32 mLogsSize ; // total current logs size
+ // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
+ if ( vMessage.params.isEmpty() ) { toLog(eError_LogRetentionNoParam , {eMessageID_SendLogRetention }); ok = false; goto lOut; }
+ if ( vMessage.params.count () < paramCount[eMessageID_SendLogRetention]) { toLog(eError_ParamCount , {eMessageID_SendLogRetention }); ok = false; goto lOut; }
+
+ tmp = vMessage.params[0];
+ mLogsCount = tmp.toUInt(&ok);
+ if ( ! ok ) { toLog(eError_ParamMismatch , {eMessageID_SendLogRetention, 0}); ok = false; goto lOut; }
+
+ tmp = vMessage.params[1];
+ mLogsSize = tmp.toUInt(&ok);
+ if ( ! ok ) { toLog(eError_ParamMismatch , {eMessageID_SendLogRetention, 1}); ok = false; goto lOut; }
+
+ //DEBUG qDebug() << " ---------- " << mLogsCount << mLogsSize;
+ emit didLogRetention( mLogsCount, mLogsSize );
+
+ LOG_APPED_CS(QString("Log retention deleted %1 files of total %2 MB.").arg(mLogsCount).arg(mLogsSize));
+
+ lOut:
+ return ok;
+}
+/// --------------------------------------------------
+
+/*!
+ * \brief CloudSyncController::sendMessage
+ * \details Makes and Sends the appropriate message for the vAction.
+ * Some messages are sent out upon request form the last received on the history and will not be asked from FW.
+ * \return true if there is a history for that message and no error happened.
+ */
+bool CloudSyncController::sendMessage(const Message &vMessage) {
+ bool ok = false;
+ // we are using the file system for the UI<=>CS communication,
+ // and the file events are multiple during the write to the file.
+ // if a write to the _out.buf trigeres the message to be sent more than once,
+ // ignore the same message, with the same sequence number.
+ static quint32 sequence ;
+ if ( sequence == vMessage.sequence ) return ok;
+ sequence = vMessage.sequence ;
+
+ //DEBUG qDebug() << Q_FUNC_INFO << vMessage.id;
+ // this function is used in sendUIResponse, therefore the message IDs which are responses should be implemented here.
+ switch (vMessage.id) {
+ case eMessageID_DeviceRegister : /* No Request/Response */ break;
+ case eMessageID_CheckIn : ok = takeCheckIn ( ); break;
+ case eMessageID_DeviceInfo : ok = sendDeviceInfo ( ); break;
+ case eMessageID_CredentialsSave : ok = sendCredentialsSave( vMessage ); break;
+ case eMessageID_UIFactoryReset : ok = sendFactoryReset ( ); break;
+ case eMessageID_DeviceState : ok = sendDeviceState ( ); break;
+
+ case eMessageID_TxCodeDisplay : ok = sendTxCodeDisplay ( vMessage ); break;
+ case eMessageID_SendLogUpload : ok = rcvdPendingLog ( vMessage ); break;
+ case eMessageID_SendLogRetention : ok = rcvdRetentionLog ( vMessage ); break;
+
+ case eMessageID_TxReport : /* No Req/Rsp, it is event based */ break; // This message doesn't have the response since there is no request. UI will send when the data ready by HD.
+
+ case eMessageID_Error : ok = errorHandler ( vMessage ); break;
+
+ }
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::saveDeviceState
+ * \details Saves the device state in the history for later request
+ * \param vData - the device information
+ * \return
+ */
+bool CloudSyncController::saveDeviceState(const QVariantList &vData)
+{
+ bool ok = false;
+ ok = saveUIHistory(eMessageID_DeviceState, vData);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendDeviceState
+ * \return Sends the last received device state from history to CloudSync
+ */
+bool CloudSyncController::sendDeviceState()
+{
+ bool ok = false;
+ ok = sendUIHistory(eMessageID_DeviceState);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::csFactoryReset
+ * \details This function is requesting CloudSync to remove all the logs
+ * in the logs folder (/media/sd-card/cloudsync/log/)
+ * during Factory Reset
+ * It is a request from UI to CS since UI Linux user (denali) should not have access
+ * to remove the CloudSync logs.
+ */
+bool CloudSyncController::csFactoryReset()
+{
+
+ bool ok = true;
+ return ok; // NOT IMPLEMENTED
+
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+ qint32 messageID = UI2CS(static_cast( eMessageID_CSFactoryReset ));
+
+ if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; }
+ sendUIBuff(makeUIBuff( messageID , { } ));
+
+ return ok;
+lErr:
+ toLog(error, args);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::Decommissioning
+ * \details This function is requesting CloudSync to remove all the credentials and configurations
+ * in the settings partition (/var/configurations/CloudSync)
+ * during decommissioning
+ * which then it means the device needs to be re-registered to able to communicate with cloud.
+ * It is a request from UI to CS since UI Linux user (denali) should not have access
+ * to remove the CloudSync credentials.
+ */
+bool CloudSyncController::csDecommissioning()
+{
+ bool ok = true;
+ QVariantList args ;
+ Errors_Enum error = eError_Unknown;
+ qint32 messageID = UI2CS(static_cast( eMessageID_CSDecommissioning ));
+
+ if ( ! isRegistered() ) { error = eError_NotRegistered ; args = {}; ok = false; goto lErr; }
+ sendUIBuff(makeUIBuff( messageID , { } ));
+
+ return ok;
+lErr:
+ toLog(error, args);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::factoryReset
+ * \details does the reset factory
+ * \return true on successful reset
+ */
+bool CloudSyncController::uiFactoryReset()
+{
+ // reset factory has not been implemented yet.
+ bool ok = true;
+ // TODO: call the UI Software Reset Factory here when it has implemented.
+ LOG_DEBUG("CloudSync Reset factory request has not been implemented yet.");
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendFactoryReset
+ * \details sends the factory reset response to CloudSync
+ * \return true on successful send.
+ */
+bool CloudSyncController::sendFactoryReset()
+{
+ enum { eSucceed, eFailed };
+ bool ok = false;
+ ok = uiFactoryReset();
+ // if ( ! ok ) { } /* Not defined */
+ qint32 messageID = UI2CS(eMessageID_UIFactoryReset);
+ // TODO : Store registration success in here
+ ok = sendUIBuff({ QString("%1").arg( messageID ) ,"1", QString("%1").arg( ok ? eSucceed : eFailed ) });
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendCredentialsSave
+ * \details validates the credentials files which their sent location.
+ * \param vMessage - the message received from CloudSync
+ * \return true on successfully validate the files.
+ */
+bool CloudSyncController::sendCredentialsSave( const Message &vMessage)
+{
+ bool ok = true;
+ QString destination = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name;
+
+ // file existence has been separated from copy remove to avoid partial copy.
+ if ( ! vMessage.params.count() ) { toLog(eError_CredentialCount , { }); ok = false; goto lOut; }
+ for ( auto fileName : vMessage.params ) {
+ QFileInfo fileinfo(fileName);
+ if ( ! fileinfo.exists() ) { toLog(eError_CredentialFile , {fileName }); ok = false; goto lOut; }
+ if ( fileinfo.absolutePath() != destination ) { toLog(eError_CredentialPath , {fileName }); ok = false; goto lOut; }
+ }
+ // no need to call for isRegistered() function, we are testing for the count, location, and existence.
+
+lOut:
+ if ( ok ) sendCredentialsResponse();
+ emit didRegisterDone(ok);
+ testReady();
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendCredentialsResponse
+ * \return send the confirmation of the credential save on the device from UI to CS to let CS know when to delete them.
+ */
+bool CloudSyncController::sendCredentialsResponse()
+{
+ enum { eSucceed, eFailed };
+ bool ok = false;
+ qint32 messageID = UI2CS(eMessageID_CredentialsSave);
+ ok = sendUIBuff({ QString("%1").arg( messageID ) ,"1", QString("%1").arg( ok ? eSucceed : eFailed ) });
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendCheckIn
+ * \details Send a check-in message and expects the same check-in message from CS
+ * \return
+ */
+bool CloudSyncController::sendCheckIn()
+{
+ _checkinRcvd = false;
+ qint32 messageID = UI2CS(eMessageID_CheckIn);
+ return sendUIBuff( { QString("%1").arg( messageID ) ,"0" } );
+}
+
+/*!
+ * \brief CloudSyncController::testCheckIn
+ * \details
+ * \return
+ */
+void CloudSyncController::testCheckIn()
+{
+ if ( ! _checkinRcvd ) {
+ LOG_APPED_UI(QString("CloudSync check-in failed"));
+ }
+}
+
+/*!
+ * \brief CloudSyncController::takeCheckIn
+ * \details if the check-in received this method will be called
+ * \return true -
+ */
+bool CloudSyncController::takeCheckIn()
+{
+ _checkinRcvd = true;
+ emit didCheckInReceive();
+ return true;
+}
+
+/*!
+ * \brief CloudSyncController::sendTxCodeDisplay
+ * \details reads the received Tx Code from CloudSync app and notifies with a signal.
+ * \param vMessage : message containing the Tx Code.
+ * \return true on successful extracting the Tc Code.
+ */
+bool CloudSyncController::sendTxCodeDisplay(const CloudSyncController::Message &vMessage)
+{
+ bool ok = true;
+ QString mTxCode;
+
+ // although it has been checked in the interpreter, we won't risk the crash and check the list empty.
+ if ( vMessage.params.isEmpty() ) { toLog(eError_TxCodeNoParam , {}); ok = false; goto lOut; }
+
+ mTxCode = vMessage.params[0].trimmed();
+ if ( mTxCode.isEmpty() ) { toLog(eError_TxCodeEmpty , {}); ok = false; goto lOut; }
+
+ //DEBUG qDebug() << " ---------- " << mTxCode;
+ emit didTxCodeReceive ( mTxCode );
+
+lOut:
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::errorHandler
+ * \details nothing for now.
+ * \param vMessage - the received message
+ * \return always true for now.
+ */
+bool CloudSyncController::errorHandler(const Message &vMessage)
+{
+ qDebug() << "ERR: " << vMessage.params;
+ return true;
+}
+
+/*!
+ * \brief CloudSyncController::sendDeviceRegister
+ * \details sends the device registration request
+ * \return true on successful send.
+ */
+bool CloudSyncController::sendDeviceRegister()
+{
+ bool ok = false;
+ ok = sendUIHistory(eMessageID_DeviceRegister);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::isRegistered
+ * \details checks if the device is registered by looking for existing credentials.
+ * \return true if device has been registered.
+ */
+bool CloudSyncController::isRegistered()
+{
+#ifdef BUILD_FOR_DESKTOP
+ return true;
+#else
+ QString source = QString(Storage::CloudSync_Base_Path_Name) + Storage::CloudSync_Credentials_Folder_Name;
+ QFileInfoList fileInfos = QDir(source).entryInfoList(QDir::NoDotAndDotDot|QDir::Files);
+ return !fileInfos.isEmpty();
+#endif
+}
+
+/*!
+ * \brief CloudSyncController::testReady
+ * \details Checks if the CloudSync POST was passed and the device registration is complete.
+ */
+void CloudSyncController::testReady()
+{
+ bool ok = _postPass && isRegistered();
+#ifdef BUILD_FOR_DESKTOP
+ ok = true;
+#endif
+ emit didCloudSyncStatus( ok
+ || gDisableCloudSyncFailStop // Development testability
+ );
+}
+
+/*!
+ * \brief CloudSyncController::saveDeviceInfo
+ * \details keeps the received device information and set a flag to wait for the next message.
+ * \param vAction - the action enum which identifies information source of HD or DG.
+ * \param vData - the device information
+ * \param vTimedOut - if true the missing device information will be filled by zero and will be sent anyway.
+ * \return
+ */
+bool CloudSyncController::saveDeviceInfo(GuiActionType vAction, const QVariantList &vData)
+{
+ bool ok = false;
+
+ // the messages are coming from different sources and the order of receiving could not be guessed.
+ // so for each of these two we check and fill the designated variable
+ // if both values received
+ initDeviceInfoWait();
+
+ if ( vAction == GuiActionType::ID_AdjustSerialHDRsp ) {
+ if ( vData.count() ) {
+ _deviceInfoHD = vData[eDeviceInfo_Ix].toString();
+ } else {
+ _deviceInfoHD = "";
+ }
+ }
+ if ( vAction == GuiActionType::ID_AdjustSerialDGRsp ) {
+ if ( vData.count() ) {
+ _deviceInfoDG = vData[eDeviceInfo_Ix].toString();
+ } else {
+ _deviceInfoDG = "";
+ }
+ }
+
+ if ( !_deviceInfoHD.isEmpty() && !_deviceInfoDG.isEmpty() ) {
+ saveDeviceInfoTimeOut();
+ ok = true;
+ }
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::saveDeviceInfoTimeOut
+ * \details send the Device information regardless of the information filled or not.
+ * \return true on successful save and send.
+ */
+bool CloudSyncController::saveDeviceInfoTimeOut()
+{
+ bool ok = false;
+ if ( _deviceInfoUI.isEmpty() ) { _deviceInfoUI = qApp->applicationVersion(); }
+ saveUIHistory(eMessageID_DeviceInfo , { _deviceInfoHD, _deviceInfoDG, _deviceInfoUI } );
+ saveUIHistory(eMessageID_DeviceRegister , { _deviceInfoHD, _deviceInfoDG, _deviceInfoUI } ); // the device registration request format is the same as Device info with different message id.
+
+ sendDeviceInfo (); // this one may need to be removed and only will be sent on the request
+
+ stopDeviceInfoWait();
+
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::sendDeviceInfo
+ * \details sends the devices information if both the HD and DG information are ready otherwise will fill the missing with 0 if the vTimeout is set to true.
+ * \return
+ */
+bool CloudSyncController::sendDeviceInfo()
+{
+ bool ok = false;
+ ok = sendUIHistory(eMessageID_DeviceInfo);
+ return ok;
+}
+
+/*!
+ * \brief CloudSyncController::testDeviceInfoWait
+ * \details tests the wait conditions if there is a wait, decrements until times out and sends the device info.
+ */
+void CloudSyncController::testDeviceInfoWait()
+{
+ if (_deviceInfoStop ) return;
+ // DEBUG: qDebug() << _deviceInfoWait;
+ if (_deviceInfoWait ){
+ _deviceInfoWait -- ;
+ }
+ else {
+ saveDeviceInfoTimeOut();
+ }
+}
+
+/*!
+ * \brief CloudSyncController::stopDeviceInfoWait
+ * \details stops waiting for the device info.
+ */
+void CloudSyncController::stopDeviceInfoWait() {
+ _deviceInfoStop = true;
+ // NOTE: if it is accepted to use the last received info just comment these 3 cleanup lines.
+ // so the last message will update the history only and it will be sent out.
+ _deviceInfoHD = "";
+ _deviceInfoDG = "";
+ _deviceInfoUI = "";
+}
+
+/*!
+ * \brief CloudSyncController::initDeviceInfoWait
+ * \details if currently not in wait, then set the wait to the secs of wait.
+ */
+void CloudSyncController::initDeviceInfoWait() {
+ if ( _deviceInfoStop ) { // if timer is stopped
+ _deviceInfoWait = _deviceInfoSecs; // enable the timer.
+ _deviceInfoStop = false;
+ }
+}
+
+/*!
+ * \brief CloudSyncController::generateCRC
+ * \details The crc algorithm is to get
+ * all the message sections including, epoch, seq, and the parameters,
+ * without any separator
+ * concatenate them together like a one long string
+ * and run the crc on them
+ * \example 1674193951,4,,1001,3,HD1234567890123,DG1234567890123,DEN-14517-UI-BN-S88.01192111.1
+ * str: 1674193951410013HD1234567890123DG1234567890123DEN-14517-UI-BN-S88.01192111.1
+ * out: 145
+ * \note the parameters values will keep untouched, meaning, if a parameter has space it will not be removed.
+ * \param vSecSinceEpoch
+ * \param vSeq - the message sequence
+ * \param vData - the message payload in list of strings
+ * \return - quint8 crc code
+ */
+quint8 CloudSyncController::generateCRC(quint64 vSecSinceEpoch, quint64 vSeq, const QStringList &vDataList)
+{
+ quint8 crc = 0;
+ QByteArray buf;
+ buf += QByteArray::number(vSecSinceEpoch);
+ buf += QByteArray::number(vSeq);
+ buf += vDataList.join("").toLatin1();
+ crc = crc8(buf);
+ return crc;
+}
Index: sources/gui/GuiController.cpp
===================================================================
diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/gui/GuiController.cpp (.../GuiController.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9)
+++ sources/gui/GuiController.cpp (.../GuiController.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -159,7 +159,7 @@
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}
Index: sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml
===================================================================
diff -u -r83b9d737cd495b34a7b42f5409962a9442f3b8f4 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml (.../PreTreatmentCreate.qml) (revision 83b9d737cd495b34a7b42f5409962a9442f3b8f4)
+++ sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml (.../PreTreatmentCreate.qml) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -427,7 +427,7 @@
SliderCreateTreatment { id: _salineBolus
objectName : "_salineBolus"
- label : "Saline Bolus"
+ label : qsTr("Saline Bolus")
flickable : _flickable
unit : Variables.unitTextFluid
minimum : vTreatmentRanges.salineBolusVolumeMin
Index: sources/storage/Logger.cpp
===================================================================
diff -u -r5687815256ae070a9a207107088e3f72dd464da0 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/storage/Logger.cpp (.../Logger.cpp) (revision 5687815256ae070a9a207107088e3f72dd464da0)
+++ sources/storage/Logger.cpp (.../Logger.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -91,8 +91,8 @@
if ( ! checkThread() ) return;
ADD_APPED_HEADER;
ADD_DEBUG_HEADER;
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
- LOG_DEBUG(tr("Application %1 Started").arg(qApp->applicationName()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("Application %1 Started").arg(qApp->applicationName()));
LOG_APPED_UI(qApp-> applicationVersion());
}
Index: sources/storage/Settings.cpp
===================================================================
diff -u -ra522e6aa7a36ac696a9a956200e89d838f319e25 -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/storage/Settings.cpp (.../Settings.cpp) (revision a522e6aa7a36ac696a9a956200e89d838f319e25)
+++ sources/storage/Settings.cpp (.../Settings.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -306,7 +306,7 @@
.arg(Storage::Settings_Path())
.arg(Storage::Settings_Category_Translation)
.arg("qm")
- .arg(_settingsLocalSeparator + QString("de")); // locale);
+ .arg(_settingsLocalSeparator + QString("es")); // locale);
qDebug() << __FUNCTION__ << ":" << __LINE__ << "-------------qmFile:" << qmFile;
Index: sources/storage/TreatmentLog.cpp
===================================================================
diff -u -r3b323bd6a1a03429c2321a889049de1c3b11302f -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision 3b323bd6a1a03429c2321a889049de1c3b11302f)
+++ sources/storage/TreatmentLog.cpp (.../TreatmentLog.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -495,7 +495,7 @@
lOut:
if ( ! ok ) {
- LOG_DEBUG(status);
+ LOG_DEBUG(status); // The log debug order in this block is by design
status = "Unable to export treatment log '" + srcFileName +"'";
}
else {
Index: sources/wifi/WifiInterface.cpp
===================================================================
diff -u -r14e9940ccba0c2d64b5e16aa34edcb995f0563fd -r4947841e8cdd7e72d4fe26e604f7e5061fb86d64
--- sources/wifi/WifiInterface.cpp (.../WifiInterface.cpp) (revision 14e9940ccba0c2d64b5e16aa34edcb995f0563fd)
+++ sources/wifi/WifiInterface.cpp (.../WifiInterface.cpp) (revision 4947841e8cdd7e72d4fe26e604f7e5061fb86d64)
@@ -205,7 +205,7 @@
_init = true;
initConnections();
- LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className()));
+ LOG_DEBUG(QString("%1 Initialized").arg(metaObject()->className()));
return true;
}