Skip to main content

Crate rusty_rtos_mqtt

Crate rusty_rtos_mqtt 

Source
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 ack refuses.
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.c remade: 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.
ClientLimits
What this client asked for.
ClientSettings
What the client told the broker, and which the CONNACK is checked against.
ClientSubscription
MQTTRetainHandling_t.
ConnAck
A CONNACK, read.
Connect
Everything a CONNECT carries.
ConnectInfo
What a CONNECT’s fixed header needs to know.
ConnectSize
The two numbers an outgoing CONNECT needs.
ConnectValidation
What validate_connect_properties learned on the way through.
ConnectionProperties
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.
DisconnectSize
The two numbers an outgoing DISCONNECT needs.
IncomingHeader
A packet’s fixed header, as far as the transport has read it.
Limits
The two connection properties an ack is checked against.
MqttContext
MQTTContext_t, as far as this slice needs it.
OutgoingPublish
Everything an outgoing PUBLISH carries.
PacketHeader
A decoded fixed header.
PacketInfo
An incoming packet, as the receive loop hands it over.
PacketSize
The two numbers every size calculation produces.
PropertyBuilder
MQTTPropBuilder_t: a section under construction.
PropertyCursor
A cursor over a property section.
PropertyReader
A cursor over a packet’s property section, with a budget.
PublishInfo
An incoming PUBLISH, read.
PublishRecords
The two arrays of in-flight messages that make up an MQTT session’s state.
PublishSize
The two numbers an outgoing PUBLISH needs.
Record
MQTTPubAckInfo_t: one in-flight message.
ServerLimits
What the broker granted.
ServerSettings
What the broker said, with zero standing for each absent property.
Subscription
MQTTRetainHandling_t.
Will
A Last Will and Testament, whole.
WillInfo
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.
BuilderError
Why a property builder could not be created.
ClientError
Why the client refused.
ConnAckError
Why a CONNACK was refused.
ConnectError
Why a CONNECT could not be built.
ConnectionStatus
MQTTConnectionStatus_t.
ContextError
Why a connection context could not be filled.
CursorError
Why a property could not be read.
DisconnectError
Why a DISCONNECT was refused.
HeaderError
Why a fixed header could not be read.
ListPacket
Which of the two list packets is being sized.
Operation
MQTTStateOperation_t: which way the packet is going.
OutboundError
Why an outgoing packet could not be built.
OutgoingError
Why an outgoing PUBLISH could not be built.
PropertyError
Why a property read was refused.
PublishError
Why a PUBLISH was refused.
PublishState
MQTTPublishState_t: where one in-flight message has got to.
QoS
MQTTQoS_t.
ReadError
Why a header could not be read.
Received
What a transport gave back when asked for one byte.
RetainHandling
MQTTRetainHandling_t.
Sent
What a transport did with the bytes it was offered.
SizeError
Why a size could not be calculated.
StateError
Why a state operation was refused.
SubscribeRetainHandling
MQTTRetainHandling_t.
SubscriptionType
Whether a list is being subscribed or unsubscribed.
TopicError
Why a match could not be decided.
ValidateError
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_PUBREL is 0x62, not the 0x60 nibble.
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 field bits.
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: write length into destination, 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: does topic match filter?
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_GetPublishPacketSize and the calculatePublishPacketSize it calls.
read_header
MQTT_GetIncomingPacketTypeAndLength.
reason_code_allowed
validateDisconnectResponse: may this reason code travel this way?
serialize_ack
MQTT_SerializeAck, serializeAckBody and serializeAckWithProperties.
serialize_ack_fixed
serializeAckFixed: a publish acknowledgement’s header and reason code.
serialize_connect
MQTT_SerializeConnect and the serializeConnectPacket it 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 the validateConnectProperty it 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 bytes length needs.
width_of
The width of the property id introduces, or None if it introduces none.