Simple usage example of MQTTS library

Dependencies:   EthernetInterface MQTTS NTPClient SDFileSystem mbed-rtos mbed wolfSSL

Fork of HelloMQTT by MQTT

MQTT is light weight protocol for M2M, IoT. MQTTS adds TLS(SSL) security layer into the MQTT. This program shows simple usage example of MQTTS library.

Connect information has to be stored in SD file "connectInfo.txt", with following lines in it.

  • Host Name
  • User Name
  • Password
  • Client ID
  • Topic

The program asks following information on the terminal

  • Port Number to be connected. If the port is >8000 it assumes MQTTS.
  • Message to be published
  • Certificate file name, if MQTTS. Input file name on SD card. Simply Return key force it to no server verification. The program set up the realtime clock by NTP for certificate verification.

This program was tested with FRDM-K64F, against Sango MQTT server by Shiguredo. https://sango.shiguredo.jp/

References:

Committer:
wolfSSL
Date:
Sat Aug 01 20:50:27 2015 +0000
Revision:
20:0404c7f31c69
Parent:
17:25584027fae0
Added QoS2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
icraggs 1:a1d5c7a6acbc 1 /*******************************************************************************
icraggs 1:a1d5c7a6acbc 2 * Copyright (c) 2014 IBM Corp.
icraggs 1:a1d5c7a6acbc 3 *
icraggs 1:a1d5c7a6acbc 4 * All rights reserved. This program and the accompanying materials
icraggs 1:a1d5c7a6acbc 5 * are made available under the terms of the Eclipse Public License v1.0
icraggs 1:a1d5c7a6acbc 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
icraggs 1:a1d5c7a6acbc 7 *
icraggs 1:a1d5c7a6acbc 8 * The Eclipse Public License is available at
icraggs 1:a1d5c7a6acbc 9 * http://www.eclipse.org/legal/epl-v10.html
icraggs 1:a1d5c7a6acbc 10 * and the Eclipse Distribution License is available at
icraggs 1:a1d5c7a6acbc 11 * http://www.eclipse.org/org/documents/edl-v10.php.
icraggs 1:a1d5c7a6acbc 12 *
icraggs 1:a1d5c7a6acbc 13 * Contributors:
icraggs 1:a1d5c7a6acbc 14 * Ian Craggs - initial API and implementation and/or initial documentation
icraggs 1:a1d5c7a6acbc 15 *******************************************************************************/
icraggs 1:a1d5c7a6acbc 16
wolfSSL 17:25584027fae0 17 /**
wolfSSL 17:25584027fae0 18 This is a sample program to illustrate the use of the MQTT Client library
wolfSSL 17:25584027fae0 19 on the mbed platform. The Client class requires two classes which mediate
wolfSSL 17:25584027fae0 20 access to system interfaces for networking and timing. As long as these two
wolfSSL 17:25584027fae0 21 classes provide the required public programming interfaces, it does not matter
wolfSSL 17:25584027fae0 22 what facilities they use underneath. In this program, they use the mbed
wolfSSL 17:25584027fae0 23 system libraries.
icraggs 2:638c854c0695 24
wolfSSL 17:25584027fae0 25 */
wolfSSL 20:0404c7f31c69 26 #define MQTTCLIENT_QOS2 1
icraggs 8:a3e3113054a1 27 #include "MQTTEthernet.h"
icraggs 2:638c854c0695 28 #include "MQTTClient.h"
icraggs 2:638c854c0695 29
wolfSSL 17:25584027fae0 30 #include "NTPClient.h"
wolfSSL 17:25584027fae0 31 #include "getline.h"
wolfSSL 17:25584027fae0 32 #include "SDFileSystem.h"
wolfSSL 17:25584027fae0 33 SDFileSystem sdCard(PTE3, PTE1, PTE2, PTE4, "sd"); /* pins for FRDM-K64F */
wolfSSL 17:25584027fae0 34 const char* certFile = "/sd/mqtts-cert.pem";
wolfSSL 17:25584027fae0 35
icraggs 2:638c854c0695 36 int arrivedcount = 0;
icraggs 2:638c854c0695 37
icraggs 9:5beb8609e9f7 38 void messageArrived(MQTT::MessageData& md)
icraggs 2:638c854c0695 39 {
icraggs 9:5beb8609e9f7 40 MQTT::Message &message = md.message;
icraggs 9:5beb8609e9f7 41 printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\n", message.qos, message.retained, message.dup, message.id);
icraggs 9:5beb8609e9f7 42 printf("Payload %.*s\n", message.payloadlen, (char*)message.payload);
icraggs 2:638c854c0695 43 ++arrivedcount;
wolfSSL 17:25584027fae0 44 puts((char*)message.payload);
wolfSSL 17:25584027fae0 45 }
wolfSSL 17:25584027fae0 46
wolfSSL 17:25584027fae0 47 static char * removeNL(char *str)
wolfSSL 17:25584027fae0 48 {
wolfSSL 17:25584027fae0 49 for(int i=strlen(str)-1; (str[i]=='\n')||(str[i]=='\r'); i--)str[i]='\0' ;
wolfSSL 17:25584027fae0 50 return str ;
icraggs 2:638c854c0695 51 }
icraggs 0:0cae29831d01 52
wolfSSL 17:25584027fae0 53 static bool getConnectInfo(char **hn, char **un, char **pwd, char **cID,
wolfSSL 17:25584027fae0 54 char **tc, int *pt, char **ms, char **cert)
wolfSSL 17:25584027fae0 55 {
wolfSSL 17:25584027fae0 56 static char hostname[100] ;
wolfSSL 17:25584027fae0 57 static char username[20] ;
wolfSSL 17:25584027fae0 58 static char password[20] ;
wolfSSL 17:25584027fae0 59 static char clientID[20] ;
wolfSSL 17:25584027fae0 60 static char topic[50] ;
wolfSSL 17:25584027fae0 61 static char port_s[10] ;
wolfSSL 17:25584027fae0 62 static int port ;
wolfSSL 17:25584027fae0 63 static char msg[100] ;
wolfSSL 17:25584027fae0 64 static char certName[30] ;
wolfSSL 17:25584027fae0 65 static char fullName[sizeof(certName)+10] ;
icraggs 2:638c854c0695 66
wolfSSL 17:25584027fae0 67 *hn = hostname ;
wolfSSL 17:25584027fae0 68 *un = username ;
wolfSSL 17:25584027fae0 69 *pwd= password ;
wolfSSL 17:25584027fae0 70 *cID= clientID ;
wolfSSL 17:25584027fae0 71 *tc = topic ;
wolfSSL 17:25584027fae0 72 *ms = msg ;
wolfSSL 17:25584027fae0 73 *cert=fullName ;
wolfSSL 17:25584027fae0 74
wolfSSL 17:25584027fae0 75 FILE *fp = fopen("/sd/connectInfo.txt", "r");
wolfSSL 17:25584027fae0 76 if (fp == NULL) {
wolfSSL 17:25584027fae0 77 printf("Cannot open \"connectInfo.txt\"\n") ;
wolfSSL 17:25584027fae0 78 return false ;
wolfSSL 17:25584027fae0 79 }
wolfSSL 17:25584027fae0 80 fgets(hostname, sizeof(hostname), fp) ;
wolfSSL 17:25584027fae0 81 fgets(username , sizeof(username), fp);
wolfSSL 17:25584027fae0 82 fgets(password, sizeof(password), fp) ;
wolfSSL 17:25584027fae0 83 fgets(clientID, sizeof(clientID), fp) ;
wolfSSL 17:25584027fae0 84 fgets(topic, sizeof(topic), fp) ;
wolfSSL 17:25584027fae0 85 getline("Port(1883/8883): ", port_s, sizeof(port_s)) ;
wolfSSL 17:25584027fae0 86 getline("Message: ", msg, sizeof(msg)) ;
wolfSSL 17:25584027fae0 87 removeNL(hostname) ;
wolfSSL 17:25584027fae0 88 removeNL(username) ;
wolfSSL 17:25584027fae0 89 removeNL(password) ;
wolfSSL 17:25584027fae0 90 removeNL(clientID) ;
wolfSSL 17:25584027fae0 91 removeNL(topic) ;
wolfSSL 17:25584027fae0 92 port = atoi(removeNL(port_s)) ;
wolfSSL 17:25584027fae0 93 *pt = port ;
wolfSSL 17:25584027fae0 94 printf("Connecting to %s:%d, %s\n", hostname, port, port>8000? "MQTT-TLS":"MQTT" );
wolfSSL 17:25584027fae0 95 if(port>8000) {
wolfSSL 17:25584027fae0 96 getline("Cert File name: ", certName, sizeof(certName)) ;
wolfSSL 17:25584027fae0 97 removeNL(certName) ;
wolfSSL 17:25584027fae0 98 if(*certName != '\0') {
wolfSSL 17:25584027fae0 99 sprintf(fullName, "/sd/%s", certName) ;
wolfSSL 17:25584027fae0 100 FILE *fp = fopen(fullName, "r");
wolfSSL 17:25584027fae0 101 if (fp != NULL) {
wolfSSL 17:25584027fae0 102 NTPClient ntp; /* set Realtime clock for cert verification */
wolfSSL 17:25584027fae0 103 if(ntp.setTime("ntp.jst.mfeed.ad.jp") != 0) {
wolfSSL 17:25584027fae0 104 printf("NTP Error\n") ;
wolfSSL 17:25584027fae0 105 return false ;
wolfSSL 17:25584027fae0 106 }
wolfSSL 17:25584027fae0 107 printf("Verify Server: %s\n", certName) ;
wolfSSL 17:25584027fae0 108 } else {
wolfSSL 17:25584027fae0 109 printf("ERROR: file not found\n") ;
wolfSSL 17:25584027fae0 110 return false ;
wolfSSL 17:25584027fae0 111 }
wolfSSL 17:25584027fae0 112 } else {
wolfSSL 17:25584027fae0 113 fullName[0] = '\0' ;
wolfSSL 17:25584027fae0 114 printf("No verify Server\n") ;
wolfSSL 17:25584027fae0 115 }
wolfSSL 17:25584027fae0 116 }
wolfSSL 17:25584027fae0 117 return true ;
wolfSSL 17:25584027fae0 118 }
wolfSSL 17:25584027fae0 119
wolfSSL 17:25584027fae0 120 void mqtt_main(void const *av)
wolfSSL 17:25584027fae0 121 {
icraggs 8:a3e3113054a1 122 MQTTEthernet ipstack = MQTTEthernet();
icraggs 9:5beb8609e9f7 123 float version = 0.47;
wolfSSL 17:25584027fae0 124
sam_grove 5:4a257f6ac09a 125 printf("Version is %f\n", version);
wolfSSL 17:25584027fae0 126 printf("Version is %f\n", version);
wolfSSL 17:25584027fae0 127
icraggs 8:a3e3113054a1 128 MQTT::Client<MQTTEthernet, Countdown> client = MQTT::Client<MQTTEthernet, Countdown>(ipstack);
wolfSSL 17:25584027fae0 129 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
wolfSSL 17:25584027fae0 130 data.MQTTVersion = 3;
wolfSSL 17:25584027fae0 131
wolfSSL 17:25584027fae0 132 /* get connect info */
wolfSSL 17:25584027fae0 133 char *hostname ;
wolfSSL 17:25584027fae0 134 char *username ;
wolfSSL 17:25584027fae0 135 char *password ;
wolfSSL 17:25584027fae0 136 char *clientID ;
wolfSSL 17:25584027fae0 137 char *topic ;
wolfSSL 17:25584027fae0 138 int port ;
wolfSSL 17:25584027fae0 139 char *msg ;
wolfSSL 17:25584027fae0 140 char *fullName ;
wolfSSL 17:25584027fae0 141
wolfSSL 17:25584027fae0 142 if(!getConnectInfo(&hostname, &username, &password, &clientID, &topic, &port, &msg, &fullName))
wolfSSL 17:25584027fae0 143 return ;
wolfSSL 17:25584027fae0 144 data.username.cstring = username ;
wolfSSL 17:25584027fae0 145 data.password.cstring = password ;
wolfSSL 17:25584027fae0 146 data.clientID.cstring = clientID ;
wolfSSL 17:25584027fae0 147
wolfSSL 17:25584027fae0 148 int rc = ipstack.connect(hostname, port, port>8000 ? fullName : NULL);
icraggs 6:e4c690c45021 149 if (rc != 0)
wolfSSL 17:25584027fae0 150 printf("rc from TCP connect is %d\n", rc);
wolfSSL 17:25584027fae0 151
icraggs 16:28d062c5522b 152 if ((rc = client.connect(data)) != 0)
wolfSSL 17:25584027fae0 153 printf("rc from MQTT connect is %d\n", rc);
wolfSSL 17:25584027fae0 154 printf("MQTT connected\n") ;
wolfSSL 17:25584027fae0 155 if ((rc = client.subscribe(topic, MQTT::QOS0, messageArrived)) != 0)
wolfSSL 17:25584027fae0 156 printf("rc from MQTT subscribe is %d\n", rc);
wolfSSL 17:25584027fae0 157 printf("Subscribed\n") ;
icraggs 2:638c854c0695 158 MQTT::Message message;
icraggs 0:0cae29831d01 159
wolfSSL 17:25584027fae0 160 // QoS 0
wolfSSL 17:25584027fae0 161 char buf[sizeof(message)+50] ;
wolfSSL 17:25584027fae0 162 sprintf(buf, "\"%s\", QoS 0 message from app version %f\n", msg, version);
icraggs 2:638c854c0695 163 message.qos = MQTT::QOS0;
icraggs 2:638c854c0695 164 message.retained = false;
icraggs 2:638c854c0695 165 message.dup = false;
icraggs 2:638c854c0695 166 message.payload = (void*)buf;
icraggs 2:638c854c0695 167 message.payloadlen = strlen(buf)+1;
icraggs 16:28d062c5522b 168 rc = client.publish(topic, message);
wolfSSL 17:25584027fae0 169
wolfSSL 17:25584027fae0 170 printf("QoS0: Published to %s\n\t%s\n", topic, message.payload) ;
icraggs 12:086a9314e8a5 171 while (arrivedcount < 1)
icraggs 2:638c854c0695 172 client.yield(100);
wolfSSL 17:25584027fae0 173
wolfSSL 17:25584027fae0 174 // QoS 1
wolfSSL 17:25584027fae0 175 sprintf(buf, "\"%s\", QoS 1 message from app version %f\n", msg, version);
icraggs 2:638c854c0695 176 message.qos = MQTT::QOS1;
wolfSSL 17:25584027fae0 177
icraggs 2:638c854c0695 178 message.payloadlen = strlen(buf)+1;
icraggs 16:28d062c5522b 179 rc = client.publish(topic, message);
wolfSSL 17:25584027fae0 180 printf("QoS1: Published to %s\n\t%s\n", topic, message.payload) ;
icraggs 12:086a9314e8a5 181 while (arrivedcount < 2)
icraggs 2:638c854c0695 182 client.yield(100);
wolfSSL 17:25584027fae0 183
wolfSSL 20:0404c7f31c69 184 #if 1 /* QoS 2 not tested */
wolfSSL 17:25584027fae0 185 // QoS 2
wolfSSL 20:0404c7f31c69 186 sprintf(buf, "\"%s\", QoS 2 message from app version %f\n", msg, version);
icraggs 2:638c854c0695 187 message.qos = MQTT::QOS2;
icraggs 2:638c854c0695 188 message.payloadlen = strlen(buf)+1;
icraggs 16:28d062c5522b 189 rc = client.publish(topic, message);
wolfSSL 17:25584027fae0 190 printf("QoS2: Published to %s\n\t%s\n", topic, message.payload) ;
icraggs 12:086a9314e8a5 191 while (arrivedcount < 3)
icraggs 2:638c854c0695 192 client.yield(100);
wolfSSL 17:25584027fae0 193
wolfSSL 17:25584027fae0 194 // n * QoS 2
wolfSSL 17:25584027fae0 195 for (int i = 1; i <= 10; ++i) {
wolfSSL 20:0404c7f31c69 196 sprintf(buf, "\"%s\", QoS 2 message number %d from app version %f\n",msg, i, version);
icraggs 12:086a9314e8a5 197 message.qos = MQTT::QOS2;
icraggs 12:086a9314e8a5 198 message.payloadlen = strlen(buf)+1;
icraggs 16:28d062c5522b 199 rc = client.publish(topic, message);
wolfSSL 17:25584027fae0 200 printf("QoS2[%d]: Published to %s\n\t%s\n", i, topic, message.payload) ;
icraggs 12:086a9314e8a5 201 while (arrivedcount < i + 3)
icraggs 12:086a9314e8a5 202 client.yield(100);
icraggs 12:086a9314e8a5 203 }
wolfSSL 17:25584027fae0 204 #endif
wolfSSL 17:25584027fae0 205
wolfSSL 17:25584027fae0 206 printf("unsubscribing\n") ;
icraggs 8:a3e3113054a1 207 if ((rc = client.unsubscribe(topic)) != 0)
sam_grove 5:4a257f6ac09a 208 printf("rc from unsubscribe was %d\n", rc);
wolfSSL 17:25584027fae0 209
icraggs 8:a3e3113054a1 210 if ((rc = client.disconnect()) != 0)
sam_grove 5:4a257f6ac09a 211 printf("rc from disconnect was %d\n", rc);
wolfSSL 17:25584027fae0 212
icraggs 2:638c854c0695 213 ipstack.disconnect();
wolfSSL 17:25584027fae0 214 printf("Version %.2f: finish %d msgs\n", version, arrivedcount);
sam_grove 5:4a257f6ac09a 215 printf("Finishing with %d messages received\n", arrivedcount);
wolfSSL 17:25584027fae0 216
wolfSSL 17:25584027fae0 217 return ;
icraggs 0:0cae29831d01 218 }
wolfSSL 17:25584027fae0 219
wolfSSL 17:25584027fae0 220 main()
wolfSSL 17:25584027fae0 221 {
wolfSSL 17:25584027fae0 222 #define STACK_SIZE 24000
wolfSSL 17:25584027fae0 223 Thread t(mqtt_main, NULL, osPriorityNormal, STACK_SIZE);
wolfSSL 17:25584027fae0 224 while (true) {
wolfSSL 17:25584027fae0 225 Thread::wait(1000);
wolfSSL 17:25584027fae0 226 }
wolfSSL 17:25584027fae0 227 }