uMQTT
MQTT client library for microcontrollers
|
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 |
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 |
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 |
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.
These functions are not thread safe. You musn't call them from different threads unless you provide your own resource lock wrapper(s).
typedef void* umqtt_Handle_t |
umqtt instance handle, to be passed to all functions.
Obtained from umqtt_New().
typedef void(* ConnackCb_t) (umqtt_Handle_t h, void *pUser, bool sessionPresent, uint8_t retCode) |
Callback function for CONNACK connection acknowledgment.
h | umqtt instance handle |
pUser | client's optional user data pointer |
sessionPresent | MQTT session present flag |
retCode | return 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.
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.
h | umqtt instance handle |
pUser | client's optional user data pointer |
dup | MQTT dup header flag was set in the packet |
retain | MQTT retain flag was set in the packet |
qos | QoS level for the packet |
pTopic | pointer to topic string |
topicLen | number of bytes in the topic string |
pMsg | pointer to topic message |
msgLen | number 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.
typedef void(* PubackCb_t) (umqtt_Handle_t h, void *pUser, uint16_t pktId) |
Callback function for Puback packets.
h | umqtt instance handle |
pUser | client's optional user data pointer |
pktId | packet 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.
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.
h | umqtt instance handle |
pUser | client's optional user data pointer |
retCodes | array of return codes, one for each subscribe topic |
retCount | number of return codes in the retCodes array |
pktId | packet 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.
typedef void(* UnsubackCb_t) (umqtt_Handle_t h, void *pUser, uint16_t pktId) |
Callback function for Unsuback packets.
h | umqtt instance handle |
pUser | client's optional user data pointer |
pktId | packet 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.
typedef void(* PingrespCb_t) (umqtt_Handle_t h, void *pUser) |
Callback function for PINGRESP packets.
h | umqtt instance handle |
pUser | client'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.
typedef void*(* malloc_t) (size_t size) |
Memory allocation function provided by application.
size | the number of bytes to be allocated |
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.
typedef void(* free_t) (void *ptr) |
Memory free function provided by application.
ptr | pointer 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.
typedef int(* netReadPacket_t) (void *hNet, uint8_t **ppBuf) |
Read a packet from the network.
hNet | is the network instance handle (not umqtt instance handle) |
ppBuf | pointer to a pointer to the received packet data |
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.
typedef int(* netWritePacket_t) (void *hNet, const uint8_t *pBuf, uint32_t len, bool isMore) |
Write a packet to the network.
hNet | is the network instance handle (not umqtt instance handle) |
pBuf | pointer to the buffer holding the packet data |
len | count of byte in the buffer |
isMore | flag to indicate that there is additional data to send |
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.
enum umqtt_Error_t |
Return codes for umqtt functions.
const char* umqtt_GetErrorString | ( | umqtt_Error_t | err | ) |
Get string representing an error code.
err | is the error code to decode |
This function is useful for debugging. It can be used to print a meaningful string for an error code.
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.
h | umqtt instance handle from umqtt_New() |
cleanSession | true to establish new session, false to resume old session |
willRetain | true if published will message should be retained |
willQos | the QoS level to be used for the will message (if used) |
keepAlive | the keep alive interval in seconds |
clientId | the name of the MQTT client to use for the session |
willTopic | optional topic name for will, or NULL |
willPayload | optional will payload, or NULL |
willPayloadLen | length of the will payload message |
username | optional authentication user name, or NULL |
password | optional authentication password, or NULL |
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_Error_t umqtt_Disconnect | ( | umqtt_Handle_t | h | ) |
Disconnect MQTT protocol.
h | umqtt instance handle from umqtt_New() |
This function attempts to send a MQTT protocol disconnect packet, frees up all pending packets and marks the instance as disconnected.
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.
h | umqtt instance handle from umqtt_New() |
topic | topic name to publish |
payload | payload or message for the topic (can be NULL) |
payloadLen | number of bytes in the payload |
qos | QoS (quality of service) level for this topic |
shouldRetain | true if MQTT broker should retain this topic |
pId | pointer to storage for assigned packet ID (optional) |
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.
Example
umqtt_Error_t umqtt_Subscribe | ( | umqtt_Handle_t | h, |
uint32_t | count, | ||
char * | topics[], | ||
uint8_t | qoss[], | ||
uint16_t * | pId | ||
) |
Subscribe to topics.
h | umqtt instance handle from umqtt_New() |
count | number of topics in the list of topics to subscribe |
topics | array of topic names to subscribe |
qoss | array of QoS values to use for subscribed topics |
pId | pointer to storage for assigned packet ID (optional) |
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_Error_t umqtt_Unsubscribe | ( | umqtt_Handle_t | h, |
uint32_t | count, | ||
const char * | topics[], | ||
uint16_t * | pId | ||
) |
Unsubscribe from topics.
h | umqtt instance handle from umqtt_New() |
count | count of topics in topic list |
topics | array of topic names to unsubscribe |
pId | pointer to storage for assigned packet ID (optional) |
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_Error_t umqtt_PingReq | ( | umqtt_Handle_t | h | ) |
Send a Ping (keep-alive) to the MQTT broker.
h | umqtt instance handle from umqtt_New() |
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_Error_t umqtt_DecodePacket | ( | umqtt_Handle_t | h, |
const uint8_t * | pIncoming, | ||
uint32_t | incomingLen | ||
) |
Decode incoming MQTT packet.
h | umqtt instance handle from umqtt_New() |
pIncoming | buffer holding incoming UMQTT packet |
incomingLen | number of bytes in the incoming buffer |
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_Error_t umqtt_GetConnectedStatus | ( | umqtt_Handle_t | h | ) |
Get the status of the connection.
h | umqtt 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_Handle_t umqtt_New | ( | umqtt_TransportConfig_t * | pTransport, |
umqtt_Callbacks_t * | pCallbacks, | ||
void * | pUser | ||
) |
Create and initialize a umqtt client instance.
pTransport | structure defining the MQTT transport interface |
pCallbacks | structure holding the callback functions |
pUser | optional caller defined data pointer that will be passed in callbacks |
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 umqtt_Delete | ( | umqtt_Handle_t | h | ) |
Clean up and free umqtt client instance.
h | umqtt 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_Error_t umqtt_Run | ( | umqtt_Handle_t | h, |
uint32_t | msTicks | ||
) |
Main loop processing for the umqtt client instance.
h | umqtt instance handle from umqtt_New() |
msTicks | milliseconds tick count |
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:
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.