ESP-AT Lib  Version v0.3
Advanced AT parser for ESP8266 WiFi module
MQTT client

MQTT client. More...

Modules

 Event helper functions
 Event helper functions.
 

Data Structures

struct  esp_mqtt_client_info_t
 MQTT client information structure. More...
 
struct  esp_mqtt_request_t
 MQTT request object. More...
 
struct  esp_mqtt_evt_t
 MQTT event structure for callback function. More...
 

Macros

#define ESP_CFG_MQTT_MAX_REQUESTS   8
 Maximal number of open connections at a time. More...
 

Typedefs

typedef struct esp_mqtt_client * esp_mqtt_client_p
 Pointer to esp_mqtt_client_t structure.
 
typedef void(* esp_mqtt_evt_fn) (esp_mqtt_client_p client, esp_mqtt_evt_t *evt)
 MQTT event callback function. More...
 

Enumerations

enum  esp_mqtt_qos_t { ESP_MQTT_QOS_AT_MOST_ONCE = 0x00, ESP_MQTT_QOS_AT_LEAST_ONCE = 0x01, ESP_MQTT_QOS_EXACTLY_ONCE = 0x02 }
 Quality of service enumeration. More...
 
enum  esp_mqtt_state_t {
  ESP_MQTT_CONN_DISCONNECTED = 0x00, ESP_MQTT_CONN_CONNECTING, ESP_MQTT_CONN_DISCONNECTING, ESP_MQTT_CONNECTING,
  ESP_MQTT_CONNECTED
}
 State of MQTT client. More...
 
enum  esp_mqtt_evt_type_t {
  ESP_MQTT_EVT_CONNECT, ESP_MQTT_EVT_SUBSCRIBE, ESP_MQTT_EVT_UNSUBSCRIBE, ESP_MQTT_EVT_PUBLISH,
  ESP_MQTT_EVT_PUBLISH_RECV, ESP_MQTT_EVT_DISCONNECT, ESP_MQTT_EVT_KEEP_ALIVE
}
 MQTT event types. More...
 
enum  esp_mqtt_conn_status_t {
  ESP_MQTT_CONN_STATUS_ACCEPTED = 0x00, ESP_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION = 0x01, ESP_MQTT_CONN_STATUS_REFUSED_ID = 0x02, ESP_MQTT_CONN_STATUS_REFUSED_SERVER = 0x03,
  ESP_MQTT_CONN_STATUS_REFUSED_USER_PASS = 0x04, ESP_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED = 0x05, ESP_MQTT_CONN_STATUS_TCP_FAILED = 0x100
}
 List of possible results from MQTT server when executing connect command. More...
 

Functions

esp_mqtt_client_p esp_mqtt_client_new (size_t tx_buff_len, size_t rx_buff_len)
 Allocate a new MQTT client structure. More...
 
void esp_mqtt_client_delete (esp_mqtt_client_p client)
 Delete MQTT client structure. More...
 
espr_t esp_mqtt_client_connect (esp_mqtt_client_p client, const char *host, esp_port_t port, esp_mqtt_evt_fn evt_fn, const esp_mqtt_client_info_t *info)
 Connect to MQTT server. More...
 
espr_t esp_mqtt_client_disconnect (esp_mqtt_client_p client)
 Disconnect from MQTT server. More...
 
uint8_t esp_mqtt_client_is_connected (esp_mqtt_client_p client)
 Test if client is connected to server and accepted to MQTT protocol. More...
 
espr_t esp_mqtt_client_subscribe (esp_mqtt_client_p client, const char *topic, esp_mqtt_qos_t qos, void *arg)
 Subscribe to MQTT topic. More...
 
espr_t esp_mqtt_client_unsubscribe (esp_mqtt_client_p client, const char *topic, void *arg)
 Unsubscribe from MQTT topic. More...
 
espr_t esp_mqtt_client_publish (esp_mqtt_client_p client, const char *topic, const void *payload, uint16_t len, esp_mqtt_qos_t qos, uint8_t retain, void *arg)
 Publish a new message on specific topic. More...
 
void * esp_mqtt_client_get_arg (esp_mqtt_client_p client)
 Get user argument on client. More...
 
void esp_mqtt_client_set_arg (esp_mqtt_client_p client, void *arg)
 Set user argument on client. More...
 

Detailed Description

MQTT client.

MQTT client app uses MQTT-3.1.1 protocol versions.

List of full specs is available here.

Example code
/*
* MQTT client example with ESP device.
*
* Once device is connected to network,
* it will try to connect to mosquitto test server and start the MQTT.
*
* If successfully connected, it will publish data to "esp8266_mqtt_topic" topic every x seconds.
*
* To check if data are sent, you can use mqtt-spy PC software to inspect
* test.mosquitto.org server and subscribe to publishing topic
*/
#include "esp/apps/esp_mqtt_client.h"
#include "esp/esp.h"
#include "esp/esp_timeout.h"
/*
* \brief MQTT client structure
*/
mqtt_client;
/*
* \brief Client ID is structured from ESP station MAC address
*/
static char
mqtt_client_id[13];
/*
* \brief Connection information for MQTT CONNECT packet
*/
mqtt_client_info = {
.id = mqtt_client_id, /* The only required field for connection! */
.keep_alive = 10,
// .user = "test_username",
// .pass = "test_password",
};
static void mqtt_cb(esp_mqtt_client_p client, esp_mqtt_evt_t* evt);
static void example_do_connect(esp_mqtt_client_p client);
static uint32_t retries = 0;
/*
* \brief Custom callback function for ESP events
*/
static espr_t
mqtt_esp_cb(esp_evt_t* evt) {
switch (esp_evt_get_type(evt)) {
#if ESP_CFG_MODE_STATION
example_do_connect(mqtt_client); /* Start connection after we have a connection to network client */
break;
}
#endif /* ESP_CFG_MODE_STATION */
default: break;
}
return espOK;
}
/*
* \brief MQTT client thread
* \param[in] arg: User argument
*/
void
mqtt_client_thread(void const* arg) {
esp_mac_t mac;
esp_evt_register(mqtt_esp_cb); /* Register new callback for general events from ESP stack */
/* Get station MAC to format client ID */
if (esp_sta_getmac(&mac, 0, NULL, NULL, 1) == espOK) {
snprintf(mqtt_client_id, sizeof(mqtt_client_id), "%02X%02X%02X%02X%02X%02X",
(unsigned)mac.mac[0], (unsigned)mac.mac[1], (unsigned)mac.mac[2],
(unsigned)mac.mac[3], (unsigned)mac.mac[4], (unsigned)mac.mac[5]
);
} else {
strcpy(mqtt_client_id, "unknown");
}
printf("MQTT Client ID: %s\r\n", mqtt_client_id);
/*
* Create a new client with 256 bytes of RAW TX data
* and 128 bytes of RAW incoming data
*/
mqtt_client = esp_mqtt_client_new(256, 128);/* Create new MQTT client */
if (esp_sta_is_joined()) { /* If ESP is already joined to network */
example_do_connect(mqtt_client); /* Start connection to MQTT server */
}
/* Make dummy delay of thread */
while (1) {
esp_delay(1000);
}
}
/*
* \brief Timeout callback for MQTT events
* \param[in] arg: User argument
*/
void
mqtt_timeout_cb(void* arg) {
static uint32_t num = 10;
esp_mqtt_client_p client = arg;
espr_t res;
static char tx_data[20];
sprintf(tx_data, "R: %u, N: %u", (unsigned)retries, (unsigned)num);
if ((res = esp_mqtt_client_publish(client, "esp8266_mqtt_topic", tx_data, ESP_U16(strlen(tx_data)), ESP_MQTT_QOS_EXACTLY_ONCE, 0, (void *)num)) == espOK) {
printf("Publishing %d...\r\n", (int)num);
num++;
} else {
printf("Cannot publish...: %d\r\n", (int)res);
}
}
esp_timeout_add(10000, mqtt_timeout_cb, client);
}
/*
* \brief MQTT event callback function
* \param[in] client: MQTT client where event occurred
* \param[in] evt: Event type and data
*/
static void
mqtt_cb(esp_mqtt_client_p client, esp_mqtt_evt_t* evt) {
switch (esp_mqtt_client_evt_get_type(client, evt)) {
/*
* Connect event
* Called if user successfully connected to MQTT server
* or even if connection failed for some reason
*/
case ESP_MQTT_EVT_CONNECT: { /* MQTT connect event occurred */
printf("MQTT accepted!\r\n");
/*
* Once we are accepted by server,
* it is time to subscribe to different topics
* We will subscrive to "mqtt_esp_example_topic" topic,
* and will also set the same name as subscribe argument for callback later
*/
esp_mqtt_client_subscribe(client, "esp8266_mqtt_topic", ESP_MQTT_QOS_EXACTLY_ONCE, "esp8266_mqtt_topic");
/* Start timeout timer after 5000ms and call mqtt_timeout_cb function */
esp_timeout_add(5000, mqtt_timeout_cb, client);
} else {
printf("MQTT server connection was not successful: %d\r\n", (int)status);
/* Try to connect all over again */
example_do_connect(client);
}
break;
}
/*
* Subscribe event just happened.
* Here it is time to check if it was successful or failed attempt
*/
const char* arg = esp_mqtt_client_evt_subscribe_get_argument(client, evt); /* Get user argument */
espr_t res = esp_mqtt_client_evt_subscribe_get_result(client, evt); /* Get result of subscribe event */
if (res == espOK) {
printf("Successfully subscribed to %s topic\r\n", arg);
if (!strcmp(arg, "esp8266_mqtt_topic")) { /* Check topic name we were subscribed */
/* Subscribed to "esp8266_mqtt_topic" topic */
/*
* Now publish an even on example topic
* and set QoS to minimal value which does not guarantee message delivery to received
*/
esp_mqtt_client_publish(client, "esp8266_mqtt_topic", "test_data", 9, ESP_MQTT_QOS_AT_MOST_ONCE, 0, (void *)1);
}
}
break;
}
/* Message published event occurred */
uint32_t val = (uint32_t)esp_mqtt_client_evt_publish_get_argument(client, evt); /* Get user argument, which is in fact our custom number */
printf("Publish event, user argument on message was: %d\r\n", (int)val);
break;
}
/*
* A new message was published to us
* and now it is time to read the data
*/
const char* topic = esp_mqtt_client_evt_publish_recv_get_topic(client, evt);
size_t topic_len = esp_mqtt_client_evt_publish_recv_get_topic_len(client, evt);
const uint8_t* payload = esp_mqtt_client_evt_publish_recv_get_payload(client, evt);
size_t payload_len = esp_mqtt_client_evt_publish_recv_get_payload_len(client, evt);
ESP_UNUSED(payload);
ESP_UNUSED(payload_len);
ESP_UNUSED(topic);
ESP_UNUSED(topic_len);
break;
}
/* Client is fully disconnected from MQTT server */
printf("MQTT client disconnected!\r\n");
example_do_connect(client); /* Connect to server all over again */
break;
}
default:
break;
}
}
static void
example_do_connect(esp_mqtt_client_p client) {
if (client == NULL) {
return;
}
/*
* Start a simple connection to open source
* MQTT server on mosquitto.org
*/
retries++;
esp_timeout_remove(mqtt_timeout_cb);
esp_mqtt_client_connect(mqtt_client, "test.mosquitto.org", 1883, mqtt_cb, &mqtt_client_info);
}

Macro Definition Documentation

◆ ESP_CFG_MQTT_MAX_REQUESTS

#define ESP_CFG_MQTT_MAX_REQUESTS   8

Maximal number of open connections at a time.

Note
This is default value. To change it, override value in esp_config.h configuration file

Typedef Documentation

◆ esp_mqtt_evt_fn

typedef void(* esp_mqtt_evt_fn) (esp_mqtt_client_p client, esp_mqtt_evt_t *evt)

MQTT event callback function.

Parameters
[in]clientMQTT client
[in]evtMQTT event with type and related data

Enumeration Type Documentation

◆ esp_mqtt_conn_status_t

List of possible results from MQTT server when executing connect command.

Enumerator
ESP_MQTT_CONN_STATUS_ACCEPTED 

Connection accepted and ready to use

ESP_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION 

Connection Refused, unacceptable protocol version

ESP_MQTT_CONN_STATUS_REFUSED_ID 

Connection refused, identifier rejected

ESP_MQTT_CONN_STATUS_REFUSED_SERVER 

Connection refused, server unavailable

ESP_MQTT_CONN_STATUS_REFUSED_USER_PASS 

Connection refused, bad user name or password

ESP_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED 

Connection refused, not authorized

ESP_MQTT_CONN_STATUS_TCP_FAILED 

TCP connection to server was not successful

◆ esp_mqtt_evt_type_t

MQTT event types.

Enumerator
ESP_MQTT_EVT_CONNECT 

MQTT client connect event

ESP_MQTT_EVT_SUBSCRIBE 

MQTT client subscribed to specific topic

ESP_MQTT_EVT_UNSUBSCRIBE 

MQTT client unsubscribed from specific topic

ESP_MQTT_EVT_PUBLISH 

MQTT client publish message to server event.

Note
When publishing packet with quality of service ESP_MQTT_QOS_AT_MOST_ONCE, you may not receive event, even if packet was successfully sent, thus do not rely on this event for packet with qos = ESP_MQTT_QOS_AT_MOST_ONCE
ESP_MQTT_EVT_PUBLISH_RECV 

MQTT client received a publish message from server

ESP_MQTT_EVT_DISCONNECT 

MQTT client disconnected from MQTT server

ESP_MQTT_EVT_KEEP_ALIVE 

MQTT keep-alive sent to server and reply received

◆ esp_mqtt_qos_t

Quality of service enumeration.

Enumerator
ESP_MQTT_QOS_AT_MOST_ONCE 

Delivery is not guaranteed to arrive, but can arrive up to 1 time = non-critical packets where losses are allowed

ESP_MQTT_QOS_AT_LEAST_ONCE 

Delivery is quaranteed at least once, but it may be delivered multiple times with the same content

ESP_MQTT_QOS_EXACTLY_ONCE 

Delivery is quaranteed exactly once = very critical packets such as billing informations or similar

◆ esp_mqtt_state_t

State of MQTT client.

Enumerator
ESP_MQTT_CONN_DISCONNECTED 

Connection with server is not established

ESP_MQTT_CONN_CONNECTING 

Client is connecting to server

ESP_MQTT_CONN_DISCONNECTING 

Client connection is disconnecting from server

ESP_MQTT_CONNECTING 

MQTT client is connecting... CONNECT command has been sent to server

ESP_MQTT_CONNECTED 

MQTT is fully connected and ready to send data on topics

Function Documentation

◆ esp_mqtt_client_connect()

espr_t esp_mqtt_client_connect ( esp_mqtt_client_p  client,
const char *  host,
esp_port_t  port,
esp_mqtt_evt_fn  evt_fn,
const esp_mqtt_client_info_t info 
)

Connect to MQTT server.

Note
After TCP connection is established, CONNECT packet is automatically sent to server
Parameters
[in]clientMQTT client
[in]hostHost address for server
[in]portHost port number
[in]evt_fnCallback function for all events on this MQTT client
[in]infoInformation structure for connection
Returns
espOK on success, member of espr_t enumeration otherwise

◆ esp_mqtt_client_delete()

void esp_mqtt_client_delete ( esp_mqtt_client_p  client)

Delete MQTT client structure.

Note
MQTT client must be disconnected first
Parameters
[in]clientMQTT client

◆ esp_mqtt_client_disconnect()

espr_t esp_mqtt_client_disconnect ( esp_mqtt_client_p  client)

Disconnect from MQTT server.

Parameters
[in]clientMQTT client
Returns
espOK if request sent to queue or member of espr_t otherwise

◆ esp_mqtt_client_get_arg()

void* esp_mqtt_client_get_arg ( esp_mqtt_client_p  client)

Get user argument on client.

Parameters
[in]clientMQTT client handle
Returns
User argument

◆ esp_mqtt_client_is_connected()

uint8_t esp_mqtt_client_is_connected ( esp_mqtt_client_p  client)

Test if client is connected to server and accepted to MQTT protocol.

Note
Function will return error if TCP is connected but MQTT not accepted
Parameters
[in]clientMQTT client
Returns
1 on success, 0 otherwise

◆ esp_mqtt_client_new()

esp_mqtt_client_p esp_mqtt_client_new ( size_t  tx_buff_len,
size_t  rx_buff_len 
)

Allocate a new MQTT client structure.

Parameters
[in]tx_buff_lenLength of raw data output buffer
[in]rx_buff_lenLength of raw data input buffer
Returns
Pointer to new allocated MQTT client structure or NULL on failure

◆ esp_mqtt_client_publish()

espr_t esp_mqtt_client_publish ( esp_mqtt_client_p  client,
const char *  topic,
const void *  payload,
uint16_t  payload_len,
esp_mqtt_qos_t  qos,
uint8_t  retain,
void *  arg 
)

Publish a new message on specific topic.

Parameters
[in]clientMQTT client
[in]topicTopic to send message to
[in]payloadMessage data
[in]payload_lenLength of payload data
[in]qosQuality of service. This parameter can be a value of esp_mqtt_qos_t enumeration
[in]retainRetian parameter value
[in]argUser custom argument used in callback
Returns
espOK on success, member of espr_t enumeration otherwise

◆ esp_mqtt_client_set_arg()

void esp_mqtt_client_set_arg ( esp_mqtt_client_p  client,
void *  arg 
)

Set user argument on client.

Parameters
[in]clientMQTT client handle
[in]argUser argument

◆ esp_mqtt_client_subscribe()

espr_t esp_mqtt_client_subscribe ( esp_mqtt_client_p  client,
const char *  topic,
esp_mqtt_qos_t  qos,
void *  arg 
)

Subscribe to MQTT topic.

Parameters
[in]clientMQTT client
[in]topicTopic name to subscribe to
[in]qosQuality of service. This parameter can be a value of esp_mqtt_qos_t
[in]argUser custom argument used in callback
Returns
espOK on success, member of espr_t enumeration otherwise

◆ esp_mqtt_client_unsubscribe()

espr_t esp_mqtt_client_unsubscribe ( esp_mqtt_client_p  client,
const char *  topic,
void *  arg 
)

Unsubscribe from MQTT topic.

Parameters
[in]clientMQTT client
[in]topicTopic name to unsubscribe from
[in]argUser custom argument used in callback
Returns
espOK on success, member of espr_t enumeration otherwise