Expand description
rusty_rtos_mqtt — the first slice of coreMQTT, remade in Rust.
What is here. Thirteen slices, each diffed against the C.
core_mqtt_state.c — the QoS 1 and QoS 2 delivery state machine, in both
directions, across 24 scenarios. The differential compares both record
arrays after every operation, not just the status, because their ORDER is
the order a resumed session resends in.
The fixed header out of core_mqtt_serializer.c — the packet type and
the variable-byte remaining length every packet starts with — over
6,291,456 calls: every one of the 256 type bytes against every length
pattern at every claimed length.
The MQTT 5 property primitives out of core_mqtt_serializer_private.c
— the bounded integer, string and user-property reads every property in
every packet goes through. The differential compares the cursor and the
budget after every read, because a refused string has already consumed its
length bytes and a transcription that tidied that up would disagree with the
C on every malformed packet.
The fixed-header writers — the header of every outgoing packet type, byte for byte, including the CONNECT flags byte that packs six independent decisions and is swept exhaustively.
The packet-size calculators that feed those writers — where the remaining length a writer is handed comes from. Proven up to and across the 268,435,455 boundary, at the exact value each check tests, and reconciled against the writers themselves.
The acknowledgement deserializers — the first code here whose whole input a broker chooses. Every ack a client can receive except a CONNACK, with all three of its single-byte decision tables swept over 256 values and the accepted set printed rather than hashed, which is how three divergences from MQTT 5.0 came out of it.
The CONNACK — the first packet a broker sends and the only one that sets connection-wide state. Its reason-code and property tables are swept over 256 values each, the property identifier five times over because each one introduces a value of a different width, and both tables turn out to be exactly MQTT 5.0’s.
The incoming PUBLISH — the last packet a broker can send, and the only one that carries application data. Its payload length is a four-term subtraction on numbers a broker chose, and an identity test asserts that the parts reconstruct the packet rather than merely fitting inside it. Two more divergences from MQTT 5.0 came out of it.
The DISCONNECT, both directions — the packet MQTT 5 made bidirectional, and the one the line above claimed too early. One validation table read twice with different answers, a property table per direction, and a server reason code a stock client refuses.
The CONNECT — the packet that starts a session, and the largest thing a client assembles: eight length-prefixed fields, four of them optional, and a flags byte that has to agree with which ones are there. Proven byte for byte, because every field carries its own length and a packet with two of them swapped still parses.
The outgoing PUBLISH, across all THREE of coreMQTT’s serializers — whole packet, header-without-payload and header-without-topic — with the trace showing that the three agree as prefixes, which no single-function differential can.
SUBSCRIBE, UNSUBSCRIBE, the acknowledgements and PINGREQ — which complete the outgoing wire codec. Sweeping the ack reason codes here showed coreMQTT validating them correctly on the way out and incorrectly on the way in: the library disagrees with itself.
The transport reader — the one function here that takes a CALLBACK rather than a buffer. Compared CALL FOR CALL, because two of its orderings are invisible in the status and plain in the log.
What is not: the property validators and the context helpers (~1,797
lines, plus 2,056 of MQTT 5 property builders) and the connection state
machine (core_mqtt.c, 5,618 lines). 38.4 % of coreMQTT is remade. This
crate can build and read every MQTT packet; it cannot yet run a
connection.
Zero allocation, no_std, forbid(unsafe).
This is the facade: it re-exports the no_std core. Depend on this crate;
reach into the sub-crates only when you are building a port or a backend.
Part of Kairos (Remade With Rust). Plan: docs/plans/rusty_rtos_mqtt.md.
Modules§
- ack
- Reading an acknowledgement off the wire. Reading an acknowledgement off the wire.
- builder
- The buffer an outgoing property section is written into. The buffer an outgoing property section is written into.
- client
- The client context, and what it refuses before it sends anything. The client context, and what it refuses before it sends anything.
- connack
- Reading the CONNACK, which sets every limit the session then runs under.
Reading the CONNACK — the one packet
ackrefuses. - connect
- Building a CONNECT, the packet that starts a session. Building a CONNECT — the packet that starts a session.
- context
- Every limit a session runs under, and where each one came from. Every limit a session runs under, and where each one came from.
- cursor
- Walking a property section back, one property at a time. Walking a property section back, one property at a time.
- disconnect
- The DISCONNECT, which in MQTT 5 travels both ways. The DISCONNECT, both directions.
- header
- The MQTT fixed header: a packet type, and a variable-byte length. The MQTT fixed header: a packet type, and a variable-byte length.
- loop_
- The receive loop and the acknowledgements that come out of it. The receive loop: one pass over whatever the transport has, and the acknowledgements that come out of it.
- outbound
- The rest of what a client sends: SUBSCRIBE, UNSUBSCRIBE, acks and PINGREQ. The rest of what a client sends: SUBSCRIBE, UNSUBSCRIBE, the publish acknowledgements and PINGREQ.
- outpublish
- Building an outgoing PUBLISH: three serializers, one packet. Building an outgoing PUBLISH — three serializers, one packet.
- prelude
- The names a firmware wants in scope.
- property
- The MQTT 5 property primitives: bounded reads out of a packet. The MQTT 5 property primitives: bounded reads out of a packet.
- publish
- Reading an incoming PUBLISH, the packet that carries application data. Reading an incoming PUBLISH — the packet that carries application data.
- reader
- Pulling a packet’s header off a transport, one byte at a time. Pulling a packet’s header off a transport, one byte at a time.
- rtos_
core rusty_rtos_core— the shared vocabulary of the Kairos family.- session
- Opening a connection: CONNECT, CONNACK and what a resumed session owes. Opening a connection: the CONNECT, the CONNACK, and what a resumed session owes the broker.
- size
- How big an outgoing packet will be. How big an outgoing packet will be.
- state
core_mqtt_state.c: the QoS publish state machine.core_mqtt_state.cremade: the QoS publish state machine.- topic
- Does this topic name match that topic filter? Does this topic name match that topic filter?
- validate
- Which property may go in which outgoing packet: six tables, swept. Which property may go in which outgoing packet.
- writer
- The fixed header of every outgoing MQTT packet. The fixed header of every outgoing MQTT packet.
Structs§
- AckInfo
- What an acknowledgement turned out to contain.
- Client
Limits - What this client asked for.
- Client
Settings - What the client told the broker, and which the CONNACK is checked against.
- Client
Subscription MQTTRetainHandling_t.- ConnAck
- A CONNACK, read.
- Connect
- Everything a CONNECT carries.
- Connect
Info - What a CONNECT’s fixed header needs to know.
- Connect
Size - The two numbers an outgoing CONNECT needs.
- Connect
Validation - What
validate_connect_propertieslearned on the way through. - Connection
Properties MQTTConnectionProperties_t: both halves, and the one field they share.- Cursor
MQTTStateCursor_t: a position in the outgoing records, for resending.- Disconnect
- An incoming DISCONNECT, read.
- Disconnect
Size - The two numbers an outgoing DISCONNECT needs.
- Incoming
Header - A packet’s fixed header, as far as the transport has read it.
- Limits
- The two connection properties an ack is checked against.
- Mqtt
Context MQTTContext_t, as far as this slice needs it.- Outgoing
Publish - Everything an outgoing PUBLISH carries.
- Packet
Header - A decoded fixed header.
- Packet
Info - An incoming packet, as the receive loop hands it over.
- Packet
Size - The two numbers every size calculation produces.
- Property
Builder MQTTPropBuilder_t: a section under construction.- Property
Cursor - A cursor over a property section.
- Property
Reader - A cursor over a packet’s property section, with a budget.
- Publish
Info - An incoming PUBLISH, read.
- Publish
Records - The two arrays of in-flight messages that make up an MQTT session’s state.
- Publish
Size - The two numbers an outgoing PUBLISH needs.
- Record
MQTTPubAckInfo_t: one in-flight message.- Server
Limits - What the broker granted.
- Server
Settings - What the broker said, with zero standing for each absent property.
- Subscription
MQTTRetainHandling_t.- Will
- A Last Will and Testament, whole.
- Will
Info - A Last Will and Testament, as far as the fixed header is concerned.
Enums§
- AckError
- Why an acknowledgement was refused.
- AckType
MQTTPubAckType_t: the four acknowledgement packets.- Builder
Error - Why a property builder could not be created.
- Client
Error - Why the client refused.
- Conn
AckError - Why a CONNACK was refused.
- Connect
Error - Why a CONNECT could not be built.
- Connection
Status MQTTConnectionStatus_t.- Context
Error - Why a connection context could not be filled.
- Cursor
Error - Why a property could not be read.
- Disconnect
Error - Why a DISCONNECT was refused.
- Header
Error - Why a fixed header could not be read.
- List
Packet - Which of the two list packets is being sized.
- Operation
MQTTStateOperation_t: which way the packet is going.- Outbound
Error - Why an outgoing packet could not be built.
- Outgoing
Error - Why an outgoing PUBLISH could not be built.
- Property
Error - Why a property read was refused.
- Publish
Error - Why a PUBLISH was refused.
- Publish
State MQTTPublishState_t: where one in-flight message has got to.- QoS
MQTTQoS_t.- Read
Error - Why a header could not be read.
- Received
- What a transport gave back when asked for one byte.
- Retain
Handling MQTTRetainHandling_t.- Sent
- What a transport did with the bytes it was offered.
- Size
Error - Why a size could not be calculated.
- State
Error - Why a state operation was refused.
- Subscribe
Retain Handling MQTTRetainHandling_t.- Subscription
Type - Whether a list is being subscribed or unsubscribed.
- Topic
Error - Why a match could not be decided.
- Validate
Error - Why an outgoing property section was refused.
- Width
- How wide a property’s value is, once its identifier has been read.
Constants§
- CONNACK_
MINIMUM_ SIZE MQTT_PACKET_CONNACK_MINIMUM_SIZE: flags, reason code, property length.- CONNECT_
HEADER_ SIZE MQTT_PACKET_CONNECT_HEADER_SIZE: the variable header before the payload.- MAX_
PACKET_ SIZE - MQTT’s largest possible packet: the greatest remaining length, plus the five bytes of fixed header that can precede it.
- MAX_
REMAINING_ LENGTH MQTT_MAX_REMAINING_LENGTH: the largest length the specification allows.- PACKET_
ID_ INVALID MQTT_PACKET_ID_INVALID: zero is never a packet id.- PINGREQ
MQTT_PACKET_TYPE_PINGREQ, which has no body at all.- PINGREQ_
PACKET_ SIZE MQTT_PACKET_PINGREQ_SIZE: a PINGREQ is always two bytes.- PINGRESP_
REMAINING_ LENGTH MQTT_PACKET_PINGRESP_REMAINING_LENGTH: a PINGRESP carries no body.- PUBREL
MQTT_PACKET_TYPE_PUBRELis0x62, not the0x60nibble.- REMAINING_
LENGTH_ INVALID MQTT_REMAINING_LENGTH_INVALID: one past the largest legal length.- SESSION_
PRESENT_ MASK MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK: the lowest bit of the flags.- VERSION
- Crate version, for manifests and logs.
- VERSION_
5 MQTT_VERSION_5.
Traits§
- Transport
- A socket, a test script, a ring buffer: something bytes go to and come from.
Functions§
- ack_
packet_ size MQTT_GetAckPacketSize: how big a publish acknowledgement will be.- ack_
reason_ code_ allowed validateReasonCodeForAck: may this acknowledgement carry this reason code?- allowed_
properties - Which properties a packet type may carry, as a mask of
fieldbits. - calculate_
state_ ack MQTT_CalculateStateAck: where an acknowledgement puts the record.- calculate_
state_ publish MQTT_CalculateStatePublish: where a PUBLISH puts the record.- connect_
packet_ size MQTT_GetConnectPacketSize.- decode_
variable_ length decodeVariableLength: the PROPERTY length, from the start of a buffer.- deserialize_
ack MQTT_DeserializeAck: read any acknowledgement except a CONNACK.- deserialize_
connack MQTT_DeserializeConnAck.- deserialize_
disconnect MQTT_DeserializeDisconnect: read a DISCONNECT a broker sent.- deserialize_
publish MQTT_DeserializePublish.- disconnect_
packet_ size MQTT_GetDisconnectPacketSize: how big an outgoing DISCONNECT will be.- encode_
string encodeString: a two-byte big-endian length, then the bytes.- encode_
variable_ length encodeVariableLength: writelengthintodestination, seven bits at a time, and return how many bytes were used.- incoming_
packet_ valid incomingPacketValid: is this a packet type a broker may send us?- list_
packet_ size calculateSubscriptionPacketSize: how big a SUBSCRIBE or UNSUBSCRIBE will be.- matches
MQTT_MatchTopic: doestopicmatchfilter?- packet_
type_ name MQTT_GetPacketTypeString: the name of a packet type byte.- process_
incoming_ packet_ type_ and_ length MQTT_ProcessIncomingPacketTypeAndLength: read a fixed header from a buffer.- publish_
packet_ size MQTT_GetPublishPacketSizeand thecalculatePublishPacketSizeit calls.- read_
header MQTT_GetIncomingPacketTypeAndLength.- reason_
code_ allowed validateDisconnectResponse: may this reason code travel this way?- serialize_
ack MQTT_SerializeAck,serializeAckBodyandserializeAckWithProperties.- serialize_
ack_ fixed serializeAckFixed: a publish acknowledgement’s header and reason code.- serialize_
connect MQTT_SerializeConnectand theserializeConnectPacketit calls.- serialize_
connect_ fixed_ header serializeConnectFixedHeader: a CONNECT up to and including the keep alive.- serialize_
disconnect MQTT_SerializeDisconnect: lay the packet down.- serialize_
disconnect_ fixed serializeDisconnectFixed: the type byte, the length, and maybe a reason.- serialize_
pingreq MQTT_SerializePingreq: two bytes that never change.- serialize_
publish MQTT_SerializePublish: the whole packet, payload and all.- serialize_
publish_ header MQTT_SerializePublishHeader: everything except the payload.- serialize_
publish_ header_ without_ topic MQTT_SerializePublishHeaderWithoutTopic: the type byte, the remaining length, and the topic’s two LENGTH bytes.- serialize_
subscribe MQTT_SerializeSubscribe.- serialize_
subscribe_ header serializeSubscribeHeader: the type byte, the length and the packet id.- serialize_
unsubscribe MQTT_SerializeUnsubscribe: the same, without the options byte.- serialize_
unsubscribe_ header serializeUnsubscribeHeader: the same shape, a different type byte.- status_
name MQTT_Status_strerror: the name of a status.- suback_
status_ codes MQTT_GetSubAckStatusCodes: the reason codes in a SUBACK, without deserializing it.- subscribe_
packet_ size MQTT_GetSubscribePacketSize.- subscription_
options - The options byte for one subscription.
- unsuback_
status_ codes MQTT_GetUnsubAckStatusCodes: the same, for an UNSUBACK.- unsubscribe_
packet_ size MQTT_GetUnsubscribePacketSize.- update_
duplicate_ flag MQTT_UpdateDuplicatePublishFlag: patch the DUP bit of a serialized header.- update_
with_ connect_ props updateContextWithConnectProps: fill the client’s half from a CONNECT’s property section.- validate_
connect_ properties MQTT_ValidateConnectProperties, and thevalidateConnectPropertyit drives.- validate_
outgoing_ properties MQTT_ValidateDisconnectProperties: check what a client is about to send.- validate_
publish_ ack_ properties MQTT_ValidatePublishAckProperties: a reason string and user properties.- validate_
publish_ params MQTT_ValidatePublishParams: the six things an outgoing PUBLISH is checked against before it is sized or serialized.- validate_
publish_ properties MQTT_ValidatePublishProperties.- validate_
subscribe_ properties MQTT_ValidateSubscribeProperties.- validate_
unsubscribe_ properties MQTT_ValidateUnsubscribeProperties: user properties, and nothing else.- validate_
will_ properties MQTT_ValidateWillProperties.- variable_
length_ encoded_ size variableLengthEncodedSize: how many byteslengthneeds.- width_
of - The width of the property
idintroduces, orNoneif it introduces none.