Index: docs/SDD/SoftwareArchitecture.puml =================================================================== diff -u -r6d2ef8c97f4bb34204e95811839b3995000c47c1 -r8b98ff34313ee5d3f5d49672d622162acfc755c9 --- docs/SDD/SoftwareArchitecture.puml (.../SoftwareArchitecture.puml) (revision 6d2ef8c97f4bb34204e95811839b3995000c47c1) +++ docs/SDD/SoftwareArchitecture.puml (.../SoftwareArchitecture.puml) (revision 8b98ff34313ee5d3f5d49672d622162acfc755c9) @@ -5,89 +5,94 @@ skinparam component { BackgroundColor<> LightYellow BackgroundColor<> LightGray + BackgroundColor<> LightCyan BackgroundColor<> #E8E8F8 BorderStyle<> dashed + BackgroundColor<> #EEEEEE + BorderStyle<> dashed } title Leahi Real-time CDT — Component Architecture -note as N1 - The Connectivity Agent process and its Unix domain socket - have been removed; CloudConnect is becoming the single - conduit to the cloud (docs/SDD/AgentMigrationPlan.md). - Dashed = planned, not yet implemented. -end note - node "Leahi Device" { node "CloudConnect (process)" { - component "CloudConnectController" as LRC + component "CloudConnectController" as CC component "Can::CanInterface" as CAN - component "Cloud pipeline\n(MessageSpool, Router,\nMqttPublisher, SpoolDrain)" as PIPE <> + component "MqttClient\n(QMqttClient, TLS/mTLS)" as MQTT + component "MessageSpool + SpoolDrain\n(durability on publish failure)" as SPOOL <> } node "Comms (lib)" { - component "CloudConnectServer\n(local-socket server)" as RS + component "CloudConnectServer\n(local-socket server)" as RS <> component "Can::MessageDispatcher\n(per-CAN-id reassembly)" as MDISP component "Can::MessageBuilder\n(frame ↔ message)" as MB - component "CloudConnectFrame\n(framing + CRC)" as AM + component "CloudConnectFrame\n(framing + CRC)" as AM <> } node "MsgUtils (lib)" { - component "LeahiMsgDefs\n(generated C++)" as MD <> + component "LeahiMsgDefs\n(generated C++ + protobuf stubs)" as MD <> } interface "CAN Bus\n(SocketCAN)" as CANBUS - interface "Unix Domain Socket\n(/tmp/cloudconnect.sock)" as APPUDS + interface "Unix Domain Socket\n(/tmp/cloudconnect.sock)" as APPUDS <> } -node "Luis application" { - component "Application client" as APP +node "Test tools" { + component "CANDumpPlayer\n(replays candump log → SocketCAN)" as CDP <> + component "DCSsim\n(local MQTT broker, TLS/mTLS)" as DCS <> } -node "CANDumpPlayer (tool)" { - component "CAN dump replay\n(writeFrame → SocketCAN)" as CDP -} - cloud "AWS Cloud" as CLOUD <> { - component "AWS IoT Core\n(MQTT broker)" as IOTCORE <> - component "Amazon S3\n(log bundles)" as S3 <> + component "AWS IoT Core\n(MQTT broker, port 8883)" as IOTCORE <> + component "Amazon S3\n(log bundles)" as S3 <> } node "Build-time (scripts)" { component "MsgUtils Python\n(msgutils)" as PYUTILS <> - component "Jinja2 Templates\n(MsgDefs_*.jinja)" as JINJA <> + component "Jinja2 Templates\n(MsgDefs_*.jinja, CanRoutingIni.jinja)" as JINJA <> component "protoc" as PROTOC <> component "LeahiMsgDefs.proto\n(generated)" as PROTO <> component "LeahiMsgDefs.h/.cpp\n(generated)" as GENCPP <> component "Protobuf stubs\n(.pb.h/.pb.cc)" as PBSTUBS <> + component "LeahiCanRouting.ini\n(generated, hand-edits preserved)" as CANINI <> } +' --- runtime data flow --- CDP --> CANBUS : writeFrame (replay) CANBUS --> CAN -CAN --> LRC : didFrameReceive -LRC --> MDISP : onFrameReceive(canId, payload) +CAN --> CC : didFrameReceive +CC --> MDISP : onFrameReceive(canId, payload) MDISP --> MB : buildMessage() MB --> MDISP : Can::Message -MDISP --> LRC : didActionReceive(Can::Message) -LRC --> MD : canMessageToProtobufByteArray() -MD --> AM : protobuf bytes -LRC --> RS : send(Type, seq, payload) -RS --> AM : build() -RS --> APPUDS : write frame -APPUDS --> APP : readyRead +MDISP --> CC : didActionReceive(Can::Message) +CC --> MD : canMessageToProtobufByteArray() +MD --> CC : protobuf bytes +CC --> MQTT : publish(topic, payload, qos = 1) +MQTT --> IOTCORE : PUBLISH / SUBSCRIBE (mTLS 8883) +IOTCORE --> MQTT : PUBACK + echo PUBLISH +MQTT --> DCS : same client, broker swapped\nvia Cloud/ServerAddress in the INI -LRC ..> PIPE : route + spool (planned) -PIPE ..> IOTCORE : PUBLISH QoS 1 (mTLS 8883) -PIPE ..> S3 : multipart upload (HTTPS) +' --- present but idle --- +CC ..> RS : listen() only; send() has no call site +RS ..> AM : build() +RS ..> APPUDS : (no traffic) +' --- planned --- +CC ..> SPOOL : spool on publish failure (planned) +SPOOL ..> MQTT : replay on reconnect (planned) +CC ..> S3 : log bundle upload, HTTPS (planned) + +' --- build-time flow --- PYUTILS --> JINJA : renders JINJA --> PROTO : generates JINJA --> GENCPP : generates +JINJA --> CANINI : generates PROTO --> PROTOC : input PROTOC --> PBSTUBS : generates GENCPP ..> MD : compiled into PBSTUBS ..> MD : compiled into +CANINI ..> CC : loadCanRouting() at startup @enduml