/*! * * 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 messagehandler.cpp * date 10/26/2019 * author Behrouz NematiPour * */ #include "messagehandler.h" // Qt #include #include // Project #include "maintimer.h" #include "applicationcontroller.h" #include "guiglobals.h" // namespace using namespace Can; // Singleton SINGLETON_INIT(MessageHandler) /*! * \brief MessageHandler Constructor * \param parent */ MessageHandler::MessageHandler(QObject *parent) : QObject(parent) { } /*! * \brief Message Handler initializer */ void MessageHandler::init() { initConnections(); } /*! * \brief Message Handler connections definition * \details Initializes the required signal/slot connection between this class and other objects\n * to be able to communicate. */ void MessageHandler::initConnections() { // From GUI connect(_ApplicationController, SIGNAL(didActionTransmit(GuiActionType, const QVariantList &)), this , SLOT( onActionTransmit(GuiActionType, const QVariantList &))); // From HD/DG connect(_CanInterface , SIGNAL( didRead(QCanBusFrame)), this , SLOT(onFrameReceive (QCanBusFrame))); connect(_MainTimer , SIGNAL( didTimeout()), this , SLOT(onMainTimerTimeout())); } void MessageHandler::checked_in() { transmitFrame(eChlid_UI, GuiActions::Check_In); } void MessageHandler::transmitFrame(Can_Id vFrameId, GuiActionType vAction, const QByteArray &vData) { QCanBusFrame mFrame; mFrame.setFrameId(vFrameId); QList mFrames = _builder.buildMessage(vAction,vData); for (auto frame : mFrames) { mFrame.setPayload(frame); //TODO : If it's necessary we can have a dispatcher // to schedule and send messages in another thread. 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; } bool MessageHandler::interpretData(const Message &vMessage, GuiActionType &vActionId, QVariantList &vData) { quint8 tmp; quint8 l = vMessage.data.length(); quint8 i = 0; vActionId = vMessage.actionId; vData.clear(); switch (vActionId) { // notice we are in receive mode case GuiActionType::PowerOff: i = GuiActions::PowerOff_Show; if (l >= i + 1) { tmp = vMessage.data[GuiActions::PowerOff_Show]; 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; } /*! * \brief Process the requested action * \details Processes the requested action * \param vAction - User requested Action */ void MessageHandler::onActionTransmit(GuiActionType vAction, const QVariantList &vData) { qDebug() << vData; QByteArray mData; for (auto data: vData) { mData += fromVariant(data); } transmitFrame(eChlid_UI, vAction, mData); } /*! * \brief MessageHandler::onRead * \param vFrame */ void MessageHandler::onFrameReceive(const QCanBusFrame &vFrame) { if (ignoreChannel(vFrame)) { return; } Message mMessage; if (! _builder.stripMessage(vFrame.payload(), mMessage)) { return; } // FIXME: Needs MessageInterpreter class for data in each action [Sprint 8] GuiActionType mActionId; QVariantList mData; if (! interpretData(mMessage, mActionId, mData)) { return; } emit didActionReceive (mActionId, mData); } void MessageHandler::onMainTimerTimeout() { //QMetaObject::invokeMethod(this, "checked_in"); checked_in(); }