Embed NanoMQTT in C
3 minute read
This topic shows the smallest synchronous flow needed to connect, subscribe, publish, and service the receive loop in a single-threaded application.
Before you begin
If you plan to use TLS, create and negotiate a NanoSSL connection:
- Create the NanoSSL handle with
SSL_connect(). - Complete the handshake with
SSL_negotiateConnection(). - Bind the SSL handle to the MQTT connection with
MQTT_setTransportSSL(connInst, sslConnInst)before you callMQTT_negotiateConnection().
Examples assume sockets are non-blocking so a single event loop can multiplex TCP/TLS traffic. Build with the asynchronous client enabled (
__ENABLE_MQTT_ASYNC_CLIENT__ or --async in the build script) and open your sockets in non-blocking mode. Blocking sockets work, but they prevent multiplexing.A reachable MQTT 5 or 3.1.1 broker (port 1883 for TCP, 8883 for TLS).
Minimal synchronous example
#include "mqtt_client.h"
#include "ssl_api.h" /* Needed only for TLS */
static void on_publish(const MqttPublishRx *msg, void *arg)
{
/* Handle inbound publishes here */
}
/* ---------- 1. Allocate an MQTT connection (stores Client-ID) */
MqttConnectionHandle conn =
MQTT_connect(MQTT_V5, "device-123", strlen("device-123"));
/* ---------- 2. Bind a transport ----------------------------------------- */
/* (a) Clear-text TCP: */
/* int socketFd = ... ; MQTT_setTransportTCP(conn, socketFd); */
/* (b) TLS transport (shown): */
MQTT_setTransportSSL(conn, sslConnInst); /* sslConnInst = NanoSSL handle */
/* Transport may be bound at any point *before* MQTT_negotiateConnection. */
/* ---------- 3. Register control-packet handlers ------------------------- */
MqttPacketHandlers h = { .publishHandler = on_publish };
MQTT_setControlPacketHandlers(conn, &h);
/* ---------- 4. Negotiate the session (CONNECT / CONNACK) --------------- */
MqttConnectOptions opts = {
.cleanStart = true,
.keepAliveInterval = 30, /* seconds; 0 disables keep-alive */
};
if (MQTT_negotiateConnection(conn, &opts) < 0) {
/* handle error */
}
/* ---------- 5. Subscribe and publish ------------------------------------ */
MqttSubscribeTopic subTopic = { .pTopic = "alerts/#", .topicLen = 8, .qos = 1 };
MqttSubscribeOptions subOpts = { 0 }; /* no extra options */
MQTT_subscribe(conn, &subTopic, 1, &subOpts);
MqttPublishOptions pubOpts = { .qos = 0, .retain = false };
const char payload[] = "Hello NanoMQTT";
MQTT_publish(conn, &pubOpts,
"telemetry", 9,
payload, sizeof payload - 1);
/* ---------- 6. Main receive loop ---------------------------------------- */
while (running) {
if (MQTT_recv(conn) < 0) { /* dispatches callbacks */
/* handle error or reconnect */
}
}
/* ---------- 7. Graceful shutdown --------------------------------------- */
MQTT_disconnect(conn, NULL); /* default DISCONNECT */
MQTT_closeConnection(conn); /* free all connection memory */
How it works
| Step | Call | Purpose |
|---|---|---|
| 1 | MQTT_connect | Allocate the client state machine and store the Client-ID. |
| 2 | MQTT_setTransportSSL / MQTT_setTransportTCP | Bind TLS or clear-text transport before negotiation. |
| 3 | MQTT_setControlPacketHandlers | Register application callbacks (publish, disconnect, etc.). |
| 4 | MQTT_negotiateConnection | Send CONNECT, wait for CONNACK, apply keep-alive. |
| 5 | MQTT_subscribe / MQTT_publish | Add subscriptions or transmit payloads. |
| 6 | MQTT_recv | Drive the synchronous loop; dispatch callbacks. |
| 7 | MQTT_disconnect / MQTT_closeConnection | Clean up network state and free all allocated memory. |
Note
Return codes: All NanoMQTT functions returnMQTT_OK (0) or a negative error code. Check each call; on failure disconnect, free, and reconnect.Implementation notes
| Topic | Note |
|---|---|
| Build toggle | NanoMQTT is part of the default TrustCore SDK build. Use ./build.sh nanomqtt (or the --module nanomqtt CMake option) if you want to build only the NanoMQTT components. |
| Auto-PING logic | MQTT_recv() automatically injects a PINGREQ whenever no other data has flowed for one keep-alive interval. Applications do not need to call MQTT_pingRequest() unless they choose to manage keep-alive manually. If the keep-alive interval is 0, NanoMQTT will not send PINGREQ packets. |
| Memory ownership | MQTT_disconnect() terminates the network session but does not free the client state. Always follow it with MQTT_closeConnection(conn) (or drop the handle) to release memory. |
Was this page helpful?
Provide feedback