Index: lib/Comms/src/CloudConnectFrame.cpp =================================================================== diff -u -rc6a4b63a37f3beb1e8a51702ec3a56a1c32cfe8f -r59b4c22f45a1d098064a886452769204e90cfb4b --- lib/Comms/src/CloudConnectFrame.cpp (.../CloudConnectFrame.cpp) (revision c6a4b63a37f3beb1e8a51702ec3a56a1c32cfe8f) +++ lib/Comms/src/CloudConnectFrame.cpp (.../CloudConnectFrame.cpp) (revision 59b4c22f45a1d098064a886452769204e90cfb4b) @@ -10,35 +10,31 @@ * \date (original) 24-May-2026 * */ -#include "CloudConnectFrame.h" - #include -// --------------------------------------------------------------------------- -// Outbound -// --------------------------------------------------------------------------- +#include "CloudConnectFrame.h" /*! * \brief CloudConnectFrame::build - * \details Builds a complete wire-ready frame with header and optional payload CRCs. - * \param type - message identifier for Agent MQTT topic + * \details Builds a complete frame with header and optional payload CRCs. + * \param topic - message identifier for MQTT topic * \param sequence - caller-managed sequence number - * \param payload - optional payload; pass empty for zero-length frames (e.g. Ack) - * \return complete frame ready to write to the transport + * \param payload - optional payload; pass empty for no payload frames + * \return complete frame with calculated CRCs */ -QByteArray CloudConnectFrame::build(Type type, quint16 sequence, const QByteArray &payload) +QByteArray CloudConnectFrame::build(Topic topic, quint16 sequence, const QByteArray &payload) { const quint32 payloadLen = static_cast(payload.size()); - // Header: sync(2) + msg_id(2) + sequence(2) + payload_length(4) + header_crc(2) = 12 bytes + // Header: sync(2) + topic(2) + sequence(2) + payload_length(4) + header_crc(2) = 12 bytes QByteArray msg(HEADER_SIZE, Qt::Uninitialized); quint8 *header = reinterpret_cast(msg.data()); header[0] = SYNC[0]; header[1] = SYNC[1]; - qToBigEndian(static_cast(type), header + SYNC_SIZE); - qToBigEndian(sequence, header + SYNC_SIZE + TYPE_SIZE); - qToBigEndian(payloadLen, header + SYNC_SIZE + TYPE_SIZE + SEQUENCE_SIZE); + qToBigEndian(static_cast(topic), header + SYNC_SIZE); + qToBigEndian(sequence, header + SYNC_SIZE + TOPIC_SIZE); + qToBigEndian(payloadLen, header + SYNC_SIZE + TOPIC_SIZE + SEQUENCE_SIZE); const quint16 hCrc = crc16ccitt(header, HEADER_SIZE - HEADER_CRC_SIZE); qToBigEndian(hCrc, header + HEADER_SIZE - HEADER_CRC_SIZE); @@ -54,43 +50,37 @@ return msg; } -// --------------------------------------------------------------------------- -// Inbound -// --------------------------------------------------------------------------- - /*! * \brief CloudConnectFrame::read - * \details Feeds raw bytes into the inbound parser state machine. - * Consumed bytes are removed from the front of the buffer. - * On HeaderError or PayloadError the caller may call read() again + * \details Reads raw bytes into the inbound parser state machine. + * \note Consumed bytes are removed from the front of the buffer. + * \note On HeaderError or PayloadError the caller may call read() again * immediately if the buffer is non-empty. * \param bytes - raw bytes from the transport; modified in-place - * \return ReadState indicating the parser outcome + * \return ReadState containing the frame state after parsing the incoming bytes. */ CloudConnectFrame::ReadState CloudConnectFrame::read(QByteArray &bytes) { int pos = 0; ReadState state = ReadState::Incomplete; - // scan for a valid header — skipped when _headerBuf is already populated from a prior read() call + // scan for a valid header, skip when _headerBuf is already populated from a prior read() call while (_headerBuf.size() == 0 && bytes.size() - pos >= HEADER_SIZE && state != ReadState::HeaderError) { if (static_cast(bytes.at(pos)) == SYNC[0] && static_cast(bytes.at(pos + 1)) == SYNC[1]) { _headerBuf.append(bytes.constData() + pos, HEADER_SIZE); if (crc16ccitt(reinterpret_cast(_headerBuf.constData()), HEADER_SIZE - HEADER_CRC_SIZE) == - qFromBigEndian(reinterpret_cast(_headerBuf.constData() + HEADER_SIZE - - HEADER_CRC_SIZE))) + qFromBigEndian(reinterpret_cast(_headerBuf.constData() + HEADER_SIZE - HEADER_CRC_SIZE))) { const quint8 *header = reinterpret_cast(_headerBuf.constData()); int header_pos = SYNC_SIZE; - _rxType = static_cast(qFromBigEndian(header + header_pos)); - header_pos += TYPE_SIZE; + _rxTopic = static_cast(qFromBigEndian(header + header_pos)); + header_pos += TOPIC_SIZE; _rxSequence = qFromBigEndian(header + header_pos); header_pos += SEQUENCE_SIZE; _rxPayloadLen = qFromBigEndian(header + header_pos); pos += HEADER_SIZE; } else { - // TODO: log the header CRC failure _headerBuf.clear(); pos += SYNC_SIZE; state = ReadState::HeaderError; @@ -107,7 +97,6 @@ state = ReadState::Complete; } else if (_rxPayloadLen > MAX_PAYLOAD_LEN) { - // TODO: log the oversized payload _headerBuf.clear(); state = ReadState::PayloadError; } @@ -121,7 +110,6 @@ state = ReadState::Complete; } else { - // TODO: log the payload CRC failure _headerBuf.clear(); state = ReadState::PayloadError; } @@ -135,21 +123,21 @@ } /*! - * \brief CloudConnectFrame::type - * \details Message identifier of the last complete frame. - * Valid only after read() returns ReadState::Complete. - * \return Type of the last complete frame + * \brief CloudConnectFrame::topic + * \details Frame topic getter + * \note Valid only after read() returns ReadState::Complete. + * \return Topic of the last complete frame */ -CloudConnectFrame::Type CloudConnectFrame::type() const +CloudConnectFrame::Topic CloudConnectFrame::topic() const { - return _rxType; + return _rxTopic; } /*! * \brief CloudConnectFrame::sequence - * \details Sequence number of the last complete frame. - * Valid only after read() returns ReadState::Complete. - * \return sequence number of the last complete frame + * \details Sequence number getter + * \note Valid only after read() returns ReadState::Complete. + * \return Sequence number of the last complete frame */ quint16 CloudConnectFrame::sequence() const { @@ -159,8 +147,8 @@ /*! * \brief CloudConnectFrame::payload * \details Payload bytes of the last complete frame. Empty for zero-length frames. - * Valid only after read() returns ReadState::Complete. - * \return payload of the last complete frame + * \note Valid only after read() returns ReadState::Complete. + * \return Payload of the last complete frame */ QByteArray CloudConnectFrame::payload() const { @@ -169,13 +157,13 @@ /*! * \brief CloudConnectFrame::reset - * \details Resets the inbound parser to its initial sync-scanning state. - * Must be called after consuming a Complete frame. + * \details Resets the frame and frame parser state. + * \note Must be called after consuming a Complete frame. */ void CloudConnectFrame::reset() { _headerBuf.clear(); - _rxType = Type::NormalPriority; + _rxTopic = Topic::NormalPriority; _rxSequence = 0; _rxPayloadLen = 0; _rxPayload.clear();