IBMIoTClientEthernetExample for WIZwiki-W7500 platform

Dependencies:   MQTT WIZnetInterface mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EthernetInterface.h"
00003 #include "MQTTClient.h"
00004 #include "MQTTEthernet.h"
00005 
00006 Serial pc(USBTX, USBRX);
00007 
00008 // Update this to the next number *before* a commit
00009 #define __APP_SW_REVISION__ "1"
00010 
00011 // Configuration values needed to connect to IBM IoT Cloud
00012 #define QUICKSTARTMODE      1
00013 #if (QUICKSTARTMODE)
00014     #define ORG         "quickstart"    // For a registered connection, replace with your org
00015     #define ID          ""              // For a registered connection, replace with your id
00016     #define AUTH_TOKEN  ""              // For a registered connection, replace with your auth-token
00017     #define TYPE DEFAULT_TYPE_NAME      // For a registered connection, replace with your type
00018 #else
00019     #define ORG         ""              // For a registered connection, replace with your org
00020     #define ID          ""              // For a registered connection, replace with your id
00021     #define AUTH_TOKEN  ""              // For a registered connection, replace with your auth-token
00022     #define TYPE        "WIZwiki-W7500" // For a registered connection, replace with your type
00023 #endif
00024 
00025 #if defined(TARGET_WIZwiki_W7500)
00026 //#warning "Compiling for mbed WIZwiki-W7500"
00027 #include "WIZwiki-W7500.h"
00028 #endif
00029 
00030 #define MQTT_PORT 1883
00031 #define MQTT_TLS_PORT 8883
00032 #define IBM_IOT_PORT MQTT_PORT
00033 
00034 #define MQTT_MAX_PACKET_SIZE 250
00035 
00036 #if defined(TARGET_WIZwiki_W7500)
00037 // RGB LED control
00038 void off();
00039 void red();
00040 void green();
00041 void blue();
00042 #endif
00043 
00044 bool quickstartMode = QUICKSTARTMODE;
00045 char org[11] = ORG;
00046 char type[30] = TYPE;
00047 char id[30] = ID;                 // mac without colons
00048 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
00049 
00050 bool connected = false;
00051 int blink_interval = 0;
00052 
00053 int connect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
00054 {
00055     const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
00056     char hostname[strlen(org) + strlen(iot_ibm) + 1];
00057     sprintf(hostname, "%s%s", org, iot_ibm);
00058     
00059     //const char* iot_ibm = "23.246.232.210";
00060     //char hostname[strlen(iot_ibm) + 1];
00061     //sprintf(hostname, "%s", iot_ibm);
00062         
00063     DEBUG("hostname is %s\r\n", hostname);
00064     int rc = ipstack->connect(hostname, IBM_IOT_PORT);
00065     if (rc != 0)
00066         return rc;
00067 
00068     // Construct clientId - d:org:type:id
00069     char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
00070     sprintf(clientId, "d:%s:%s:%s", org, type, id);    
00071     DEBUG("clientid is %s\r\n", clientId);
00072 
00073     // MQTT Connect
00074     MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
00075     data.MQTTVersion = 3;
00076     data.clientID.cstring = clientId;
00077 
00078     if (!quickstartMode) {
00079         data.username.cstring = "use-token-auth";
00080         data.password.cstring = auth_token;
00081     }
00082 
00083     if ((rc = client->connect(data)) == 0) {
00084         connected = true;
00085 #if defined(TARGET_WIZwiki_W7500)       
00086         green();
00087 #endif  
00088         printf("Connected\r\n");
00089         wait(2);
00090     }
00091     return rc;
00092 }
00093 
00094 int getConnTimeout(int attemptNumber)
00095 {
00096     // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
00097     // after 20 attempts, retry every 10 minutes
00098     return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
00099 }
00100 
00101 
00102 void attemptConnect(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
00103 {
00104     int retryAttempt = 0;
00105     connected = false;
00106 
00107     // make sure a cable is connected before starting to connect
00108     /*
00109     while (!linkStatus()) {
00110         wait(1.0f);
00111         WARN("Ethernet link not present. Check cable connection\n");
00112     }
00113     */
00114 
00115     while (connect(client, ipstack) != 0) {
00116 #if defined(TARGET_WIZwiki_W7500)
00117         red();
00118 #endif
00119         int timeout = getConnTimeout(++retryAttempt);
00120         WARN("Retry attempt number %d waiting %d\r\n", retryAttempt, timeout);        
00121 
00122         // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
00123         //  or maybe just add the proper members to do this disconnect and call attemptConnect(...)
00124 
00125         // this works - reset the system when the retry count gets to a threshold
00126         if (retryAttempt == 5)
00127             NVIC_SystemReset();
00128         else
00129             wait(timeout);
00130     }
00131 }
00132 
00133 int publish(MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTEthernet* ipstack)
00134 {
00135     MQTT::Message message;
00136     char* pubTopic = "iot-2/evt/status/fmt/json";
00137 
00138     char buf[250];    
00139     
00140     sprintf(buf, "{\"d\":{\"myName\":\"IoT mbed\",\"potentiometer\":%0.3f}}", ain0.read());
00141     //sprintf(buf, "{\"d\":{\"myName\":\"IoT mbed\",\"potentiometer\":%0.4f}}", ain0.read());
00142             
00143     message.qos = MQTT::QOS0;
00144     message.retained = false;
00145     message.dup = false;
00146     message.payload = (void*)buf;
00147     message.payloadlen = strlen(buf);
00148 
00149     LOG("Publishing %s\r\n", buf);
00150     return client->publish(pubTopic, message);
00151 }
00152 
00153 char* getMac(EthernetInterface& eth, char* buf, int buflen)    // Obtain MAC address
00154 {
00155     strncpy(buf, eth.getMACAddress(), buflen);
00156 
00157     char* pos;                                                 // Remove colons from mac address
00158     while ((pos = strchr(buf, ':')) != NULL)
00159         memmove(pos, pos + 1, strlen(pos) + 1);
00160     return buf;
00161 }
00162 
00163 void messageArrived(MQTT::MessageData& md)
00164 {
00165     MQTT::Message &message = md.message;
00166     char topic[md.topicName.lenstring.len + 1];
00167 
00168     sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data);
00169 
00170     LOG("Message arrived on topic %s: %.*s\r\n",  topic, message.payloadlen, message.payload);
00171 
00172     // Command topic: iot-2/cmd/blink/fmt/json - cmd is the string between cmd/ and /fmt/
00173     char* start = strstr(topic, "/cmd/") + 5;
00174     int len = strstr(topic, "/fmt/") - start;
00175 
00176     if (memcmp(start, "blink", len) == 0) {
00177         char payload[message.payloadlen + 1];
00178         sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload);
00179 
00180         char* pos = strchr(payload, '}');
00181         if (pos != NULL) {
00182             *pos = '\0';
00183             if ((pos = strchr(payload, ':')) != NULL) {
00184                 int blink_rate = atoi(pos + 1);
00185                 blink_interval = (blink_rate <= 0) ? 0 : (blink_rate > 50 ? 1 : 50/blink_rate);
00186             }
00187         }
00188     } else
00189         WARN("Unsupported command: %.*s\r\n", len, start);        
00190 }
00191 
00192 int main (void)
00193 {
00194     pc.baud(115200);   
00195     
00196 #if defined(TARGET_WIZwiki_W7500)
00197     // Board init indicator : Init success    
00198     red();
00199     wait(0.2);
00200     blue();
00201     wait(0.2);
00202     green();
00203     wait(0.2);
00204     off();
00205     wait(0.2);
00206     // end of board init indicator
00207 #endif
00208 
00209     quickstartMode = (strcmp(org, "quickstart") == 0);    
00210     printf("Connecting...\r\n");
00211 
00212 #if defined(TARGET_WIZwiki_W7500)
00213     blue();
00214 #endif
00215 
00216     MQTTEthernet ipstack;
00217     MQTT::Client<MQTTEthernet, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
00218 
00219     if (quickstartMode) {
00220         getMac(ipstack.getEth(), id, sizeof(id));        
00221         //printf("getMac: %s\r\n", id);        
00222     }
00223     
00224     attemptConnect(&client, &ipstack);
00225     
00226     if (!quickstartMode) 
00227     {
00228         int rc = 0;
00229         if ((rc = client.subscribe("iot-2/cmd/+/fmt/json", MQTT::QOS1, messageArrived)) != 0)
00230             WARN("rc from MQTT subscribe is %d\r\n", rc);             
00231     }
00232     
00233     blink_interval = 0;
00234     int count = 0;
00235     
00236     while(true) 
00237     {
00238         if (++count == 100)        
00239         {               // Publish a message every second        
00240             
00241             //printf("A0: %0.4f\r\n", ain0.read());
00242         
00243             if (publish(&client, &ipstack) != 0) 
00244                 attemptConnect(&client, &ipstack);   // if we have lost the connection
00245             count = 0;
00246         }
00247         
00248         
00249         // Control the LED Blink interval: By Bluemix Node-RED        
00250         if (blink_interval == 0)            
00251             off();
00252         else if (count % blink_interval == 0)            
00253             b = !b;
00254         
00255         client.yield(10);  // allow the MQTT client to receive messages    
00256     }   
00257 }
00258 
00259 #if defined(TARGET_WIZwiki_W7500)
00260 // RGB LED control -> DigitalOut
00261 void off()
00262 {    
00263     r = g = b = 1;
00264 }
00265 
00266 void red()
00267 {    
00268     r = 0; g = 1; b = 1;
00269 }
00270 
00271 void green()
00272 {    
00273     r = 1; g = 0; b = 1;
00274 }
00275 
00276 void blue()
00277 {    
00278     r = 1; g = 1; b = 0;
00279 }
00280 #endif
00281