This is example for using IBM IoT Client on W5500(Hardware Stack)
Dependencies: MQTT W5500Interface mbed
main.cpp@2:87c816cd88e2, 2014-09-29 (annotated)
- Committer:
- kaizen
- Date:
- Mon Sep 29 05:06:13 2014 +0000
- Revision:
- 2:87c816cd88e2
- Parent:
- 1:532d83b9f910
This is example for using IBM Iot Client
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kaizen | 0:910036879da0 | 1 | #include "mbed.h" |
kaizen | 0:910036879da0 | 2 | #include "MQTTClient.h" |
kaizen | 0:910036879da0 | 3 | #include "MQTTEthernet.h" |
kaizen | 0:910036879da0 | 4 | |
kaizen | 0:910036879da0 | 5 | // Configuration values needed to connect to IBM IoT Cloud |
kaizen | 1:532d83b9f910 | 6 | #define QUICKSTARTMODE 0 |
kaizen | 0:910036879da0 | 7 | #if (QUICKSTARTMODE) |
kaizen | 1:532d83b9f910 | 8 | #define ORG "uasfg" |
kaizen | 0:910036879da0 | 9 | #define ID "" |
kaizen | 1:532d83b9f910 | 10 | #define AUTH_TOKEN "mhhWy4Qg)C*w3jL@(O" |
kaizen | 1:532d83b9f910 | 11 | #define TYPE "W5500" |
kaizen | 0:910036879da0 | 12 | #else |
kaizen | 1:532d83b9f910 | 13 | #define ORG "uasfg" |
kaizen | 1:532d83b9f910 | 14 | #define ID "" |
kaizen | 1:532d83b9f910 | 15 | #define AUTH_TOKEN "mhhWy4Qg)C*w3jL@(O" |
kaizen | 1:532d83b9f910 | 16 | #define TYPE "W5500" |
kaizen | 0:910036879da0 | 17 | #endif |
kaizen | 0:910036879da0 | 18 | |
kaizen | 0:910036879da0 | 19 | #define MQTT_PORT 1883 |
kaizen | 0:910036879da0 | 20 | #define MQTT_TLS_PORT 8883 |
kaizen | 0:910036879da0 | 21 | #define IBM_IOT_PORT MQTT_PORT |
kaizen | 0:910036879da0 | 22 | |
kaizen | 0:910036879da0 | 23 | #define MQTT_MAX_PACKET_SIZE 250 |
kaizen | 0:910036879da0 | 24 | |
kaizen | 0:910036879da0 | 25 | |
kaizen | 1:532d83b9f910 | 26 | #define USING_HW_STACK_W5500 |
kaizen | 1:532d83b9f910 | 27 | |
kaizen | 0:910036879da0 | 28 | bool quickstartMode = (QUICKSTARTMODE) ? true : false; |
kaizen | 0:910036879da0 | 29 | char org[11] = ORG; |
kaizen | 0:910036879da0 | 30 | char type[30] = TYPE; |
kaizen | 0:910036879da0 | 31 | char id[30] = ID; // mac without colons |
kaizen | 0:910036879da0 | 32 | char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode |
kaizen | 0:910036879da0 | 33 | |
kaizen | 0:910036879da0 | 34 | bool connected = false; |
kaizen | 0:910036879da0 | 35 | |
kaizen | 0:910036879da0 | 36 | |
kaizen | 0:910036879da0 | 37 | char* getMac(EthernetInterface& eth, char* buf, int buflen) // Obtain MAC address |
kaizen | 0:910036879da0 | 38 | { |
kaizen | 1:532d83b9f910 | 39 | strncpy(buf, eth.getMACAddress(), buflen); |
kaizen | 0:910036879da0 | 40 | |
kaizen | 0:910036879da0 | 41 | char* pos; // Remove colons from mac address |
kaizen | 0:910036879da0 | 42 | while ((pos = strchr(buf, ':')) != NULL) |
kaizen | 0:910036879da0 | 43 | memmove(pos, pos + 1, strlen(pos) + 1); |
kaizen | 0:910036879da0 | 44 | return buf; |
kaizen | 0:910036879da0 | 45 | } |
kaizen | 0:910036879da0 | 46 | |
kaizen | 0:910036879da0 | 47 | |
kaizen | 0:910036879da0 | 48 | int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
kaizen | 0:910036879da0 | 49 | { |
kaizen | 0:910036879da0 | 50 | const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; |
kaizen | 0:910036879da0 | 51 | |
kaizen | 0:910036879da0 | 52 | char hostname[strlen(org) + strlen(iot_ibm) + 1]; |
kaizen | 0:910036879da0 | 53 | sprintf(hostname, "%s%s", org, iot_ibm); |
kaizen | 0:910036879da0 | 54 | int rc = ipstack->connect(hostname, IBM_IOT_PORT); |
kaizen | 1:532d83b9f910 | 55 | |
kaizen | 0:910036879da0 | 56 | if (rc != 0) |
kaizen | 0:910036879da0 | 57 | return rc; |
kaizen | 0:910036879da0 | 58 | |
kaizen | 0:910036879da0 | 59 | // Construct clientId - d:org:type:id |
kaizen | 0:910036879da0 | 60 | char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; |
kaizen | 0:910036879da0 | 61 | sprintf(clientId, "d:%s:%s:%s", org, type, id); |
kaizen | 0:910036879da0 | 62 | DEBUG("clientid is %s\r\n", clientId); |
kaizen | 0:910036879da0 | 63 | |
kaizen | 0:910036879da0 | 64 | // MQTT Connect |
kaizen | 0:910036879da0 | 65 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
kaizen | 0:910036879da0 | 66 | data.MQTTVersion = 3; |
kaizen | 0:910036879da0 | 67 | data.clientID.cstring = clientId; |
kaizen | 0:910036879da0 | 68 | |
kaizen | 0:910036879da0 | 69 | if (!quickstartMode) |
kaizen | 0:910036879da0 | 70 | { |
kaizen | 0:910036879da0 | 71 | data.username.cstring = "use-token-auth"; |
kaizen | 0:910036879da0 | 72 | data.password.cstring = auth_token; |
kaizen | 0:910036879da0 | 73 | } |
kaizen | 0:910036879da0 | 74 | |
kaizen | 0:910036879da0 | 75 | if ((rc = client->connect(&data)) == 0) |
kaizen | 0:910036879da0 | 76 | { |
kaizen | 0:910036879da0 | 77 | connected = true; |
kaizen | 0:910036879da0 | 78 | } |
kaizen | 1:532d83b9f910 | 79 | |
kaizen | 0:910036879da0 | 80 | return rc; |
kaizen | 0:910036879da0 | 81 | } |
kaizen | 0:910036879da0 | 82 | |
kaizen | 0:910036879da0 | 83 | |
kaizen | 0:910036879da0 | 84 | int getConnTimeout(int attemptNumber) |
kaizen | 0:910036879da0 | 85 | { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute |
kaizen | 0:910036879da0 | 86 | // after 20 attempts, retry every 10 minutes |
kaizen | 0:910036879da0 | 87 | return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; |
kaizen | 0:910036879da0 | 88 | } |
kaizen | 0:910036879da0 | 89 | |
kaizen | 0:910036879da0 | 90 | |
kaizen | 0:910036879da0 | 91 | void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
kaizen | 0:910036879da0 | 92 | { |
kaizen | 0:910036879da0 | 93 | int retryAttempt = 0; |
kaizen | 0:910036879da0 | 94 | connected = false; |
kaizen | 0:910036879da0 | 95 | |
kaizen | 0:910036879da0 | 96 | // make sure a cable is connected before starting to connect |
kaizen | 0:910036879da0 | 97 | while ( !ipstack->getEth().linkstatus() ) { |
kaizen | 0:910036879da0 | 98 | wait(1.0f); |
kaizen | 0:910036879da0 | 99 | WARN("Ethernet link not present. Check cable connection\r\n"); |
kaizen | 0:910036879da0 | 100 | } |
kaizen | 0:910036879da0 | 101 | |
kaizen | 0:910036879da0 | 102 | while (connect(client, ipstack) != 0) |
kaizen | 0:910036879da0 | 103 | { |
kaizen | 0:910036879da0 | 104 | int timeout = getConnTimeout(++retryAttempt); |
kaizen | 0:910036879da0 | 105 | WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout); |
kaizen | 0:910036879da0 | 106 | wait(timeout); |
kaizen | 0:910036879da0 | 107 | } |
kaizen | 0:910036879da0 | 108 | } |
kaizen | 0:910036879da0 | 109 | |
kaizen | 0:910036879da0 | 110 | int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack) |
kaizen | 0:910036879da0 | 111 | { |
kaizen | 0:910036879da0 | 112 | MQTT::Message message; |
kaizen | 0:910036879da0 | 113 | char* pubTopic = "iot-2/evt/status/fmt/json"; |
kaizen | 0:910036879da0 | 114 | |
kaizen | 0:910036879da0 | 115 | char buf[250]; |
kaizen | 0:910036879da0 | 116 | sprintf(buf, |
kaizen | 1:532d83b9f910 | 117 | "{\"d\":{\"myName\":\"IoT mbed\",\"cputemp\":%0.4f,\"testvalue\":%s}}", |
kaizen | 1:532d83b9f910 | 118 | 12.4,"W5500"); |
kaizen | 0:910036879da0 | 119 | |
kaizen | 0:910036879da0 | 120 | message.qos = MQTT::QOS0; |
kaizen | 0:910036879da0 | 121 | message.retained = false; |
kaizen | 0:910036879da0 | 122 | message.dup = false; |
kaizen | 0:910036879da0 | 123 | message.payload = (void*)buf; |
kaizen | 0:910036879da0 | 124 | message.payloadlen = strlen(buf); |
kaizen | 0:910036879da0 | 125 | |
kaizen | 0:910036879da0 | 126 | LOG("Publishing %s\r\n", buf); |
kaizen | 0:910036879da0 | 127 | return client->publish(pubTopic, &message); |
kaizen | 0:910036879da0 | 128 | } |
kaizen | 0:910036879da0 | 129 | |
kaizen | 0:910036879da0 | 130 | |
kaizen | 0:910036879da0 | 131 | void messageArrived(MQTT::MessageData& md) |
kaizen | 0:910036879da0 | 132 | { |
kaizen | 0:910036879da0 | 133 | MQTT::Message &message = md.message; |
kaizen | 0:910036879da0 | 134 | char topic[md.topicName.lenstring.len + 1]; |
kaizen | 0:910036879da0 | 135 | |
kaizen | 0:910036879da0 | 136 | sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); |
kaizen | 0:910036879da0 | 137 | |
kaizen | 0:910036879da0 | 138 | LOG("Message arrived on topic %s: %.*s\r\n", topic, message.payloadlen, message.payload); |
kaizen | 0:910036879da0 | 139 | |
kaizen | 0:910036879da0 | 140 | // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/ |
kaizen | 0:910036879da0 | 141 | char* start = strstr(topic, "/cmd/") + 5; |
kaizen | 0:910036879da0 | 142 | int len = strstr(topic, "/fmt/") - start; |
kaizen | 0:910036879da0 | 143 | |
kaizen | 0:910036879da0 | 144 | if (memcmp(start, "blink", len) == 0) |
kaizen | 0:910036879da0 | 145 | { |
kaizen | 0:910036879da0 | 146 | char payload[message.payloadlen + 1]; |
kaizen | 0:910036879da0 | 147 | sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); |
kaizen | 0:910036879da0 | 148 | |
kaizen | 0:910036879da0 | 149 | char* pos = strchr(payload, '}'); |
kaizen | 0:910036879da0 | 150 | if (pos != NULL) |
kaizen | 0:910036879da0 | 151 | { |
kaizen | 0:910036879da0 | 152 | *pos = '\0'; |
kaizen | 0:910036879da0 | 153 | if ((pos = strchr(payload, ':')) != NULL) |
kaizen | 0:910036879da0 | 154 | { |
kaizen | 0:910036879da0 | 155 | } |
kaizen | 0:910036879da0 | 156 | } |
kaizen | 0:910036879da0 | 157 | } |
kaizen | 0:910036879da0 | 158 | else |
kaizen | 0:910036879da0 | 159 | WARN("Unsupported command: %.*s\r\n", len, start); |
kaizen | 0:910036879da0 | 160 | } |
kaizen | 0:910036879da0 | 161 | |
kaizen | 0:910036879da0 | 162 | int main() |
kaizen | 0:910036879da0 | 163 | { |
kaizen | 1:532d83b9f910 | 164 | #if defined(TARGET_KL25Z) |
kaizen | 2:87c816cd88e2 | 165 | Serial pc(USBTX, USBRX); |
kaizen | 2:87c816cd88e2 | 166 | pc.baud(115200); |
kaizen | 2:87c816cd88e2 | 167 | |
kaizen | 2:87c816cd88e2 | 168 | SPI spi(D11, D12, D13); // mosi, miso, sclk |
kaizen | 2:87c816cd88e2 | 169 | wait(1); |
kaizen | 1:532d83b9f910 | 170 | |
kaizen | 2:87c816cd88e2 | 171 | MQTTEthernet ipstack(&spi, D10, D9); //scs(D10), nRESET(PTA20) |
kaizen | 2:87c816cd88e2 | 172 | MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); |
kaizen | 1:532d83b9f910 | 173 | #endif |
kaizen | 0:910036879da0 | 174 | |
kaizen | 1:532d83b9f910 | 175 | getMac(ipstack.getEth(), id, sizeof(id)); |
kaizen | 0:910036879da0 | 176 | attemptConnect(&client, &ipstack); |
kaizen | 0:910036879da0 | 177 | |
kaizen | 0:910036879da0 | 178 | int count = 0; |
kaizen | 0:910036879da0 | 179 | while (true) |
kaizen | 0:910036879da0 | 180 | { |
kaizen | 0:910036879da0 | 181 | if (!ipstack.getEth().linkstatus()) { |
kaizen | 0:910036879da0 | 182 | NVIC_SystemReset(); |
kaizen | 0:910036879da0 | 183 | // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed |
kaizen | 0:910036879da0 | 184 | // or maybe just add the proper members to do this disconnect and call attemptConnect(...) |
kaizen | 0:910036879da0 | 185 | } |
kaizen | 0:910036879da0 | 186 | |
kaizen | 0:910036879da0 | 187 | if (++count == 100) |
kaizen | 0:910036879da0 | 188 | { // Publish a message every second |
kaizen | 0:910036879da0 | 189 | if (publish(&client, &ipstack) != 0) |
kaizen | 0:910036879da0 | 190 | attemptConnect(&client, &ipstack); // if we have lost the connection |
kaizen | 0:910036879da0 | 191 | count = 0; |
kaizen | 0:910036879da0 | 192 | } |
kaizen | 0:910036879da0 | 193 | |
kaizen | 0:910036879da0 | 194 | client.yield(10); // allow the MQTT client to receive messages |
kaizen | 0:910036879da0 | 195 | } |
kaizen | 0:910036879da0 | 196 | } |