Index: sources/canbus/MessageDispatcher.cpp =================================================================== diff -u -rab28e427d67bdb054a0173efb719e820f97b20b0 -r9b80e4d4211d9d6e5730e619794d2d1313c1a3a0 --- sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision ab28e427d67bdb054a0173efb719e820f97b20b0) +++ sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision 9b80e4d4211d9d6e5730e619794d2d1313c1a3a0) @@ -1,1096 +1,1108 @@ -/*! - * - * Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. - * \copyright - * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN - * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. - * - * \file MessageDispatcher.cpp - * \author (last) Dara Navaei - * \date (last) 28-Feb-2024 - * \author (original) Behrouz NematiPour - * \date (original) 26-Aug-2020 - * - */ -#include "MessageDispatcher.h" - -// Qt -#include -#include - -// Project -#include "Logger.h" -#include "ApplicationController.h" -#include "FrameInterface.h" -#include "MessageAcknowModel.h" - -//#define DEBUG_ACKBACK_HD_TO_UI -//#define DEBUG_OUT_OF_SYNC - -using namespace Can; - -/*! - * \brief MessageDispatcher::MessageDispatcher - * \details Constructor - * \param parent - QObject parent owner object. - * Qt handles the children destruction by their parent objects life-cycle. - */ -MessageDispatcher::MessageDispatcher(QObject *parent) : QObject(parent) { } - -/*! - * \brief Message Handler initializer - */ -bool MessageDispatcher::init() -{ - if ( _init ) return false; - _init = true; - - // runs in the thread - initConnections(); - - LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className())); - - return true; -} - -/*! - * \brief MessageDispatcher::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 MessageDispatcher::init(QThread &vThread) -{ - if ( ! init() ) return false; - initThread(vThread); - return true; -} - -/*! - * \brief MessageDispatcher::quit - * \details quits the class - * Calls quitThread - */ -void MessageDispatcher::quit() -{ - // disabled coco begin validated: Application termination is not correctly done in coco!!! - // it has been tested and works perfectly fine in normal run. - quitThread(); // validated -} -// disabled coco end - -/*! - * \brief Message Handler connections definition - * \details Initializes the required signal/slot connection between this class and other objects - * to be able to communicate. - */ -void MessageDispatcher::initConnections() -{ - // From GUI - connect(&_ApplicationController, SIGNAL(didActionTransmit(GuiActionType , const QVariantList &)), - this , SLOT( onActionTransmit(GuiActionType , const QVariantList &))); - - // From HD - connect(&_FrameInterface , SIGNAL(didFrameReceive (Can_Id , const QByteArray &)), - this , SLOT( onFrameReceive (Can_Id , const QByteArray &))); - - // From Message Acknow Model timer timeout. - connect(&_MessageAcknowModel , SIGNAL(didFramesTransmit(Can_Id, Sequence, const FrameList &)), - this , SLOT( onFramesTransmit(Can_Id, Sequence, const FrameList &))); - - connect(&_MessageAcknowModel , SIGNAL(didFailedTransmit( Sequence )), - this , SLOT( onFailedTransmit( Sequence ))); - - // Application Settings are ready - connect(&_ApplicationController, SIGNAL(didSettingsDone ()), - this , SLOT( onSettingsDone ())); - - // ---- Signal/Slots - ADJUST_TRANSMT_MODEL_BRIDGE_CONNECTIONS(_ApplicationController) - ACTION_RECEIVE_MODEL_BRIDGE_CONNECTIONS(_interpreter ) -} - -/*! - * \brief ApplicationController::initThread - * \details Moves this object into the thread vThread. - * And checks that this method is called from main thread. - * Also connects quitThread to application aboutToQuit. - * \param vThread - the thread - */ -void MessageDispatcher::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 MessageDispatcher::quitThread - * \details Moves this object to main thread to be handled by QApplication - * And to be destroyed there. - */ -void MessageDispatcher::quitThread() -{ - // disabled coco begin validated: Application 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 MessageDispatcher::onFrameReceive - * \details Upon message has been received over CANBus this slot will be called - * by FrameInterface::didFrameReceive signal to process the frame - * Upon completion of collected all the required frames - * on successful interpretation of the message, emits didActionReceived signal. - * The message will be removed from list of the channel vCan_Id messages. - * \param vCan_Id - CANBus channel of the frame - * \param vPayload - Payload of the frame - */ -void MessageDispatcher::onFrameReceive(Can_Id vCan_Id, const QByteArray &vPayload) -{ - // Append a message to the list - // disabled coco begin validated: if empty (first condition) is true, it must never check for the complete (second condition) - // because if the list is empty there is no last() item - if (_messageList[vCan_Id].isEmpty() || _messageList[vCan_Id].last().isComplete()) { - // disabled coco end - _messageList[vCan_Id].append(Message()); - } - - // build the message and check. - if (! buildMessage(vCan_Id, vPayload)) { - return; - } - Message mMessage = _messageList[vCan_Id].last(); - - // TODO : must be moved to a MessageModel class - if (mMessage.isComplete()) { - rxCount(); - #ifdef DEBUG_OUT_OF_SYNC - if (_rxSequence != mMessage.sequence) { - qDebug() << tr("Out of Sync : %1 , %2").arg(_rxSequence).arg(mMessage.sequence); - } - #endif - interpretMessage(mMessage); - } -} - -/*! - * \brief MessageDispatcher::onFramesTransmit - * \details this slots calls the framesTransmit to emit the didFrameTransmit signal - * to queue the frame(s) to be sent - * \param vSequence - sequence of the message which is going to be resent. (not used) - * \param vFrameList - frame(s) to be sent - */ -void MessageDispatcher::onFramesTransmit(Can_Id vCan_Id, Sequence vSequence, const FrameList &vFrameList) -{ - Q_UNUSED(vSequence) - framesTransmit(vCan_Id, vFrameList); -} - -/*! - * \brief MessageDispatcher::onFailedTransmit - * \details the slot which will be called on transmit failed on MessageAcknowModel - * \param vSequence - */ -void MessageDispatcher::onFailedTransmit(Sequence vSequence) -{ - // disabled coco begin validated: Is a placeholder and has not been implemented yet - emit didFailedTransmit(vSequence); -} -// disabled coco end - -/*! - * \brief MessageDispatcher::onActionTransmit - * \details This slot will be called by ApplicationController::didActionTransmit - * upon UI message transmit request and calls MessageDispatcher::actionTransmit method. - * \param vActionId - The ActionID of the message - * \param vData - The data of the Message - */ -void MessageDispatcher::onActionTransmit(GuiActionType vActionId, const QVariantList &vData) -{ - actionTransmit(vActionId, vData); -} - -/*! - * \brief MessageDispatcher::onSettingsDone - * \details The slot to handle didSettingsDone signal of the ApplicationController - */ -void MessageDispatcher::onSettingsDone() -{ - _interpreter.updateUnhandledMessages(); -} - -// ---------------------------------------------------------------------------------------------------- - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Blood/Dialysate Adjustment Denali message. - * \param vData - Data model contains Blood Flow Rate - and Dialysate Flow Rate - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustBloodDialysateRequestData &vData) -{ - QVariantList mData; - mData += vData.bloodFlow; - mData += vData.dialysateFlow; - onActionTransmit(GuiActionType::ID_AdjustBloodDialysateReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the treatment duration Adjustment Denali message. - * \param vData - Data model contains treatment duration adjustment value in minutes - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDurationRequestData &vData) -{ - QVariantList mData; - mData += vData.duration; - onActionTransmit(GuiActionType::ID_AdjustDurationReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Ultrafiltration State Adjustment Denali message. - * \param vData - Data model contains treatment ultrafiltration state adjustment - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationStateRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - actionTransmit(GuiActionType::ID_AdjustUltrafiltrationStateReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Ultrafiltration Adjustment Denali message. - * \param vData - Data model contains treatment ultrafiltration adjustment volume - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationEditRequestData &vData) -{ - QVariantList mData; - mData += vData.volume; - onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationEditReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Ultrafiltration Adjustment User Selected Option Denali message. - * \param vData - Data model contains treatment ultrafiltration adjustment volume and user selected option. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationConfirmRequestData &vData) -{ - QVariantList mData; - mData += vData.volume; - mData += vData.option; - onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Alarm Request Silence message. - * \param vData - Data model contains the silence request information. - * \return void - */ -void MessageDispatcher::onAdjustment(const AlarmSilenceRequestData &vData) -{ - QVariantList mData; - mData += vData.silence; - onActionTransmit(GuiActionType::ID_AlarmSilenceReq, mData); -} - -/** - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the User Action Denali message. - * \param vData - Data model contains User Action on the alarm dialog. - * \return void - */ -void MessageDispatcher::onAdjustment(const AlarmUserActionRequestData &vData) -{ - QVariantList mData; - mData += vData.action; - onActionTransmit(GuiActionType::ID_AlarmUserActionReq, mData); -} - -/** - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Alarm Active List Request denali message. - * \param vData - Data model contains Alarm Active List payload. - * \return void - */ -void MessageDispatcher::onAdjustment(const AlarmActiveListRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AlarmActiveListReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the DG Set Date Time Denali message. - * \details This method transmits the request to set the alarm volume. - * \param vData - Data model contains the alarm volume - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustHDAlarmVolumeRequestData &vData) -{ - QVariantList mData; - mData += vData.volume2HD(); - onActionTransmit(GuiActionType::ID_AlarmVolumeSetReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Alarm Acknowledge Request message. - * \param vData - Data model contains the user acknowledge request information. - * \return void - */ -/* // disabled coco begin validated: Manually tested. This model class is a placeholder and there is no use case for this now. -void MessageDispatcher::onAdjustment(const AlarmClearedConditionRequestData &vData) -{ - QVariantList mData; - mData += vData.alarmID; - onActionTransmit(GuiActionType::ID_AlarmClearedConditionReq, mData); -} -// disabled coco end */ - -/** - * \details This method transmits the Saline Bolus Adjustment Denali message. - * \param vData - Data model contains treatment Saline Bolus adjustment state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustSalineRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustSalineReq, mData); -} - -/** - * \details This method transmits the Heparin Adjustment Denali message. - * \param vData - Data model contains treatment Heparin adjustment state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustHeparinRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustHeparinReq, mData); -} - -/** - * \details This method transmits the Rinseback Adjustment Denali message. - * \param vData - Data model contains treatment Rinseback adjustment state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustRinsebackRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustRinsebackReq, mData); -} - -/** - * \details This method transmits the Recirculate Adjustment Denali message. - * \param vData - Data model contains treatment Recirculate adjustment state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustRecirculateRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustRecirculateReq, mData); -} - -/** - * \details This method transmits the Treatment End Adjustment Denali message. - * \param vData - Data model contains treatment end adjustment state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustTreatmentEndRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustTreatmentEndReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the HD Version Denali message. - * \param vData - Data model contains HD Version state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustVersionsRequestData &vData) -{ - QVariantList mData; - mData += QVariant::fromValue(vData.ver_major); - mData += QVariant::fromValue(vData.ver_minor); - mData += QVariant::fromValue(vData.ver_micro); - mData += QVariant::fromValue(vData.ver_revis); - mData += QVariant::fromValue(vData.ver_comp ); - onActionTransmit(GuiActionType::ID_AdjustVersionsUIReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the HD Version Denali message. - * \param vData - Data model contains HD Version state. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustVersionsResponseData &vData) -{ - QVariantList mData; - mData += QVariant::fromValue(vData.ver_major); - mData += QVariant::fromValue(vData.ver_minor); - mData += QVariant::fromValue(vData.ver_micro); - mData += QVariant::fromValue(vData.ver_revis); - mData += QVariant::fromValue(vData.ver_comp ); - onActionTransmit(GuiActionType::ID_AdjustVersionsUIRsp, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the DG Set Date Time Denali message. - * \param vData - Data model contains the epoch time - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustServiceDatesRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustServiceDatesReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disposables Removal Confirm Adjustment Denali message. - * \param vData - Data model contains Service Mode adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustServiceModeRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustServiceModeReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Pressures Limits Adjustment Denali message. - * \param vData - Data model contains treatment Pressures Limits adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustPressuresLimitsRequestData &vData) -{ - QVariantList mData; - mData += vData.mArterialPressureLimitWindow ; - mData += vData.mVenousPressureLimitWindow ; - mData += vData.mVenousPressureLimitAsymtrc ; - onActionTransmit(GuiActionType::ID_AdjustPressuresLimitsReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the InitTreatment request message. - * \param vData - Data model contains the init treatment request information. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustInitTreatmentRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustInitTreatmentReq, mData); -} - -/** - * \details This method transmits the Treatment Parameter request message. - * \param vData - Data model contains treatment parameter adjustment data structure - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustParametersValidationRequestData &vData) -{ - QVariantList mData; - mData += vData.mBloodFlowRate ; - mData += vData.mDialysateFlowRate ; - mData += vData.mTreatmentDuration ; - mData += vData.mHeparinStopTime ; - mData += vData.mSalineBolus ; - mData += vData.mAcidConcentrate ; - mData += vData.mBicarbonateConcentrate ; - mData += vData.mDialyzerType ; - mData += vData.mHeparinType ; - mData += vData.mBloodPressureMeasureInterval ; - mData += vData.mRinsebackFlowRate ; - mData += vData.mArterialPressureLimitWindow ; - mData += vData.mVenousPressureLimitWindow ; - mData += vData.mVenousPressureLimitAsymtrc ; - mData += vData.mHeparinDispensingRate ; - mData += vData.mHeparinBolusVolume ; - mData += vData.mDialysateTemp ; - - onActionTransmit(GuiActionType::ID_AdjustParametersValidationReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Confirm Treatment request message. - * \param vData - Data model contains the confirm treatment request - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustParametersConfirmRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustParametersConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Water Sample Adjustment Denali message. - * \param vData - Data model contains Water Sample adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustWaterSampleRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustWaterSampleReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Water Sample Result Adjustment Denali message. - * \param vData - Data model contains Water Sample Result adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustWaterSampleResultRequestData &vData) -{ - QVariantList mData; - mData += vData.requestedState; - onActionTransmit(GuiActionType::ID_AdjustWaterSampleResultReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Consumables Confirm Adjustment Denali message. - * \param vData - Data model contains Consumables Confirm adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustConsumablesConfirmRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustConsumablesConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disposables Confirm Adjustment Denali message. - * \param vData - Data model contains Disposables Confirm adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDisposablesConfirmRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustDisposablesConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disposables Prime Adjustment Denali message. - * \param vData - Data model contains Disposables Prime adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDisposablesPrimeRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustDisposablesPrimeReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Patient Connection Begin Adjustment Denali message. - * \param vData - Data model contains Patient Connection Begin adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustPatientConnectionBeginRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustPatientConnectionBeginReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Ultrafiltration Adjustment Denali message. - * \param vData - Data model contains treatment ultrafiltration adjustment volume - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationInitRequestData &vData) -{ - QVariantList mData; - mData += vData.volume; - onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationInitReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Patient Connection Confirm Adjustment Denali message. - * \param vData - Data model contains Patient Connection Confirm adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustPatientConnectionConfirmRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustPatientConnectionConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Start Treatment Adjustment Denali message. - * \param vData - Data model contains Start Treatment adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustStartTreatmentRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustStartTreatmentReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Patient Disconnection Notify Adjustment Denali message. - * \param vData - Data model contains Patient Disconnection Notify adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustPatientDisconnectionNotifyRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustPatientDisconnectNotifyReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Patient Disconnection Confirm Adjustment Denali message. - * \param vData - Data model contains Patient Disconnection Confirm adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustPatientDisconnectionConfirmRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustPatientDisconnectConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disposables Removal Confirm Adjustment Denali message. - * \param vData - Data model contains Disposables Removal Confirm adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDisposablesRemovalConfirmRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustDisposablesRemovalConfirmReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Treatment Log Adjustment Denali message. - * \param vData - Data model contains Treatment Log adjustment. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustTreatmentLogRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustTreatmentLogReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the HD Set Date Time Denali message. - * \param vData - Data model contains the epoch time - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustHDDateTimeRequestData &vData) -{ - QVariantList mData; - mData += vData.mEpoch ; - onActionTransmit(GuiActionType::ID_AdjustHDDateTimeReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the DG Set Date Time Denali message. - * \param vData - Data model contains the epoch time - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDGDateTimeRequestData &vData) -{ - QVariantList mData; - mData += vData.mEpoch ; - onActionTransmit(GuiActionType::ID_AdjustDGDateTimeReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the DG Cleaning Usage request message. - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDGCleaningUsageRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustDGCleaningUsageReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disinfect request Denali message. - * \param vData - Data model contains the epoch time - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDisinfectStartRequestData &vData) -{ - QVariantList mData; - mData += vData.mState; - onActionTransmit(GuiActionType::ID_AdjustDisinfectStartReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the Disinfect mode request Denali message. - * \param vData - Data model contains the initiate/cancel boolean disinfection mode - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustDisinfectModeRequestData &vData) -{ - QVariantList mData; - mData += vData.mInititate; - onActionTransmit(GuiActionType::ID_AdjustDisinfectModeReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the UI power on self test final result - * \param vData - Data model contains the final result of the UI POST - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustUIPostFinalResultRequestData &vData) -{ - QVariantList mData; - mData += vData.mResult; - onActionTransmit(GuiActionType::ID_UIPostFinalResultData, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the UI Generic User Confirmation result. - * \param vData - Data model contains the Generic User Confirmation result. - * \return void - */ -void MessageDispatcher::onAdjustment(const DuetConfirmUIrData &vData) -{ - QVariantList mData; - mData += vData.mId; - mData += vData.mConfirm; - onActionTransmit(GuiActionType::ID_DuetConfirmUIr, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the UI RO Water Mode adjustment request. - * \param vData - Data model contains the UI RO Water Mode adjustment request data. - * \return void - */ -void MessageDispatcher::onAdjustment(const DuetRoWaterModeUIiData &vData) -{ - QVariantList mData; - mData += vData.mStatus; - onActionTransmit(GuiActionType::ID_DuetRoWaterModeUIi, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the HD Usage Info Denali message. - * \param vData - - * \return void - */ -void MessageDispatcher::onAdjustment(const HDUsageInfoRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_HDUsageInfoReq, mData); -} - -/*! - * \brief MessageDispatcher::onAdjustment - * \details This method transmits the HD institutional record request to HD. - * \param vData - - * \return void - */ -void MessageDispatcher::onAdjustment(const AdjustInstitutionalRequestData &) -{ - QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustInstitutionalRecordReq, mData); -} -// ---------------------------------------------------------------------------------------------------- - -/*! - * \brief MessageDispatcher::actionTransmit - * \details This method is called by slot MessageDispatcher::onActionTransmit - * which emits didFrameTransmit on successful interpretation of the requested message - * and successfully creating of frame(s). - * \param vActionId - The ActionID of the message - * \param vData - The data of the Message - */ -void MessageDispatcher::actionTransmit(GuiActionType vActionId, const QVariantList &vData, Sequence vSequence, Can_Id vCanId) -{ - txCount(); - if (vSequence == 0) { // initialize - // it's obvious that this assignment does not effect outside of the function. - // but is make it easier to just assume the correct value has been passed - // and still using the same variable (function parameter) as a local variable. - vSequence = _txSequence; - } - - QByteArray mData; - Can_Id canid = vCanId; - if (! _interpreter.interpretMessage(vActionId, vData, mData, canid)) { - LOG_DEBUG(QString("Incorrect Message, cannot be interpreted, %1").arg(Format::toHexString(vActionId))); // TODO : LogInfo Improvement - return; - } - - // TODO : Create a buildFrames method - FrameList frameList; - Sequence mSequence = vSequence; - bool mNeedsAcknow = needsAcknow(vActionId); - if (mNeedsAcknow) { - mSequence = -mSequence; - if ( ! gDisableAcknowLog ) { - LOG_APPED_UI(tr("Ack Req, Sq:%1, ID:%2").arg(mSequence).arg(Format::toHexString(vActionId))); - } -#ifdef DEBUG_ACKBACK_HD_TO_UI - qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckReq : %1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence); -#endif - } - - // disabled coco begin validated: Has been tested manually but in this function this cannot be false because the message interpreter is doing the same validation. - // still checking here in case the logic has changed therefore buildFrame should still validate the message for developer safety. - if ( ! _builder.buildFrames(vActionId, mData, frameList, mSequence) ) { - LOG_DEBUG(QString("Incorrect Message cannot be built")); // TODO : LogInfo Improvement - return; - } - // disabled coco end - if (mNeedsAcknow) { - // NOTE : here vSequence should be used which is not negative - // because when we get the Acknow it is not the negative - // since it does not need Re-Acknow - // and this is the sequence number which will be used - // to remove the message from the Acknow list. - emit didAcknowTransmit(canid, vSequence, frameList); - } - framesTransmit(canid, frameList); -} - -/*! - * \brief MessageDispatcher::framesTransmit - * \details iterates through all the frames and emits to send the frames - * \param vCan_Id - The channel to send the frames to - * \param vFrameList - List of the frames to be sent - */ -void MessageDispatcher::framesTransmit(Can_Id vCan_Id, const FrameList &vFrameList) -{ - for (const auto &frame : vFrameList) { - emit didFrameTransmit(vCan_Id, frame); - } -} - -/*! - * \brief MessageDispatcher::buildMessage - * \details Calls the messageBuilder buildMessage method. - * \param vCan_Id - CANBus channel of the frame - * \param vPayload - Payload of the frame - * \return false on error - */ -bool MessageDispatcher::buildMessage(Can_Id vCan_Id, const QByteArray &vPayload) -{ - if (vPayload.length() < eLenCanFrame) { - // Each frame has to have exactly 8 (eLenCanFrame) bytes of data and unused bytes should be passed as 00. - LOG_DEBUG(QString("Incorrect frame length. Exp:%1,got:%2").arg(eLenCanFrame).arg(vPayload.length())); - return false; - } - if (! _builder.buildMessage(vPayload, _messageList[vCan_Id].last(), vCan_Id)) { - _messageList[vCan_Id].removeLast(); - return false; - } - return true; -} - -/*! - * \brief MessageDispatcher::checkAcknowReceived - * \details check if the message was an acknowledge. - * \param vMessage - The received message - * \param vSrcText - The source entity identifier text - * \return true if the message is Acknow - */ -bool MessageDispatcher::checkAcknowReceived(const Message &vMessage, const QString &vSrcText) -{ - GuiActionType mActionId = vMessage.actionId; - Sequence mSequence = vMessage.sequence; - bool ok = false; - if ( mActionId == GuiActionType::ID_Acknow ) { - ok = true; - if ( ! gDisableAcknowLog ) { - LOG_APPED(tr(" ,%1,Ack Bak, Sq:%2").arg(vSrcText).arg(mSequence)); - } - #ifdef DEBUG_ACKBACK_HD_TO_UI - qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence).arg(vMessage.actionId); - #endif - emit didAcknowReceive(mSequence); - } - return ok; -} - -/*! - * \brief MessageDispatcher::checkAcknowTransmit - * \details Sends the Ack message. - * \param vMessage - the received message which to check if it may need Ack. - * \param vSrcText - the source of the message which needs Ack. - * \return returns true if the message needs an Ack (Negative Sequence) - */ -bool MessageDispatcher::checkAcknowTransmit(const Message &vMessage, const QString &vSrcText) -{ - bool ok = false; - GuiActionType mActionId = vMessage.actionId; - Sequence mSequence = vMessage.sequence; - - // UI shall acknowledge the messages is intended for UI. - if ( ! needsAcknow(vMessage.can_id)) return ok; // false - - if (mSequence < 0) { - ok = true; - if ( ! gDisableAcknowLog ) { - LOG_APPED(tr(" ,%1,Ack Req, Sq:%2, ID:%3").arg(vSrcText).arg(mSequence).arg(Format::toHexString(mActionId))); - } - #ifdef DEBUG_ACKBACK_HD_TO_UI - qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckReq : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence).arg(vMessage.actionId); - #endif - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak is immediately handled at the same place. - QString dstText; - Can_Id dstID = MessageInterpreter::identifyDestination(vMessage.can_id, &dstText); - actionTransmit(GuiActionType::ID_Acknow, {}, -mSequence, dstID); - if ( ! gDisableAcknowLog ) { - LOG_APPED_UI(tr("Ack Bak, Sq:%1, Dst:%2").arg(-mSequence).arg(dstText)); - } - #ifdef DEBUG_ACKBACK_HD_TO_UI - qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(-mSequence).arg(vMessage.actionId); - #endif - } - return ok; -} - -/*! - * \brief MessageDispatcher::interpretMessage - * \details Calls the MessageInterpreter interpretMessage method - * Regarding the Message Id and the sequence emit different signals - * to handle the normal or acknowledge messages. - * \param vMessage - The Message - * \return false on error - */ -bool MessageDispatcher::interpretMessage(const Message &vMessage) -{ - bool ok = false; - QVariantList mData; - QString srcText; - MessageInterpreter::identifySource(vMessage.can_id, &srcText); - if ( ! checkAcknowReceived(vMessage, srcText) ) { // check if the message was an acknowledge. - checkAcknowTransmit(vMessage, srcText); // then if needs acknow send it immediately. - } - - // disabled coco begin validated: Has been validated manually. If MessageInterpreter::interpretMessage fails, this also returns false - if ( _interpreter.interpretMessage( vMessage, mData ) ) { - ok = true; - emit didActionReceive(vMessage.actionId, mData); - } - // disabled coco end - - _messageList[vMessage.can_id].removeLast(); - return ok; -} - -/*! - * \brief MessageDispatcher::rxCount - * \details count received messages up the size of the Sequence type size - * \return message count - */ -Sequence MessageDispatcher::rxCount() -{ - // disabled coco begin validated: has been manually validated since it requires so many received messages to reset the seq - if ( _rxSequence < SEQUENCE_MAX ) { - ++_rxSequence; - } else { - _rxSequence = 1; - } - return _rxSequence; -} -// disabled coco end - -/*! - * \brief MessageDispatcher::txCount - * \details count transmitted messages up the size of the Sequence type size - * \return message count - */ -Sequence MessageDispatcher::txCount() -{ - // disabled coco begin validated: has been manually validated since it requires so many received messages to reset the seq - if ( _txSequence < SEQUENCE_MAX ) { - ++_txSequence; - } else { - _txSequence = 1; - } - return _txSequence; -} -// disabled coco end - -/*! - * \brief MessageDispatcher::needsAcknow - * \details List of the Action types which need Acknow - * \param vActionId - Action Type id - * \return true if needs an Acknow - */ -bool MessageDispatcher::needsAcknow(GuiActionType vActionId) -{ - return _needsAcknow.contains(vActionId); -} - -/*! - * \brief MessageDispatcher::needsAcknow - * \details List of the CAN channels which need Acknow - * \param vCan_Id - The message CANBus id - * \return true if needs an Acknow - */ -bool MessageDispatcher::needsAcknow(Can_Id vCan_Id) -{ - bool ok = true; - switch(vCan_Id) { // list if the channels UI shall not Ack - case eChlid_HD_DG : // 0x008, ///< HD => DG - case eChlid_DG_HD : // 0x010, ///< DG => HD - case eDialin_HD : // 0x400, ///< dialin => HD - case eHD_Dialin : // 0x401, ///< HD => dialin - case eDialin_DG : // 0x402, ///< dialin => DG - case eDG_Dialin : // 0x403, ///< DG => dialin - ok = false; break; - - default: break; - } - - return ok; -} +/*! + * + * Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. + * \copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN + * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * \file MessageDispatcher.cpp + * \author (last) Dara Navaei + * \date (last) 28-Feb-2024 + * \author (original) Behrouz NematiPour + * \date (original) 26-Aug-2020 + * + */ +#include "MessageDispatcher.h" + +// Qt +#include +#include + +// Project +#include "Logger.h" +#include "ApplicationController.h" +#include "FrameInterface.h" +#include "MessageAcknowModel.h" + +//#define DEBUG_ACKBACK_HD_TO_UI +//#define DEBUG_OUT_OF_SYNC + +using namespace Can; + +/*! + * \brief MessageDispatcher::MessageDispatcher + * \details Constructor + * \param parent - QObject parent owner object. + * Qt handles the children destruction by their parent objects life-cycle. + */ +MessageDispatcher::MessageDispatcher(QObject *parent) : QObject(parent) { } + +/*! + * \brief Message Handler initializer + */ +bool MessageDispatcher::init() +{ + if ( _init ) return false; + _init = true; + + // runs in the thread + initConnections(); + + LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className())); + + return true; +} + +/*! + * \brief MessageDispatcher::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 MessageDispatcher::init(QThread &vThread) +{ + if ( ! init() ) return false; + initThread(vThread); + return true; +} + +/*! + * \brief MessageDispatcher::quit + * \details quits the class + * Calls quitThread + */ +void MessageDispatcher::quit() +{ + // disabled coco begin validated: Application termination is not correctly done in coco!!! + // it has been tested and works perfectly fine in normal run. + quitThread(); // validated +} +// disabled coco end + +/*! + * \brief Message Handler connections definition + * \details Initializes the required signal/slot connection between this class and other objects + * to be able to communicate. + */ +void MessageDispatcher::initConnections() +{ + // From GUI + connect(&_ApplicationController, SIGNAL(didActionTransmit(GuiActionType , const QVariantList &)), + this , SLOT( onActionTransmit(GuiActionType , const QVariantList &))); + + // From HD + connect(&_FrameInterface , SIGNAL(didFrameReceive (Can_Id , const QByteArray &)), + this , SLOT( onFrameReceive (Can_Id , const QByteArray &))); + + // From Message Acknow Model timer timeout. + connect(&_MessageAcknowModel , SIGNAL(didFramesTransmit(Can_Id, Sequence, const FrameList &)), + this , SLOT( onFramesTransmit(Can_Id, Sequence, const FrameList &))); + + connect(&_MessageAcknowModel , SIGNAL(didFailedTransmit( Sequence )), + this , SLOT( onFailedTransmit( Sequence ))); + + // Application Settings are ready + connect(&_ApplicationController, SIGNAL(didSettingsDone ()), + this , SLOT( onSettingsDone ())); + + // ---- Signal/Slots + ADJUST_TRANSMT_MODEL_BRIDGE_CONNECTIONS(_ApplicationController) + ACTION_RECEIVE_MODEL_BRIDGE_CONNECTIONS(_interpreter ) +} + +/*! + * \brief ApplicationController::initThread + * \details Moves this object into the thread vThread. + * And checks that this method is called from main thread. + * Also connects quitThread to application aboutToQuit. + * \param vThread - the thread + */ +void MessageDispatcher::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 MessageDispatcher::quitThread + * \details Moves this object to main thread to be handled by QApplication + * And to be destroyed there. + */ +void MessageDispatcher::quitThread() +{ + // disabled coco begin validated: Application 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 MessageDispatcher::onFrameReceive + * \details Upon message has been received over CANBus this slot will be called + * by FrameInterface::didFrameReceive signal to process the frame + * Upon completion of collected all the required frames + * on successful interpretation of the message, emits didActionReceived signal. + * The message will be removed from list of the channel vCan_Id messages. + * \param vCan_Id - CANBus channel of the frame + * \param vPayload - Payload of the frame + */ +void MessageDispatcher::onFrameReceive(Can_Id vCan_Id, const QByteArray &vPayload) +{ + // Append a message to the list + // disabled coco begin validated: if empty (first condition) is true, it must never check for the complete (second condition) + // because if the list is empty there is no last() item + if (_messageList[vCan_Id].isEmpty() || _messageList[vCan_Id].last().isComplete()) { + // disabled coco end + _messageList[vCan_Id].append(Message()); + } + + // build the message and check. + if (! buildMessage(vCan_Id, vPayload)) { + return; + } + Message mMessage = _messageList[vCan_Id].last(); + + // TODO : must be moved to a MessageModel class + if (mMessage.isComplete()) { + rxCount(); + #ifdef DEBUG_OUT_OF_SYNC + if (_rxSequence != mMessage.sequence) { + qDebug() << tr("Out of Sync : %1 , %2").arg(_rxSequence).arg(mMessage.sequence); + } + #endif + interpretMessage(mMessage); + } +} + +/*! + * \brief MessageDispatcher::onFramesTransmit + * \details this slots calls the framesTransmit to emit the didFrameTransmit signal + * to queue the frame(s) to be sent + * \param vSequence - sequence of the message which is going to be resent. (not used) + * \param vFrameList - frame(s) to be sent + */ +void MessageDispatcher::onFramesTransmit(Can_Id vCan_Id, Sequence vSequence, const FrameList &vFrameList) +{ + Q_UNUSED(vSequence) + framesTransmit(vCan_Id, vFrameList); +} + +/*! + * \brief MessageDispatcher::onFailedTransmit + * \details the slot which will be called on transmit failed on MessageAcknowModel + * \param vSequence + */ +void MessageDispatcher::onFailedTransmit(Sequence vSequence) +{ + // disabled coco begin validated: Is a placeholder and has not been implemented yet + emit didFailedTransmit(vSequence); +} +// disabled coco end + +/*! + * \brief MessageDispatcher::onActionTransmit + * \details This slot will be called by ApplicationController::didActionTransmit + * upon UI message transmit request and calls MessageDispatcher::actionTransmit method. + * \param vActionId - The ActionID of the message + * \param vData - The data of the Message + */ +void MessageDispatcher::onActionTransmit(GuiActionType vActionId, const QVariantList &vData) +{ + actionTransmit(vActionId, vData); +} + +/*! + * \brief MessageDispatcher::onSettingsDone + * \details The slot to handle didSettingsDone signal of the ApplicationController + */ +void MessageDispatcher::onSettingsDone() +{ + _interpreter.updateUnhandledMessages(); +} + +// ---------------------------------------------------------------------------------------------------- + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Blood/Dialysate Adjustment Denali message. + * \param vData - Data model contains Blood Flow Rate + and Dialysate Flow Rate + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustBloodDialysateRequestData &vData) +{ + QVariantList mData; + mData += vData.bloodFlow; + mData += vData.dialysateFlow; + onActionTransmit(GuiActionType::ID_AdjustBloodDialysateReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the treatment duration Adjustment Denali message. + * \param vData - Data model contains treatment duration adjustment value in minutes + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDurationRequestData &vData) +{ + QVariantList mData; + mData += vData.duration; + onActionTransmit(GuiActionType::ID_AdjustDurationReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Ultrafiltration State Adjustment Denali message. + * \param vData - Data model contains treatment ultrafiltration state adjustment + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationStateRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + actionTransmit(GuiActionType::ID_AdjustUltrafiltrationStateReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Ultrafiltration Adjustment Denali message. + * \param vData - Data model contains treatment ultrafiltration adjustment volume + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationEditRequestData &vData) +{ + QVariantList mData; + mData += vData.volume; + onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationEditReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Ultrafiltration Adjustment User Selected Option Denali message. + * \param vData - Data model contains treatment ultrafiltration adjustment volume and user selected option. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationConfirmRequestData &vData) +{ + QVariantList mData; + mData += vData.volume; + mData += vData.option; + onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Alarm Request Silence message. + * \param vData - Data model contains the silence request information. + * \return void + */ +void MessageDispatcher::onAdjustment(const AlarmSilenceRequestData &vData) +{ + QVariantList mData; + mData += vData.silence; + onActionTransmit(GuiActionType::ID_AlarmSilenceReq, mData); +} + +/** + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the User Action Denali message. + * \param vData - Data model contains User Action on the alarm dialog. + * \return void + */ +void MessageDispatcher::onAdjustment(const AlarmUserActionRequestData &vData) +{ + QVariantList mData; + mData += vData.action; + onActionTransmit(GuiActionType::ID_AlarmUserActionReq, mData); +} + +/** + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Alarm Active List Request denali message. + * \param vData - Data model contains Alarm Active List payload. + * \return void + */ +void MessageDispatcher::onAdjustment(const AlarmActiveListRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AlarmActiveListReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the DG Set Date Time Denali message. + * \details This method transmits the request to set the alarm volume. + * \param vData - Data model contains the alarm volume + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustHDAlarmVolumeRequestData &vData) +{ + QVariantList mData; + mData += vData.volume2HD(); + onActionTransmit(GuiActionType::ID_AlarmVolumeSetReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Alarm Acknowledge Request message. + * \param vData - Data model contains the user acknowledge request information. + * \return void + */ +/* // disabled coco begin validated: Manually tested. This model class is a placeholder and there is no use case for this now. +void MessageDispatcher::onAdjustment(const AlarmClearedConditionRequestData &vData) +{ + QVariantList mData; + mData += vData.alarmID; + onActionTransmit(GuiActionType::ID_AlarmClearedConditionReq, mData); +} +// disabled coco end */ + +/** + * \details This method transmits the Saline Bolus Adjustment Denali message. + * \param vData - Data model contains treatment Saline Bolus adjustment state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustSalineRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustSalineReq, mData); +} + +/** + * \details This method transmits the Heparin Adjustment Denali message. + * \param vData - Data model contains treatment Heparin adjustment state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustHeparinRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustHeparinReq, mData); +} + +/** + * \details This method transmits the Rinseback Adjustment Denali message. + * \param vData - Data model contains treatment Rinseback adjustment state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustRinsebackRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustRinsebackReq, mData); +} + +/** + * \details This method transmits the Recirculate Adjustment Denali message. + * \param vData - Data model contains treatment Recirculate adjustment state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustRecirculateRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustRecirculateReq, mData); +} + +/** + * \details This method transmits the Treatment End Adjustment Denali message. + * \param vData - Data model contains treatment end adjustment state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustTreatmentEndRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustTreatmentEndReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the HD Version Denali message. + * \param vData - Data model contains HD Version state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustVersionsRequestData &vData) +{ + QVariantList mData; + mData += QVariant::fromValue(vData.ver_major); + mData += QVariant::fromValue(vData.ver_minor); + mData += QVariant::fromValue(vData.ver_micro); + mData += QVariant::fromValue(vData.ver_revis); + mData += QVariant::fromValue(vData.ver_comp ); + onActionTransmit(GuiActionType::ID_AdjustVersionsUIReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the HD Version Denali message. + * \param vData - Data model contains HD Version state. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustVersionsResponseData &vData) +{ + QVariantList mData; + mData += QVariant::fromValue(vData.ver_major); + mData += QVariant::fromValue(vData.ver_minor); + mData += QVariant::fromValue(vData.ver_micro); + mData += QVariant::fromValue(vData.ver_revis); + mData += QVariant::fromValue(vData.ver_comp ); + onActionTransmit(GuiActionType::ID_AdjustVersionsUIRsp, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the DG Set Date Time Denali message. + * \param vData - Data model contains the epoch time + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustServiceDatesRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustServiceDatesReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disposables Removal Confirm Adjustment Denali message. + * \param vData - Data model contains Service Mode adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustServiceModeRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustServiceModeReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Pressures Limits Adjustment Denali message. + * \param vData - Data model contains treatment Pressures Limits adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustPressuresLimitsRequestData &vData) +{ + QVariantList mData; + mData += vData.mArterialPressureLimitWindow ; + mData += vData.mVenousPressureLimitWindow ; + mData += vData.mVenousPressureLimitAsymtrc ; + onActionTransmit(GuiActionType::ID_AdjustPressuresLimitsReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the InitTreatment request message. + * \param vData - Data model contains the init treatment request information. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustInitTreatmentRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustInitTreatmentReq, mData); +} + +/** + * \details This method transmits the Treatment Parameter request message. + * \param vData - Data model contains treatment parameter adjustment data structure + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustParametersValidationRequestData &vData) +{ + QVariantList mData; + mData += vData.mBloodFlowRate ; + mData += vData.mDialysateFlowRate ; + mData += vData.mTreatmentDuration ; + mData += vData.mHeparinStopTime ; + mData += vData.mSalineBolus ; + mData += vData.mAcidConcentrate ; + mData += vData.mBicarbonateConcentrate ; + mData += vData.mDialyzerType ; + mData += vData.mHeparinType ; + mData += vData.mBloodPressureMeasureInterval ; + mData += vData.mRinsebackFlowRate ; + mData += vData.mArterialPressureLimitWindow ; + mData += vData.mVenousPressureLimitWindow ; + mData += vData.mVenousPressureLimitAsymtrc ; + mData += vData.mHeparinDispensingRate ; + mData += vData.mHeparinBolusVolume ; + mData += vData.mDialysateTemp ; + + onActionTransmit(GuiActionType::ID_AdjustParametersValidationReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Confirm Treatment request message. + * \param vData - Data model contains the confirm treatment request + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustParametersConfirmRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustParametersConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Water Sample Adjustment Denali message. + * \param vData - Data model contains Water Sample adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustWaterSampleRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustWaterSampleReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Water Sample Result Adjustment Denali message. + * \param vData - Data model contains Water Sample Result adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustWaterSampleResultRequestData &vData) +{ + QVariantList mData; + mData += vData.requestedState; + onActionTransmit(GuiActionType::ID_AdjustWaterSampleResultReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Consumables Confirm Adjustment Denali message. + * \param vData - Data model contains Consumables Confirm adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustConsumablesConfirmRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustConsumablesConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disposables Confirm Adjustment Denali message. + * \param vData - Data model contains Disposables Confirm adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDisposablesConfirmRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustDisposablesConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disposables Prime Adjustment Denali message. + * \param vData - Data model contains Disposables Prime adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDisposablesPrimeRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustDisposablesPrimeReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Patient Connection Begin Adjustment Denali message. + * \param vData - Data model contains Patient Connection Begin adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustPatientConnectionBeginRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustPatientConnectionBeginReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Ultrafiltration Adjustment Denali message. + * \param vData - Data model contains treatment ultrafiltration adjustment volume + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustUltrafiltrationInitRequestData &vData) +{ + QVariantList mData; + mData += vData.volume; + onActionTransmit(GuiActionType::ID_AdjustUltrafiltrationInitReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Patient Connection Confirm Adjustment Denali message. + * \param vData - Data model contains Patient Connection Confirm adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustPatientConnectionConfirmRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustPatientConnectionConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Start Treatment Adjustment Denali message. + * \param vData - Data model contains Start Treatment adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustStartTreatmentRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustStartTreatmentReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Patient Disconnection Notify Adjustment Denali message. + * \param vData - Data model contains Patient Disconnection Notify adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustPatientDisconnectionNotifyRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustPatientDisconnectNotifyReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Patient Disconnection Confirm Adjustment Denali message. + * \param vData - Data model contains Patient Disconnection Confirm adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustPatientDisconnectionConfirmRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustPatientDisconnectConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disposables Removal Confirm Adjustment Denali message. + * \param vData - Data model contains Disposables Removal Confirm adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDisposablesRemovalConfirmRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustDisposablesRemovalConfirmReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Treatment Log Adjustment Denali message. + * \param vData - Data model contains Treatment Log adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustTreatmentLogRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustTreatmentLogReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the HD Set Date Time Denali message. + * \param vData - Data model contains the epoch time + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustHDDateTimeRequestData &vData) +{ + QVariantList mData; + mData += vData.mEpoch ; + onActionTransmit(GuiActionType::ID_AdjustHDDateTimeReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the DG Set Date Time Denali message. + * \param vData - Data model contains the epoch time + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDGDateTimeRequestData &vData) +{ + QVariantList mData; + mData += vData.mEpoch ; + onActionTransmit(GuiActionType::ID_AdjustDGDateTimeReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the DG Cleaning Usage request message. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDGCleaningUsageRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustDGCleaningUsageReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disinfect request Denali message. + * \param vData - Data model contains the epoch time + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDisinfectStartRequestData &vData) +{ + QVariantList mData; + mData += vData.mState; + onActionTransmit(GuiActionType::ID_AdjustDisinfectStartReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disinfect mode request Denali message. + * \param vData - Data model contains the initiate/cancel boolean disinfection mode + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustDisinfectModeRequestData &vData) +{ + QVariantList mData; + mData += vData.mInititate; + onActionTransmit(GuiActionType::ID_AdjustDisinfectModeReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the UI power on self test final result + * \param vData - Data model contains the final result of the UI POST + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustUIPostFinalResultRequestData &vData) +{ + QVariantList mData; + mData += vData.mResult; + onActionTransmit(GuiActionType::ID_UIPostFinalResultData, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the UI Generic User Confirmation result. + * \param vData - Data model contains the Generic User Confirmation result. + * \return void + */ +void MessageDispatcher::onAdjustment(const DuetConfirmUIrData &vData) +{ + QVariantList mData; + mData += vData.mId; + mData += vData.mConfirm; + onActionTransmit(GuiActionType::ID_DuetConfirmUIr, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the UI RO Water Mode adjustment request. + * \param vData - Data model contains the UI RO Water Mode adjustment request data. + * \return void + */ +void MessageDispatcher::onAdjustment(const DuetRoWaterModeUIiData &vData) +{ + QVariantList mData; + mData += vData.mStatus; + onActionTransmit(GuiActionType::ID_DuetRoWaterModeUIi, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the HD Usage Info Denali message. + * \param vData - + * \return void + */ +void MessageDispatcher::onAdjustment(const HDUsageInfoRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_HDUsageInfoReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the HD institutional record request to HD. + * \param vData - + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustInstitutionalRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_AdjustInstitutionalRecordReq, mData); +} + +/*! + * \brief MessageDispatcher::onAdjustment + * \details This method transmits the Disposables Removal Confirm Adjustment Denali message. + * \param vData - Data model contains Service Mode adjustment. + * \return void + */ +void MessageDispatcher::onAdjustment(const AdjustHDResetInSrvcRequestData &) +{ + QVariantList mData; + onActionTransmit(GuiActionType::ID_ResetHDInServiceModeReq, mData); +} +// ---------------------------------------------------------------------------------------------------- + +/*! + * \brief MessageDispatcher::actionTransmit + * \details This method is called by slot MessageDispatcher::onActionTransmit + * which emits didFrameTransmit on successful interpretation of the requested message + * and successfully creating of frame(s). + * \param vActionId - The ActionID of the message + * \param vData - The data of the Message + */ +void MessageDispatcher::actionTransmit(GuiActionType vActionId, const QVariantList &vData, Sequence vSequence, Can_Id vCanId) +{ + txCount(); + if (vSequence == 0) { // initialize + // it's obvious that this assignment does not effect outside of the function. + // but is make it easier to just assume the correct value has been passed + // and still using the same variable (function parameter) as a local variable. + vSequence = _txSequence; + } + + QByteArray mData; + Can_Id canid = vCanId; + if (! _interpreter.interpretMessage(vActionId, vData, mData, canid)) { + LOG_DEBUG(QString("Incorrect Message, cannot be interpreted, %1").arg(Format::toHexString(vActionId))); // TODO : LogInfo Improvement + return; + } + + // TODO : Create a buildFrames method + FrameList frameList; + Sequence mSequence = vSequence; + bool mNeedsAcknow = needsAcknow(vActionId); + if (mNeedsAcknow) { + mSequence = -mSequence; + if ( ! gDisableAcknowLog ) { + LOG_APPED_UI(tr("Ack Req, Sq:%1, ID:%2").arg(mSequence).arg(Format::toHexString(vActionId))); + } +#ifdef DEBUG_ACKBACK_HD_TO_UI + qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckReq : %1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence); +#endif + } + + // disabled coco begin validated: Has been tested manually but in this function this cannot be false because the message interpreter is doing the same validation. + // still checking here in case the logic has changed therefore buildFrame should still validate the message for developer safety. + if ( ! _builder.buildFrames(vActionId, mData, frameList, mSequence) ) { + LOG_DEBUG(QString("Incorrect Message cannot be built")); // TODO : LogInfo Improvement + return; + } + // disabled coco end + if (mNeedsAcknow) { + // NOTE : here vSequence should be used which is not negative + // because when we get the Acknow it is not the negative + // since it does not need Re-Acknow + // and this is the sequence number which will be used + // to remove the message from the Acknow list. + emit didAcknowTransmit(canid, vSequence, frameList); + } + framesTransmit(canid, frameList); +} + +/*! + * \brief MessageDispatcher::framesTransmit + * \details iterates through all the frames and emits to send the frames + * \param vCan_Id - The channel to send the frames to + * \param vFrameList - List of the frames to be sent + */ +void MessageDispatcher::framesTransmit(Can_Id vCan_Id, const FrameList &vFrameList) +{ + for (const auto &frame : vFrameList) { + emit didFrameTransmit(vCan_Id, frame); + } +} + +/*! + * \brief MessageDispatcher::buildMessage + * \details Calls the messageBuilder buildMessage method. + * \param vCan_Id - CANBus channel of the frame + * \param vPayload - Payload of the frame + * \return false on error + */ +bool MessageDispatcher::buildMessage(Can_Id vCan_Id, const QByteArray &vPayload) +{ + if (vPayload.length() < eLenCanFrame) { + // Each frame has to have exactly 8 (eLenCanFrame) bytes of data and unused bytes should be passed as 00. + LOG_DEBUG(QString("Incorrect frame length. Exp:%1,got:%2").arg(eLenCanFrame).arg(vPayload.length())); + return false; + } + if (! _builder.buildMessage(vPayload, _messageList[vCan_Id].last(), vCan_Id)) { + _messageList[vCan_Id].removeLast(); + return false; + } + return true; +} + +/*! + * \brief MessageDispatcher::checkAcknowReceived + * \details check if the message was an acknowledge. + * \param vMessage - The received message + * \param vSrcText - The source entity identifier text + * \return true if the message is Acknow + */ +bool MessageDispatcher::checkAcknowReceived(const Message &vMessage, const QString &vSrcText) +{ + GuiActionType mActionId = vMessage.actionId; + Sequence mSequence = vMessage.sequence; + bool ok = false; + if ( mActionId == GuiActionType::ID_Acknow ) { + ok = true; + if ( ! gDisableAcknowLog ) { + LOG_APPED(tr(" ,%1,Ack Bak, Sq:%2").arg(vSrcText).arg(mSequence)); + } + #ifdef DEBUG_ACKBACK_HD_TO_UI + qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence).arg(vMessage.actionId); + #endif + emit didAcknowReceive(mSequence); + } + return ok; +} + +/*! + * \brief MessageDispatcher::checkAcknowTransmit + * \details Sends the Ack message. + * \param vMessage - the received message which to check if it may need Ack. + * \param vSrcText - the source of the message which needs Ack. + * \return returns true if the message needs an Ack (Negative Sequence) + */ +bool MessageDispatcher::checkAcknowTransmit(const Message &vMessage, const QString &vSrcText) +{ + bool ok = false; + GuiActionType mActionId = vMessage.actionId; + Sequence mSequence = vMessage.sequence; + + // UI shall acknowledge the messages is intended for UI. + if ( ! needsAcknow(vMessage.can_id)) return ok; // false + + if (mSequence < 0) { + ok = true; + if ( ! gDisableAcknowLog ) { + LOG_APPED(tr(" ,%1,Ack Req, Sq:%2, ID:%3").arg(vSrcText).arg(mSequence).arg(Format::toHexString(mActionId))); + } + #ifdef DEBUG_ACKBACK_HD_TO_UI + qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckReq : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence).arg(vMessage.actionId); + #endif + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak is immediately handled at the same place. + QString dstText; + Can_Id dstID = MessageInterpreter::identifyDestination(vMessage.can_id, &dstText); + actionTransmit(GuiActionType::ID_Acknow, {}, -mSequence, dstID); + if ( ! gDisableAcknowLog ) { + LOG_APPED_UI(tr("Ack Bak, Sq:%1, Dst:%2").arg(-mSequence).arg(dstText)); + } + #ifdef DEBUG_ACKBACK_HD_TO_UI + qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(-mSequence).arg(vMessage.actionId); + #endif + } + return ok; +} + +/*! + * \brief MessageDispatcher::interpretMessage + * \details Calls the MessageInterpreter interpretMessage method + * Regarding the Message Id and the sequence emit different signals + * to handle the normal or acknowledge messages. + * \param vMessage - The Message + * \return false on error + */ +bool MessageDispatcher::interpretMessage(const Message &vMessage) +{ + bool ok = false; + QVariantList mData; + QString srcText; + MessageInterpreter::identifySource(vMessage.can_id, &srcText); + if ( ! checkAcknowReceived(vMessage, srcText) ) { // check if the message was an acknowledge. + checkAcknowTransmit(vMessage, srcText); // then if needs acknow send it immediately. + } + + // disabled coco begin validated: Has been validated manually. If MessageInterpreter::interpretMessage fails, this also returns false + if ( _interpreter.interpretMessage( vMessage, mData ) ) { + ok = true; + emit didActionReceive(vMessage.actionId, mData); + } + // disabled coco end + + _messageList[vMessage.can_id].removeLast(); + return ok; +} + +/*! + * \brief MessageDispatcher::rxCount + * \details count received messages up the size of the Sequence type size + * \return message count + */ +Sequence MessageDispatcher::rxCount() +{ + // disabled coco begin validated: has been manually validated since it requires so many received messages to reset the seq + if ( _rxSequence < SEQUENCE_MAX ) { + ++_rxSequence; + } else { + _rxSequence = 1; + } + return _rxSequence; +} +// disabled coco end + +/*! + * \brief MessageDispatcher::txCount + * \details count transmitted messages up the size of the Sequence type size + * \return message count + */ +Sequence MessageDispatcher::txCount() +{ + // disabled coco begin validated: has been manually validated since it requires so many received messages to reset the seq + if ( _txSequence < SEQUENCE_MAX ) { + ++_txSequence; + } else { + _txSequence = 1; + } + return _txSequence; +} +// disabled coco end + +/*! + * \brief MessageDispatcher::needsAcknow + * \details List of the Action types which need Acknow + * \param vActionId - Action Type id + * \return true if needs an Acknow + */ +bool MessageDispatcher::needsAcknow(GuiActionType vActionId) +{ + return _needsAcknow.contains(vActionId); +} + +/*! + * \brief MessageDispatcher::needsAcknow + * \details List of the CAN channels which need Acknow + * \param vCan_Id - The message CANBus id + * \return true if needs an Acknow + */ +bool MessageDispatcher::needsAcknow(Can_Id vCan_Id) +{ + bool ok = true; + switch(vCan_Id) { // list if the channels UI shall not Ack + case eChlid_HD_DG : // 0x008, ///< HD => DG + case eChlid_DG_HD : // 0x010, ///< DG => HD + case eDialin_HD : // 0x400, ///< dialin => HD + case eHD_Dialin : // 0x401, ///< HD => dialin + case eDialin_DG : // 0x402, ///< dialin => DG + case eDG_Dialin : // 0x403, ///< DG => dialin + ok = false; break; + + default: break; + } + + return ok; +}