Index: sources/canbus/messagebuilder.cpp =================================================================== diff -u -r8c69137f18382bdc55a5678e6ed44a7683fe4dea -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 8c69137f18382bdc55a5678e6ed44a7683fe4dea) +++ sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -42,12 +42,12 @@ * \param vFrameList - The list of frames which has been created by vAction and vData to be sent. * \return false on error */ -bool MessageBuilder::buildFrames(Gui::GuiActionType vAction, const QByteArray &vData, FrameList &vFrameList) +bool MessageBuilder::buildFrames(Gui::GuiActionType vAction, const QByteArray &vData, FrameList &vFrameList, Sequence vSequence) { QByteArray mPayload ; addSyncByte (mPayload); // Sync Byte - addSequence (mPayload); // adding sequence - if ( ! addActionId (mPayload, vAction) ) { // MessageID + addSequence (mPayload, vSequence); // adding sequence + if ( ! addActionId (mPayload, vAction ) ) { // MessageID return false; } if ( ! addData (mPayload, vAction, vData) ) { // Regarding Payload Length, Adding required Data @@ -80,11 +80,13 @@ vPayload.append(ePayload_Sync); // Sync byte } -void MessageBuilder::addSequence(QByteArray &/*vPayload*/) +void MessageBuilder::addSequence(QByteArray &vPayload, Sequence vSequence) { -// Types::S16 seq; -// seq.value = -// vPayload.append(); + Sequence_Bytes mSequence; + mSequence.value = vSequence; + for (quint8 index = 0; index < sizeof(mSequence); index++) { + vPayload += mSequence.bytes[index]; + } } /*! @@ -299,7 +301,6 @@ */ Sequence MessageBuilder::getSequence(QByteArray &vPayload) { - // be careful about using the Types::S16 type and always check with the Sequence type. Sequence_Bytes mSequence; int index = 0; Types::getValue<>(vPayload, index, mSequence); Index: sources/canbus/messagebuilder.h =================================================================== diff -u -r8c69137f18382bdc55a5678e6ed44a7683fe4dea -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/canbus/messagebuilder.h (.../messagebuilder.h) (revision 8c69137f18382bdc55a5678e6ed44a7683fe4dea) +++ sources/canbus/messagebuilder.h (.../messagebuilder.h) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -52,9 +52,9 @@ bool _enableConsoleOut = false; void addSyncByte ( QByteArray &vPayload); - void addSequence ( QByteArray &vPayload); - bool addActionId ( QByteArray &vPayload, Gui::GuiActionType vAction) __attribute_warn_unused_result__; - bool addData ( QByteArray &vPayload, Gui::GuiActionType vAction, const QByteArray &vData) __attribute_warn_unused_result__; + void addSequence (QByteArray &vPayload, Sequence vSequence); + bool addActionId ( QByteArray &vPayload, Gui::GuiActionType vAction) __attribute_warn_unused_result__; + bool addData ( QByteArray &vPayload, Gui::GuiActionType vAction, const QByteArray &vData) __attribute_warn_unused_result__; void addCRC ( QByteArray &vPayload); void addPadding ( QByteArray &vPayload); @@ -76,12 +76,14 @@ explicit MessageBuilder(QObject *parent = nullptr); // build message to be sent frame by frame - bool buildFrames(Gui::GuiActionType vAction , const QByteArray &vData, FrameList &vFrameList) __attribute_warn_unused_result__; + bool buildFrames (Gui::GuiActionType vAction , const QByteArray &vData, FrameList &vFrameList, Sequence vSequence) __attribute_warn_unused_result__; // build message from received frames - bool buildMessage(const QByteArray &vPayload, Message &vMessage, Can_Id vCan_Id) __attribute_warn_unused_result__; + bool buildMessage(const QByteArray &vPayload, Message &vMessage, Can_Id vCan_Id) __attribute_warn_unused_result__; - void enableConsoleOut( bool vEnabled) { _enableConsoleOut = vEnabled; } + void enableConsoleOut(bool vEnabled) { _enableConsoleOut = vEnabled; } + + signals: public slots: Index: sources/canbus/messagedispatcher.cpp =================================================================== diff -u -r8c69137f18382bdc55a5678e6ed44a7683fe4dea -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/canbus/messagedispatcher.cpp (.../messagedispatcher.cpp) (revision 8c69137f18382bdc55a5678e6ed44a7683fe4dea) +++ sources/canbus/messagedispatcher.cpp (.../messagedispatcher.cpp) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -22,6 +22,8 @@ #include "applicationcontroller.h" #include "frameinterface.h" +#define DEBUG_ACKBACK_HD_TO_UI + using namespace Can; /*! @@ -87,6 +89,9 @@ // From HD connect(&_FrameInterface , SIGNAL(didFrameReceive ( Can_Id, const QByteArray &)), this , SLOT( onFrameReceive ( Can_Id, const QByteArray &))); + + connect(this ,SIGNAL(didFramesTransmit( Can_Id, const FrameList &)), + this , SLOT( onFramesTransmit( Can_Id, const FrameList &))); } /*! @@ -145,11 +150,29 @@ // TODO : must be moved to a MessageModel class if (mMessage.isComplete()) { + rxCount(); + #ifdef QT_DEBUG + 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 vCan_Id - CanBus channel + * \param vFrameList - frame(s) to be sent + */ +void MessageDispatcher::onFramesTransmit(Can_Id vCan_Id, const FrameList &vFrameList) +{ + framesTransmit(vCan_Id, vFrameList); +} + +/*! * \brief MessageDispatcher::onActionTransmit * \details This slot will be called by ApplicationController::didActionTransmit * upon UI message transmit request and calls MessageDispatcher::actionTransmit method. @@ -158,7 +181,7 @@ */ void MessageDispatcher::onActionTransmit(GuiActionType vActionId, const QVariantList &vData) { - actionTransmit(vActionId, vData); + actionTransmit(vActionId, vData, txCount()); } /*! @@ -169,25 +192,49 @@ * \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) { QByteArray mData; if (! _interpreter.interpretMessage(vActionId, vData, mData)) { LOG_ERROR(tr("Incorrect Message, can't be interpreted")); return; } + // TODO : Create a buildFrames method FrameList frameList; - if ( ! _builder.buildFrames(vActionId, mData, frameList) ) { + Sequence mSequence = vSequence; + bool mNeedsAcknow = needsAcknow(vActionId); + if (mNeedsAcknow) mSequence = -mSequence; + + if ( ! _builder.buildFrames(vActionId, mData, frameList, mSequence) ) { LOG_ERROR(tr("Incorrect Message can't be built")); return; } - for (const auto &frame : frameList) { - emit didFrameTransmit(eChlid_UI_HD, frame); + 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(vSequence, eChlid_UI_HD, frameList); } + framesTransmit(eChlid_UI_HD, 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 @@ -228,7 +275,8 @@ break; default: if (vMessage.sequence < 0) { - //actionTransmit(-vMessage.sequence, GuiActionType::Acknow,{}); + actionTransmit(GuiActionType::Acknow, {}, vMessage.sequence); + qDebug() << tr(" ~~~~~~~~~~ Ack Back : %1~~~~~~~~~~ ").arg(vMessage.sequence); } emit didActionReceive(mActionId, mData); break; @@ -239,3 +287,58 @@ } +/*! + * \brief MessageDispatcher::rxCount + * \details count received messages up the size of the Sequence type size + * \return message count + */ +Sequence MessageDispatcher::rxCount() +{ + if ( _rxSequence < SEQUENCE_MAX ) { + ++_rxSequence; + } else { + _rxSequence = 1; + } + return _rxSequence; +} + +/*! + * \brief MessageDispatcher::txCount + * \details count transmitted messages up the size of the Sequence type size + * \return message count + */ +Sequence MessageDispatcher::txCount() +{ + if ( _txSequence < SEQUENCE_MAX ) { + ++_txSequence; + } else { + _txSequence = 1; + } + return _txSequence; +} + +/*! + * \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) +{ + switch(vActionId) { + case GuiActionType::Acknow: + // this is the Acknow itself + // since the actionTransmit will make any needsAcknow sequence to negative + // and the Ack Back should be in positive after receiving it in negative + // actually this make it positive and send it back. + return true; + default: + // TEST : this code is for test. +#ifdef DEBUG_ACKBACK_HD_TO_UI + return ( ! (_txSequence % 21) ); +#else + return false; +#endif + } + return false; +} Index: sources/canbus/messagedispatcher.h =================================================================== diff -u -r8c69137f18382bdc55a5678e6ed44a7683fe4dea -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/canbus/messagedispatcher.h (.../messagedispatcher.h) (revision 8c69137f18382bdc55a5678e6ed44a7683fe4dea) +++ sources/canbus/messagedispatcher.h (.../messagedispatcher.h) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -88,6 +88,9 @@ QHash _messageList; + Sequence _txSequence = 0; + Sequence _rxSequence = 0; + MessageBuilder _builder; MessageInterpreter _interpreter; @@ -113,10 +116,18 @@ void initThread(QThread &vThread); void quitThread(); - void actionTransmit(GuiActionType vActionId, const QVariantList &vData, Sequence vSequence = 0); + void actionTransmit (GuiActionType vActionId, const QVariantList &vData, Sequence vSequence = 0); + void framesTransmit (Can_Id vCan_Id, const FrameList &vFrameList); + bool needsAcknow (GuiActionType vActionId); + bool buildMessage (Can_Id vCan_Id, const QByteArray &vPayload); bool interpretMessage(const Message &vMessage); + + Sequence txCount(); + Sequence rxCount(); + + signals: /*! * \brief didActionReceive @@ -126,38 +137,57 @@ * \param vAction - The action has been extracted from CANBUS message header to be done * \param vData - The data has been collected from CANBUS frame(s) */ - void didActionReceive(GuiActionType vAction , const QVariantList &vData); + void didActionReceive (GuiActionType vAction , const QVariantList &vData); /*! * \brief didActionReceive * \details Emits when a message requires * \param vData */ - void didActionReceive(const Message &vMessage); + void didActionReceive (const Message &vMessage); /** * @brief didAcknowReceive * @details if the type the received message id is and Acknow this signal will be emitted * @param vData - the data of the Acknow message which is the message Sequence * which we got the Ack for. */ - void didAcknowReceive(const Sequence &vSequence); + void didAcknowReceive (Sequence vSequence); /*! + * \brief didAcknowTransmit + * \details this signal will be emitted when the message which has been sent + * needs Acknowledge back. + * \param vFrameList - the frames which has been send + * and will be used to be send on retries. + */ + void didAcknowTransmit(Sequence vSequence, Can_Id vCan_Id, const FrameList &vFrameList); + + /*! + * \brief didFramesTransmit + * \details when this signal is emitted frame(s) in the vFramesList + * will be queued to be sent. + * \param vFrameList - list of the frame(s) to be sent. + */ + void didFramesTransmit(Can_Id vCan_Id, const FrameList &vFrameList); + + /*! * \brief didFrameTransmit * \details When a message is requested to be transmitted this signal is emitted * on successful interpretation and building the message into frames * \param vCan_Id - Target channel of the CANBUS message * \param vPayload - The payload of the message to be sent */ - void didFrameTransmit(Can_Id vCan_Id , const QByteArray &vPayload); + void didFrameTransmit (Can_Id vCan_Id, const QByteArray &vPayload); private slots: // A Frame has been received from CanInterface - void onFrameReceive (Can_Id vCan_Id , const QByteArray &vPayload); + void onFrameReceive (Can_Id vCan_Id, const QByteArray &vPayload); + void onFramesTransmit (Can_Id vCan_Id, const FrameList &vFrameList); // An Action has been requested to be transmitted. - void onActionTransmit(GuiActionType vActionId, const QVariantList &vData); + void onActionTransmit (GuiActionType vActionId, const QVariantList &vData); + }; } Index: sources/canbus/messageinterpreter.cpp =================================================================== diff -u -r8c69137f18382bdc55a5678e6ed44a7683fe4dea -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 8c69137f18382bdc55a5678e6ed44a7683fe4dea) +++ sources/canbus/messageinterpreter.cpp (.../messageinterpreter.cpp) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -66,6 +66,12 @@ // Mentioned in the switch/case to be registered as a valid message. break; + case Gui::GuiActionType::Acknow: + // Nothing needs to be done. + // Acknow has No data. + // Mentioned in the switch/case to be registered as a valid message. + break; + case Gui::GuiActionType::String: vPayload = Format::fromVariant(vData[0]); break; @@ -440,7 +446,7 @@ Types::getValue<>(vMessage.data, index, vTop ); Types::getValue<>(vMessage.data, index, vMuteTimeout ); Types::getValue<>(vMessage.data, index, vEscalatesIn ); - Types::getBits (vMessage.data, index, vFlags , 16); + Types::getBits (vMessage.data, index, vFlags, static_cast(Gui::GuiActionIndx::AlarmStatus_Flag_Bits_Length)); return true; } Index: sources/gui/guiglobals.h =================================================================== diff -u -re58b907a69d4ca7daa77d69791593b886d1b80e8 -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/gui/guiglobals.h (.../guiglobals.h) (revision e58b907a69d4ca7daa77d69791593b886d1b80e8) +++ sources/gui/guiglobals.h (.../guiglobals.h) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -82,6 +82,8 @@ AlarmStatus_Flag_bypassDialyzer , AlarmStatus_Flag_alarmsToEscalate , AlarmStatus_Flag_alarmsSilenced , + AlarmStatus_Flag_Bits_Length = 16, + }; enum class GuiActionsData_Enum /*: quint8 QML doesn't support*/ { Index: sources/gui/qml/main.qml =================================================================== diff -u -r442d1c4f53c96991d4103485ff5ff683ed00d4f7 -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/gui/qml/main.qml (.../main.qml) (revision 442d1c4f53c96991d4103485ff5ff683ed00d4f7) +++ sources/gui/qml/main.qml (.../main.qml) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -82,7 +82,7 @@ } // 9 - Others - Text { // TODO : Test Code + Text { // TEST : Appliaction version should be voved into the information screen later. color: Colors.textMain x: 1172 y: 767 Index: sources/gui/qml/pages/TreatmentStart.qml =================================================================== diff -u -r442d1c4f53c96991d4103485ff5ff683ed00d4f7 -r0e87420e50dd94c37eb25f289ef3262e0e45d7f4 --- sources/gui/qml/pages/TreatmentStart.qml (.../TreatmentStart.qml) (revision 442d1c4f53c96991d4103485ff5ff683ed00d4f7) +++ sources/gui/qml/pages/TreatmentStart.qml (.../TreatmentStart.qml) (revision 0e87420e50dd94c37eb25f289ef3262e0e45d7f4) @@ -170,7 +170,7 @@ } Connections { target: _treatmentMenu onItemPressed: { - // TEST CODE : this is a test code since the back button has been removed + // TEST : this is a test code since the back button has been removed // and also we don't have Treatment complete yet. if (vIndex == 0) { _treatmentMenu.hidden = true