/*! * * 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" // 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 QByteArray &)), this , SLOT( onActionTransmit(GuiActionType, const QByteArray &))); // 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, 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; 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 QByteArray &vData) { qDebug() << vData; transmitFrame(eChlid_UI, vAction, vData); } /*! * \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; GuiActionData mData; if (! interpretData(mMessage, mActionId, mData)) { return; } emit didActionReceive (mActionId, mData); } void MessageHandler::onMainTimerTimeout() { //QMetaObject::invokeMethod(this, "checked_in"); checked_in(); }