IBMIoTClientEthernetExample for WIZwiki-W7500 platform
Dependencies: MQTT WIZnetInterface mbed-src
Diff: main.cpp
- Revision:
- 0:7488a229e6fc
- Child:
- 2:b1dcfd885d7f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jun 29 11:57:28 2015 +0000 @@ -0,0 +1,281 @@ +#include "mbed.h" +#include "EthernetInterface.h" +#include "MQTTClient.h" +#include "MQTTEthernet.h" + +// Update this to the next number *before* a commit +#define __APP_SW_REVISION__ "1" + +// Configuration values needed to connect to IBM IoT Cloud +#define ORG "pya466" // For a registered connection, replace with your org +#define ID "0008DC1D69F3" // For a registered connection, replace with your id +#define AUTH_TOKEN "RS-NqB7J72H8rwIA7Q" // For a registered connection, replace with your auth-token +#define TYPE "WIZwiki-W7500_Eric" // For a registered connection, replace with your type + +#define MQTT_PORT 1883 +#define MQTT_TLS_PORT 8883 +#define IBM_IOT_PORT MQTT_PORT + +#define MQTT_MAX_PACKET_SIZE 250 + +#if defined(TARGET_WIZwiki_W7500) +#warning "Compiling for mbed WIZwiki-W7500" +#include "WIZwiki-W7500.h" +#endif + +bool quickstartMode = true; +char org[11] = ORG; +char type[30] = TYPE; +char id[30] = ID; // mac without colons +char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode + +bool connected = false; +int blink_interval = 0; + +void baud(int baudrate) +{ + Serial s(USBTX, USBRX); + s.baud(baudrate); +} + +// PWM: RGB LED control +void off() +{ + r = g = b = 1.0; // 1 is off, 0 is full brightness +} + +void red() +{ + r = 0.7; + g = 1.0; + b = 1.0; // 1 is off, 0 is full brightness +} + +void yellow() +{ + r = 0.7; + g = 0.7; + b = 1.0; // 1 is off, 0 is full brightness +} + +void green() +{ + r = 1.0; + g = 0.7; + b = 1.0; // 1 is off, 0 is full brightness +} + +int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; + char hostname[strlen(org) + strlen(iot_ibm) + 1]; + sprintf(hostname, "%s%s", org, iot_ibm); + + //const char* iot_ibm = "23.246.232.210"; + //char hostname[strlen(iot_ibm) + 1]; + //sprintf(hostname, "%s", iot_ibm); + + //DEBUG("hostname is %s\n", hostname); + DEBUG("hostname is %s\r\n", hostname); + int rc = ipstack->connect(hostname, IBM_IOT_PORT); + if (rc != 0) + return rc; + + // Construct clientId - d:org:type:id + char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; + sprintf(clientId, "d:%s:%s:%s", org, type, id); + //DEBUG("clientid is %s\n", clientId); + DEBUG("clientid is %s\r\n", clientId); + + // MQTT Connect + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 3; + data.clientID.cstring = clientId; + + if (!quickstartMode) { + data.username.cstring = "use-token-auth"; + data.password.cstring = auth_token; + } + + if ((rc = client->connect(data)) == 0) { + connected = true; + green(); + //displayMessage("Connected"); + printf("Connected\r\n"); + wait(2); + } + return rc; +} + +int getConnTimeout(int attemptNumber) +{ + // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute + // after 20 attempts, retry every 10 minutes + return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; +} + + +void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + int retryAttempt = 0; + connected = false; + + // make sure a cable is connected before starting to connect + /* + while (!linkStatus()) { + wait(1.0f); + WARN("Ethernet link not present. Check cable connection\n"); + } + */ + + while (connect(client, ipstack) != 0) { +#if defined(TARGET_WIZwiki_W7500) + red(); +#endif + int timeout = getConnTimeout(++retryAttempt); + WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout); + //WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); + + // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed + // or maybe just add the proper members to do this disconnect and call attemptConnect(...) + + // this works - reset the system when the retry count gets to a threshold + if (retryAttempt == 5) + NVIC_SystemReset(); + else + wait(timeout); + } +} + +int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) +{ + MQTT::Message message; + char* pubTopic = "iot-2/evt/status/fmt/json"; + + char buf[250]; + /* + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}", + MMA.x(), MMA.y(), MMA.z(), sensor.temp(), joystickPos, ain1.read(), ain2.read()); + */ + /* + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"temp\":%0.4f,\"light\":%0.4f}}", + ain0.read(), ain1.read()); + */ + + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"temp\":%0.4f,\"light\":%0.4f}}", + ain0.read(), ain1.read()); + + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + LOG("Publishing %s\r\n", buf); + return client->publish(pubTopic, message); +} + +char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address +{ + strncpy(buf, eth.getMACAddress(), buflen); + + char* pos; // Remove colons from mac address + while ((pos = strchr(buf, ':')) != NULL) + memmove(pos, pos + 1, strlen(pos) + 1); + return buf; +} + +void messageArrived(MQTT::MessageData& md) +{ + MQTT::Message &message = md.message; + char topic[md.topicName.lenstring.len + 1]; + + sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); + + LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload); + + // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ + char* start = strstr(topic, "/cmd/") + 5; + int len = strstr(topic, "/fmt/") - start; + + if (memcmp(start, "blink", len) == 0) { + char payload[message.payloadlen + 1]; + sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); + + char* pos = strchr(payload, '}'); + if (pos != NULL) { + *pos = '\0'; + if ((pos = strchr(payload, ':')) != NULL) { + int blink_rate = atoi(pos + 1); + blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate); + } + } + } else + WARN("Unsupported command: %.*s\r\n", len, start); + //WARN("Unsupported command: %.*s\n", len, start); +} + +int main (void) +{ + baud(115200); + + // Board init indicator : Init success + red(); + wait(0.2); + yellow(); + wait(0.2); + green(); + wait(0.2); + off(); + wait(0.2); + // end of board init indicator + + quickstartMode = (strcmp(org, "quickstart") == 0); + //displayMessage("Connecting"); + printf("Connecting...\r\n"); + +#if defined(TARGET_WIZwiki_W7500) + yellow(); +#endif + + MQTTEthernet ipstack; + MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); + + if (quickstartMode) { + getMac(ipstack.getEth(), id, sizeof(id)); + //printf("%s\r\n", id); //?? + } + + attemptConnect(&client, &ipstack); + + if (!quickstartMode) + { + int rc = 0; + if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0) + WARN("rc from MQTT subscribe is %d\r\n", rc); + //WARN("rc from MQTT subscribe is %d\n", rc); + } + + blink_interval = 0; + int count = 0; + + while(true) + { + //if (++count == 100) + if (++count == 500) + { // Publish a message every second + + //printf("A0: %0.4f, A1: %0.4f\r\n", ain0.read(), ain1.read()); + + if (publish(&client, &ipstack) != 0) + attemptConnect(&client, &ipstack); // if we have lost the connection + count = 0; + } + + client.yield(10); // allow the MQTT client to receive messages + } +} +