#004 — Understanding MQTT 3.1
MQTT 5 recently reached the 'working draft' stage. When going through the new stuff that’s coming through, I realized that although I have used the soon-to-be-old MQTT in a bunch of places, I’ve never read the spec for the same.
I’m going to simultaneously read the implementation of the Eclipse Mosquitto client & server implementation for MQTT 3.1. It can be found here.
The structure of this post is going to be roughly similar to the MQTT spec.
- MQTT Control packets
- Operating behaviour
- Security (TLS)
MQTT Control packets
If you are familiar with HTTP communication, control packets are similar to methods i.e. PUT, POST, GET, etc. Simply put, these are the types of packets that are exchanged between a client a server at different points of time based on the task at hand.
In MQTT 3.1, we have 14 different control packets.
The header packet is divided into 3 parts as follows -
- Fixed header (2 bytes — 4 bits of packet type (see table below), 4 bits of packet specific flag bits, 8 bits of remaining length)
- Variable header (2 bytes for packet identifier (see table below)
- Payload (9 of the 14 require no payload)
Quality of Service
Quality of service are levels that decide with what certainty a particular message should be delivered. It is a matter of policy, and has to be set as per the importance of information that is being transmitted. For example, sensor data that is frequent can have a QoS of 0. Whereas information about a new firmware update has to be QoS 1.
Overall, there are 3 levels
- QoS 0 — At most once
- QoS 1 — At least once — PUBACK message ensures receipt of delivery
- QoS 2 — Exactly once — PUBREL, PUBCOM messages used for a two-step acknowledgment process
Topics are roughly the equivalent of URLs in HTTP. Once you are connected to a particular server, you can send data on a particular topic. For example a topic would look like ‘/companyname/username/devicename/data’
- ‘/’ — forward slash is used to create levels and hierarchies in topics
- ‘#’ — hashtag is used as a multilevel wildcard
- ‘+’ — plus is used a single level wildcard
- ‘$’ — the dollar sign is used at the start of topics that deal with meta information related to the server or service. They are not to be used for client to client communication
MQTT is a transport layer protocol. As such it doesn’t concern itself with authentication directly.
In general, one has to worry about authentication and authorisation, for both client to server and server to client communication. More about this can be found in implementation notes section of the MQTT 3.1 spec
TLS — Transport Level Security — is a cryptographic protocol that fits in here perfectly, and takes care of data integrity and privacy.
Data integrity is ensuring that the received data has not been tampered with. Privacy ensures that unless one has the right keys, one cannot make sense of the data even if it has been intercepted.
The way TLS works is by using symmetric key cryptography. Authentication is done using public-key cryptography. TLS in itself is quite interesting and perhaps deserves its own spec reading.
In the context of MQTT, it is highly recommended that one setup or pick a MQTT broker which supports TLS1.2. Note that the addition of TLS on the mqtt client end might increase the hardware requirements. Not all microcontrollers are capable of TLS1.2 encryption/decryption.
Port 8883 is reserverd for MQTT over SSL and 1883 for plain MQTT.
MQTT was initially designed to work directly over basic TCP but is not limited to that. WebSockets is a quite recent (2011, MQTT in contrast debuted in 1999) standard that allows full-dulplex (unlike HTTP) communication over a single TCP connection.
WebSockets allow for very fast data transfer between the client and server.
It is possible to use MQTT on top of WebSocket (which works on top of TCP) — which allows for applications in webpages and webapps where WebSockets are predominantly used.
Now that this is done, it’ll be a lot more fun to dive into MQTT 5.