Index: sources/canbus/messagebuilder.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -r1ec7b44e6d1d66460d2da943ff65f3c0c0755d8f --- sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 1ec7b44e6d1d66460d2da943ff65f3c0c0755d8f) @@ -1,6 +1,6 @@ /*! * - * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, * IN PART OR IN WHOLE, @@ -23,6 +23,12 @@ // namespace using namespace Can; +/*! + * \brief MessageBuilder::MessageBuilder + * \details Constructor + * \param parent - QObject parent owner object. + * Qt handles the children destruction by their parent objects life-cycle. + */ MessageBuilder::MessageBuilder(QObject *parent) : QObject(parent) { } /*! @@ -31,18 +37,17 @@ * and vData of type QByteArray which has been requested to be sent by UI. * The message will be chopped into 8 bytes frames to be able to be send * by fixed length CANBUS protocol. - * \param vAction - The ActionID of the requested message. - * \param vData - The payload of the message. - * \param ok - Will be set if any error happens. - * This parameter has been defined as mandatory check - * so it has been passed and checked. - * \return list of frames of type FrameList + * \param vAction - The ActionID of the requested message. + * \param vData - The payload of the message. + * \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 - 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 @@ -76,6 +81,21 @@ } /*! + * \brief MessageBuilder::addSequence + * \details Adds the sequence number to the Denali message. + * \param vPayload - The message payload to be used for adding the sequence number to. + * \param vSequence - The sequence number + */ +void MessageBuilder::addSequence(QByteArray &vPayload, Sequence vSequence) +{ + Sequence_Bytes mSequence; + mSequence.value = vSequence; + for (quint8 index = 0; index < sizeof(mSequence); index++) { + vPayload += mSequence.bytes[index]; + } +} + +/*! * \brief MessageBuilder::addActionId * \details Adds the sync/start byte at the end of the Payload vPayload of type QByteArray * \param vPayload - payload which is going to be constructed by appending byte @@ -170,18 +190,20 @@ * \brief MessageBuilder::checkCRC * \details This method checks the crc8 of the vData of type QByteArray * by using the last byte as the crc8 of the rest of the data - * \param vData - The data of type QByteArray to be used for crc8 calculation. + * \param vData - The data of type QByteArray to be used for crc8 calculation. + * \param vExpected - The expected CRC value + * \param vActual - The actual value which has been read * \return returns false if the crc8 is not correct or the data is empty. */ -bool MessageBuilder::checkCRC(const QByteArray &vData, quint8 &vExpected, quint8 &vBeenRead) +bool MessageBuilder::checkCRC(const QByteArray &vData, quint8 &vExpected, quint8 &vActual) // TODO : This section better to be in the MessageModel { #ifndef DISABLE_CRC int len = vData.length(); if ( ! len ) return false; - vBeenRead = vData.back(); + vActual = vData.back(); vExpected = calcCRC(vData.mid(0, len - 1)); - bool ok = vExpected == vBeenRead; + bool ok = vExpected == vActual; // it's very good but I'm not sure if it's correct. //bool ok = calcCRC(vData) == 0; return ok; @@ -191,6 +213,27 @@ } /*! + * \brief MessageBuilder::checkCRC + * \details Overloaded CheckCRC which checks the CRC and Log the error if there is. + * \param vMessage - The message to check for the CRC + * \return false if has error + */ +bool MessageBuilder::checkCRC(const Message &vMessage) +{ + consoleOut("", false, Can_Id::eChlid_NONE); + QByteArray crcData = vMessage.head + vMessage.data; + quint8 mExpected = 0; + quint8 mBeenRead = 0; + if ( ! checkCRC(crcData, mExpected, mBeenRead ) ) { // CRC is always next byte after Data + LOG_ERROR(tr("CRC error, expected %1 but got %2") + .arg(Format::toHexString(mExpected, true, eLenCRCDigits)) + .arg(Format::toHexString(mBeenRead, true, eLenCRCDigits))); + return false; + } + return true; +} + +/*! * \brief MessageBuilder::buildMessage * \details Builds Message out of vPayload of type QByteArray * by adding Sync byte, ActionID(MessageID), data length, data, CANBUS channel id for header @@ -208,6 +251,7 @@ consoleOut(vPayload, true, vCan_Id); vMessage.can_id = vCan_Id; vMessage.head = getHeader (mPayload); // keep header before taking it out of the payload. doesn't affect payload + vMessage.sequence = getSequence (mPayload); vMessage.actionId = getActionId (mPayload); vMessage.length = getLength (mPayload); vMessage.data = getData (mPayload, vMessage.length); @@ -226,16 +270,8 @@ // and when Message model identifies the message is complete // will SIGNAL builder to check for crc. if (vMessage.isComplete()) { - consoleOut("", false, Can_Id::eChlid_NONE); - QByteArray crcData = vMessage.head + vMessage.data; - quint8 mExpected = 0; - quint8 mBeenRead = 0; - if ( ! checkCRC(crcData, mExpected, mBeenRead ) ) { // CRC is always next byte after Data - LOG_ERROR(tr("CRC error, expected %1 but got %2") - .arg(Format::toHexString(mExpected, true, eLenCRCDigits)) - .arg(Format::toHexString(mBeenRead, true, eLenCRCDigits))); - return false; - } + bool ok = checkCRC(vMessage); + if (!ok) return false; } return true; @@ -261,6 +297,24 @@ } /*! + * \brief MessageBuilder::getSequence + * \details Extract the 2 bytes of the sequence + * out of the vPayload of type QByteArray + * \param vPayload - The payload of the CANBUS message + * \return Returns ActionId of type GuiActionType + * \note Removes the 2 bytes of ActionID from vPayload + * It starts from the first byte so those 2 bytes should be the first 2 bytes. + */ +Sequence MessageBuilder::getSequence(QByteArray &vPayload) +{ + Sequence_Bytes mSequence; + int index = 0; + Types::getValue<>(vPayload, index, mSequence); + vPayload = vPayload.mid(eLenSequence); + return mSequence.value; +} + +/*! * \brief MessageBuilder::getHeader * \details Collect the 3 bytes (Frame_Data::eLenHeaderInfo) * as header portion of the payload @@ -277,6 +331,10 @@ QByteArray MessageBuilder::getHeader(const QByteArray &vPayload) { QByteArray headInfo; + if (vPayload.length() < eLenHeaderInfo) { + LOG_ERROR("Incorrect Message Header"); + return headInfo; + } for (int i = 0; i < eLenHeaderInfo; i++) { headInfo += vPayload[i]; } @@ -296,10 +354,6 @@ { quint16 mActionId; mActionId = (vPayload[0] << 8) | vPayload[1]; - - //TODO : It needs to be checked that the ActionID is Correct. - //return GuiActionType::Unknown; - vPayload = vPayload.mid(eLenActionId); return static_cast(mActionId); } @@ -403,6 +457,8 @@ void MessageBuilder::consoleOut(const QByteArray &vPayload, bool vIsHeader, Can_Id vCan_Id, bool vUseColor) { if ( ! _enableConsoleOut) return; - LOG_EVENT(QObject::tr("console out MessageDispatcher Enabled")); + + LOG_EVENT_ONCE(QObject::tr("console out MessageDispatcher Enabled")); + printPayload(vPayload, vIsHeader, vCan_Id, vUseColor); }