Index: denali.pro =================================================================== diff -u -rf623529d6ec25b555f3ac2248d71fc2b5e7063d6 -r68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b --- denali.pro (.../denali.pro) (revision f623529d6ec25b555f3ac2248d71fc2b5e7063d6) +++ denali.pro (.../denali.pro) (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -22,7 +22,9 @@ sources/applicationcontroller.h \ sources/applicationpost.h \ sources/canbus/caninterface.h \ + sources/canbus/messageglobals.h \ sources/canbus/messagehandler.h \ + sources/canbus/messagepartitioner.h \ sources/configuration/display.h \ sources/configuration/sound.h \ sources/gui/guiactions.h \ @@ -41,6 +43,7 @@ sources/applicationpost.cpp \ sources/canbus/caninterface.cpp \ sources/canbus/messagehandler.cpp \ + sources/canbus/messagepartitioner.cpp \ sources/configuration/display.cpp \ sources/configuration/sound.cpp \ sources/gui/guiactions.cpp \ Index: sources/canbus/messageglobals.h =================================================================== diff -u --- sources/canbus/messageglobals.h (revision 0) +++ sources/canbus/messageglobals.h (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -0,0 +1,68 @@ +/*! + * + * 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, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file MessageGlobals.h + * date 12/6/2019 + * author Behrouz NematiPour + * + */ +#pragma once + +#include "guiactions.h" + +namespace Can { +namespace Message { + +const QHash payloadLen { + {Gui::GuiActionType::PowerOff, 255}, + {Gui::GuiActionType::Check_In, 0} +}; + +// constants +enum Payload_Data : quint8 { + ePayload_None = 0x00, + ePayload_Sync = 0xA5, +}; + +enum Frame_Data : quint8 { + eLenCanFrame = 8, + eLenMaxHeaderData = 3, + eLenMaxData = 255, + + eLenSyncByte = 1, + eLenActionId = 2, + eLenLength = 1, + +}; + +enum Can_Id : quint16 { + // Broadcasts + //// Alarm + eChlid_HD_Alarm = 0x001, ///< HD alarm broadcast + eChlid_DG_Alarm = 0x002, ///< DG alarm broadcast + eChlid_UI_Alarm = 0x004, ///< UI alarm broadcast [Out] + //// Sync + eChlid_HD_Sync = 0x040, ///< HD sync broadcast + eChlid_DG_Sync = 0x080, ///< DG sync broadcast + eChlid_UI_Sync = 0x200, ///< UI sync broadcast [Out] + + // UI not listening + eChlid_HD_DG = 0x008, ///< HD => DG + eChlid_DG_HD = 0x010, ///< DG => HD + + // UI is listening + eChlid_HD = 0x020, ///< HD => UI + eChlid_UI = 0x100, ///< UI => HD [Out] + + // UI lessens occasionally + eChlid_DG_UI = eChlid_DG_Alarm, ///< No direct channel has been defined between DG&UI, May be required for logging + eChlid_UI_DG = eChlid_UI_Sync , ///< No direct channel has been defined between DG&UI, May be required for logging + +}; +} +} Index: sources/canbus/messagehandler.cpp =================================================================== diff -u -r4c53c7c62df7562a6c0915f0c5af7ea0ed884ca3 -r68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b --- sources/canbus/messagehandler.cpp (.../messagehandler.cpp) (revision 4c53c7c62df7562a6c0915f0c5af7ea0ed884ca3) +++ sources/canbus/messagehandler.cpp (.../messagehandler.cpp) (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -66,14 +66,14 @@ void MessageHandler::checked_in() { - transmitFrame(eChlid_UI, GuiActions::Check_In); + transmitFrame(Message::eChlid_UI, GuiActions::Check_In); } -void MessageHandler::transmitFrame(MessageHandler::Can_Id vCan_Id, GuiActionType vAction, const QByteArray &vData) +void MessageHandler::transmitFrame(Message::Can_Id vFrameId, GuiActionType vAction, const QByteArray &vData) { QCanBusFrame mFrame; - mFrame.setFrameId(vCan_Id); - QList mFrames = buildMessage(vAction,vData); + mFrame.setFrameId(vFrameId); + QList mFrames = _partitioner.buildMessage(vAction,vData); for (auto frame : mFrames) { mFrame.setPayload(frame); //TODO : If it's necessary we can have a dispatcher @@ -85,168 +85,23 @@ 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()); + Message::Can_Id mCanId = static_cast(vFrame.frameId()); switch (mCanId) { - case eChlid_HD_DG: - case eChlid_DG_HD: + case Message::eChlid_HD_DG: + case Message::eChlid_DG_HD: return true; break; - case eChlid_HD: + case Message::eChlid_HD: break; default: break; } return false; } -QList MessageHandler::buildMessage(GuiActionType vAction, const QByteArray &vData) -{ - QList mFrames; - QByteArray mPayload ; - addSyncByte (mPayload); // SyncByte - addActionId (mPayload, vAction); // Message ID - addData (mPayload, vAction, vData); // Regarding Payload Length, Adding required Data - addCRC (mPayload); // CRC - quint16 len = mPayload.length(); - if (len > eLenCanFrame) { - quint8 frameCount = len / eLenCanFrame; - for (quint8 i = 0; i <= frameCount; i++) { - mFrames += mPayload.mid(i*eLenCanFrame,eLenCanFrame); - } - } else { - mFrames += mPayload; - } - - addPadding (mFrames.last()); // Padded to 8 byte frame - return mFrames; -} - -void MessageHandler::addSyncByte(QByteArray &vPayload) +bool MessageHandler::interpretData(const MessagePartitioner::Packet &vMessage, GuiActionType &vActionId, GuiActionData &vData) { - vPayload.append(ePayload_Sync); // Sync byte -} - -void MessageHandler::addActionId(QByteArray &vPayload, GuiActionType vAction) -{ - if (vAction != GuiActions::Unknown) { - vPayload += (vAction >> 8) & 0xFF;//high byte - vPayload += vAction & 0xFF;// low byte - } -} - -void MessageHandler::addData(QByteArray &vPayload, GuiActionType vAction, const QByteArray &vData) -{ - quint8 len = payloadLen[vAction]; - // if len has been set to max(255) - // it means it has no limit and can be as long as 255 bytes - if (len == eLenMaxData) { - len = vData.length(); - if (vData.length() > eLenMaxData) { - len = eLenMaxData ; - } - } - vPayload += len; - vPayload += vData.mid(0, len); // Adding required Data -} - -void MessageHandler::addPadding(QByteArray &vPayload) -{ - vPayload = vPayload.leftJustified(eLenCanFrame, '\0'); -} - -quint8 MessageHandler::calcCRC(const QByteArray &vData) -{ - // TODO : calcCRC has not been used yet - Q_UNUSED(vData) - return '\0'; -} - -bool MessageHandler::checkCRC(const QByteArray &vData, quint8 vCRC) -{ - //TODO : enable when the calcCRC implemented - Q_UNUSED(vData) - Q_UNUSED(vCRC ) - 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]; - if (mSyncByte == ePayload_Sync) { - vPayload = vPayload.mid(eLenSyncByte); - return true; - } - return false; -} - -GuiActionType MessageHandler::getActionId(QByteArray &vPayload) -{ - quint16 mActionId; - mActionId = (vPayload[0] << 8) | vPayload[1]; - - //TODO : It needs to be checked that the Action ID is Correct. - //return GuiActionType::Unknown; - - vPayload = vPayload.mid(eLenActionId); - return static_cast(mActionId); -} - -quint8 MessageHandler::getLength(QByteArray &vPayload) -{ - quint8 mlen = vPayload[0]; - vPayload = vPayload.mid(eLenLength); - return mlen; -} - -QByteArray MessageHandler::getData(QByteArray &vPayload, quint8 vLen, bool *ok) -{ - QByteArray mData; - if (vLen <= eLenMaxHeaderData) { - mData = vPayload.mid(0,vLen); - if (ok) { - *ok = checkCRC(mData,vPayload[vLen+1]); // CRC is always next byte after Data - } - } else { - mData = vPayload; - } - 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 @@ -255,18 +110,15 @@ vData = static_cast(tmp); //TODO: (MessageInterpreter) There should be an easy way to check if a correct data has been provided. break; + case GuiActionType::BloodFlow: + 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 @@ -275,7 +127,7 @@ void MessageHandler::onActionTransmit(GuiActionType vAction, const QByteArray &vData) { qDebug() << vData; - transmitFrame(eChlid_UI, vAction, vData); + transmitFrame(Message::eChlid_UI, vAction, vData); } /*! @@ -288,15 +140,15 @@ return; } - Message mMessage; - if (! stripMessage(vFrame,mMessage)) { + MessagePartitioner::Packet mPacket; + if (! _partitioner.stripMessage(vFrame.payload(), mPacket)) { return; } // FIXME: Needs MessageInterpreter class for data in each action [Sprint 8] GuiActionType mActionId; GuiActionData mData; - if (! interpretData(mMessage, mActionId, mData)) { + if (! interpretData(mPacket, mActionId, mData)) { return; } Index: sources/canbus/messagehandler.h =================================================================== diff -u -r4c53c7c62df7562a6c0915f0c5af7ea0ed884ca3 -r68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b --- sources/canbus/messagehandler.h (.../messagehandler.h) (revision 4c53c7c62df7562a6c0915f0c5af7ea0ed884ca3) +++ sources/canbus/messagehandler.h (.../messagehandler.h) (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -25,6 +25,7 @@ // Project #include "main.h" #include "guiactions.h" +#include "messagepartitioner.h" // Define #define _MessageHandler MessageHandler::I() @@ -39,93 +40,15 @@ #define CAN_FRAME_LENGTH 8 #define MAX_PAYLOAD_IN_HEADER_FRAME 3 -/*! - * - * \brief The MessageHandler class - * \details This class is handling the can message by building and striping it. - * - * // -- CAN PAYLOAD STRUCTURE -- - * #0 #1 #2 #3 #4 #5 #6 #7 - * +---+---+---+---+---+---+---+---+--.......--+ - * | 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) - * - */ class MessageHandler : public QObject { Q_OBJECT // friends friend class ::unittests; - const QHash payloadLen { - {GuiActionType::PowerOff, 1}, - {GuiActionType::Check_In, 0} - }; + MessagePartitioner _partitioner; - // constants - enum Payload_Data : quint8 { - ePayload_None = 0x00, - ePayload_Sync = 0xA5, - }; - - enum Frame_Data : quint8 { - eLenCanFrame = 8, - eLenMaxHeaderData = 3, - eLenMaxData = 255, - - eLenSyncByte = 1, - eLenActionId = 2, - eLenLength = 1, - - }; - - enum Can_Id : quint16 { - // Broadcasts - //// Alarm - eChlid_HD_Alarm = 0x001, ///< HD alarm broadcast - eChlid_DG_Alarm = 0x002, ///< DG alarm broadcast - eChlid_UI_Alarm = 0x004, ///< UI alarm broadcast [Out] - //// Sync - eChlid_HD_Sync = 0x040, ///< HD sync broadcast - eChlid_DG_Sync = 0x080, ///< DG sync broadcast - eChlid_UI_Sync = 0x200, ///< UI sync broadcast [Out] - - // UI not listening - eChlid_HD_DG = 0x008, ///< HD => DG - eChlid_DG_HD = 0x010, ///< DG => HD - - // UI is listening - eChlid_HD = 0x020, ///< HD => UI - eChlid_UI = 0x100, ///< UI => HD [Out] - - // UI lessens occasionally - eChlid_DG_UI = eChlid_DG_Alarm, ///< No direct channel has been defined between DG&UI, May be required for logging - eChlid_UI_DG = eChlid_UI_Sync , ///< No direct channel has been defined between DG&UI, May be required for logging - - }; - - struct Message { // Private Data Class - quint8 length; - GuiActionType actionId; - QByteArray data; - - bool isComplete() { return data.length() == length; } - bool isEmpty () { return data.length() == 0 ; } - }; - typedef QList MessageList; - QHash messages; - // Singleton SINGLETON_DECL(MessageHandler) public: @@ -135,31 +58,13 @@ void initConnections(); void checked_in(); - void transmitFrame(MessageHandler::Can_Id vCan_Id, GuiActionType vAction, const QByteArray &vData = 0); + void transmitFrame(Message::Can_Id vCan_Id, GuiActionType vAction, const QByteArray &vData = 0); bool ignoreChannel(const QCanBusFrame &vFrame); - // build message to be sent - QList buildMessage(GuiActionType vAction , const QByteArray &vData); - void addSyncByte (QByteArray &vPayload); - void addActionId (QByteArray &vPayload, GuiActionType vAction); - void addData (QByteArray &vPayload, GuiActionType vAction, const QByteArray &vData); - 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 - 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); - // interpret the data into GUI understandable Actions/Data - bool interpretData(const Message &vMessage, GuiActionType &vActionId, GuiActionData &vData); + bool interpretData(const MessagePartitioner::Packet &vMessage, GuiActionType &vActionId, GuiActionData &vData); private slots: // Should be private for thread safety and is connected internally. void onActionTransmit(GuiActionType vAction, const QByteArray &vData); // UI => HD/DG Index: sources/canbus/messagepartitioner.cpp =================================================================== diff -u --- sources/canbus/messagepartitioner.cpp (revision 0) +++ sources/canbus/messagepartitioner.cpp (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -0,0 +1,175 @@ +/*! + * + * 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, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file messagepartitioner.cpp + * date 12/6/2019 + * author Behrouz NematiPour + * + */ +#include "messagepartitioner.h" + +// Qt +#include + +// Project +// namespace +using namespace Can; + +MessagePartitioner::MessagePartitioner(QObject *parent) : QObject(parent) { } + +QList MessagePartitioner::buildMessage(GuiActionType vAction, const QByteArray &vData) +{ + QList mFrames; + QByteArray mPayload ; + addSyncByte (mPayload); // SyncByte + addActionId (mPayload, vAction); // Message ID + addData (mPayload, vAction, vData); // Regarding Payload Length, Adding required Data + addCRC (mPayload); // CRC + + quint16 len = mPayload.length(); + if (len > Message::eLenCanFrame) { + quint8 frameCount = len / Message::eLenCanFrame; + for (quint8 i = 0; i <= frameCount; i++) { + mFrames += mPayload.mid(i * Message::eLenCanFrame, Message::eLenCanFrame); + } + } else { + mFrames += mPayload; + } + + addPadding (mFrames.last()); // Padded to 8 byte frame + return mFrames; +} + +void MessagePartitioner::addSyncByte(QByteArray &vPayload) +{ + vPayload.append(Message::ePayload_Sync); // Sync byte +} + +void MessagePartitioner::addActionId(QByteArray &vPayload, GuiActionType vAction) +{ + if (vAction != GuiActions::Unknown) { + vPayload += (vAction >> 8) & 0xFF;//high byte + vPayload += vAction & 0xFF;// low byte + } +} + +void MessagePartitioner::addData(QByteArray &vPayload, GuiActionType vAction, const QByteArray &vData) +{ + quint8 len = Message::payloadLen[vAction]; + // if len has been set to max(255) + // it means it has no limit and can be as long as 255 bytes + if (len == Message::eLenMaxData) { + len = vData.length(); + if (vData.length() > Message::eLenMaxData) { + len = Message::eLenMaxData ; + } + } + vPayload += len; + vPayload += vData.mid(0, len); // Adding required Data +} + +void MessagePartitioner::addCRC(QByteArray &vPayload) +{ + vPayload += calcCRC(vPayload); +} + +void MessagePartitioner::addPadding(QByteArray &vPayload) +{ + vPayload = vPayload.leftJustified(Message::eLenCanFrame, '\0'); +} + +quint8 MessagePartitioner::calcCRC(const QByteArray &vData) +{ + // TODO : calcCRC has not been used yet + Q_UNUSED(vData) + return '\0'; +} + +bool MessagePartitioner::checkCRC(const QByteArray &vData, quint8 vCRC) +{ + //TODO : enable when the calcCRC implemented + Q_UNUSED(vData) + Q_UNUSED(vCRC ) + return true;//calcCRC(vData) == vCRC; +} + +bool MessagePartitioner::stripMessage(const QByteArray &vPayload, Packet &vMessage) +{ + QByteArray mPayload = vPayload; + //Can_Id mCanId = static_cast(vFrame.frameId()); + //if (messages[mCanId].isEmpty()) { + // messages[mCanId].append(Message()); + //} else { + // 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 MessagePartitioner::hasSyncByte(QByteArray &vPayload) +{ + quint8 mSyncByte = vPayload[0]; + if (mSyncByte == Message::ePayload_Sync) { + vPayload = vPayload.mid(Message::eLenSyncByte); + return true; + } + return false; +} + +GuiActionType MessagePartitioner::getActionId(QByteArray &vPayload) +{ + quint16 mActionId; + mActionId = (vPayload[0] << 8) | vPayload[1]; + + //TODO : It needs to be checked that the Action ID is Correct. + //return GuiActionType::Unknown; + + vPayload = vPayload.mid(Message::eLenActionId); + return static_cast(mActionId); +} + +quint8 MessagePartitioner::getLength(QByteArray &vPayload) +{ + quint8 mlen = vPayload[0]; + vPayload = vPayload.mid(Message::eLenLength); + return mlen; +} + +QByteArray MessagePartitioner::getData(QByteArray &vPayload, quint8 vLen, bool *ok) +{ + QByteArray mData; + if (vLen <= Message::eLenMaxHeaderData) { + mData = vPayload.mid(0,vLen); + if (ok) { + *ok = checkCRC(mData,vPayload[vLen+1]); // CRC is always next byte after Data + } + } else { + mData = vPayload; + } + return mData; +} Index: sources/canbus/messagepartitioner.h =================================================================== diff -u --- sources/canbus/messagepartitioner.h (revision 0) +++ sources/canbus/messagepartitioner.h (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -0,0 +1,92 @@ +/*! + * + * 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, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file messagepartitioner.h + * date 12/6/2019 + * author Behrouz NematiPour + * + */ +#pragma once + +// Qt +#include +#include + +// Project +#include "guiactions.h" +#include "messageglobals.h" + +using namespace Gui; +namespace Can { + +/*! + * + * \brief The MessagePartitioner class + * \details This class is handling the can message by building and striping it. + * + * // -- CAN PAYLOAD STRUCTURE -- + * #0 #1 #2 #3 #4 #5 #6 #7 + * +---+---+---+---+---+---+---+---+--.......--+ + * | 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) + * + */ +class MessagePartitioner : public QObject +{ + Q_OBJECT + +public: + + + struct Packet { // Private Data Class + quint8 length; + GuiActionType actionId; + QByteArray data; + + bool isComplete() { return data.length() == length; } + bool isEmpty () { return data.length() == 0 ; } + }; + typedef QList PacketList; + QHash packets; + + explicit MessagePartitioner(QObject *parent = nullptr); + + // build message to be sent + QList buildMessage(GuiActionType vAction , const QByteArray &vData); + void addSyncByte (QByteArray &vPayload); + void addActionId (QByteArray &vPayload, GuiActionType vAction); + void addData (QByteArray &vPayload, GuiActionType vAction, const QByteArray &vData); + 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 + bool stripMessage (const QByteArray &vPayload, Packet &vMessage); + bool hasSyncByte (QByteArray &vPayload); + GuiActionType getActionId (QByteArray &vPayload); + quint8 getLength (QByteArray &vPayload); + QByteArray getData (QByteArray &vPayload, quint8 vLen, bool *ok = nullptr); + +signals: + +public slots: +}; +} Index: sources/gui/guiactions.h =================================================================== diff -u -rf36dd9c29f633b54bf7f0232093ecaefa5452ca8 -r68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b --- sources/gui/guiactions.h (.../guiactions.h) (revision f36dd9c29f633b54bf7f0232093ecaefa5452ca8) +++ sources/gui/guiactions.h (.../guiactions.h) (revision 68fe14b0d2f0e79d03c95cc0dfff5b47948b6d5b) @@ -26,6 +26,7 @@ Unknown = 0x0000, PowerOff = 0x0100, Check_In = 0x0700, + BloodFlow = 0x0500, }; enum GuiActionsData_Enum /*: quint8 QML doesn't support*/ { NoData = 0x00,