Embed NanoMQTT in C
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--asyncin 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 |
| Allocate the client state machine and store the Client-ID. |
2 |
| Bind TLS or clear-text transport before negotiation. |
3 |
| Register application callbacks (publish, disconnect, etc.). |
4 |
| Send CONNECT, wait for CONNACK, apply keep-alive. |
5 |
| Add subscriptions or transmit payloads. |
6 |
| Drive the synchronous loop; dispatch callbacks. |
7 |
| Clean up network state and free all allocated memory. |
Note
Return codes: All NanoMQTT functions return MQTT_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 |
Auto-PING logic |
|
Memory ownership |
|