/**
 * @file datalink.h
 * @date 2025-09-06 08:00:37
 * This file defines the data link object between CAN and the V-API devices.
 * This file was generated by the DBC utility from:
 *   "", "datalink_4doors_example.dbc"
 *   DBC file version: 1.0.0.1
 */
#ifndef __DBC_GENERATED__DATALINK_H__20250906_080037_856__
#define __DBC_GENERATED__DATALINK_H__20250906_080037_856__

#include <support/component_impl.h>
#include <interfaces/can.h>
#include <support/interface_ptr.h>
#include <support/signal_support.h>

/**
 * @brief Data link class.
 */
class CDataLink : public sdv::CSdvObject, public sdv::IObjectControl, public sdv::can::IReceive
{
public:
    /**
     * @brief Constructor
     */
    CDataLink();

    /**
     * @brief Destructor
     */
    ~CDataLink();

    // Interface map
    BEGIN_SDV_INTERFACE_MAP()
        SDV_INTERFACE_ENTRY(sdv::IObjectControl)
        SDV_INTERFACE_ENTRY(sdv::can::IReceive)
    END_SDV_INTERFACE_MAP()

    // Declarations
    DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
    DECLARE_OBJECT_CLASS_NAME("CAN_data_link")
    DECLARE_DEFAULT_OBJECT_NAME("DataLink")
    DECLARE_OBJECT_SINGLETON()

    /**
     * @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
     * @param[in] ssObjectConfig Optional configuration string.
     */
    void Initialize(const sdv::u8string& ssObjectConfig) override;

    /**
     * @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
     * @return Return the current status of the object.
     */
    sdv::EObjectStatus GetStatus() const override;

    /**
     * @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
     * @param[in] eMode The operation mode, the component should run in.
     */
    void SetOperationMode(sdv::EOperationMode eMode) override;

    /**
     * @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
     */
    void Shutdown() override;

    /**
     * @brief Process a receive a CAN message. Overload of sdv::can::IReceive::Receive.
     * @param[in] sMsg Message that was received.
     * @param[in] uiIfcIndex Interface index of the received message.
     */
    virtual void Receive(/*in*/ const sdv::can::SMessage& sMsg, /*in*/ uint32_t uiIfcIndex) override;

    /**
     * @brief Process an error frame. Overload of sdv::can::IReceive::Error.
     * @param[in] sError Error frame that was received.
     * @param[in] uiIfcIndex Interface index of the received message.
     */
    virtual void Error(/*in*/ const sdv::can::SErrorFrame& sError, /*in*/ uint32_t uiIfcIndex) override;

private:
    /**
     * @brief Union containing all the compound values needed to convert between the DBC defined types.
     */
    union UValueHelper
    {
        uint64_t    uiUint64Value;      ///< The 64-bit unsingned value.
        int64_t     iInt64Value;        ///< The 64-bit signed value.

        /**
         * @brief The structure mapping the 32-bit value types into the 64-bit.
         */
        struct S32
        {
    #if (!defined(_MSC_VER) || defined(__clang__)) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
            uint32_t uiPadding;     ///< Padding for big endian byte ordering (MSB)
    #endif
            /**
             * @brief The 32-bit union containing the possible 32-bit values.
             */
            union U32Value
            {
                int32_t     iValue;     ///< 32-bit signed integer.
                uint32_t    uiValue;    ///< 32-bit unsigned integer.
                float       fValue;     ///< 32-bit floating point number.
            } u32;  ///< 32-bit union instance.

    #if (defined(_MSC_VER) && !defined(__clang__)) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
            uint32_t uiPadding;     ///< Padding for little endian byte ordering (MSB)
    #endif
        } s32;

        double      dValue;     ///< 64-bit double precision floating point number.
    };

    /**
     * @brief RX CAN message definition of: CAN_Input_L1 [id=1]
     */
    struct SRxMsg_CAN_Input_L1
    {
        /**
         * @brief Constructor
         * @param[in] rdispatch Reference to the dispatch service.
         */
        SRxMsg_CAN_Input_L1(sdv::core::CDispatchService& rdispatch);

        /**
         * @brief Initialize the message by registering all signals.
         */
        bool Init();

        /**
         * @brief Terminate the message by unregistering all signals.
         */
        void Term();

        /**
         * @brief Process received data.
         * @param[in] rseqData Reference to the message data to process.
         */
        void Process(const sdv::sequence<uint8_t>& rseqData);

        sdv::core::CDispatchService&    m_rdispatch;        ///< Reference to the dispatch service.
        
        /// Signal Door01LeftIsOpen with unit 
        sdv::core::CSignal      m_sigDoor01LeftIsOpen;
    } m_sRxMsgCAN_Input_L1;

    /**
     * @brief RX CAN message definition of: CAN_Input_R1 [id=2]
     */
    struct SRxMsg_CAN_Input_R1
    {
        /**
         * @brief Constructor
         * @param[in] rdispatch Reference to the dispatch service.
         */
        SRxMsg_CAN_Input_R1(sdv::core::CDispatchService& rdispatch);

        /**
         * @brief Initialize the message by registering all signals.
         */
        bool Init();

        /**
         * @brief Terminate the message by unregistering all signals.
         */
        void Term();

        /**
         * @brief Process received data.
         * @param[in] rseqData Reference to the message data to process.
         */
        void Process(const sdv::sequence<uint8_t>& rseqData);

        sdv::core::CDispatchService&    m_rdispatch;        ///< Reference to the dispatch service.
        
        /// Signal Door01RightIsOpen with unit 
        sdv::core::CSignal      m_sigDoor01RightIsOpen;
    } m_sRxMsgCAN_Input_R1;

    /**
     * @brief RX CAN message definition of: CAN_Input_L2 [id=3]
     */
    struct SRxMsg_CAN_Input_L2
    {
        /**
         * @brief Constructor
         * @param[in] rdispatch Reference to the dispatch service.
         */
        SRxMsg_CAN_Input_L2(sdv::core::CDispatchService& rdispatch);

        /**
         * @brief Initialize the message by registering all signals.
         */
        bool Init();

        /**
         * @brief Terminate the message by unregistering all signals.
         */
        void Term();

        /**
         * @brief Process received data.
         * @param[in] rseqData Reference to the message data to process.
         */
        void Process(const sdv::sequence<uint8_t>& rseqData);

        sdv::core::CDispatchService&    m_rdispatch;        ///< Reference to the dispatch service.
        
        /// Signal Door02LeftIsOpen with unit 
        sdv::core::CSignal      m_sigDoor02LeftIsOpen;
    } m_sRxMsgCAN_Input_L2;

    /**
     * @brief RX CAN message definition of: CAN_Input_R2 [id=4]
     */
    struct SRxMsg_CAN_Input_R2
    {
        /**
         * @brief Constructor
         * @param[in] rdispatch Reference to the dispatch service.
         */
        SRxMsg_CAN_Input_R2(sdv::core::CDispatchService& rdispatch);

        /**
         * @brief Initialize the message by registering all signals.
         */
        bool Init();

        /**
         * @brief Terminate the message by unregistering all signals.
         */
        void Term();

        /**
         * @brief Process received data.
         * @param[in] rseqData Reference to the message data to process.
         */
        void Process(const sdv::sequence<uint8_t>& rseqData);

        sdv::core::CDispatchService&    m_rdispatch;        ///< Reference to the dispatch service.
        
        /// Signal Door02RightIsOpen with unit 
        sdv::core::CSignal      m_sigDoor02RightIsOpen;
    } m_sRxMsgCAN_Input_R2;

    /**
     * @brief TX CAN message definition of: CAN_Output [id=5]
     */
    struct STxMsg_CAN_Output
    {
        /**
         * @brief Constructor
         * @param[in] rdispatch Reference to the dispatch service.
         */
        STxMsg_CAN_Output(sdv::core::CDispatchService& rdispatch);

        /**
         * @brief Initialize the message by registering all signals.
         * @param[in] pSend The send-interface of the CAN.
         */
        bool Init(sdv::can::ISend* pSend);

        /**
         * @brief Terminate the message by unregistering all signals.
         */
        void Term();

        /**
         * @brief Transmit data.
         * @param[in] pCanSend Pointer to the CAN send interface.
         */
        void Transmit();

        sdv::core::CDispatchService&    m_rdispatch;            ///< Reference to the dispatch service.
        sdv::core::CTrigger             m_trigger;              ///< Message trigger being called by the dispatch service.
        sdv::can::ISend*        m_pSend = nullptr;      ///< Message sending interface.
        
        /// Signal LockDoor02Right with unit 
        sdv::core::CSignal      m_sigLockDoor02Right;
        /// Signal LockDoor02Left with unit 
        sdv::core::CSignal      m_sigLockDoor02Left;
        /// Signal LockDoor01Right with unit 
        sdv::core::CSignal      m_sigLockDoor01Right;
        /// Signal LockDoor01Left with unit 
        sdv::core::CSignal      m_sigLockDoor01Left;
    } m_sTxMsgCAN_Output;

    sdv::EObjectStatus              m_eStatus = sdv::EObjectStatus::initialization_pending;  ///< Keep track of the object status.
    size_t                          m_nIfcIndex = 0;              ///< CAN Interface index.
    sdv::can::IRegisterReceiver*    m_pRegister = nullptr;                  ///< CAN receiver registration interface.
    sdv::can::ISend*                m_pSend = nullptr;                      ///< CAN sender interface.
    sdv::core::CDispatchService     m_dispatch;                             ///< Dispatch service
};

DEFINE_SDV_OBJECT(CDataLink)

#endif // !defined __DBC_GENERATED__DATALINK_H__20250906_080037_856__
