HelloMQTT over TLS.

Dependencies:   MQTT

Fork of HelloMQTT by Osamu Koizumi

HelloMQTT over TLS

This program is a fork of HelloMQTT. Added TLS capability by using TLSSocket library. Tested on K64F.

This sample program connects to iot.eclipse.org:8883 by default. Verifies server identification. Subscribes a certain topic. Then publishes three messages with different QoSs, i.e. QoS0, QoS1, and QoS2.

Warning

Some brokers do not accept QoS2 and/or QoS1 message. For example, AWS IoT Message Broker doesn't accept QoS2. In such broker, this program doesn't work as is. Change QoS level.

Output from console

HelloMQTT: version is 0.70

Opening network interface...
Network interface opened successfully.

Connecting to host iot.eclipse.org:8883 ...
Connection established.

MQTT client is trying to connect the server ...
Client connected.

Client is trying to subscribe a topic "mbed-test".
Client has subscribed a topic "mbed-test".

Client publishes messages ...
Publishing message QoS 0.
QoS 0 message published.
! Message arrived: qos 0, retained 0, dup 0, packetid 6257
! Payload Hello World!  QoS 0 message from app version 0.700000

Publishing message QoS 1.
QoS 1 message published.
! Message arrived: qos 1, retained 0, dup 0, packetid 1
! Payload Hello World!  QoS 1 message from app version 0.700000

Publishing message QoS 2.
QoS 2 message published.
! Message arrived: qos 2, retained 0, dup 0, packetid 2
! Payload Hello World!  QoS 2 message from app version 0.700000

Version 0.70: finish 3 msgs

Known Issues

On K64F, when serial baud rate is changed from 9600 to 115200, program fails.

main.cpp

Committer:
Osamu Koizumi
Date:
2018-06-15
Revision:
43:4dfeeaa9713e
Parent:
39:1421615a44f5

File content as of revision 43:4dfeeaa9713e:

/*******************************************************************************
 * Copyright (c) 2014, 2015 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial API and implementation and/or initial documentation
 *    Ian Craggs - make sure QoS2 processing works, and add device headers
 *******************************************************************************/

 /**
  This is a sample program to illustrate the use of the MQTT Client library
  on the mbed platform.  The Client class requires two classes which mediate
  access to system interfaces for networking and timing.  As long as these two
  classes provide the required public programming interfaces, it does not matter
  what facilities they use underneath. In this program, they use the mbed
  system libraries.

 */

#define MQTTCLIENT_QOS2 1

#include "easy-connect.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "MQTTClient.h"
#include "MQTT_server_setting.h"
#include "mbed-trace/mbed_trace.h"

// Number of messages received from server.
volatile unsigned int arrivedcount = 0;

/*
 * Callback function called when a message arrived from server.
 */
void messageArrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;
    printf("! Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n",
            message.qos, message.retained, message.dup, message.id);
    printf("! Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
    ++arrivedcount;
}


int main(int argc, char* argv[])
{
    mbed_trace_init();

    NetworkInterface* network = NULL;
    MQTTNetwork* mqttNetwork = NULL;
    MQTT::Client<MQTTNetwork, Countdown>* mqttClient = NULL;
    
    const float version = 0.7;
    const char* topic = "mbed-test";
    bool isSubscribed = false;

    printf("HelloMQTT: version is %.2f\r\n", version);
    printf("\r\n");

    printf("Opening network interface...\r\n");
    {
        network = easy_connect(false);    // If true, prints out connection details.
        if (!network) {
            printf("Unable to open network interface.\r\n");
            return -1;
        }
    }
    printf("Network interface opened successfully.\r\n");
    printf("\r\n");

    printf("Connecting to host %s:%d ...\r\n", MQTT_SERVER_HOST_NAME, MQTT_SERVER_PORT);
    {
        mqttNetwork = new MQTTNetwork(network);
#if MBED_CONF_APP_USE_TLS == 1
        int rc = mqttNetwork->connect(MQTT_SERVER_HOST_NAME, MQTT_SERVER_PORT, SSL_CA_PEM,
                SSL_CLIENT_CERT_PEM, SSL_CLIENT_PRIVATE_KEY_PEM);
#else
        int rc = mqttNetwork->connect(MQTT_SERVER_HOST_NAME, MQTT_SERVER_PORT);
#endif /* MBED_CONF_APP_USE_TLS */
        if (rc != MQTT::SUCCESS){
            printf("ERROR: rc from TCP connect is %d\r\n", rc);
            goto ERROR;
        }
    }
    printf("Connection established.\r\n");
    printf("\r\n");

    printf("MQTT client is trying to connect the server ...\r\n");
    {
        MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
        data.MQTTVersion = 3;
        data.clientID.cstring = (char*)"mbed-sample";
        data.username.cstring = (char*)"testuser";
        data.password.cstring = (char*)"testpassword";

        mqttClient = new MQTT::Client<MQTTNetwork, Countdown>(*mqttNetwork);
        int rc = mqttClient->connect(data);
        if (rc != MQTT::SUCCESS) {
            printf("ERROR: rc from MQTT connect is %d\r\n", rc);
            goto ERROR;
        }
    }
    printf("Client connected.\r\n");
    printf("\r\n");

    printf("Client is trying to subscribe a topic \"%s\".\r\n", topic);
    {
        int rc = mqttClient->subscribe(topic, MQTT::QOS2, messageArrived);
        if (rc != MQTT::SUCCESS) {
            printf("ERROR: rc from MQTT subscribe is %d\r\n", rc);
            goto ERROR;
        }
        isSubscribed = true;
    }
    printf("Client has subscribed a topic \"%s\".\r\n", topic);
    printf("\r\n");

    printf("Client publishes messages ...\r\n");
    {
        MQTT::Message message;
        message.retained = false;
        message.dup = false;

        const size_t buf_size = 100;
        char *buf = new char[buf_size];
        message.payload = (void*)buf;

        const MQTT::QoS q[] = {MQTT::QOS0, MQTT::QOS1, MQTT::QOS2};
        for(unsigned int i=0; i < (sizeof(q)/sizeof(q[0])); i++) {
            message.qos = q[i];
            message.id = i;
            sprintf(buf, "Hello World!  QoS %d message from app version %f\r\n", i, version);
            message.payloadlen = strlen(buf)+1;
            // Publish a message.
            printf("Publishing message QoS %d.\r\n", i);
            int rc = mqttClient->publish(topic, message);
            if(rc != MQTT::SUCCESS) {
                printf("ERROR: rc from MQTT publish is %d\r\n", rc);
                goto ERROR;
            }
            printf("QoS %d message published.\r\n", i);
            while (arrivedcount < (i+1)){
                mqttClient->yield(100);
            }
        }
        delete[] buf;
    }
    printf("Version %.2f: finish %d msgs\r\n", version, arrivedcount);

ERROR:
    if(mqttClient) {
        if(isSubscribed) {
            mqttClient->unsubscribe(topic);
            mqttClient->setMessageHandler(topic, 0);
        }
        if(mqttClient->isConnected()) 
            mqttClient->disconnect();
        delete mqttClient;
    }
    if(mqttNetwork) {
        mqttNetwork->disconnect();
        delete mqttNetwork;
    }
    if(network) {
        network->disconnect();
        // network is not created by new.
    }

    exit(0);
}