Index: sources/canbus/MessageDispatcher.cpp =================================================================== diff -u -r13d6a4fae2f910ab6e289ac9280258a94f734405 -rb5afbc61af03dd2e84acf8439cb6be1f022a2921 --- sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision 13d6a4fae2f910ab6e289ac9280258a94f734405) +++ sources/canbus/MessageDispatcher.cpp (.../MessageDispatcher.cpp) (revision b5afbc61af03dd2e84acf8439cb6be1f022a2921) @@ -1,15 +1,15 @@ /*! * - * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * Copyright (c) 2020-2022 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) Behrouz NematiPour - * \date (last) 31-Aug-2020 - * \author (original) Behrouz NematiPour - * \date (original) 26-Aug-2020 + * \file MessageDispatcher.cpp + * \author (last) Behrouz NematiPour + * \date (last) 18-Apr-2022 + * \author (original) Behrouz NematiPour + * \date (original) 26-Aug-2020 * */ #include "MessageDispatcher.h" @@ -48,7 +48,7 @@ // runs in the thread initConnections(); - LOG_DEBUG("UI," + tr("%1 Initialized").arg(metaObject()->className())); + LOG_DEBUG(tr("%1 Initialized").arg(metaObject()->className())); return true; } @@ -75,11 +75,11 @@ */ void MessageDispatcher::quit() { - // coco begin validated: Application termination is not correctly done in coco!!! + // 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 } -// coco end +// disabled coco end /*! * \brief Message Handler connections definition @@ -103,6 +103,10 @@ 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 ) @@ -128,38 +132,38 @@ /*! * \brief MessageDispatcher::quitThread - * \details Moves this object to main thread to be handled by QApplicaiton + * \details Moves this object to main thread to be handled by QApplication * And to be destroyed there. */ void MessageDispatcher::quitThread() { - // coco begin validated: Application termination is not correctly done in coco!!! + // 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 } -// coco end +// disabled coco end /*! * \brief MessageDispatcher::onFrameReceive - * \details Upon message has been received over CANBUS this slot will be called + * \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 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 - // coco begin validated: if empty (first condition) is true, it must never check for the complete (second condition) + // 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()) { - // coco end + // disabled coco end _messageList[vCan_Id].append(Message()); } @@ -201,10 +205,10 @@ */ void MessageDispatcher::onFailedTransmit(Sequence vSequence) { - // coco begin validated: Is a placeholder and has not been implemented yet + // disabled coco begin validated: Is a placeholder and has not been implemented yet emit didFailedTransmit(vSequence); } -// coco end +// disabled coco end /*! * \brief MessageDispatcher::onActionTransmit @@ -218,6 +222,15 @@ actionTransmit(vActionId, vData); } +/*! + * \brief MessageDispatcher::onSettingsDone + * \details The slot to handle didSettingsDone signal of the ApplicationController + */ +void MessageDispatcher::onSettingsDone() +{ + _interpreter.updateUnhandledMessages(); +} + // ---------------------------------------------------------------------------------------------------- /*! @@ -336,7 +349,8 @@ void MessageDispatcher::onAdjustment(const AdjustHDAlarmVolumeRequestData &vData) { QVariantList mData; - mData += vData.volume / 20; // HD vol range is [1-5] and we show [20%-100%] to user. + const int hw2ui = 20; // HD vol range is [1-5] and we show [20%-100%] to user (100 / 5). + mData += vData.volume / hw2ui; onActionTransmit(GuiActionType::ID_AlarmVolumeSetReq, mData); } @@ -346,14 +360,14 @@ * \param vData - Data model contains the user acknowledge request information. * \return void */ -/* // coco begin validated: Manually tested. This model class is a placeholder and there is no use case for this now. +/* // 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); } -// coco end */ +// disabled coco end */ /** * \details This method transmits the Saline Bolus Adjustment Denali message. @@ -421,24 +435,57 @@ * \param vData - Data model contains HD Version state. * \return void */ -void MessageDispatcher::onAdjustment(const AdjustVersionsRequestData &) +void MessageDispatcher::onAdjustment(const AdjustVersionsRequestData &vData) { QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustVersionsReq, 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 AdjustServiceRequestData &) +void MessageDispatcher::onAdjustment(const AdjustServiceDatesRequestData &) { QVariantList mData; - onActionTransmit(GuiActionType::ID_AdjustServiceReq, 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 @@ -485,6 +532,7 @@ mData += vData.acidConcentrate ; mData += vData.bicarbonateConcentrate ; mData += vData.dialyzerType ; + mData += vData.heparinType ; mData += vData.bloodPressureMeasureInterval ; mData += vData.rinsebackFlowRate ; mData += vData.arterialPressureLimitLow ; @@ -709,6 +757,33 @@ onActionTransmit(GuiActionType::ID_AdjustChemicalConfirmReq, 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); +} + // ---------------------------------------------------------------------------------------------------- /*! @@ -719,7 +794,7 @@ * \param vActionId - The ActionID of the message * \param vData - The data of the Message */ -void MessageDispatcher::actionTransmit(GuiActionType vActionId, const QVariantList &vData, Sequence vSequence) +void MessageDispatcher::actionTransmit(GuiActionType vActionId, const QVariantList &vData, Sequence vSequence, Can_Id vCanId) { txCount(); if (vSequence == 0) { // initialize @@ -730,9 +805,9 @@ } QByteArray mData; - Can_Id canid; + Can_Id canid = vCanId; if (! _interpreter.interpretMessage(vActionId, vData, mData, canid)) { - LOG_DEBUG(QString("Incorrect Message, can't be interpreted, %1").arg(Format::toHexString(vActionId))); // TODO : LogInfo Improvement + LOG_DEBUG(QString("Incorrect Message, cannot be interpreted, %1").arg(Format::toHexString(vActionId))); // TODO : LogInfo Improvement return; } @@ -750,13 +825,13 @@ #endif } - // coco begin validated: Has been tested manually but in this function this can't be false because the message interpreter is doing the same validation. + // 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 can't be built")); // TODO : LogInfo Improvement + LOG_DEBUG(QString("Incorrect Message cannot be built")); // TODO : LogInfo Improvement return; } - // coco end + // 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 @@ -784,7 +859,7 @@ /*! * \brief MessageDispatcher::buildMessage * \details Calls the messageBuilder buildMessage method. - * \param vCan_Id - CANBUS channel of the frame + * \param vCan_Id - CANBus channel of the frame * \param vPayload - Payload of the frame * \return false on error */ @@ -802,15 +877,22 @@ return true; } -bool MessageDispatcher::checkAcknowReceived(const Message &vMessage, const char *src) +/*! + * \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; #ifndef DISABLE_ACKNOW_CHECKIN_MESSAGE_LOG - LOG_EVENT(tr("%1,Ack Bak, Sq:%2").arg(src).arg(mSequence)); + LOG_EVENT(tr("%1,Ack Bak, Sq:%2").arg(vSrcText).arg(mSequence)); #endif #ifdef DEBUG_ACKBACK_HD_TO_UI qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HD AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(mSequence).arg(vMessage.actionId); @@ -820,23 +902,36 @@ return ok; } -bool MessageDispatcher::checkAcknowTransmit(const Message &vMessage, const char *src) +/*! + * \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; #ifndef DISABLE_ACKNOW_CHECKIN_MESSAGE_LOG - LOG_EVENT(tr("%1,Ack Req, Sq:%2, ID:%3").arg(src).arg(mSequence).arg(Format::toHexString(mActionId))); + LOG_EVENT(tr("%1,Ack Req, Sq:%2, ID:%3").arg(vSrcText).arg(mSequence).arg(Format::toHexString(mActionId))); #endif #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. - actionTransmit(GuiActionType::ID_Acknow, {}, -mSequence); + QString dstText; + Can_Id dstID = MessageInterpreter::identifyDestination(vMessage.can_id, &dstText); + actionTransmit(GuiActionType::ID_Acknow, {}, -mSequence, dstID); #ifndef DISABLE_ACKNOW_CHECKIN_MESSAGE_LOG - LOG_EVENT(tr("UI,Ack Bak, Sq:%1").arg(-mSequence)); + LOG_EVENT(tr("UI,Ack Bak, Sq:%1, Dst:%2").arg(-mSequence).arg(dstText)); #endif #ifdef DEBUG_ACKBACK_HD_TO_UI qDebug() << tr(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UI AckBak : %1 %2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ").arg(-mSequence).arg(vMessage.actionId); @@ -857,18 +952,18 @@ { bool ok = false; QVariantList mData; - Can_Source srcID = MessageInterpreter::identifySource(vMessage.can_id); - const char *srcText = (srcID == Can_Source::eCan_HD) ? "HD" : ((srcID == Can_Source::eCan_DG) ? "DG" : "XX"); + 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. } - // coco begin validated: Has been validated manually. If MessageInterpreter::interpretMessage fails, this also returns false + // 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); } - // coco end + // disabled coco end _messageList[vMessage.can_id].removeLast(); return ok; @@ -881,15 +976,15 @@ */ Sequence MessageDispatcher::rxCount() { - // coco begin validated: has been manually validated since it requires so many received messages to reset the seq + // 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; } -// coco end +// disabled coco end /*! * \brief MessageDispatcher::txCount @@ -898,15 +993,15 @@ */ Sequence MessageDispatcher::txCount() { - // coco begin validated: has been manually validated since it requires so many received messages to reset the seq + // 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; } -// coco end +// disabled coco end /*! * \brief MessageDispatcher::needsAcknow @@ -918,3 +1013,27 @@ { 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; +}