@startuml Seq_CanFrameToCloud title Real-time Data Transfer — CAN Frame to Cloud participant "CAN Bus\n(SocketCAN)" as CANBUS participant "Can::CanInterface" as CAN participant "Can::MessageDispatcher" as DISP participant "CloudConnectController" as CC participant "MqttClient" as MQTT participant "AWS IoT Core\n(MQTT broker)" as AWS == CAN frame(s) → CAN message == CANBUS -> CAN : frame available on the device CAN -> CC : didFrameReceive(QCanBusFrame)\n→ onCanFrameReceive() CC -> DISP : onFrameReceive(canId, payload) DISP -> DISP : MessageBuilder::buildMessage()\nreassembles multi-frame Can::Message alt Message not yet Complete DISP -> DISP : continue accumulating CAN frames else Complete Message Received DISP -> CC : didActionReceive(Can::Message)\n→ onCanMessageReceive() end == Publish CAN Message == alt msgId not in CAN routing CC -> CC : discard (no action defined) else action == Drop CC -> CC : discard else action == SendDelta AND payload unchanged CC -> CC : discard (no change) else action == SendAlways OR SendDelta with new payload CC -> CC : leahi::canMessageToProtobufByteArray()\n→ serialized protobuf alt serialization succeeded CC -> MQTT : publish(topic, payload, pubId, QoS) alt client accepted the publish MQTT -> AWS : PUBLISH AWS -> MQTT : PUBACK MQTT -> CC : didMessageStatusChanged(id, Acknowledged, props)\n→ onCloudMessageStatusChanged() else client rejected the publish CC -> CC : log warning, message lost end else serialization failed CC -> CC : log warning, message dropped end CC -> CC : update message cache for SendDelta check end @enduml