MQTT Client API

MQTT Client API provides sequential API built on top of MQTT Client.

MQTT API application example code
  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, NULL otherwise

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_close(lwcell_mqtt_client_api_p client)

Close MQTT connection.

Parameters

client[in] MQTT API client handle

Returns

lwcellOK on success, member of lwcellr_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

lwcellOK on success, member of lwcellr_t otherwise

lwcellr_t lwcell_mqtt_client_api_unsubscribe(lwcell_mqtt_client_api_p client, const char *topic)

Unsubscribe from topic.

Parameters
  • client[in] MQTT API client handle

  • topic[in] Topic to unsubscribe from

Returns

lwcellOK on success, member of lwcellr_t otherwise

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 1 for retain flag, 0 otherwise

Returns

lwcellOK on success, member of lwcellr_t otherwise

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

1 on success, 0 otherwise

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.

Public Members

char *topic

Topic data

size_t topic_len

Topic length

uint8_t *payload

Payload data

size_t payload_len

Payload length

lwcell_mqtt_qos_t qos

Quality of service

uint8_t retain

Retain status of the packet