# MQTT : Packets ## Structure - All packets have a *Fixed Header*. - Some packets have a *Variable Header*. - Some packets have a *Payload*. ### Fixed Header - *Packet Type* (1..14) - *Packet Length* (<= 256MB) (not including Fixed Header) - In PUBLISH packets only -> a set of flags ### Variable Header Varies by packet type and instance. - *Packet ID* — Used in all Pub/Sub/Unsub packets (except PUBLISH w/QoS=0) to correlate replies. - Arbitrary two-byte value that must NOT currently be in use. - When re-sending the same packet, you must use the same Packet ID. - Once the Client has processed the corresponding acknowledgement packet(s), that ID is freed and can be re-used. - Same for Broker in the opposite direction. - It's possible for a Client to send a PUBLISH Packet with Packet ID 0x1234 and then receive a different PUBLISH with Packet ID 0x1234 from the Broker before it receives a PUBACK for the PUBLISH that it sent. Each direction uses a different ID namespace. ### Payload Packet Types with Payloads: - CONNECT — connection information - PUBLISH — aka "Application Message" (optional - can have zero-byte payloads) - SUBSCRIBE — list of topics + requested QoS - SUBACK — list of topics + granted QoS - UNSUBSCRIBE — list of topics w/unsub results ## Packet Types ``` 1 CONNECT -> Client request to connect to Server 2 CONNACK <- Connect acknowledgment 3 PUBLISH <-> Publish message 4 PUBACK <-> Publish acknowledgment 5 PUBREC <-> Publish received (assured delivery part 1) 6 PUBREL <-> Publish release (assured delivery part 2) 7 PUBCOMP <-> Publish complete (assured delivery part 3) 8 SUBSCRIBE -> Client subscribe request 9 SUBACK <- Subscribe acknowledgment 10 UNSUBSCRIBE -> Unsubscribe request 11 UNSUBACK <- Unsubscribe acknowledgment 12 PINGREQ -> PING request 13 PINGRESP <- PING response 14 DISCONNECT -> Client is disconnecting ``` ## Packet Details #### CONNECT **Variable Header** - *Protocol Name* -> always "MQTT" - *Protocol Level* - 4 -> v3.1.1 - 5 -> v5.0 - Connect Flags - *User Name* -> whether *User Name* is present in the Payload - *Password* -> whether *Password* is present in the Payload (if so, must also include User Name) - *Will* -> whether *Will Topic* + *Will Message* are present in the Payload - *Will Retain* -> whether the Will is a Retained Message - *Will QoS* -> the publish QoS of the Will message - *Keep-Alive* -> two-byte integer value, expressed in seconds (max: 65535 / 18h12m15s) - It's the Client's responsibility to ensure that the interval between Packets does not exceed the Keep-Alive value. - Client can use PINGREQ to keep connection alive. **Payload** - Client ID -> required; unique; 1 <= length <= 23; valid chars: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - If another Client with same ID is currently connected, they will be disconnected. - *Will Topic* - *Will Message* - *User Name* - *Password* Clients need not wait for a CONNACK Packet to send more Packets. #### CONNACK **Variable Header** - Flags: - *SP* (Session Present) -> whether an existing Session was found and resumed - *Return Code*: - 0 -> accepted - 1..5 -> various rejection reasons #### PUBLISH **Fixed Header** - *DUP* -> 0 if first time sending, 1 if re-sending - Even if sent multiple times to Broker, DUP will be set to 0 when Broker publishes to subscribing Clients. - *QoS* -> 0..2 (for that hop, only — QoS used to publish to Broker has nothing to do with QoS used by Broker to publish to Client, which is negotiated during subscription) - *RETAIN* -> 1 for Retained Message - Set on Packet sent to Broker to make it the new Retained Message on that Topic. - Set on Packet sent from Broker when receiving a Retained Messages as a result of subscribing to that Topic. - To un-retain a message in a Topic, send a new Retained Message with no Payload. **Variable Header** - *Topic Name* - *Packet ID* (if QoS > 0) **Payload** - zero or more arbitrary bytes (Application Message) #### PUBACK, PUBREC, PUBREL, PUBCOMP **Variable Header** - *Packet ID* -> the PUBLISH packet's ID #### SUBSCRIBE **Variable Header** - *Packet ID* **Payload** - list of Topic Filters w/Requested QoS > [!NOTE] > If an identical Subscription exists, it will be replaced, and Retained Messages will be re-sent. #### SUBACK **Variable Header** - *Packet ID* -> the SUBSCRIBE packet's ID **Payload** - list of return codes in same order as list of Topic Filters in SUBSCRIBE packet - 0..2 -> granted QoS - 128 -> Subscription failed #### UNSUBSCRIBE **Variable Header** - *Packet ID* **Payload** - list of Topic Filters (must exactly match Topic Filters used to subscribe) After unsubscribing, Broker... - MUST stop adding any new messages for delivery to the Client - MUST complete the delivery of any QoS 1 or QoS 2 messages which it has started to send to the Client - MAY continue to deliver any existing messages buffered for delivery to the Client #### UNSUBACK **Variable Header** - *Packet ID* -> the UNSUBSCRIBE packet's ID #### PINGREQ, PINGRESP, DISCONNECT No Variable Header or Payload.