IBMIoTClientEthernetExample for WIZwiki-W7500 platform

Dependencies:   MQTT WIZnetInterface mbed-src

Committer:
hkjung
Date:
Tue Sep 15 00:43:05 2015 +0000
Revision:
2:b1dcfd885d7f
Parent:
0:7488a229e6fc
Child:
4:167fd0256a06
.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hkjung 0:7488a229e6fc 1 #include "mbed.h"
hkjung 0:7488a229e6fc 2 #include "EthernetInterface.h"
hkjung 0:7488a229e6fc 3 #include "MQTTClient.h"
hkjung 0:7488a229e6fc 4 #include "MQTTEthernet.h"
hkjung 0:7488a229e6fc 5
hkjung 2:b1dcfd885d7f 6 Serial pc(USBTX, USBRX);
hkjung 2:b1dcfd885d7f 7
hkjung 0:7488a229e6fc 8 // Update this to the next number *before* a commit
hkjung 0:7488a229e6fc 9 #define __APP_SW_REVISION__ "1"
hkjung 0:7488a229e6fc 10
hkjung 0:7488a229e6fc 11 // Configuration values needed to connect to IBM IoT Cloud
hkjung 2:b1dcfd885d7f 12 #define QUICKSTARTMODE 1
hkjung 2:b1dcfd885d7f 13 #if (QUICKSTARTMODE)
hkjung 2:b1dcfd885d7f 14 #define ORG "quickstart" // For a registered connection, replace with your org
hkjung 2:b1dcfd885d7f 15 #define ID "" // For a registered connection, replace with your id
hkjung 2:b1dcfd885d7f 16 #define AUTH_TOKEN "" // For a registered connection, replace with your auth-token
hkjung 2:b1dcfd885d7f 17 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
hkjung 2:b1dcfd885d7f 18 #else
hkjung 2:b1dcfd885d7f 19 #define ORG "l24fbu" // For a registered connection, replace with your org
hkjung 2:b1dcfd885d7f 20 #define ID "0008DC1D69F3" // For a registered connection, replace with your id
hkjung 2:b1dcfd885d7f 21 #define AUTH_TOKEN "4uvlg2&uQRO-WVf_14" // For a registered connection, replace with your auth-token
hkjung 2:b1dcfd885d7f 22 #define TYPE "WIZwiki-W7500" // For a registered connection, replace with your type
hkjung 2:b1dcfd885d7f 23 #endif
hkjung 2:b1dcfd885d7f 24
hkjung 2:b1dcfd885d7f 25
hkjung 2:b1dcfd885d7f 26 #if defined(TARGET_WIZwiki_W7500)
hkjung 2:b1dcfd885d7f 27 //#warning "Compiling for mbed WIZwiki-W7500"
hkjung 2:b1dcfd885d7f 28 #include "WIZwiki-W7500.h"
hkjung 2:b1dcfd885d7f 29 #endif
hkjung 0:7488a229e6fc 30
hkjung 0:7488a229e6fc 31 #define MQTT_PORT 1883
hkjung 0:7488a229e6fc 32 #define MQTT_TLS_PORT 8883
hkjung 0:7488a229e6fc 33 #define IBM_IOT_PORT MQTT_PORT
hkjung 0:7488a229e6fc 34
hkjung 0:7488a229e6fc 35 #define MQTT_MAX_PACKET_SIZE 250
hkjung 0:7488a229e6fc 36
hkjung 0:7488a229e6fc 37 #if defined(TARGET_WIZwiki_W7500)
hkjung 2:b1dcfd885d7f 38 // PWM: RGB LED control
hkjung 2:b1dcfd885d7f 39 void off();
hkjung 2:b1dcfd885d7f 40 void red();
hkjung 2:b1dcfd885d7f 41 void green();
hkjung 2:b1dcfd885d7f 42 void blue();
hkjung 2:b1dcfd885d7f 43 //void yellow();
hkjung 0:7488a229e6fc 44 #endif
hkjung 0:7488a229e6fc 45
hkjung 2:b1dcfd885d7f 46 bool quickstartMode = QUICKSTARTMODE;
hkjung 0:7488a229e6fc 47 char org[11] = ORG;
hkjung 0:7488a229e6fc 48 char type[30] = TYPE;
hkjung 0:7488a229e6fc 49 char id[30] = ID; // mac without colons
hkjung 0:7488a229e6fc 50 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
hkjung 0:7488a229e6fc 51
hkjung 0:7488a229e6fc 52 bool connected = false;
hkjung 0:7488a229e6fc 53 int blink_interval = 0;
hkjung 0:7488a229e6fc 54
hkjung 0:7488a229e6fc 55 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
hkjung 0:7488a229e6fc 56 {
hkjung 0:7488a229e6fc 57 const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
hkjung 0:7488a229e6fc 58 char hostname[strlen(org) + strlen(iot_ibm) + 1];
hkjung 0:7488a229e6fc 59 sprintf(hostname, "%s%s", org, iot_ibm);
hkjung 0:7488a229e6fc 60
hkjung 0:7488a229e6fc 61 //const char* iot_ibm = "23.246.232.210";
hkjung 0:7488a229e6fc 62 //char hostname[strlen(iot_ibm) + 1];
hkjung 0:7488a229e6fc 63 //sprintf(hostname, "%s", iot_ibm);
hkjung 2:b1dcfd885d7f 64
hkjung 0:7488a229e6fc 65 DEBUG("hostname is %s\r\n", hostname);
hkjung 0:7488a229e6fc 66 int rc = ipstack->connect(hostname, IBM_IOT_PORT);
hkjung 0:7488a229e6fc 67 if (rc != 0)
hkjung 0:7488a229e6fc 68 return rc;
hkjung 0:7488a229e6fc 69
hkjung 0:7488a229e6fc 70 // Construct clientId - d:org:type:id
hkjung 0:7488a229e6fc 71 char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
hkjung 2:b1dcfd885d7f 72 sprintf(clientId, "d:%s:%s:%s", org, type, id);
hkjung 0:7488a229e6fc 73 DEBUG("clientid is %s\r\n", clientId);
hkjung 0:7488a229e6fc 74
hkjung 0:7488a229e6fc 75 // MQTT Connect
hkjung 0:7488a229e6fc 76 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
hkjung 0:7488a229e6fc 77 data.MQTTVersion = 3;
hkjung 0:7488a229e6fc 78 data.clientID.cstring = clientId;
hkjung 0:7488a229e6fc 79
hkjung 0:7488a229e6fc 80 if (!quickstartMode) {
hkjung 0:7488a229e6fc 81 data.username.cstring = "use-token-auth";
hkjung 0:7488a229e6fc 82 data.password.cstring = auth_token;
hkjung 0:7488a229e6fc 83 }
hkjung 0:7488a229e6fc 84
hkjung 0:7488a229e6fc 85 if ((rc = client->connect(data)) == 0) {
hkjung 0:7488a229e6fc 86 connected = true;
hkjung 2:b1dcfd885d7f 87 #if defined(TARGET_WIZwiki_W7500)
hkjung 0:7488a229e6fc 88 green();
hkjung 2:b1dcfd885d7f 89 #endif
hkjung 0:7488a229e6fc 90 printf("Connected\r\n");
hkjung 0:7488a229e6fc 91 wait(2);
hkjung 0:7488a229e6fc 92 }
hkjung 0:7488a229e6fc 93 return rc;
hkjung 0:7488a229e6fc 94 }
hkjung 0:7488a229e6fc 95
hkjung 0:7488a229e6fc 96 int getConnTimeout(int attemptNumber)
hkjung 0:7488a229e6fc 97 {
hkjung 0:7488a229e6fc 98 // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
hkjung 0:7488a229e6fc 99 // after 20 attempts, retry every 10 minutes
hkjung 0:7488a229e6fc 100 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
hkjung 0:7488a229e6fc 101 }
hkjung 0:7488a229e6fc 102
hkjung 0:7488a229e6fc 103
hkjung 0:7488a229e6fc 104 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
hkjung 0:7488a229e6fc 105 {
hkjung 0:7488a229e6fc 106 int retryAttempt = 0;
hkjung 0:7488a229e6fc 107 connected = false;
hkjung 0:7488a229e6fc 108
hkjung 0:7488a229e6fc 109 // make sure a cable is connected before starting to connect
hkjung 0:7488a229e6fc 110 /*
hkjung 0:7488a229e6fc 111 while (!linkStatus()) {
hkjung 0:7488a229e6fc 112 wait(1.0f);
hkjung 0:7488a229e6fc 113 WARN("Ethernet link not present. Check cable connection\n");
hkjung 0:7488a229e6fc 114 }
hkjung 0:7488a229e6fc 115 */
hkjung 0:7488a229e6fc 116
hkjung 0:7488a229e6fc 117 while (connect(client, ipstack) != 0) {
hkjung 0:7488a229e6fc 118 #if defined(TARGET_WIZwiki_W7500)
hkjung 0:7488a229e6fc 119 red();
hkjung 0:7488a229e6fc 120 #endif
hkjung 0:7488a229e6fc 121 int timeout = getConnTimeout(++retryAttempt);
hkjung 2:b1dcfd885d7f 122 WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout);
hkjung 0:7488a229e6fc 123
hkjung 0:7488a229e6fc 124 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
hkjung 0:7488a229e6fc 125 // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
hkjung 0:7488a229e6fc 126
hkjung 0:7488a229e6fc 127 // this works - reset the system when the retry count gets to a threshold
hkjung 0:7488a229e6fc 128 if (retryAttempt == 5)
hkjung 0:7488a229e6fc 129 NVIC_SystemReset();
hkjung 0:7488a229e6fc 130 else
hkjung 0:7488a229e6fc 131 wait(timeout);
hkjung 0:7488a229e6fc 132 }
hkjung 0:7488a229e6fc 133 }
hkjung 0:7488a229e6fc 134
hkjung 0:7488a229e6fc 135 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
hkjung 0:7488a229e6fc 136 {
hkjung 0:7488a229e6fc 137 MQTT::Message message;
hkjung 0:7488a229e6fc 138 char* pubTopic = "iot-2/evt/status/fmt/json";
hkjung 0:7488a229e6fc 139
hkjung 0:7488a229e6fc 140 char buf[250];
hkjung 2:b1dcfd885d7f 141
hkjung 2:b1dcfd885d7f 142 sprintf(buf, "{\"d\":{\"myName\":\"IoT mbed\",\"potentiometer\":%0.4f}}", ain0.read());
hkjung 0:7488a229e6fc 143
hkjung 0:7488a229e6fc 144 message.qos = MQTT::QOS0;
hkjung 0:7488a229e6fc 145 message.retained = false;
hkjung 0:7488a229e6fc 146 message.dup = false;
hkjung 0:7488a229e6fc 147 message.payload = (void*)buf;
hkjung 0:7488a229e6fc 148 message.payloadlen = strlen(buf);
hkjung 0:7488a229e6fc 149
hkjung 0:7488a229e6fc 150 LOG("Publishing %s\r\n", buf);
hkjung 0:7488a229e6fc 151 return client->publish(pubTopic, message);
hkjung 0:7488a229e6fc 152 }
hkjung 0:7488a229e6fc 153
hkjung 0:7488a229e6fc 154 char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address
hkjung 0:7488a229e6fc 155 {
hkjung 0:7488a229e6fc 156 strncpy(buf, eth.getMACAddress(), buflen);
hkjung 0:7488a229e6fc 157
hkjung 0:7488a229e6fc 158 char* pos; // Remove colons from mac address
hkjung 0:7488a229e6fc 159 while ((pos = strchr(buf, ':')) != NULL)
hkjung 0:7488a229e6fc 160 memmove(pos, pos + 1, strlen(pos) + 1);
hkjung 0:7488a229e6fc 161 return buf;
hkjung 0:7488a229e6fc 162 }
hkjung 0:7488a229e6fc 163
hkjung 0:7488a229e6fc 164 void messageArrived(MQTT::MessageData& md)
hkjung 0:7488a229e6fc 165 {
hkjung 0:7488a229e6fc 166 MQTT::Message &message = md.message;
hkjung 0:7488a229e6fc 167 char topic[md.topicName.lenstring.len + 1];
hkjung 0:7488a229e6fc 168
hkjung 0:7488a229e6fc 169 sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
hkjung 0:7488a229e6fc 170
hkjung 0:7488a229e6fc 171 LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload);
hkjung 0:7488a229e6fc 172
hkjung 0:7488a229e6fc 173 // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
hkjung 0:7488a229e6fc 174 char* start = strstr(topic, "/cmd/") + 5;
hkjung 0:7488a229e6fc 175 int len = strstr(topic, "/fmt/") - start;
hkjung 0:7488a229e6fc 176
hkjung 0:7488a229e6fc 177 if (memcmp(start, "blink", len) == 0) {
hkjung 0:7488a229e6fc 178 char payload[message.payloadlen + 1];
hkjung 0:7488a229e6fc 179 sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
hkjung 0:7488a229e6fc 180
hkjung 0:7488a229e6fc 181 char* pos = strchr(payload, '}');
hkjung 0:7488a229e6fc 182 if (pos != NULL) {
hkjung 0:7488a229e6fc 183 *pos = '\0';
hkjung 0:7488a229e6fc 184 if ((pos = strchr(payload, ':')) != NULL) {
hkjung 0:7488a229e6fc 185 int blink_rate = atoi(pos + 1);
hkjung 0:7488a229e6fc 186 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
hkjung 0:7488a229e6fc 187 }
hkjung 0:7488a229e6fc 188 }
hkjung 0:7488a229e6fc 189 } else
hkjung 2:b1dcfd885d7f 190 WARN("Unsupported command: %.*s\r\n", len, start);
hkjung 0:7488a229e6fc 191 }
hkjung 0:7488a229e6fc 192
hkjung 0:7488a229e6fc 193 int main (void)
hkjung 0:7488a229e6fc 194 {
hkjung 2:b1dcfd885d7f 195 pc.baud(115200);
hkjung 2:b1dcfd885d7f 196
hkjung 2:b1dcfd885d7f 197 #if defined(TARGET_WIZwiki_W7500)
hkjung 2:b1dcfd885d7f 198 // Board init indicator : Init success
hkjung 0:7488a229e6fc 199 red();
hkjung 0:7488a229e6fc 200 wait(0.2);
hkjung 2:b1dcfd885d7f 201 blue();
hkjung 0:7488a229e6fc 202 wait(0.2);
hkjung 0:7488a229e6fc 203 green();
hkjung 0:7488a229e6fc 204 wait(0.2);
hkjung 0:7488a229e6fc 205 off();
hkjung 0:7488a229e6fc 206 wait(0.2);
hkjung 0:7488a229e6fc 207 // end of board init indicator
hkjung 2:b1dcfd885d7f 208 #endif
hkjung 0:7488a229e6fc 209
hkjung 2:b1dcfd885d7f 210 quickstartMode = (strcmp(org, "quickstart") == 0);
hkjung 0:7488a229e6fc 211 printf("Connecting...\r\n");
hkjung 0:7488a229e6fc 212
hkjung 0:7488a229e6fc 213 #if defined(TARGET_WIZwiki_W7500)
hkjung 2:b1dcfd885d7f 214 blue();
hkjung 0:7488a229e6fc 215 #endif
hkjung 0:7488a229e6fc 216
hkjung 0:7488a229e6fc 217 MQTTEthernet ipstack;
hkjung 0:7488a229e6fc 218 MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
hkjung 0:7488a229e6fc 219
hkjung 0:7488a229e6fc 220 if (quickstartMode) {
hkjung 0:7488a229e6fc 221 getMac(ipstack.getEth(), id, sizeof(id));
hkjung 2:b1dcfd885d7f 222 //printf("getMac: %s\r\n", id);
hkjung 0:7488a229e6fc 223 }
hkjung 0:7488a229e6fc 224
hkjung 0:7488a229e6fc 225 attemptConnect(&client, &ipstack);
hkjung 0:7488a229e6fc 226
hkjung 0:7488a229e6fc 227 if (!quickstartMode)
hkjung 0:7488a229e6fc 228 {
hkjung 0:7488a229e6fc 229 int rc = 0;
hkjung 0:7488a229e6fc 230 if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
hkjung 2:b1dcfd885d7f 231 WARN("rc from MQTT subscribe is %d\r\n", rc);
hkjung 0:7488a229e6fc 232 }
hkjung 0:7488a229e6fc 233
hkjung 0:7488a229e6fc 234 blink_interval = 0;
hkjung 0:7488a229e6fc 235 int count = 0;
hkjung 0:7488a229e6fc 236
hkjung 0:7488a229e6fc 237 while(true)
hkjung 0:7488a229e6fc 238 {
hkjung 2:b1dcfd885d7f 239 if (++count == 100)
hkjung 2:b1dcfd885d7f 240 { // Publish a message every second
hkjung 2:b1dcfd885d7f 241
hkjung 2:b1dcfd885d7f 242 //printf("A0: %0.4f\r\n", ain0.read());
hkjung 0:7488a229e6fc 243
hkjung 0:7488a229e6fc 244 if (publish(&client, &ipstack) != 0)
hkjung 0:7488a229e6fc 245 attemptConnect(&client, &ipstack); // if we have lost the connection
hkjung 0:7488a229e6fc 246 count = 0;
hkjung 0:7488a229e6fc 247 }
hkjung 0:7488a229e6fc 248
hkjung 2:b1dcfd885d7f 249
hkjung 2:b1dcfd885d7f 250 // LED Blink: By Bluemix
hkjung 2:b1dcfd885d7f 251
hkjung 2:b1dcfd885d7f 252 if (blink_interval == 0)
hkjung 2:b1dcfd885d7f 253 off();
hkjung 2:b1dcfd885d7f 254 else if (count % blink_interval == 0)
hkjung 2:b1dcfd885d7f 255 b = !b;
hkjung 2:b1dcfd885d7f 256
hkjung 0:7488a229e6fc 257 client.yield(10); // allow the MQTT client to receive messages
hkjung 0:7488a229e6fc 258 }
hkjung 0:7488a229e6fc 259 }
hkjung 0:7488a229e6fc 260
hkjung 2:b1dcfd885d7f 261 #if defined(TARGET_WIZwiki_W7500)
hkjung 2:b1dcfd885d7f 262 // PWM: RGB LED control -> DigitalOut
hkjung 2:b1dcfd885d7f 263 void off()
hkjung 2:b1dcfd885d7f 264 {
hkjung 2:b1dcfd885d7f 265 //r = g = b = 1.0; // 1 is off, 0 is full brightness
hkjung 2:b1dcfd885d7f 266 r = g = b = 1;
hkjung 2:b1dcfd885d7f 267 }
hkjung 2:b1dcfd885d7f 268
hkjung 2:b1dcfd885d7f 269 void red()
hkjung 2:b1dcfd885d7f 270 {
hkjung 2:b1dcfd885d7f 271 //r = 0.7; g = 1.0; b = 1.0; // 1 is off, 0 is full brightness
hkjung 2:b1dcfd885d7f 272 r = 0; g = 1; b = 1;
hkjung 2:b1dcfd885d7f 273 }
hkjung 2:b1dcfd885d7f 274
hkjung 2:b1dcfd885d7f 275 void green()
hkjung 2:b1dcfd885d7f 276 {
hkjung 2:b1dcfd885d7f 277 //r = 1.0; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
hkjung 2:b1dcfd885d7f 278 r = 1; g = 0; b = 1;
hkjung 2:b1dcfd885d7f 279 }
hkjung 2:b1dcfd885d7f 280
hkjung 2:b1dcfd885d7f 281 void blue()
hkjung 2:b1dcfd885d7f 282 {
hkjung 2:b1dcfd885d7f 283 //r = 1.0; g = 1.0; b = 0.7; // 1 is off, 0 is full brightness
hkjung 2:b1dcfd885d7f 284 r = 1; g = 1; b = 0;
hkjung 2:b1dcfd885d7f 285 }
hkjung 2:b1dcfd885d7f 286
hkjung 2:b1dcfd885d7f 287
hkjung 2:b1dcfd885d7f 288 //void yellow()
hkjung 2:b1dcfd885d7f 289 //{
hkjung 2:b1dcfd885d7f 290 //r = 0.7; g = 0.7; b = 1.0; // 1 is off, 0 is full brightness
hkjung 2:b1dcfd885d7f 291 //}
hkjung 2:b1dcfd885d7f 292 #endif
hkjung 2:b1dcfd885d7f 293