MQTT Client¶
MQTT client v3.1.1 implementation, based on callback (non-netconn) connection API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /*
* 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 "lwesp/apps/lwesp_mqtt_client.h"
#include "lwesp/lwesp.h"
#include "lwesp/lwesp_timeout.h"
#include "mqtt_client.h"
/**
* \brief MQTT client structure
*/
static lwesp_mqtt_client_p
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
*/
static const lwesp_mqtt_client_info_t
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(lwesp_mqtt_client_p client, lwesp_mqtt_evt_t* evt);
static void example_do_connect(lwesp_mqtt_client_p client);
static uint32_t retries = 0;
/**
* \brief Custom callback function for ESP events
*/
static lwespr_t
mqtt_lwesp_cb(lwesp_evt_t* evt) {
switch (lwesp_evt_get_type(evt)) {
#if LWESP_CFG_MODE_STATION
case LWESP_EVT_WIFI_GOT_IP: {
example_do_connect(mqtt_client); /* Start connection after we have a connection to network client */
break;
}
#endif /* LWESP_CFG_MODE_STATION */
default:
break;
}
return lwespOK;
}
/**
* \brief MQTT client thread
* \param[in] arg: User argument
*/
void
mqtt_client_thread(void const* arg) {
lwesp_mac_t mac;
lwesp_evt_register(mqtt_lwesp_cb); /* Register new callback for general events from ESP stack */
/* Get station MAC to format client ID */
if (lwesp_sta_getmac(&mac, NULL, NULL, 1) == lwespOK) {
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 = lwesp_mqtt_client_new(256, 128);/* Create new MQTT client */
if (lwesp_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) {
lwesp_delay(1000);
}
}
/**
* \brief Timeout callback for MQTT events
* \param[in] arg: User argument
*/
void
mqtt_timeout_cb(void* arg) {
static uint32_t num = 10;
lwesp_mqtt_client_p client = arg;
lwespr_t res;
static char tx_data[20];
if (lwesp_mqtt_client_is_connected(client)) {
sprintf(tx_data, "R: %u, N: %u", (unsigned)retries, (unsigned)num);
if ((res = lwesp_mqtt_client_publish(client, "esp8266_mqtt_topic", tx_data, LWESP_U16(strlen(tx_data)), LWESP_MQTT_QOS_EXACTLY_ONCE, 0, (void*)num)) == lwespOK) {
printf("Publishing %d...\r\n", (int)num);
num++;
} else {
printf("Cannot publish...: %d\r\n", (int)res);
}
}
lwesp_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(lwesp_mqtt_client_p client, lwesp_mqtt_evt_t* evt) {
switch (lwesp_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 LWESP_MQTT_EVT_CONNECT: { /* MQTT connect event occurred */
lwesp_mqtt_conn_status_t status = lwesp_mqtt_client_evt_connect_get_status(client, evt);
if (status == LWESP_MQTT_CONN_STATUS_ACCEPTED) {
printf("MQTT accepted!\r\n");
/*
* Once we are accepted by server,
* it is time to subscribe to different topics
* We will subscrive to "mqtt_lwesp_example_topic" topic,
* and will also set the same name as subscribe argument for callback later
*/
lwesp_mqtt_client_subscribe(client, "esp8266_mqtt_topic", LWESP_MQTT_QOS_EXACTLY_ONCE, "esp8266_mqtt_topic");
/* Start timeout timer after 5000ms and call mqtt_timeout_cb function */
lwesp_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
*/
case LWESP_MQTT_EVT_SUBSCRIBE: {
const char* arg = lwesp_mqtt_client_evt_subscribe_get_argument(client, evt); /* Get user argument */
lwespr_t res = lwesp_mqtt_client_evt_subscribe_get_result(client, evt); /* Get result of subscribe event */
if (res == lwespOK) {
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
*/
lwesp_mqtt_client_publish(client, "esp8266_mqtt_topic", "test_data", 9, LWESP_MQTT_QOS_AT_MOST_ONCE, 0, (void*)1);
}
}
break;
}
/* Message published event occurred */
case LWESP_MQTT_EVT_PUBLISH: {
uint32_t val = (uint32_t)lwesp_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
*/
case LWESP_MQTT_EVT_PUBLISH_RECV: {
const char* topic = lwesp_mqtt_client_evt_publish_recv_get_topic(client, evt);
size_t topic_len = lwesp_mqtt_client_evt_publish_recv_get_topic_len(client, evt);
const uint8_t* payload = lwesp_mqtt_client_evt_publish_recv_get_payload(client, evt);
size_t payload_len = lwesp_mqtt_client_evt_publish_recv_get_payload_len(client, evt);
LWESP_UNUSED(payload);
LWESP_UNUSED(payload_len);
LWESP_UNUSED(topic);
LWESP_UNUSED(topic_len);
break;
}
/* Client is fully disconnected from MQTT server */
case LWESP_MQTT_EVT_DISCONNECT: {
printf("MQTT client disconnected!\r\n");
example_do_connect(client); /* Connect to server all over again */
break;
}
default:
break;
}
}
/** Make a connection to MQTT server in non-blocking mode */
static void
example_do_connect(lwesp_mqtt_client_p client) {
if (client == NULL) {
return;
}
/*
* Start a simple connection to open source
* MQTT server on mosquitto.org
*/
retries++;
lwesp_timeout_remove(mqtt_timeout_cb);
lwesp_mqtt_client_connect(mqtt_client, "test.mosquitto.org", 1883, mqtt_cb, &mqtt_client_info);
}
|
-
group
LWESP_APP_MQTT_CLIENT
MQTT client.
Typedefs
-
typedef struct lwesp_mqtt_client *
lwesp_mqtt_client_p
¶ Pointer to lwesp_mqtt_client_t structure.
-
typedef void (*
lwesp_mqtt_evt_fn
)(lwesp_mqtt_client_p client, lwesp_mqtt_evt_t *evt)¶ MQTT event callback function.
- Parameters
[in] client
: MQTT client[in] evt
: MQTT event with type and related data
Enums
-
enum
lwesp_mqtt_qos_t
¶ Quality of service enumeration.
Values:
-
enumerator
LWESP_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
-
enumerator
LWESP_MQTT_QOS_AT_LEAST_ONCE
¶ Delivery is quaranteed
at least once
, but it may be delivered multiple times with the same content
-
enumerator
LWESP_MQTT_QOS_EXACTLY_ONCE
¶ Delivery is quaranteed
exactly once
= very critical packets such as billing informations or similar
-
enumerator
-
enum
lwesp_mqtt_state_t
¶ State of MQTT client.
Values:
-
enumerator
LWESP_MQTT_CONN_DISCONNECTED
¶ Connection with server is not established
-
enumerator
LWESP_MQTT_CONN_CONNECTING
¶ Client is connecting to server
-
enumerator
LWESP_MQTT_CONN_DISCONNECTING
¶ Client connection is disconnecting from server
-
enumerator
LWESP_MQTT_CONNECTING
¶ MQTT client is connecting… CONNECT command has been sent to server
-
enumerator
LWESP_MQTT_CONNECTED
¶ MQTT is fully connected and ready to send data on topics
-
enumerator
-
enum
lwesp_mqtt_evt_type_t
¶ MQTT event types.
Values:
-
enumerator
LWESP_MQTT_EVT_CONNECT
¶ MQTT client connect event
-
enumerator
LWESP_MQTT_EVT_SUBSCRIBE
¶ MQTT client subscribed to specific topic
-
enumerator
LWESP_MQTT_EVT_UNSUBSCRIBE
¶ MQTT client unsubscribed from specific topic
-
enumerator
LWESP_MQTT_EVT_PUBLISH
¶ MQTT client publish message to server event.
- Note
When publishing packet with quality of service LWESP_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 = LWESP_MQTT_QOS_AT_MOST_ONCE
-
enumerator
LWESP_MQTT_EVT_PUBLISH_RECV
¶ MQTT client received a publish message from server
-
enumerator
LWESP_MQTT_EVT_DISCONNECT
¶ MQTT client disconnected from MQTT server
-
enumerator
LWESP_MQTT_EVT_KEEP_ALIVE
¶ MQTT keep-alive sent to server and reply received
-
enumerator
-
enum
lwesp_mqtt_conn_status_t
¶ List of possible results from MQTT server when executing connect command.
Values:
-
enumerator
LWESP_MQTT_CONN_STATUS_ACCEPTED
¶ Connection accepted and ready to use
-
enumerator
LWESP_MQTT_CONN_STATUS_REFUSED_PROTOCOL_VERSION
¶ Connection Refused, unacceptable protocol version
-
enumerator
LWESP_MQTT_CONN_STATUS_REFUSED_ID
¶ Connection refused, identifier rejected
-
enumerator
LWESP_MQTT_CONN_STATUS_REFUSED_SERVER
¶ Connection refused, server unavailable
-
enumerator
LWESP_MQTT_CONN_STATUS_REFUSED_USER_PASS
¶ Connection refused, bad user name or password
-
enumerator
LWESP_MQTT_CONN_STATUS_REFUSED_NOT_AUTHORIZED
¶ Connection refused, not authorized
-
enumerator
LWESP_MQTT_CONN_STATUS_TCP_FAILED
¶ TCP connection to server was not successful
-
enumerator
Functions
-
lwesp_mqtt_client_p
lwesp_mqtt_client_new
(size_t tx_buff_len, size_t rx_buff_len)¶ Allocate a new MQTT client structure.
- Return
Pointer to new allocated MQTT client structure or
NULL
on failure- Parameters
[in] tx_buff_len
: Length of raw data output buffer[in] rx_buff_len
: Length of raw data input buffer
-
void
lwesp_mqtt_client_delete
(lwesp_mqtt_client_p client)¶ Delete MQTT client structure.
- Note
MQTT client must be disconnected first
- Parameters
[in] client
: MQTT client
-
lwespr_t
lwesp_mqtt_client_connect
(lwesp_mqtt_client_p client, const char *host, lwesp_port_t port, lwesp_mqtt_evt_fn evt_fn, const lwesp_mqtt_client_info_t *info)¶ Connect to MQTT server.
- Note
After TCP connection is established, CONNECT packet is automatically sent to server
- Return
lwespOK on success, member of lwespr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] host
: Host address for server[in] port
: Host port number[in] evt_fn
: Callback function for all events on this MQTT client[in] info
: Information structure for connection
-
lwespr_t
lwesp_mqtt_client_disconnect
(lwesp_mqtt_client_p client)¶ Disconnect from MQTT server.
-
uint8_t
lwesp_mqtt_client_is_connected
(lwesp_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
- Return
1
on success,0
otherwise- Parameters
[in] client
: MQTT client
-
lwespr_t
lwesp_mqtt_client_subscribe
(lwesp_mqtt_client_p client, const char *topic, lwesp_mqtt_qos_t qos, void *arg)¶ Subscribe to MQTT topic.
- Return
lwespOK on success, member of lwespr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] topic
: Topic name to subscribe to[in] qos
: Quality of service. This parameter can be a value of lwesp_mqtt_qos_t[in] arg
: User custom argument used in callback
-
lwespr_t
lwesp_mqtt_client_unsubscribe
(lwesp_mqtt_client_p client, const char *topic, void *arg)¶ Unsubscribe from MQTT topic.
-
lwespr_t
lwesp_mqtt_client_publish
(lwesp_mqtt_client_p client, const char *topic, const void *payload, uint16_t len, lwesp_mqtt_qos_t qos, uint8_t retain, void *arg)¶ Publish a new message on specific topic.
- Return
lwespOK on success, member of lwespr_t enumeration otherwise
- Parameters
[in] client
: MQTT client[in] topic
: Topic to send message to[in] payload
: Message data[in] payload_len
: Length of payload data[in] qos
: Quality of service. This parameter can be a value of lwesp_mqtt_qos_t enumeration[in] retain
: Retian parameter value[in] arg
: User custom argument used in callback
-
void *
lwesp_mqtt_client_get_arg
(lwesp_mqtt_client_p client)¶ Get user argument on client.
- Return
User argument
- Parameters
[in] client
: MQTT client handle
-
void
lwesp_mqtt_client_set_arg
(lwesp_mqtt_client_p client, void *arg)¶ Set user argument on client.
- Parameters
[in] client
: MQTT client handle[in] arg
: User argument
-
struct
lwesp_mqtt_client_info_t
¶ - #include <lwesp_mqtt_client.h>
MQTT client information structure.
Public Members
-
const char *
id
¶ Client unique identifier. It is required and must be set by user
-
const char *
user
¶ Authentication username. Set to
NULL
if not required
-
const char *
pass
¶ Authentication password, set to
NULL
if not required
-
uint16_t
keep_alive
¶ Keep-alive parameter in units of seconds. When set to
0
, functionality is disabled (not recommended)
-
const char *
will_topic
¶ Will topic
-
const char *
will_message
¶ Will message
-
lwesp_mqtt_qos_t
will_qos
¶ Will topic quality of service
-
const char *
-
struct
lwesp_mqtt_request_t
¶ - #include <lwesp_mqtt_client.h>
MQTT request object.
Public Members
-
uint8_t
status
¶ Entry status flag for in use or pending bit
-
uint16_t
packet_id
¶ Packet ID generated by client on publish
-
void *
arg
¶ User defined argument
-
uint32_t
expected_sent_len
¶ Number of total bytes which must be sent on connection before we can say “packet was sent”.
-
uint32_t
timeout_start_time
¶ Timeout start time in units of milliseconds
-
uint8_t
-
struct
lwesp_mqtt_evt_t
¶ - #include <lwesp_mqtt_client.h>
MQTT event structure for callback function.
Public Members
-
lwesp_mqtt_evt_type_t
type
¶ Event type
-
lwesp_mqtt_conn_status_t
status
¶ Connection status with MQTT
-
struct lwesp_mqtt_evt_t::[anonymous]::[anonymous]
connect
¶ Event for connecting to server
-
uint8_t
is_accepted
¶ Status if client was accepted to MQTT prior disconnect event
-
struct lwesp_mqtt_evt_t::[anonymous]::[anonymous]
disconnect
¶ Event for disconnecting from server
-
void *
arg
¶ User argument for callback function
-
struct lwesp_mqtt_evt_t::[anonymous]::[anonymous]
sub_unsub_scribed
¶ Event for (un)subscribe to/from topics
-
struct lwesp_mqtt_evt_t::[anonymous]::[anonymous]
publish
¶ Published event
-
const uint8_t *
topic
¶ Pointer to topic identifier
-
size_t
topic_len
¶ Length of topic
-
const void *
payload
¶ Topic payload
-
size_t
payload_len
¶ Length of topic payload
-
uint8_t
dup
¶ Duplicate flag if message was sent again
-
lwesp_mqtt_qos_t
qos
¶ Received packet quality of service
-
struct lwesp_mqtt_evt_t::[anonymous]::[anonymous]
publish_recv
¶ Publish received event
-
union lwesp_mqtt_evt_t::[anonymous]
evt
¶ Event data parameters
-
lwesp_mqtt_evt_type_t
-
typedef struct lwesp_mqtt_client *
-
group
LWESP_APP_MQTT_CLIENT_EVT
Event helper functions.
Connect event
- Note
Use these functions on LWESP_MQTT_EVT_CONNECT event
-
lwesp_mqtt_client_evt_connect_get_status
(client, evt)¶ Get connection status.
- Return
Connection status. Member of lwesp_mqtt_conn_status_t
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Disconnect event
- Note
Use these functions on LWESP_MQTT_EVT_DISCONNECT event
-
lwesp_mqtt_client_evt_disconnect_is_accepted
(client, evt)¶ Check if MQTT client was accepted by server when disconnect event occurred.
- Return
1
on success,0
otherwise- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Subscribe/unsubscribe event
- Note
Use these functions on LWESP_MQTT_EVT_SUBSCRIBE or LWESP_MQTT_EVT_UNSUBSCRIBE events
-
lwesp_mqtt_client_evt_subscribe_get_argument
(client, evt)¶ Get user argument used on lwesp_mqtt_client_subscribe.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_subscribe_get_result
(client, evt)¶ Get result of subscribe event.
-
lwesp_mqtt_client_evt_unsubscribe_get_argument
(client, evt)¶ Get user argument used on lwesp_mqtt_client_unsubscribe.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Publish receive event
- Note
Use these functions on LWESP_MQTT_EVT_PUBLISH_RECV event
-
lwesp_mqtt_client_evt_publish_recv_get_topic
(client, evt)¶ Get topic from received publish packet.
- Return
Topic name
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_publish_recv_get_topic_len
(client, evt)¶ Get topic length from received publish packet.
- Return
Topic length
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_publish_recv_get_payload
(client, evt)¶ Get payload from received publish packet.
- Return
Packet payload
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_publish_recv_get_payload_len
(client, evt)¶ Get payload length from received publish packet.
- Return
Payload length
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_publish_recv_is_duplicate
(client, evt)¶ Check if packet is duplicated.
- Return
1
if duplicated,0
otherwise- Parameters
[in] client
: MQTT client[in] evt
: Event handle
-
lwesp_mqtt_client_evt_publish_recv_get_qos
(client, evt)¶ Get received quality of service.
- Return
Member of lwesp_mqtt_qos_t enumeration
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Publish event
- Note
Use these functions on LWESP_MQTT_EVT_PUBLISH event
-
lwesp_mqtt_client_evt_publish_get_argument
(client, evt)¶ Get user argument used on lwesp_mqtt_client_publish.
- Return
User argument
- Parameters
[in] client
: MQTT client[in] evt
: Event handle
Defines
-
lwesp_mqtt_client_evt_get_type
(client, evt)¶ Get MQTT event type.
- Return
MQTT Event type, value of lwesp_mqtt_evt_type_t enumeration
- Parameters
[in] client
: MQTT client[in] evt
: Event handle