/*! * * Copyright (c) 2020-2026 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 MessageDispatcher.h * \author (last) Stephen Quong * \date (last) 12-Jun-2026 * \author (original) Behrouz NematiPour * \date (original) 26-Aug-2020 * */ // SQ Ported from luis application/sources/canbus/MessageDispatcher.h. // SQ Only the inbound per-CAN-id frame reassembly path is kept active; the // SQ GUI/action/acknowledge machinery is commented out (not deleted) so the // SQ original luis structure stays recognizable and re-enabling stays trivial. #pragma once // Qt #include #include // Project // #include "main.h" // Doxygen : do not remove // SQ commented out: luis singleton/logging infra #include "MessageBuilder.h" // #include "MessageInterpreter.h" // SQ commented out: GUI message interpretation // define // #define _MessageDispatcher Can::MessageDispatcher::I() // SQ commented out: singleton accessor not used here // forward declarations // class tst_canbus; // SQ commented out: luis test friends // class tst_acknow; // class tst_messaging; // since this class is the interface between GUI and Can // it needs to use Gui namespace otherwise it makes code hard to read. // using namespace Gui; // SQ commented out: no Gui namespace in this project namespace Can { /*! * \brief The MessageDispatcher class \n * \details Message Dispatcher is the class which is the mediator between CanBus Frames \n * and Application Messages. \n * The massages and frames need to be interpreted form/to hex \n * and also need to be split into frames or constructor from frames to be a message. \n * ---------------------------------------------------------------------------------------- \n * \n * Interpreter : message [ toHex , fromHex] \n * \n * Builder : message [ toFrame , fromFrame ] \n * \n * Dispatcher : signal->Handler( .. frame .. ) \n * \n * Handler : signal->Dispatcher( .. frame .. ) \n * \n * ---------------------------------------------------------------------------------------- \n * \n * *** UI <-> AppController <-> Dispatcher <-> Handler <-> HD *** \n * \n * ---------------------------------------------------------------------------------------- \n * \n * UI -> message -> \n * AppController { \n * signal->Dispatcher ( .. message .. ) \n * } \n * \n * Dispatcher { \n * .. \n * messageList[ch][frameList] += Builder.toFrame ( Interpreter.toHex ( message ) ) \n * .. \n * signal->Handler( .. frame .. ) \n * } \n * \n * ---------------------------------------------------------------------------------------- \n * \n * HD -> frame -> \n * Handler { \n * signal->Dispatcher ( .. frame .. ) \n * } \n * \n * Dispatcher { \n * messageList[ch][frameList] += Interpreter.fromHex( frame ) \n * isComplete => Builder.fromFrame( frameList ) : signal->AppController \n * } \n * \n * ---------------------------------------------------------------------------------------- \n */ class MessageDispatcher : public QObject { Q_OBJECT // Singleton // SINGLETON(MessageDispatcher) // SQ commented out: not a singleton here, owned by LeahiRtController // friends // friend class ::tst_canbus; // SQ commented out: luis test friends // friend class ::tst_acknow; // friend class ::tst_messaging; QHash _messageList; // SQ Can_Id -> CanId (this project's enum name) Sequence _txSequence = 0; Sequence _rxSequence = 0; MessageBuilder _builder; // MessageInterpreter _interpreter; // SQ commented out: GUI message interpretation // QThread *_thread = nullptr; // SQ commented out: thread owned by LeahiRtController // bool _init = false; // SQ commented out: init()/thread mgmt removed // SQ commented out: list of transmit(request) messages that require AckBack -- GUI/action specific. #if 0 // List of the transmit(request) only, messages which require acknowledge back(AckBack). QList _needsAcknow { GuiActionType::ID_TDCheckIn , // ... (full luis list of ~60 GuiActionType ids) ... GuiActionType::ID_ResetHDInServiceModeReq , }; #endif // public slots: // SQ commented out: init()/quit() thread lifecycle (controller-managed) // bool init(); // bool init(QThread &vThread); // void quit(); public: explicit MessageDispatcher(QObject *parent = nullptr); // SQ replaced singleton with plain ctor // void enableConsoleOut(bool vEnable) { _builder.enableConsoleOut(vEnable); } // SQ commented out: console-out passthrough private: // void initConnections(); // SQ commented out: wiring now done in LeahiRtController // void initThread(QThread &vThread); // SQ commented out: thread mgmt removed // void quitThread(); // SQ commented out: outbound action/frame transmit + acknowledge path (GUI/action specific) #if 0 void actionTransmit (GuiActionType vActionId, const QVariantList &vData, Sequence vSequence = 0, Can_Id vCanId = Can::Can_Id::eChlid_UI_TD); void framesTransmit (Can_Id vCan_Id, const FrameList &vFrameList); bool needsAcknow (GuiActionType vActionId); bool needsAcknow (Can_Id vCan_Id); #endif bool buildMessage (CanId vCanId, const QByteArray &vPayload); // SQ Can_Id -> CanId // bool interpretMessage(const Message &vMessage); // SQ commented out: GUI interpretation // SQ commented out: tx/rx sequence counters -- rxCount() kept, txCount() unused here // Sequence txCount(); // SQ commented out: no outbound path here Sequence rxCount(); // SQ commented out: acknowledge check/transmit (GUI/action specific, needs Message::actionId) #if 0 bool checkAcknowReceived(const Message &vMessage, const QString &vSrcText); bool checkAcknowTransmit(const Message &vMessage, const QString &vSrcText); #endif signals: // SQ commented out: GUI action-level receive signal (needs GuiActionType) // void didActionReceive (GuiActionType vAction , const QVariantList &vData); /*! * \brief didActionReceive * \details Emitted when a complete message has been reassembled from CAN frame(s). * \param vMessage - the completed message // SQ documented param (luis left it blank) */ void didActionReceive (const Message &vMessage); // SQ kept: repurposed as the message-complete signal // SQ commented out: acknowledge + outbound-transmit signals (GUI/action specific) #if 0 void didAcknowReceive (Sequence vSequence); void didAcknowTransmit(Can_Id vCan_Id, Sequence vSequence, const FrameList &vFrameList); void didFrameTransmit (Can_Id vCan_Id, const QByteArray &vPayload); void didFailedTransmit(Sequence vSequence); #endif public slots: // SQ was private slots in luis; public so controller can connect/forward // A Frame has been received from CanInterface void onFrameReceive (CanId vCanId, const QByteArray &vPayload); // SQ Can_Id -> CanId // SQ commented out: outbound transmit + action/settings slots (GUI/action specific) #if 0 void onFramesTransmit (Can_Id vCan_Id, Sequence vSequence, const FrameList &vFrameList); void onFailedTransmit ( Sequence vSequence); // An Action has been requested to be transmitted. void onActionTransmit (GuiActionType vActionId, const QVariantList &vData); void onSettingsDone (); // ---- Signal/Slots ADJUST_TRANSMT_MODEL_BRIDGE_DEFINITIONS_NOEMIT ACTION_RECEIVE_MODEL_BRIDGE_DEFINITIONS ACTION_RECEIVE_PRIVATE_SLOT(UIPostFinalResultHDRequestData) #endif }; }