Index: sources/canbus/caninterface.cpp =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -78,7 +78,7 @@ { if (_canDevice) { connect(_canDevice, SIGNAL( framesReceived()), - this , SLOT (onFrameReceive ())); + this , SLOT (onFrameReceive ())); connect(_canDevice, SIGNAL( errorOccurred(QCanBusDevice::CanBusError)), this , SLOT (onError (QCanBusDevice::CanBusError))); @@ -122,6 +122,15 @@ _canDevice->writeFrame(vFrame); } +void CanInterface::consoleout(const QCanBusFrame &vFrame, const QString &vView) +{ + const QString time = QString::fromLatin1("%1.%2 ") + .arg(vFrame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) + .arg(vFrame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); + const QString flags = frameFlags(vFrame); + qDebug() << time + flags + vView; +} + /*! * \brief CanInterface quit * \details Quit the Can Interface by disconnecting the bus and device. @@ -144,7 +153,7 @@ * \param frame Can message frame * \return Frame flag */ -static QString frameFlags(const QCanBusFrame &frame) +QString CanInterface::frameFlags(const QCanBusFrame &frame) { QString result = QLatin1String(" --- "); @@ -199,15 +208,8 @@ view = frame.toString(); } - const QString time = QString::fromLatin1("%1.%2 ") - .arg(frame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) - .arg(frame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); + //consoleout(frame, view); - const QString flags = frameFlags(frame); - - // qDebug() << time + flags + view; - // TODO : Needs to be investigated on how the messages on canBus will be received. - // may require to be moved at the end of the function, to not to be called for each message. emit didRead(frame); } } Index: sources/canbus/caninterface.h =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/canbus/caninterface.h (.../caninterface.h) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/canbus/caninterface.h (.../caninterface.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -64,9 +64,12 @@ private: void initConnections(); - void status(const QString &vDescription, QString vError = ""); - void transmit(const QCanBusFrame &vFrame); + void status (const QString &vDescription, QString vError = ""); + void transmit (const QCanBusFrame &vFrame); + void consoleout (const QCanBusFrame &vFrame, const QString &vView); + static QString frameFlags(const QCanBusFrame &frame); + signals: void didRead (const QCanBusFrame &vFrame ); void didError(const QString &vStatus); Index: sources/canbus/messagehandler.cpp =================================================================== diff -u -rf37a92ae779a27d59fa26d91f0656bd55852c6e1 -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/canbus/messagehandler.cpp (.../messagehandler.cpp) (revision f37a92ae779a27d59fa26d91f0656bd55852c6e1) +++ sources/canbus/messagehandler.cpp (.../messagehandler.cpp) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -22,6 +22,7 @@ #include // Project +#include "maintimer.h" #include "applicationcontroller.h" // namespace @@ -42,8 +43,6 @@ void MessageHandler::init() { initConnections(); - checked_in(); - //startTimer(1000); } /*! @@ -59,6 +58,9 @@ // From HD/DG connect(_CanInterface , SIGNAL( didRead(QCanBusFrame)), this , SLOT(onFrameReceive (QCanBusFrame))); + + connect(_MainTimer , SIGNAL( didTimeout()), + this , SLOT(onMainTimerTimeout())); } void MessageHandler::checked_in() @@ -74,6 +76,23 @@ emit didFrameTransmit(mFrame); } +bool MessageHandler::ignoreChannel(const QCanBusFrame &vFrame) +{ + //TODO : There should be an easy way to find if the correct CAN ID has been received + Can_Id mCanId = static_cast(vFrame.frameId()); + switch (mCanId) { + case eChlid_HD_DG: + case eChlid_DG_HD: + return true; + break; + case eChlid_HD: + break; + default: + break; + } + return false; +} + QByteArray MessageHandler::buildMessage(GuiActionType vAction, GuiActionData vData) { QByteArray mPayload ; @@ -131,6 +150,38 @@ return true;//calcCRC(vData) == vCRC; } +bool MessageHandler::stripMessage(const QCanBusFrame &vFrame, Message &vMessage) +{ + QByteArray mPayload = vFrame.payload(); + + //if (messages[mCanId].isEmpty()) { + // messages[mCanId].append(Message()); + //} + //if (messages[mCanId].last().isComplete()) { + // messages[mCanId].append(Message()); + //} + // + //Message message = messages[mCanId].last(); + + // when we are here the message is new or partial. + bool ok = false; + if (hasSyncByte(mPayload)) { + vMessage.actionId = getActionId(mPayload); + vMessage.length = getLength (mPayload); + vMessage.data = getData (mPayload, vMessage.length, &ok); + if (!ok) { + qDebug() << "ERROR : CRC error"; + return false; + } + } else { + qDebug() << "ERROR : incomplete message or corrupted without sync byte (without header)"; + return false; + } + + //messages[mCanId].append(message); + return true; +} + bool MessageHandler::hasSyncByte(QByteArray &vPayload) { quint8 mSyncByte = vPayload[0]; @@ -174,12 +225,28 @@ return mData; } +bool MessageHandler::interpretData(const Message &vMessage, GuiActionType &vActionId, GuiActionData &vData) +{ + quint8 tmp; + vActionId = vMessage.actionId; + switch (vActionId) { // notice we are in receive mode + case GuiActionType::PowerOff: + tmp = vMessage.data[0]; + vData = static_cast(tmp); + //TODO: (MessageInterpreter) There should be an easy way to check if a correct data has been provided. + break; + default: + vData = GuiActionData::Command; + break; + } + return true; +} + void MessageHandler::addCRC(QByteArray &vPayload) { vPayload += calcCRC(vPayload); } - /*! * \brief Process the requested action * \details Processes the requested action @@ -196,55 +263,27 @@ */ void MessageHandler::onFrameReceive(const QCanBusFrame &vFrame) { - bool isUnknown = false; - bool isIgnored = false; + if (ignoreChannel(vFrame)) { + return; + } - //TODO : There should be a way to find if the correct CAN ID has been received - Can_Id mCanId = static_cast(vFrame.frameId()); - switch (mCanId) { - case eChlid_HD_DG: - case eChlid_DG_HD: - isIgnored = true; - break; - case eChlid_HD: - break; - default: - break; + Message mMessage; + if (! stripMessage(vFrame,mMessage)) { + return; } - QByteArray mPayload = vFrame.payload(); - - //if (messages[mCanId].isEmpty()) { - // messages[mCanId].append(Message()); - //} - //if (messages[mCanId].last().isComplete()) { - // messages[mCanId].append(Message()); - //} - // - //Message message = messages[mCanId].last(); - - Message message; - // when we are here the message is new or partial. - bool ok = false; - if (hasSyncByte(mPayload)) { - message.actionId = getActionId(mPayload); - message.length = getLength (mPayload); - message.data = getData (mPayload, message.length, &ok); - if (!ok) { - qDebug() << "ERROR : CRC error"; - } - } else { - qDebug() << "ERROR : incomplete message or corrupted without sync byte (without header)"; + // FIXME: Needs MessageInterpreter class for data in each action [Sprint 8] + GuiActionType mActionId; + GuiActionData mData; + if (! interpretData(mMessage, mActionId, mData)) { + return; } - //messages[mCanId].append(message); - - if (isUnknown || isIgnored) return; - - emit didActionReceive (message.actionId, GuiActionData::Accepted); + emit didActionReceive (mActionId, mData); } -void MessageHandler::timerEvent(QTimerEvent *event) +void MessageHandler::onMainTimerTimeout() { - QObject::timerEvent(event); + //QMetaObject::invokeMethod(this, "checked_in"); + checked_in(); } Index: sources/canbus/messagehandler.h =================================================================== diff -u -rf37a92ae779a27d59fa26d91f0656bd55852c6e1 -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/canbus/messagehandler.h (.../messagehandler.h) (revision f37a92ae779a27d59fa26d91f0656bd55852c6e1) +++ sources/canbus/messagehandler.h (.../messagehandler.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -43,17 +43,20 @@ * * \brief The MessageHandler class * \details This class is handling the can message by building and striping it. - * // -- CAN MESSAGE STRUCTURE -- + * + * // -- CAN PAYLOAD STRUCTURE -- * #0 #1 #2 #3 #4 #5 #6 #7 * +---+---+---+---+---+---+---+---+--.......--+ - * | A5| MsgId |Len| Payload |CRC|..padding..| + * | A5| MsgId |Len| Data |CRC|..padding..| * +---+---+---+---+---+---+---+---+--.......--+ + * * Header Frame: * 1 - CRC is last after payload * Ex1 - If Len=0 then CRC is #4 * Ex2 - If Len=1 then CRC is #5 and payload is #4 * 2 - If CRC is not the last by in the frame * then there is padding 0x00 to make the frame 8 byte fix + * * Tail Frame: * 3 - Partial frames only have Payload and CRC ( and padded) * @@ -124,15 +127,17 @@ // Singleton SINGLETON_DECL(MessageHandler) - public: +public: void init(); private: void initConnections(); - void checked_in(); // TODO : needs to be renamed and called from the main timer to tell HD, UI is alive + void checked_in(); void transmitFrame(MessageHandler::Can_Id vCan_Id, GuiActionType vAction, GuiActionData vData = GuiActionData::NoData); + bool ignoreChannel(const QCanBusFrame &vFrame); + // build message to be sent QByteArray buildMessage (GuiActionType vAction , GuiActionData vData); void addSyncByte (QByteArray &vPayload); @@ -142,23 +147,26 @@ void addCRC (QByteArray &vPayload); void addPadding (QByteArray &vPayload); + // CRC tools quint8 calcCRC (const QByteArray &vData); bool checkCRC (const QByteArray &vData, quint8 vCRC); // strip message to its parts - QByteArray stripMessage (const QCanBusFrame &vFrame ); + bool stripMessage(const QCanBusFrame &vFrame, Message &vMessage); bool hasSyncByte (QByteArray &vPayload); GuiActionType getActionId (QByteArray &vPayload); quint8 getLength (QByteArray &vPayload); - QByteArray getData (QByteArray &vPayload, quint8 vLen , bool *ok = nullptr ); + QByteArray getData (QByteArray &vPayload, quint8 vLen, bool *ok = nullptr); -protected: - virtual void timerEvent(QTimerEvent *event) override; + // interpret the data into GUI understandable Actions/Data + bool interpretData(const Message &vMessage, GuiActionType &vActionId, GuiActionData &vData); private slots: // Should be private for thread safety and is connected internally. void onActionTransmit(GuiActionType vAction, GuiActionData vData); // UI => HD/DG void onFrameReceive (const QCanBusFrame &vFrame ); // UI <= HD/DG + void onMainTimerTimeout(); + signals: void didActionReceive (GuiActionType vAction, GuiActionData vData); // UI <= HD/DG void didFrameTransmit (const QCanBusFrame &vFrame ); // UI => HD/DG Index: sources/gui/guiactions.h =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/gui/guiactions.h (.../guiactions.h) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/gui/guiactions.h (.../guiactions.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -29,8 +29,16 @@ }; enum GuiActionsData_Enum /*: quint8 QML doesn't support*/ { NoData = 0x00, + + Command = 0x00, // HD=>UI : should be handled in receive + Request = 0x00, // UI=>HD : should be handled in transmit + + // Power-Off Data // UI=>HD : should be handled in transmit Accepted = 0x01, Rejected = 0x02, + + // Power-Off Data // HD=>UI : should be handled in receive + Timeout = 0x01, }; Q_ENUM(GuiActionsType_Enum) Index: sources/gui/guicontroller.cpp =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -41,7 +41,6 @@ this , SLOT( onActionReceive (GuiActionType, GuiActionData))); } - /*! * \brief GuiController initializer */ @@ -61,22 +60,35 @@ */ void GuiController::doActionTransmit(GuiActionType vAction, GuiActionData vData) { + if (! handleTransmit(vAction, vData)) { + emit didActionTransmit(vAction, vData); + } +} + +bool GuiController::handleTransmit(GuiActionType, GuiActionData) +{ + // This is an example implementation of how to handle + // which does not require HD approval in GuiController + /* // Process the GuiView Request. // It can be processed in GuiController take action and notify GuiView switch (vAction) { case GuiActionType::PowerOff: - //GUI Controller decides (loop back) - //case Another_Command_Which_Doesn't_Require_HD_Approval: - if (vData == GuiActionData::NoData) // PowerOff noData is a request + // GUI Controller decides (loop back) + if (vData == GuiActionData::NoData){ + // PowerOff noData is a request emit didActionReceive (vAction, GuiActionData::Accepted); - else - emit didActionTransmit(vAction, vData); + return true; + } break; + //case Another_Command_Which_Doesn't_Require_HD_Approval: + //return true; + //break; default: - // If it requires to be Confirmed by HD/DG send the request to ApplicationController - emit didActionTransmit(vAction, vData); break; } + */ + return false; } /*! Index: sources/gui/guicontroller.h =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/gui/guicontroller.h (.../guicontroller.h) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/gui/guicontroller.h (.../guicontroller.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -37,6 +37,8 @@ private: void initConnections(); + bool handleTransmit(GuiActionType vAction, GuiActionData vData); + public slots: void doActionTransmit(GuiActionType vAction, GuiActionData vData); // UI => HD/DG Index: sources/gui/qml/main.qml =================================================================== diff -u -r2085b749d1d0aafe823e840f5aa0bc88a340798a -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/gui/qml/main.qml (.../main.qml) (revision 2085b749d1d0aafe823e840f5aa0bc88a340798a) +++ sources/gui/qml/main.qml (.../main.qml) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -39,8 +39,10 @@ onDidActionReceive: { switch(vAction) { case GuiActions.PowerOff: - if (vData === GuiActions.Accepted) + if (vData === GuiActions.Command) _powerOffDialog.open() + if (vData === GuiActions.Timeout) + _powerOffDialog.close() break; } } Index: sources/maintimer.cpp =================================================================== diff -u -rde2f87e15fa05b1c45581cfedd8f1af0c47c2b48 -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/maintimer.cpp (.../maintimer.cpp) (revision de2f87e15fa05b1c45581cfedd8f1af0c47c2b48) +++ sources/maintimer.cpp (.../maintimer.cpp) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -32,8 +32,8 @@ void MainTimer::init() { - connect(_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); - connect(_timer, SIGNAL(timeout()), this, SIGNAL(timeout())); + connect(_timer, SIGNAL(timeout()), this, SLOT( onTimeout())); + connect(_timer, SIGNAL(timeout()), this, SIGNAL(didTimeout())); _timer->start(_timeout); } Index: sources/maintimer.h =================================================================== diff -u -r9a3ee027dbc33f39ee7df2a9dc5a7897c6b1854d -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 --- sources/maintimer.h (.../maintimer.h) (revision 9a3ee027dbc33f39ee7df2a9dc5a7897c6b1854d) +++ sources/maintimer.h (.../maintimer.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) @@ -42,7 +42,7 @@ void quit(); signals: - void timeout(); + void didTimeout(); private slots: void onTimeout();