Index: docs/SDD/Class_Overview.puml =================================================================== diff -u -rf9eefe0a6092719f35d5a73fa43632c8c779e0df -r8b98ff34313ee5d3f5d49672d622162acfc755c9 --- docs/SDD/Class_Overview.puml (.../Class_Overview.puml) (revision f9eefe0a6092719f35d5a73fa43632c8c779e0df) +++ docs/SDD/Class_Overview.puml (.../Class_Overview.puml) (revision 8b98ff34313ee5d3f5d49672d622162acfc755c9) @@ -6,28 +6,47 @@ skinparam class { BackgroundColor<> LightYellow BackgroundColor<> LightCyan - BackgroundColor<> #EEEEEE - BorderStyle<> dashed + BackgroundColor<> #E8F0E8 } package "CloudConnect (process)" { class CloudConnectController { - -_settings: QSettings -_canInterface: Can::CanInterface - -_canThread: QThread -_dispatcher: Can::MessageDispatcher - -_msgHandling: QHash - -_msgCache: QMap> - -_appServer: CloudConnectServer - -_txSequence: quint16 + -_canCache: QMap> + -_canRouting: QHash + -_appServerSocketPath: QString + -_appServer: QSharedPointer + -_mqttClient: MqttClient + -_topicPrefix: QString + -_deviceId: QString __ - +CloudConnectController(configPath, msgHandlingPath) + +CloudConnectController(parent) + +loadConfig(configPath): bool + +initThread(QThread&) + +startCan(): bool +listenForApp(): bool - -loadMsgHandling(msgHandlingPath) + +connectToCloud(): bool + -loadCanRouting(canRoutingPath): bool + -mqttTopic(Topic): QString __ - -onFrameReceive(QCanBusFrame) - -onMessageReceive(Can::Message) + -onCanFrameReceive(QCanBusFrame) <> + -onCanMessageReceive(Can::Message) <> + -onCloudStateChanged(ClientState) <> + -onCloudMessageStatusChanged(id, status, props) <> + -onCloudMessageReceived(QByteArray, QMqttTopicName) <> } + + enum "CloudConnectController::CanAction" as CanAction { + Drop + SendAlways + SendDelta + } + + class "CloudConnectController::CanRouting" as CanRouting { + +action: CanAction = Drop + +topic: CloudConnectFrame::Topic = NormalPriority + } } package "Comms (lib)" { @@ -37,7 +56,7 @@ -_txFrameCount: FrameCount -_erFrameCount: FrameCount __ - +init(thread: QThread&): bool + +init(): bool +quitDevice() +enableConsoleOut(bool) +status(): QString @@ -53,18 +72,47 @@ -onFrameWritten(qint64) <> } - class CloudConnectClient <> { + class MqttClient { + -_client: QMqttClient* + -_config: Config + -_sslConfig: QSslConfiguration + __ + +init(Config): bool + +open(): bool + +close() + +publish(topic, payload, msgId&, qos = 1): bool + +subscribe(topicFilter, qos = 1): bool + __ + +didStateChanged(ClientState) <> + +didMessageStatusChanged(id, status, props) <> + +didMessageReceived(QByteArray, QMqttTopicName) <> + __ + -onStateChanged() <> + } + + class "MqttClient::Config" as MqttConfig { + +endpoint: QString + +port: quint16 = 8883 + +certPath: QString + +keyPath: QString + +caPath: QString + +clientId: QString + +keepAliveSecs: quint16 = 30 + +cleanSession: bool = true + } + + class CloudConnectClient { -_socket: QLocalSocket -_reconnectTimer: QTimer -_socketPath: QString -_rxBuf: QByteArray -_rxMsg: CloudConnectFrame __ +init(socketPath, reconnectIntervalMs, thread): bool - +send(type, sequence, payload): bool + +send(topic, sequence, payload): bool +quit() <> __ - +didMessageReceive(Type, seq, payload) <> + +didMessageReceive(Topic, seq, payload) <> +didConnect() <> +didDisconnect() <> __ @@ -75,24 +123,17 @@ -onReconnectTimer() <> } - note bottom of CloudConnectClient - No call sites. The agent socket it served - was removed in Phase 1; the class and its - build entries in Comms remain. Delete or - repurpose — see AgentMigrationPlan.md §7. - end note - class CloudConnectServer { -_server: QLocalServer -_client: QLocalSocket* -_rxBuf: QByteArray -_rxMsg: CloudConnectFrame __ +listen(socketPath): bool - +send(type, sequence, payload): bool + +send(topic, sequence, payload): bool +isConnected(): bool __ - +didMessageReceive(Type, seq, payload) <> + +didMessageReceive(Topic, seq, payload) <> +didConnect() <> +didDisconnect() <> __ @@ -122,20 +163,20 @@ class CloudConnectFrame { -_headerBuf: QByteArray - -_rxType: Type + -_rxTopic: Topic -_rxSequence: quint16 -_rxPayloadLen: quint32 -_rxPayload: QByteArray __ - +{static} build(type, sequence, payload): QByteArray + +{static} build(topic, sequence, payload): QByteArray +read(bytes: QByteArray&): ReadState - +type(): Type + +topic(): Topic +sequence(): quint16 +payload(): QByteArray +reset() } - enum "CloudConnectFrame::Type" as Type { + enum "CloudConnectFrame::Topic" as Topic { HighPriority = 0x0001 NormalPriority = 0x0002 DeviceLogFile = 0x0003 @@ -151,33 +192,72 @@ } } -package "CANDumpPlayer (process)" { +package "MsgUtils (lib)" { + class "leahi (generated)" as MsgDefs <> { + +{static} msgIdString(MsgId): QString + +{static} msgIdToProtoName(msgId): std::string + +{static} canMessageToProtobufByteArray(when, msg, out): bool + __ + Generated from LeahiUnhandled.conf — + see CodeGenPipeline + } + + class "leahi::messages (protobuf)" as Proto <> { + Envelope + Header + <474 message types> + } +} + +package "Tools (processes)" { class "CANDumpPlayer\n(main)" <> { +can_interface: string +candump_file: string +--speed: double +--test: bool __ - Parses candump log and replays\nframes onto SocketCAN at a\nconfigurable speed multiplier + Replays a candump log onto\nSocketCAN at a configurable\nspeed multiplier } + + class "DCSsim\n(DCSSimController)" <> { + -_server: SslTcpServer + __ + Local MQTT broker simulator.\nTLS/mTLS via SslTcpServer,\nhand-rolled MqttPacket codec.\nStands in for AWS IoT Core. + } } +package "luis (process)" { + class "luis application" as LUIS <> { + -_ccClient: CloudConnectClient + } +} + ' --- composition --- CloudConnectController *-- CanInterface -CloudConnectController *-- CloudConnectServer CloudConnectController *-- MessageDispatcher +CloudConnectController *-- MqttClient +CloudConnectController o-- CloudConnectServer +' --- nested types --- +CloudConnectController +-- CanAction +CloudConnectController +-- CanRouting +MqttClient +-- MqttConfig +CloudConnectFrame +-- Topic +CloudConnectFrame +-- ReadState + ' --- internal composition --- MessageDispatcher *-- MessageBuilder +' --- external client --- +LUIS *-- CloudConnectClient +CloudConnectClient --> CloudConnectServer : connects via LocalSocket\n(CloudConnectFrame stream) + ' --- usage --- +CloudConnectController ..> MsgDefs : serialize / decode +MsgDefs ..> Proto : builds +CanRouting ..> Topic : uses CloudConnectServer ..> CloudConnectFrame : uses -CloudConnectClient ..> CloudConnectFrame : uses -' --- enum nesting --- -CloudConnectFrame +-- Type -CloudConnectFrame +-- ReadState - ' --- layout hints --- CanInterface -[hidden]- CloudConnectClient