uMQTT
MQTT client library for microcontrollers
uMQTT API

Detailed Description

Functions you call to operate MQTT client

Function Name Description
umqtt_New() Create and initialize umqtt instance
umqtt_Delete() de-initialize umqtt instace (frees resources)
umqtt_Run() main run loop
umqtt_Connect() establish protocol connection to MQTT broker
umqtt_Disconnect() protocol disconnect from MQTT broker
umqtt_Publish() publish a topic
umqtt_Subscribe() subscribe to topic(s)
umqtt_Unsubscribe() unsubscribe from topic(s)
umqtt_GetErrorString() get string representation of error code
umqtt_GetConnectedStatus() determine if connected

The following are available but you don't need to call these directly, they are called from umqtt_Run() when needed.

Function Name Description
umqtt_PingReq() send ping request to MQTT broker
umqtt_DecodePacket() decode a MQTT packet and perform actions

Functions you must implement

These are populated into a umqtt_TransportConfig_t structure and passed to umqtt_New():

Function Name Description
malloc_t() memory allocation for packets
free_t() free allocated memory
netReadPacket_t() read a packet from the network
netWritePacket_t() write a packet to the network

Optional functions to implement

These callback functions are used to notify the application when certain events occur. These are populated into a umqtt_Callbacks_t structure and passed to umqtt_New(). Unimplemented callback functions can be set to NULL.

Function Name Description
ConnackCb_t() CONNACK received from broker to acknowledge a CONNECT
PublishCb_t() PUBLISH received from broker
PubackCb_t() PUBACK received from broker in response to PUBLISH with QoS != 0
SubackCb_t() SUBACK received in response to SUBSCRIBE
UnsubackCb_t() UNSUBACK received in response to UNSUBSCRIBE
PingrespCb_t() PINGRESP received in response to PINGREQ

Run loop and timing

You must call umqtt_Run() repeatedly from your main run loop. It is not required that timing be exact between calls. You must maintain a source of millisecond tick values (like a tick timer) and pass the millisecond ticks to umqtt_Run() each time it is called. This is how umqtt keeps track of timing for timeouts and retries.

Not thread safe

These functions are not thread safe. You musn't call them from different threads unless you provide your own resource lock wrapper(s).

Typedef Documentation

◆ umqtt_Handle_t

typedef void* umqtt_Handle_t

umqtt instance handle, to be passed to all functions.

Obtained from umqtt_New().

◆ ConnackCb_t

typedef void(* ConnackCb_t) (umqtt_Handle_t h, void *pUser, bool sessionPresent, uint8_t retCode)

Callback function for CONNACK connection acknowledgment.

Parameters
humqtt instance handle
pUserclient's optional user data pointer
sessionPresentMQTT session present flag
retCodereturn code for the MQTT connection attempt

This function is called when a CONNACK is received in response to umqtt_Connect(). The application can use this callback to know when a connection is complete and ready to be used.

◆ PublishCb_t

typedef void(* PublishCb_t) (umqtt_Handle_t h, void *pUser, bool dup, bool retain, uint8_t qos, const char *pTopic, uint16_t topicLen, const uint8_t *pMsg, uint16_t msgLen)

Callback function for Publish packets.

Parameters
humqtt instance handle
pUserclient's optional user data pointer
dupMQTT dup header flag was set in the packet
retainMQTT retain flag was set in the packet
qosQoS level for the packet
pTopicpointer to topic string
topicLennumber of bytes in the topic string
pMsgpointer to topic message
msgLennumber of bytes in the topic message

This function is called when the umqtt client receives a publish packet from the MQTT broker. While this callback function is optional, it is the only way for the umqtt client application to be notified of publish messages. If any of the packet contents such as the topic or message needs to be retained, then this function must make a copy. Once this function returns the pointers will be no longer valid.

◆ PubackCb_t

typedef void(* PubackCb_t) (umqtt_Handle_t h, void *pUser, uint16_t pktId)

Callback function for Puback packets.

Parameters
humqtt instance handle
pUserclient's optional user data pointer
pktIdpacket ID of the received packet

This function is called when the umqtt client receives a Puback packet in response to umqtt_Publish(). It is not necessary for the application to use this callback unless it needs to track completion of publish messages. The pktId parameter should match the message ID that was returned when using umqtt_Publish(). This method could be used to throttle publish actions (ensure that only one publish is sent at a time). The umqtt_Run() function takes care of tracking acknowledgments and handling retries, so this function is just informative.

◆ SubackCb_t

typedef void(* SubackCb_t) (umqtt_Handle_t h, void *pUser, const uint8_t *retCodes, uint16_t retCount, uint16_t pktId)

Callback function for Suback packets.

Parameters
humqtt instance handle
pUserclient's optional user data pointer
retCodesarray of return codes, one for each subscribe topic
retCountnumber of return codes in the retCodes array
pktIdpacket ID of the received packet

This function is called when the umqtt client receives a Suback packet in response to umqtt_Subscribe(). It is not necessary for the application to use this callback unless it needs to track completion of subscribe messages or needs confirmation of subscribe topic return codes. The pktId parameter should match the message ID that was returned when using umqtt_Subscribe(). The umqtt_Run() function takes care of tracking acknowledgments and handling retries.

◆ UnsubackCb_t

typedef void(* UnsubackCb_t) (umqtt_Handle_t h, void *pUser, uint16_t pktId)

Callback function for Unsuback packets.

Parameters
humqtt instance handle
pUserclient's optional user data pointer
pktIdpacket ID of the received packet

This function is called when the umqtt client receives a Unsuback packet in response to umqtt_Unsubscribe(). It is not necessary for the application to use this callback unless it needs to track completion of unsubscribe messages. The pktId parameter should match the message ID that was returned when using umqtt_Unsubscribe(). The umqtt_Run() function takes care of tracking acknowledgments and handling retries.

◆ PingrespCb_t

typedef void(* PingrespCb_t) (umqtt_Handle_t h, void *pUser)

Callback function for PINGRESP packets.

Parameters
humqtt instance handle
pUserclient's optional user data pointer

This function is called when the umqtt client receives a PINGRESP in response to umqtt_Pingreq(). There is no reason for the application to use this callback but it is here for completeness. It could be used as a kind of heartbeat although the interval will not be reliable. The umqtt_Run() function takes care of sending and receiving ping messages at the appropriate time.

◆ malloc_t

typedef void*(* malloc_t) (size_t size)

Memory allocation function provided by application.

Parameters
sizethe number of bytes to be allocated
Returns
pointer to the allocated memory or NULL

This function must be implemented by the application. The umqtt library uses this when it needs to request memory for building MQTT packets. The application is free to implement this in any way. It can just pass through the system malloc, or it could use other memory allocator methods (such as bget). Or it can implement a simple list of fixed buffers and just allocate one of those each time this function is called.

◆ free_t

typedef void(* free_t) (void *ptr)

Memory free function provided by application.

Parameters
ptrpointer to the previously allocated memory buffer

This function must be implemented by the application. The umqtt library uses this when it needs to free memory that was earlier allocated for packet memory.

◆ netReadPacket_t

typedef int(* netReadPacket_t) (void *hNet, uint8_t **ppBuf)

Read a packet from the network.

Parameters
hNetis the network instance handle (not umqtt instance handle)
ppBufpointer to a pointer to the received packet data
Returns
number of bytes that were read from the network. This will be 0 if no data was read, or negative if there is an error.

This function must be implemented by the application. It is used by the umqtt library when it needs to read a new packet from the network. A double pointer is used (ppBuf) so that the umqtt library does not need to make any additional copy of the data. This function must allocate the memory used to hold the packet in a method compatible with the malloc_t() / free_t() functions. The umqtt_Run() function will use the free_t() function to free this packet after it has been decoded.

The incoming packet must be a complete packet. The umqtt library does not handle partial packets or misaligned packets.

◆ netWritePacket_t

typedef int(* netWritePacket_t) (void *hNet, const uint8_t *pBuf, uint32_t len, bool isMore)

Write a packet to the network.

Parameters
hNetis the network instance handle (not umqtt instance handle)
pBufpointer to the buffer holding the packet data
lencount of byte in the buffer
isMoreflag to indicate that there is additional data to send
Returns
number of bytes that were written to the network. This will be 0 if no data was written or negative if there was an error.

This function must be implemented by the application. It is called by the umqtt library when it needs to send a packet to the network. The packet must be all sent or none. The umqtt library cannot handle a partial transmit. If anything less than the complete number of bytes are sent it will be considered a network error. The network write function can optionally use the isMore parameter to aggregate packet data before sending it over the network link. Usually isMore is false.

Enumeration Type Documentation

◆ umqtt_Error_t

Return codes for umqtt functions.

Enumerator
UMQTT_ERR_OK 

normal return code, no errors

UMQTT_ERR_PACKET_ERROR 

detected error in packet during decoding

UMQTT_ERR_BUFSIZE 

unable to allocate memory for a packet

UMQTT_ERR_PARM 

problem with function input parameter

UMQTT_ERR_NETWORK 

error writing or reading network

UMQTT_ERR_CONNECT_PENDING 

connect is in progress

UMQTT_ERR_CONNECTED 

umqtt client is connected to MQTT broker

UMQTT_ERR_DISCONNECTED 

umqtt client is not connected to MQTT broker

UMQTT_ERR_TIMEOUT 

a timeout occurred waiting on some reply

Function Documentation

◆ umqtt_GetErrorString()

const char* umqtt_GetErrorString ( umqtt_Error_t  err)

Get string representing an error code.

Parameters
erris the error code to decode

This function is useful for debugging. It can be used to print a meaningful string for an error code.

Returns
a human readable string representation of the error code

◆ umqtt_Connect()

umqtt_Error_t umqtt_Connect ( umqtt_Handle_t  h,
bool  cleanSession,
bool  willRetain,
uint8_t  willQos,
uint16_t  keepAlive,
const char *  clientId,
const char *  willTopic,
const uint8_t *  willPayload,
uint32_t  willPayloadLen,
const char *  username,
const char *  password 
)

Initiate MQTT protocol Connect.

Parameters
humqtt instance handle from umqtt_New()
cleanSessiontrue to establish new session, false to resume old session
willRetaintrue if published will message should be retained
willQosthe QoS level to be used for the will message (if used)
keepAlivethe keep alive interval in seconds
clientIdthe name of the MQTT client to use for the session
willTopicoptional topic name for will, or NULL
willPayloadoptional will payload, or NULL
willPayloadLenlength of the will payload message
usernameoptional authentication user name, or NULL
passwordoptional authentication password, or NULL
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function will create a MQTT Connect packet and attempt to send it to the MQTT broker. The network connection to the MQTT server port should already be established. When the function returns, the Connect packet has been sent or there was an error. Upon return, the MQTT connection is pending, it is not yet established. The connection is not established until the MQTT broker sends a Connack packet, which can be detected by either using the Connack callback function, or when umqtt_GetConnectedStatus() returns UMQTT_ERR_CONNECTED.

Possible return codes:

Code Reason
UMQTT_ERR_OK Connect packet was transmitted
UMQTT_ERR_PARM detected an error in a function parameter
UMQTT_ERR_BUFSIZE memory allocation failed
UMQTT_ERR_NETWORK error writing packet to network
UMQTT_ERR_CONNECTED MQTT connection is already established
UMQTT_ERR_CONNECT_PENDING MQTT connection is already in progress

Example

umqtt_Handle_t h; // previously acquired instance handle
char clientName[] = "myMqttClient";
char willTopic[] = "myWillTopic";
uint8_t willPayload[] = (uint8_t *)"myWillMessage";
err = umqtt_Connect(h, true, false, 0, 30, // clean session, 30 secs keep alive
clientName, willTopic,
willPayload, strlen(willPayload),
NULL, NULL); // no username or password
if (err != UMQTT_ERR_OK)
{
// handle error
}
else
{
// connect is in progress
}

◆ umqtt_Disconnect()

umqtt_Error_t umqtt_Disconnect ( umqtt_Handle_t  h)

Disconnect MQTT protocol.

Parameters
humqtt instance handle from umqtt_New()
Returns
UMQTT_ERR_OK or an error code

This function attempts to send a MQTT protocol disconnect packet, frees up all pending packets and marks the instance as disconnected.

◆ umqtt_Publish()

umqtt_Error_t umqtt_Publish ( umqtt_Handle_t  h,
const char *  topic,
const uint8_t *  payload,
uint32_t  payloadLen,
uint32_t  qos,
bool  shouldRetain,
uint16_t *  pId 
)

Send MQTT protocol Publish packet.

Parameters
humqtt instance handle from umqtt_New()
topictopic name to publish
payloadpayload or message for the topic (can be NULL)
payloadLennumber of bytes in the payload
qosQoS (quality of service) level for this topic
shouldRetaintrue if MQTT broker should retain this topic
pIdpointer to storage for assigned packet ID (optional)
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function is used to publish a topic with an optional payload. A publish packet will be assembled and sent to the connected UMQTT broker. If the QoS > 0 then the packet will be held and resent as needed until an acknowledgment is received. If this happens, then the Publish packet will have a packet ID. The pId parameter can be used to get the packet ID if needed. Otherwise, this parameter can be set to NULL. If the QoS is 0, then there is no packet ID.

If a callback function was provided for Puback, then the Puback callback will be called when the publish packet is acknowledged.

A payload is not required. MQTT can publish only a topic name with no payload. If a payload is not used then the parameter can be set to NULL. The payload can be binary data and not necessarily a string.

Note
At this time, the umqtt library does not support QoS level 2

Example

umqtt_Handle_t h; // previously acquired instance handle
char topicName[] = "myTopic";
uint8_t payload[] = (uint8_t *)"myPayloadMessage";
uint16_t msgId;
err = umqtt_Publish(h, topicName, payload, strlen(payload),
1, true, *msgId);
if (err == UMQTT_ERR_OK)
{
// Publish packet has been sent with QoS 1
// Packet is pending acknowledgment
// msgId now contains the packet ID that was used
}
else // error occurred
{
// handle publish error
}

◆ umqtt_Subscribe()

umqtt_Error_t umqtt_Subscribe ( umqtt_Handle_t  h,
uint32_t  count,
char *  topics[],
uint8_t  qoss[],
uint16_t *  pId 
)

Subscribe to topics.

Parameters
humqtt instance handle from umqtt_New()
countnumber of topics in the list of topics to subscribe
topicsarray of topic names to subscribe
qossarray of QoS values to use for subscribed topics
pIdpointer to storage for assigned packet ID (optional)
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function is used to send a subscribe request to an MQTT broker. It can be used to subscribe to one or more topics at one time. Each subscribed topic can be assigned a QoS level.

A subscribe packet will be held pending until it is acknowledged by the MQTT broker. If the caller provided the pId parameter, then the packet ID will be saved for the caller. If the caller does not need the packet ID, then pId parameter can be NULL.

If the caller provided a Suback callback function, then it will be notified when the subscribe request is acknowledged.

Example

umqtt_Handle_t h; // previously acquired instance handle
char *topics[] = { "topic1", "topic2" };
uint8_t qoss[] = { 0, 1 };
uint16_t msgId;
err = umqtt_Subscribe(h, 2, topics, qoss, &msgId);
if (err == UMQTT_ERR_OK)
{
// Subscribe packet has been sent with requested topics
// Packet is pending acknowledgment
// msgId now contains the packet ID that was used
}
else // error occurred
{
// handle subscribe error
}

◆ umqtt_Unsubscribe()

umqtt_Error_t umqtt_Unsubscribe ( umqtt_Handle_t  h,
uint32_t  count,
const char *  topics[],
uint16_t *  pId 
)

Unsubscribe from topics.

Parameters
humqtt instance handle from umqtt_New()
countcount of topics in topic list
topicsarray of topic names to unsubscribe
pIdpointer to storage for assigned packet ID (optional)
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function is used to send an unsubscribe request to an MQTT broker. It can be used to unsubscribe from one or more topics at one time.

An unsubscribe packet will be held pending until it is acknowledged by the MQTT broker. If the caller provided the pId parameter, then the packet ID will be saved for the caller. If the caller does not need the packet ID, then pId parameter can be NULL.

If the caller provided a Unsuback callback function, then it will be notified when the unsubscribe request is acknowledged.

Example

umqtt_Handle_t h; // previously acquired instance handle
char *topics[] = { "topic1", "topic2" };
uint16_t msgId;
err = umqtt_Unsubscribe(h, 2, topics, &msgId);
if (err == UMQTT_ERR_OK)
{
// Unsubscribe packet has been sent with topic list
// Packet is pending acknowledgment
// msgId now contains the packet ID that was used
}
else // error occurred
{
// handle unsubscribe error
}

◆ umqtt_PingReq()

umqtt_Error_t umqtt_PingReq ( umqtt_Handle_t  h)

Send a Ping (keep-alive) to the MQTT broker.

Parameters
humqtt instance handle from umqtt_New()
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function is used to send a Ping Request to the MQTT broker. The client is required to periodically send Ping messages to keep the connection alive. This function is provided as a convenience but should not normally ever need to be called by the client application. The keep-alive/ping process is handled by the umqtt_Run() function.

◆ umqtt_DecodePacket()

umqtt_Error_t umqtt_DecodePacket ( umqtt_Handle_t  h,
const uint8_t *  pIncoming,
uint32_t  incomingLen 
)

Decode incoming MQTT packet.

Parameters
humqtt instance handle from umqtt_New()
pIncomingbuffer holding incoming UMQTT packet
incomingLennumber of bytes in the incoming buffer
Returns
UMQTT_ERR_OK if successful, or an error code if an error occurred

This function is used to decode incoming MQTT packets from the server. It is normally called from umqtt_Run() and the client application does not need to call this directly. However, it is provided for completeness.

The caller passes a buffer containing an MQTT protocol packet that was received from the network. The packet will be decoded and if valid the appropriate action taken. The action depends on the packet:

Type Action
CONNACK Free pending connect, notify client if callback is provided
PUBLISH Extract publish topic, notify client through callback
PUBACK Free pending Publish, notify client if callback is provided
SUBACK Free pending Subscribe, notify client if callback is provided
UNSUBACK Free pending Unsubscribe, notify client if callback is provided
PINGRESP No action except notify client if a callback is provided

◆ umqtt_GetConnectedStatus()

umqtt_Error_t umqtt_GetConnectedStatus ( umqtt_Handle_t  h)

Get the status of the connection.

Parameters
humqtt instance handle from umqtt_New()

Use this function to determine the state of connectedness of the UMQTT client. It will return one of the following:

  • UMQTT_ERR_CONNECTED
  • UMQTT_ERR_CONNECT_PENDING
  • UMQTT_ERR_DISCONNECTED
Returns
return code indicating the connection state

◆ umqtt_New()

umqtt_Handle_t umqtt_New ( umqtt_TransportConfig_t pTransport,
umqtt_Callbacks_t pCallbacks,
void *  pUser 
)

Create and initialize a umqtt client instance.

Parameters
pTransportstructure defining the MQTT transport interface
pCallbacksstructure holding the callback functions
pUseroptional caller defined data pointer that will be passed in callbacks
Returns
umqtt instance handle that should be used for all other function calls, or NULL if there is an error.

This function will allocate a umqtt instance and initialize it. No actual MQTT operations are performed. The caller must provide the network access functions through the pTransport parameter. Callback functions are used for notification and are optional. If used, callback functions are provided by the pCallbacks parameter. The entire parameter can be NULL if no callbacks are used, or individual callbacks can be NULL within the structure.

Example

void PublishCb(umqtt_Handle_t h, void *pUser, bool dup, bool retain,
const char *topic, uint16_t topicLen,
const uint8_t *msg, uint16_t msgLen)
{
// publish handler
}
{
myNetworkHandle, // optional, if network has a handle or instance
malloc, free,
myNetReadFunction, myNetWriteFunction
};
umqtt_Callbacks_t callbacks = // only publish callback is defined
{ NULL, PublishCb, NULL, NULL, NULL, NULL };
h = umqtt_New(&transport, &callbacks, NULL);
if (h == NULL)
{
// handle error
}

◆ umqtt_Delete()

void umqtt_Delete ( umqtt_Handle_t  h)

Clean up and free umqtt client instance.

Parameters
humqtt instance handle from umqtt_New()

This function is used to free all allocated memory by the umqtt instance. It should be called as part of an orderly shutdown.

◆ umqtt_Run()

umqtt_Error_t umqtt_Run ( umqtt_Handle_t  h,
uint32_t  msTicks 
)

Main loop processing for the umqtt client instance.

Parameters
humqtt instance handle from umqtt_New()
msTicksmilliseconds tick count
Returns
UMQTT_ERR_OK if everything is normal, or an error code if something goes wrong

This function should be called repeatedly from the application main loop. The application must maintain an incrementing millisecond tick counter and pass that to the Run function. This tick value is used to keep track of internal timeouts. The Run function performs the following actions:

  • check for any incoming packets, decode and process
  • check for ping timeout and send ping packet if needed
  • check for timed out pending packets and resend or expire

The Run function can encounter several kinds of errors while peforming its process. If nothing goes wrong it will return UMQTT_ERR_OK. If something goes wrong, it will return the most recent error code, even if multiple errors are encountered. For this reason, the caller cannot conclusively know the cause of a problem based on error code. Instead, the presence of a non-OK return value means that something has gone wrong and the caller should probably initiate a recovery procedure. Even when errors are encountered, the Run function attempts to carry out all required actions and does not automatically disconnect or change internal state. The following error codes can be returned:

Code Reason
UMQTT_ERR_OK Run() did not encounter any problem
UMQTT_ERR_PARM detected an error in a function parameter
UMQTT_ERR_BUFSIZE memory allocation failed
UMQTT_ERR_NETWORK error reading or writing the network
UMQTT_ERR_TIMEOUT a pending packet has timed out

In the case of UMQTT_ERR_TIMEOUT, it means either that no CONNACK was received in response to a Connect attempt, or that one of the other pending packet types has completely expired all of its retry attempts. In any case this probably indicates something has gone wrong with the connection to the MQTT broker.