MQTT Client API
MQTT Client API provides sequential API built on top of MQTT Client.
1/*
2 * MQTT client API example with GSM device.
3 *
4 * Once device is connected to network,
5 * it will try to connect to mosquitto test server and start the MQTT.
6 *
7 * If successfully connected, it will publish data to "lwcell_mqtt_topic" topic every x seconds.
8 *
9 * To check if data are sent, you can use mqtt-spy PC software to inspect
10 * test.mosquitto.org server and subscribe to publishing topic
11 */
12
13#include "mqtt_client_api.h"
14#include "lwcell/apps/lwcell_mqtt_client_api.h"
15#include "lwcell/lwcell.h"
16#include "lwcell/lwcell_mem.h"
17#include "lwcell/lwcell_network_api.h"
18
19/**
20 * \brief Connection information for MQTT CONNECT packet
21 */
22static const lwcell_mqtt_client_info_t mqtt_client_info = {
23 .keep_alive = 10,
24
25 /* Server login data */
26 .user = "8a215f70-a644-11e8-ac49-e932ed599553",
27 .pass = "26aa943f702e5e780f015cd048a91e8fb54cca28",
28
29 /* Device identifier address */
30 .id = "2c3573a0-0176-11e9-a056-c5cffe7f75f9",
31};
32
33/**
34 * \brief Memory for temporary topic
35 */
36static char mqtt_topic_str[256];
37
38/**
39 * \brief Generate random number and write it to string
40 * \param[out] str: Output string with new number
41 */
42static void
43generate_random(char* str) {
44 static uint32_t random_beg = 0x8916;
45 random_beg = random_beg * 0x00123455 + 0x85654321;
46 sprintf(str, "%u", (unsigned)((random_beg >> 8) & 0xFFFF));
47}
48
49/**
50 * \brief MQTT client API thread
51 */
52void
53lwcell_mqtt_client_api_thread(void const* arg) {
54 lwcell_mqtt_client_api_p client;
55 lwcell_mqtt_conn_status_t conn_status;
56 lwcell_mqtt_client_api_buf_p buf;
57 lwcellr_t res;
58 char random_str[10];
59
60 LWCELL_UNUSED(arg);
61
62 /* Request network attach */
63 while (lwcell_network_request_attach() != lwcellOK) {
64 lwcell_delay(1000);
65 }
66
67 /* Create new MQTT API */
68 if ((client = lwcell_mqtt_client_api_new(256, 128)) == NULL) {
69 goto terminate;
70 }
71
72 while (1) {
73 /* Make a connection */
74 printf("Joining MQTT server\r\n");
75
76 /* Try to join */
77 conn_status = lwcell_mqtt_client_api_connect(client, "mqtt.mydevices.com", 1883, &mqtt_client_info);
78 if (conn_status == LWCELL_MQTT_CONN_STATUS_ACCEPTED) {
79 printf("Connected and accepted!\r\n");
80 printf("Client is ready to subscribe and publish to new messages\r\n");
81 } else {
82 printf("Connect API response: %d\r\n", (int)conn_status);
83 lwcell_delay(5000);
84 continue;
85 }
86
87 /* Subscribe to topics */
88 sprintf(mqtt_topic_str, "v1/%s/things/%s/cmd/#", mqtt_client_info.user, mqtt_client_info.id);
89 if (lwcell_mqtt_client_api_subscribe(client, mqtt_topic_str, LWCELL_MQTT_QOS_AT_LEAST_ONCE) == lwcellOK) {
90 printf("Subscribed to topic\r\n");
91 } else {
92 printf("Problem subscribing to topic!\r\n");
93 }
94
95 while (1) {
96 /* Receive MQTT packet with timeout */
97 if ((res = lwcell_mqtt_client_api_receive(client, &buf, 5000)) == lwcellOK) {
98 if (buf != NULL) {
99 printf("Publish received!\r\n");
100 printf("Topic: %s, payload: %s\r\n", buf->topic, buf->payload);
101 lwcell_mqtt_client_api_buf_free(buf);
102 buf = NULL;
103 }
104 } else if (res == lwcellCLOSED) {
105 printf("MQTT connection closed!\r\n");
106 break;
107 } else if (res == lwcellTIMEOUT) {
108 printf("Timeout on MQTT receive function. Manually publishing.\r\n");
109
110 /* Publish data on channel 1 */
111 generate_random(random_str);
112 sprintf(mqtt_topic_str, "v1/%s/things/%s/data/1", mqtt_client_info.user, mqtt_client_info.id);
113 lwcell_mqtt_client_api_publish(client, mqtt_topic_str, random_str, strlen(random_str),
114 LWCELL_MQTT_QOS_AT_LEAST_ONCE, 0);
115 }
116 }
117 goto terminate;
118 }
119
120terminate:
121 lwcell_mqtt_client_api_delete(client);
122 lwcell_network_request_detach();
123 printf("MQTT client thread terminate\r\n");
124 lwcell_sys_thread_terminate(NULL);
125}
- group LWCELL_APP_MQTT_CLIENT_API
Sequential, single thread MQTT client API.
Typedefs
-
typedef struct lwcell_mqtt_client_api_buf *lwcell_mqtt_client_api_buf_p
Pointer to lwcell_mqtt_client_api_buf_t structure.
Functions
-
lwcell_mqtt_client_api_p lwcell_mqtt_client_api_new(size_t tx_buff_len, size_t rx_buff_len)
Create new MQTT client API.
- Parameters
tx_buff_len – [in] Maximal TX buffer for maximal packet length
rx_buff_len – [in] Maximal RX buffer
- Returns
Client handle on success,
NULLotherwise
-
void lwcell_mqtt_client_api_delete(lwcell_mqtt_client_api_p client)
Delete client from memory.
- Parameters
client – [in] MQTT API client handle
-
lwcell_mqtt_conn_status_t lwcell_mqtt_client_api_connect(lwcell_mqtt_client_api_p client, const char *host, lwcell_port_t port, const lwcell_mqtt_client_info_t *info)
Connect to MQTT broker.
- Parameters
client – [in] MQTT API client handle
host – [in] TCP host
port – [in] TCP port
info – [in] MQTT client info
- Returns
LWCELL_MQTT_CONN_STATUS_ACCEPTED on success, member of lwcell_mqtt_conn_status_t otherwise
-
lwcellr_t lwcell_mqtt_client_api_subscribe(lwcell_mqtt_client_api_p client, const char *topic, lwcell_mqtt_qos_t qos)
Subscribe to topic.
- Parameters
client – [in] MQTT API client handle
topic – [in] Topic to subscribe on
qos – [in] Quality of service. This parameter can be a value of lwcell_mqtt_qos_t
- Returns
-
lwcellr_t lwcell_mqtt_client_api_unsubscribe(lwcell_mqtt_client_api_p client, const char *topic)
Unsubscribe from topic.
-
lwcellr_t lwcell_mqtt_client_api_publish(lwcell_mqtt_client_api_p client, const char *topic, const void *data, size_t btw, lwcell_mqtt_qos_t qos, uint8_t retain)
Publish new packet to MQTT network.
- Parameters
client – [in] MQTT API client handle
topic – [in] Topic to publish on
data – [in] Data to send
btw – [in] Number of bytes to send for data parameter
qos – [in] Quality of service. This parameter can be a value of lwcell_mqtt_qos_t
retain – [in] Set to
1for retain flag,0otherwise
- Returns
-
uint8_t lwcell_mqtt_client_api_is_connected(lwcell_mqtt_client_api_p client)
Check if client MQTT connection is active.
- Parameters
client – [in] MQTT API client handle
- Returns
1on success,0otherwise
-
lwcellr_t lwcell_mqtt_client_api_receive(lwcell_mqtt_client_api_p client, lwcell_mqtt_client_api_buf_p *p, uint32_t timeout)
Receive next packet in specific timeout time.
Note
This function can be called from separate thread than the rest of API function, which allows you to handle receive data separated with custom timeout
- Parameters
client – [in] MQTT API client handle
p – [in] Pointer to output buffer
timeout – [in] Maximal time to wait before function returns timeout
- Returns
lwcellOK on success, lwcellCLOSED if MQTT is closed, lwcellTIMEOUT on timeout
-
void lwcell_mqtt_client_api_buf_free(lwcell_mqtt_client_api_buf_p p)
Free buffer memory after usage.
- Parameters
p – [in] Buffer to free
-
struct lwcell_mqtt_client_api_buf_t
- #include <lwcell_mqtt_client_api.h>
MQTT API RX buffer.
-
typedef struct lwcell_mqtt_client_api_buf *lwcell_mqtt_client_api_buf_p