How to write a C MQTT client using Mosquitto

Introduction

How to write a C MQTT client using Mosquitto The 2018 version, based upon this excellent post by Kevin Boone:

Writing an MQTT client C for ActiveMQ from the ground up

The article above is a good and easy starting point, but it hasn’t been updated for 2 years so when you run it with the latest version of Mosquitto, it doesn’t work – and it’s a bit hacky (using “sleep” to avoid a concurrency problem).

So I analyzed the latest mosquitto_pub code from mosquitto repository itself to see how it’s working, and this article is the result.

What’s changed

  • There’s a queue inside mosquitto, `mosquitto_loop` must be called for it to be processed. Alternatively, you can also use the `mosquitto_loop_start` and `mosquitto_loop_stop`
  • I added asynchronous (callback) processing to wait for calls to complete, instead of the ole’ sleep function
  • It’s 2018! Everyone is adopting HTTPS. Accordingly, your MQTT traffic shouldn’t be left bare for all to see! Let’s use TLS to encrypt the traffic

The code

How to use callback

I want to publish just once message, so my flow is the following

  • On connect complete -> publish a message
  • On publish complete -> start to disconnect
  • On disconnect complete -> exit the loop and return control to the main thread. If you don’t wait for this, data may not even get sent!

To do this, I set up 3 “hooks” (callback function), like this

mosquitto_connect_callback_set(mosq, my_connect_callback);

mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);

mosquitto_publish_callback_set(mosq, my_publish_callback);
And then write the callback functions to execute my flow
void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
{
    int rc = MOSQ_ERR_SUCCESS;
    if(!result){
        printf("Sending message...\n");
        rc = mosquitto_publish(mosq, &mid_sent, MQTT_TOPIC, strlen(text), text, qos, retain);
        if(rc){
            switch(rc){
                case MOSQ_ERR_INVAL:
                    fprintf(stderr, "Error: Invalid input. Does your topic contain '+' or '#'?\n");
                    break;
                case MOSQ_ERR_NOMEM:
                    fprintf(stderr, "Error: Out of memory when trying to publish message.\n");
                    break;
                case MOSQ_ERR_NO_CONN:
                    fprintf(stderr, "Error: Client not connected when trying to publish.\n");
                    break;
                case MOSQ_ERR_PROTOCOL:
                    fprintf(stderr, "Error: Protocol error when communicating with broker.\n");
                    break;
                case MOSQ_ERR_PAYLOAD_SIZE:
                    fprintf(stderr, "Error: Message payload is too large.\n");
                    break;
            }
            mosquitto_disconnect(mosq);
        }
    } else {
        if(result){
            fprintf(stderr, "%s\n", mosquitto_connack_string(result));
        }
    }
}

void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
{
    printf("Disconnected!\n");
    connected = false;
}

void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
    printf("Published!\n");
    if(disconnect_sent == false){
        mosquitto_disconnect(mosq);
        disconnect_sent = true;
    }
}

How to process the queue with mosquitto_loop

In the main trunk of your code, do this

int rc;
do {
//network동작 끝나기 전에 모스키토 동작을 막기위해 잠깐 딜레이가 필요
  rc = mosquitto_loop(mosq, -1, 1);
} while (rc == MOSQ_ERR_SUCCESS && connected);

How to add TLS to the connection process

Before connecting, set TLS options with mosquitto_tls_set

mosquitto_username_pw_set(mosq, MQTT_USERNAME, MQTT_PASSWORD);
mosquitto_tls_set(mosq, "ca-cert.pem", NULL, NULL, NULL, NULL);
int ret = mosquitto_connect(mosq, MQTT_HOSTNAME, MQTT_PORT, 0);

Complete publish – subscribe sample

Available at https://github.com/thanhphu/mosquitto-sample. Happy cloning!

 

Facebook is now using MQTT

Recently I discovered Facebook is now using MQTT, the IoT protocol in its Messenger and Instagram app in an effort to lower battery usage.

From IBM (https://www.ibm.com/developerworks/community/blogs/mobileblog/entry/why_facebook_is_using_mqtt_on_mobile?lang=en)

Why Facebook is using MQTT on mobile

We can all relate to the concept of protocols, sensors and meters that are used to measure and analyze data. But what does Facebook have to do with that? If you are curious, keep reading this blog post to learn more how Facebook took a huge advantage by using Message Queue Telemetry Transport (MQTT).

image

 

A little history on MQTT

Back in time when Roy Fielding came out with his dissertation introducing the Representational State Transfer (REST) concept, people paid attention mainly because (a) it showed a different and simpler way of having websites, databases and other systems interact and (b) it came from one of the HTTP specification authors.
In 1999, Andy Stanford-Clark of IBM collaborated with Arlen Nipper of Eurotech to create a specification for a new messaging protocol, MQTT. Being dissatisfied with the current technologies, both were working on projects to help get remote data onto disparate devices. They were seeking to leverage communications among devices using reduced network bandwidth and providing assured message delivery in a very constrained environment with (a) high latency, (b) devices that were limited in capacity and power and (c) expensive and even unreliable networks. Think of it as a messaging protocol to be used for sensors, meters, actuators and so on. MQTT is all about machine to machine, or M2M, since it is a specification to cover device communications.

That said, both Roy Fielding and Andy and Arlen were searching for something simpler than what was out there. And don’t get me wrong—I am not comparing REST and MQTT as specifications or by their applicability; I just mean to highlight ideas that made communications simpler.

image

MQTT and the Internet of Things

MQTT, specifically, was a great fit for the new buzzword Internet of Things, which brings all sorts of devices onto the same network. For example let’s think of the hundreds of sensors inside a car, or as part of oil and gas plant, or even temperature meters, satellites and so on—all of them collecting and pushing data outside. Using MQTT, these devices (or sensors, if you prefer) can now be smart enough to share their data in the network, making it possible to have smart systems taking actions based on the data shared by these constrained devices.

A nice case study on this is shown by Red Funnel, a UK Ferry Service that tweets its passengers about their ferry’s arrival and departure based on information gathered from sensors and processed by data analytics systems.

With the popularity of smartphones, a new applicability was envisioned for these sorts of devices. MQTT.org presents a list of articles covering MQTT on the Android platform.

MQTT for Facebook’s messaging app

An amazing new MQTT use case came out in 2012, when the Facebook software engineer Lucy Zhang announced through the Facebook blogsome details of the new Facebook Messenger app that was available for smartphones, including both Android and iOS devices.

Lucy said Facebook had to rebuild a new messaging mechanism for their app, this time using MQTT to have assured and faster message delivery. Not only that, but as for any smartphone app, bandwidth usage and battery life are real concerns that had to be overcome as they started to use MQTT as their messaging protocol.

Another highlight of the Facebook Messenger app was the possibility to have individual chat sessions between two people or a group chat, thanks to the publisher-subscriber nature of MQTT.
image

Using MQTT, Facebook brought to the game a fast and reliable messenger application—small and lightweight, a battery and cost saver—that would function well even with the varying Internet connections available across the world.