Pavle Radojkovic / mbed-mqtt
Committer:
pavleradojkovic
Date:
Mon Jun 20 16:24:43 2022 +0000
Revision:
0:ba7e439238ab
Inital commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pavleradojkovic 0:ba7e439238ab 1 /*******************************************************************************
pavleradojkovic 0:ba7e439238ab 2 * Copyright (c) 2014 IBM Corp.
pavleradojkovic 0:ba7e439238ab 3 *
pavleradojkovic 0:ba7e439238ab 4 * All rights reserved. This program and the accompanying materials
pavleradojkovic 0:ba7e439238ab 5 * are made available under the terms of the Eclipse Public License v1.0
pavleradojkovic 0:ba7e439238ab 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
pavleradojkovic 0:ba7e439238ab 7 *
pavleradojkovic 0:ba7e439238ab 8 * The Eclipse Public License is available at
pavleradojkovic 0:ba7e439238ab 9 * http://www.eclipse.org/legal/epl-v10.html
pavleradojkovic 0:ba7e439238ab 10 * and the Eclipse Distribution License is available at
pavleradojkovic 0:ba7e439238ab 11 * http://www.eclipse.org/org/documents/edl-v10.php.
pavleradojkovic 0:ba7e439238ab 12 *
pavleradojkovic 0:ba7e439238ab 13 * Contributors:
pavleradojkovic 0:ba7e439238ab 14 * Ian Craggs - refactoring to remove STL and other changes
pavleradojkovic 0:ba7e439238ab 15 *******************************************************************************/
pavleradojkovic 0:ba7e439238ab 16
pavleradojkovic 0:ba7e439238ab 17 #define WARN printf
pavleradojkovic 0:ba7e439238ab 18
pavleradojkovic 0:ba7e439238ab 19 #include "MQTTClient.h"
pavleradojkovic 0:ba7e439238ab 20
pavleradojkovic 0:ba7e439238ab 21 #define DEFAULT_STACK_SIZE -1
pavleradojkovic 0:ba7e439238ab 22
pavleradojkovic 0:ba7e439238ab 23 #include "linux.cpp"
pavleradojkovic 0:ba7e439238ab 24
pavleradojkovic 0:ba7e439238ab 25 #include <stdlib.h>
pavleradojkovic 0:ba7e439238ab 26
pavleradojkovic 0:ba7e439238ab 27 // Configuration values needed to connect to IBM IoT Cloud
pavleradojkovic 0:ba7e439238ab 28 #define ORG "quickstart" // For a registered connection, replace with your org
pavleradojkovic 0:ba7e439238ab 29 #define ID "8002f7f1ad23" // For a registered connection, replace with your id
pavleradojkovic 0:ba7e439238ab 30 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
pavleradojkovic 0:ba7e439238ab 31 #define TYPE "mytype" // For a registered connection, replace with your type
pavleradojkovic 0:ba7e439238ab 32
pavleradojkovic 0:ba7e439238ab 33 #define MQTT_PORT 1883
pavleradojkovic 0:ba7e439238ab 34 #define MQTT_TLS_PORT 8883
pavleradojkovic 0:ba7e439238ab 35 #define IBM_IOT_PORT MQTT_PORT
pavleradojkovic 0:ba7e439238ab 36
pavleradojkovic 0:ba7e439238ab 37 #define MQTT_MAX_PACKET_SIZE 250
pavleradojkovic 0:ba7e439238ab 38
pavleradojkovic 0:ba7e439238ab 39 bool quickstartMode = true;
pavleradojkovic 0:ba7e439238ab 40 char org[11] = ORG;
pavleradojkovic 0:ba7e439238ab 41 char type[30] = TYPE;
pavleradojkovic 0:ba7e439238ab 42 char id[30] = ID; // mac without colons
pavleradojkovic 0:ba7e439238ab 43 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
pavleradojkovic 0:ba7e439238ab 44
pavleradojkovic 0:ba7e439238ab 45 bool connected = false;
pavleradojkovic 0:ba7e439238ab 46 const char* joystickPos = "CENTRE";
pavleradojkovic 0:ba7e439238ab 47 int blink_interval = 0;
pavleradojkovic 0:ba7e439238ab 48
pavleradojkovic 0:ba7e439238ab 49
pavleradojkovic 0:ba7e439238ab 50
pavleradojkovic 0:ba7e439238ab 51 int connect(MQTT::Client<IPStack, Countdown, MQTT_MAX_PACKET_SIZE>* client, IPStack* ipstack)
pavleradojkovic 0:ba7e439238ab 52 {
pavleradojkovic 0:ba7e439238ab 53 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
pavleradojkovic 0:ba7e439238ab 54
pavleradojkovic 0:ba7e439238ab 55 char hostname[strlen(org) + strlen(iot_ibm) + 1];
pavleradojkovic 0:ba7e439238ab 56 sprintf(hostname, "%s%s", org, iot_ibm);
pavleradojkovic 0:ba7e439238ab 57 DEBUG("connecting to %s\n", hostname);
pavleradojkovic 0:ba7e439238ab 58 int rc = ipstack->connect(hostname, IBM_IOT_PORT);
pavleradojkovic 0:ba7e439238ab 59 if (rc != 0)
pavleradojkovic 0:ba7e439238ab 60 return rc;
pavleradojkovic 0:ba7e439238ab 61
pavleradojkovic 0:ba7e439238ab 62 // Construct clientId - d:org:type:id
pavleradojkovic 0:ba7e439238ab 63 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
pavleradojkovic 0:ba7e439238ab 64 sprintf(clientId, "d:%s:%s:%s", org, type, id);
pavleradojkovic 0:ba7e439238ab 65 DEBUG("clientid is %s\n", clientId);
pavleradojkovic 0:ba7e439238ab 66
pavleradojkovic 0:ba7e439238ab 67 // MQTT Connect
pavleradojkovic 0:ba7e439238ab 68 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
pavleradojkovic 0:ba7e439238ab 69 data.MQTTVersion = 4;
pavleradojkovic 0:ba7e439238ab 70 data.clientID.cstring = clientId;
pavleradojkovic 0:ba7e439238ab 71
pavleradojkovic 0:ba7e439238ab 72 if (!quickstartMode)
pavleradojkovic 0:ba7e439238ab 73 {
pavleradojkovic 0:ba7e439238ab 74 data.username.cstring = "use-token-auth";
pavleradojkovic 0:ba7e439238ab 75 data.password.cstring = auth_token;
pavleradojkovic 0:ba7e439238ab 76 }
pavleradojkovic 0:ba7e439238ab 77
pavleradojkovic 0:ba7e439238ab 78 if ((rc = client->connect(data)) == 0)
pavleradojkovic 0:ba7e439238ab 79 connected = true;
pavleradojkovic 0:ba7e439238ab 80 return rc;
pavleradojkovic 0:ba7e439238ab 81 }
pavleradojkovic 0:ba7e439238ab 82
pavleradojkovic 0:ba7e439238ab 83
pavleradojkovic 0:ba7e439238ab 84 int getConnTimeout(int attemptNumber)
pavleradojkovic 0:ba7e439238ab 85 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
pavleradojkovic 0:ba7e439238ab 86 // after 20 attempts, retry every 10 minutes
pavleradojkovic 0:ba7e439238ab 87 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
pavleradojkovic 0:ba7e439238ab 88 }
pavleradojkovic 0:ba7e439238ab 89
pavleradojkovic 0:ba7e439238ab 90
pavleradojkovic 0:ba7e439238ab 91 void attemptConnect(MQTT::Client<IPStack, Countdown, MQTT_MAX_PACKET_SIZE>* client, IPStack* ipstack)
pavleradojkovic 0:ba7e439238ab 92 {
pavleradojkovic 0:ba7e439238ab 93 int retryAttempt = 0;
pavleradojkovic 0:ba7e439238ab 94 connected = false;
pavleradojkovic 0:ba7e439238ab 95
pavleradojkovic 0:ba7e439238ab 96 while (connect(client, ipstack) != 0)
pavleradojkovic 0:ba7e439238ab 97 {
pavleradojkovic 0:ba7e439238ab 98 int timeout = getConnTimeout(++retryAttempt);
pavleradojkovic 0:ba7e439238ab 99 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
pavleradojkovic 0:ba7e439238ab 100
pavleradojkovic 0:ba7e439238ab 101 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
pavleradojkovic 0:ba7e439238ab 102 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
pavleradojkovic 0:ba7e439238ab 103
pavleradojkovic 0:ba7e439238ab 104 sleep(timeout);
pavleradojkovic 0:ba7e439238ab 105 }
pavleradojkovic 0:ba7e439238ab 106 }
pavleradojkovic 0:ba7e439238ab 107
pavleradojkovic 0:ba7e439238ab 108
pavleradojkovic 0:ba7e439238ab 109 int publish(MQTT::Client<IPStack, Countdown, MQTT_MAX_PACKET_SIZE>* client, IPStack* ipstack)
pavleradojkovic 0:ba7e439238ab 110 {
pavleradojkovic 0:ba7e439238ab 111 MQTT::Message message;
pavleradojkovic 0:ba7e439238ab 112 char* pubTopic = "iot-2/evt/status/fmt/json";
pavleradojkovic 0:ba7e439238ab 113 static const char* joypos[] = {"LEFT", "RIGHT", "CENTRE", "UP", "DOWN"};
pavleradojkovic 0:ba7e439238ab 114
pavleradojkovic 0:ba7e439238ab 115 char buf[250];
pavleradojkovic 0:ba7e439238ab 116 sprintf(buf,
pavleradojkovic 0:ba7e439238ab 117 "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}",
pavleradojkovic 0:ba7e439238ab 118 (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) * 2.0, (rand() % 10) + 18.0, joypos[rand() % 5], (rand() % 10) * 30.0, (rand() % 10) * 30.0);
pavleradojkovic 0:ba7e439238ab 119 //MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read());
pavleradojkovic 0:ba7e439238ab 120 message.qos = MQTT::QOS0;
pavleradojkovic 0:ba7e439238ab 121 message.retained = false;
pavleradojkovic 0:ba7e439238ab 122 message.dup = false;
pavleradojkovic 0:ba7e439238ab 123 message.payload = (void*)buf;
pavleradojkovic 0:ba7e439238ab 124 message.payloadlen = strlen(buf);
pavleradojkovic 0:ba7e439238ab 125
pavleradojkovic 0:ba7e439238ab 126 LOG("Publishing %s\n", buf);
pavleradojkovic 0:ba7e439238ab 127 return client->publish(pubTopic, message);
pavleradojkovic 0:ba7e439238ab 128 }
pavleradojkovic 0:ba7e439238ab 129
pavleradojkovic 0:ba7e439238ab 130
pavleradojkovic 0:ba7e439238ab 131 void messageArrived(MQTT::MessageData& md)
pavleradojkovic 0:ba7e439238ab 132 {
pavleradojkovic 0:ba7e439238ab 133 MQTT::Message &message = md.message;
pavleradojkovic 0:ba7e439238ab 134 char topic[md.topicName.lenstring.len + 1];
pavleradojkovic 0:ba7e439238ab 135
pavleradojkovic 0:ba7e439238ab 136 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
pavleradojkovic 0:ba7e439238ab 137
pavleradojkovic 0:ba7e439238ab 138 LOG("Message arrived on topic %s: %.*s\n", topic, message.payloadlen, message.payload);
pavleradojkovic 0:ba7e439238ab 139
pavleradojkovic 0:ba7e439238ab 140 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
pavleradojkovic 0:ba7e439238ab 141 char* start = strstr(topic, "/cmd/") + 5;
pavleradojkovic 0:ba7e439238ab 142 int len = strstr(topic, "/fmt/") - start;
pavleradojkovic 0:ba7e439238ab 143
pavleradojkovic 0:ba7e439238ab 144 if (memcmp(start, "blink", len) == 0)
pavleradojkovic 0:ba7e439238ab 145 {
pavleradojkovic 0:ba7e439238ab 146 char payload[message.payloadlen + 1];
pavleradojkovic 0:ba7e439238ab 147 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
pavleradojkovic 0:ba7e439238ab 148
pavleradojkovic 0:ba7e439238ab 149 char* pos = strchr(payload, '}');
pavleradojkovic 0:ba7e439238ab 150 if (pos != NULL)
pavleradojkovic 0:ba7e439238ab 151 {
pavleradojkovic 0:ba7e439238ab 152 *pos = '\0';
pavleradojkovic 0:ba7e439238ab 153 if ((pos = strchr(payload, ':')) != NULL)
pavleradojkovic 0:ba7e439238ab 154 {
pavleradojkovic 0:ba7e439238ab 155 int blink_rate = atoi(pos + 1);
pavleradojkovic 0:ba7e439238ab 156 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
pavleradojkovic 0:ba7e439238ab 157 }
pavleradojkovic 0:ba7e439238ab 158 }
pavleradojkovic 0:ba7e439238ab 159 }
pavleradojkovic 0:ba7e439238ab 160 else
pavleradojkovic 0:ba7e439238ab 161 WARN("Unsupported command: %.*s\n", len, start);
pavleradojkovic 0:ba7e439238ab 162 }
pavleradojkovic 0:ba7e439238ab 163
pavleradojkovic 0:ba7e439238ab 164
pavleradojkovic 0:ba7e439238ab 165 int main()
pavleradojkovic 0:ba7e439238ab 166 {
pavleradojkovic 0:ba7e439238ab 167 quickstartMode = (strcmp(org, "quickstart") == 0);
pavleradojkovic 0:ba7e439238ab 168
pavleradojkovic 0:ba7e439238ab 169 IPStack ipstack = IPStack();
pavleradojkovic 0:ba7e439238ab 170 MQTT::Client<IPStack, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
pavleradojkovic 0:ba7e439238ab 171
pavleradojkovic 0:ba7e439238ab 172 attemptConnect(&client, &ipstack);
pavleradojkovic 0:ba7e439238ab 173
pavleradojkovic 0:ba7e439238ab 174 if (!quickstartMode)
pavleradojkovic 0:ba7e439238ab 175 {
pavleradojkovic 0:ba7e439238ab 176 int rc = 0;
pavleradojkovic 0:ba7e439238ab 177 if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
pavleradojkovic 0:ba7e439238ab 178 WARN("rc from MQTT subscribe is %d\n", rc);
pavleradojkovic 0:ba7e439238ab 179 }
pavleradojkovic 0:ba7e439238ab 180
pavleradojkovic 0:ba7e439238ab 181 int count = 0;
pavleradojkovic 0:ba7e439238ab 182 while (true)
pavleradojkovic 0:ba7e439238ab 183 {
pavleradojkovic 0:ba7e439238ab 184 if (++count == 100)
pavleradojkovic 0:ba7e439238ab 185 { // Publish a message every second
pavleradojkovic 0:ba7e439238ab 186 if (publish(&client, &ipstack) != 0)
pavleradojkovic 0:ba7e439238ab 187 attemptConnect(&client, &ipstack); // if we have lost the connection
pavleradojkovic 0:ba7e439238ab 188 count = 0;
pavleradojkovic 0:ba7e439238ab 189 }
pavleradojkovic 0:ba7e439238ab 190 client.yield(10); // allow the MQTT client to receive messages
pavleradojkovic 0:ba7e439238ab 191 }
pavleradojkovic 0:ba7e439238ab 192 }
pavleradojkovic 0:ba7e439238ab 193