/*! * * Copyright (c) 2024-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 AgentInterface.h * \author (original) Stephen Quong * \date (original) 24-May-2026 * */ #pragma once #include #include #include #include #include #include #include "AgentMessage.h" /*! * \brief UDS interface to the Connectivity Agent. * \details Manages the QLocalSocket connection to the Connectivity Agent, * including automatic reconnection on disconnect or error. * * \b Outbound: call send() to build and write an AgentMessage frame * to the socket. Returns false if the socket is not connected. * * \b Inbound: raw bytes received from the socket are fed through * an AgentMessage parser. When a complete frame is assembled the * didMessageReceive() signal is emitted with the decoded fields. * * Call init() with the socket path, reconnect interval, and an optional * QThread to run the interface on a dedicated thread. The class handles * all reconnect attempts internally. */ class AgentInterface : public QObject { Q_OBJECT public: /*! * \brief Construct an AgentInterface. * \param parent Optional QObject parent. */ explicit AgentInterface(QObject *parent = nullptr); /*! * \brief Initialize and connect to the Connectivity Agent UDS socket. * \details Stores the socket path and reconnect interval, then initiates * the first connection attempt. Reconnection is handled automatically * on disconnect or error. * \param socketPath Path to the Unix domain socket. * \param reconnectIntervalMs Interval in milliseconds between reconnect attempts. */ bool init(const QString &socketPath, int reconnectIntervalMs); /*! * \brief Initialize on a dedicated thread and connect to the Connectivity Agent UDS socket. * \details Calls init() then moves this object onto \p thread. * Must be called from the main thread. * \param socketPath Path to the Unix domain socket. * \param reconnectIntervalMs Interval in milliseconds between reconnect attempts. * \param thread The thread to move this object onto. */ bool init(const QString &socketPath, int reconnectIntervalMs, QThread &thread); /*! * \brief Send a message to the Connectivity Agent. * \details Builds a wire-ready AgentMessage frame and writes it to the socket. * \param msgId Message identifier for Agent MQTT routing. * \param sequence Caller-managed sequence number. * \param payload Message payload. Pass an empty QByteArray for zero-length frames. * \return true if the frame was written to the socket, false if not connected. */ bool send(AgentMessage::MsgId msgId, quint16 sequence, const QByteArray &payload = {}); public Q_SLOTS: /*! * \brief Quit the interface and move back to the main thread for destruction. */ void quit(); Q_SIGNALS: /*! * \brief Emitted when a complete inbound AgentMessage frame has been parsed. * \param msgId Message identifier from the frame header. * \param sequence Sequence number from the frame header. * \param payload Decoded payload bytes, empty for zero-length frames. */ void didMessageReceive(AgentMessage::MsgId msgId, quint16 sequence, QByteArray payload); /*! * \brief Emitted when the socket connects successfully. */ void didConnect(); /*! * \brief Emitted when the socket disconnects. */ void didDisconnect(); private Q_SLOTS: void onConnected(); void onDisconnected(); void onError(QLocalSocket::LocalSocketError error); void onReadyRead(); void onReconnectTimer(); private: void connectToServer(); void initThread(QThread &thread); void quitThread(); QLocalSocket _socket; QTimer _reconnectTimer; QString _socketPath; QByteArray _rxBuf; AgentMessage _rxMsg; bool _init = false; };