INSAT_MiniPRoject

Dependencies:   MQTT NDefLib NetworkSocketAPI Servo Light_Sensor_Nucleo X_NUCLEO_IDW01M1v2 mbed

Fork of IDW01M1_Cloud_IBM by ST

Revision:
14:641560b57584
Parent:
13:0b31131bf711
Child:
16:233b89a6b72f
--- a/main.cpp	Wed Sep 07 14:14:27 2016 +0000
+++ b/main.cpp	Wed Sep 28 13:28:44 2016 +0000
@@ -15,81 +15,224 @@
  */
 
 #include "mbed.h"
-#include "SPWFInterface.h"
+#include "SpwfInterface.h"
 #include "TCPSocket.h"
-
 #include "MQTTClient.h"
-
+#include "MQTTWiFi.h"
+#include <ctype.h>
+#include "x_nucleo_iks01a1.h"
 
 //------------------------------------
 // Hyperterminal configuration
 // 9600 bauds, 8-bit data, no parity
 //------------------------------------
-
 Serial pc(SERIAL_TX, SERIAL_RX); 
 DigitalOut myled(LED1);
-SpwfSAInterface spwf(PA_9, PA_10, PC_12, PC_8, PA_12, true);
+SpwfSAInterface spwf(D8, D2, false);
+bool quickstartMode = true;    
+    
+#define MQTT_MAX_PACKET_SIZE 250   
+#define MQTT_MAX_PAYLOAD_SIZE 300 
+ // Configuration values needed to connect to IBM IoT Cloud
+#define ORG "quickstart"             // For a registered connection, replace with your org
+#define ID ""                        // For a registered connection, replace with your id
+#define AUTH_TOKEN ""                // For a registered connection, replace with your auth-token
+#define DEFAULT_TYPE_NAME "iotsample-mbed-NucleoF401RE"
+#define TYPE DEFAULT_TYPE_NAME       // For a registered connection, replace with your type
+#define MQTT_PORT 1883
+#define MQTT_TLS_PORT 8883
+#define IBM_IOT_PORT MQTT_PORT
+    
+char id[30] = ID;                 // mac without colons  
+char org[12] = ORG;        
+int connack_rc = 0; // MQTT connack return code
+const char* ip_addr = "";
+char* host_addr = "";
+char type[30] = TYPE;
+char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
+bool netConnecting = false;
+//int connectTimeout = 1000;
+int connectTimeout = 10;
+bool mqttConnecting = false;
+bool netConnected = false;
+bool connected = false;
+int retryAttempt = 0;
+
+PressureSensor *pressure_sensor;
+HumiditySensor *humidity_sensor;
+TempSensor *temp_sensor1;
+
+
+int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
+{   
+    const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
+    
+    char hostname[strlen(org) + strlen(iot_ibm) + 1];
+    sprintf(hostname, "%s%s", org, iot_ibm);
+    SpwfSAInterface& WiFi = ipstack->getWiFi();
+    ip_addr = WiFi.get_ip_address();
+    printf ("ID: %s\n\r",id);
+    // Construct clientId - d:org:type:id
+    char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
+    sprintf(clientId, "d:%s:%s:%s", org, type, id);    
+    // Network debug statements 
+    LOG("=====================================\n\r");
+    LOG("Connecting WiFi.\n\r");
+    LOG("IP ADDRESS: %s\n\r", WiFi.get_ip_address());
+    LOG("MAC ADDRESS: %s\n\r", WiFi.get_mac_address());
+    LOG("Server Hostname: %s\n\r", hostname);
+    for(int i = 0; clientId[i]; i++){
+       clientId[i] = tolower(clientId[i]);
+    }    
+    LOG("Client ID: %s\n\r", clientId);
+    LOG("=====================================\n\r");
+    
+    netConnecting = true;
+    ipstack->open(&ipstack->getWiFi());
+    int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);
+    if (rc != 0)
+    {
+        WARN("IP Stack connect returned: %d\n", rc);    
+        return rc;
+    }
+    netConnected = true;
+    netConnecting = false;
+
+    // MQTT Connect
+    mqttConnecting = true;
+    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;
+        printf ("--->Connected\n\r");
+    }
+    else {
+        WARN("MQTT connect returned %d\n", rc);        
+    }
+    if (rc >= 0)
+        connack_rc = rc;
+    mqttConnecting = false;
+    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<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
+{
+    connected = false;
+           
+    while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) 
+    {    
+        if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
+            printf ("File: %s, Line: %d\n\r",__FILE__,__LINE__);        
+            return; // don't reattempt to connect if credentials are wrong
+        }          
+        int timeout = getConnTimeout(++retryAttempt);
+        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<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
+{
+    MQTT::Message message;
+    char* pubTopic = "iot-2/evt/status/fmt/json";
+            
+    char buf[MQTT_MAX_PAYLOAD_SIZE];
+    float temp, press, hum;
+    temp_sensor1->GetTemperature(&temp);
+    pressure_sensor->GetPressure(&press);
+    humidity_sensor->GetHumidity(&hum);
+    sprintf(buf,
+     "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":\"%0.4f,\",\"Humidity\":%0.4f}}",
+              temp, press, hum);
+    message.qos = MQTT::QOS0;
+    message.retained = false;
+    message.dup = false;
+    message.payload = (void*)buf;
+    message.payloadlen = strlen(buf);
+    
+    LOG("Publishing %s\n", buf);
+    return client->publish(pubTopic, message);
+} 
+ 
     
 int main()
 {
     int err;    
-    char * ssid = "crespan"; // Network must be visible otherwise it can't connect
-    char * seckey = "Elfrontal0";
+    const char * ssid = "crespan"; // Network must be visible otherwise it can't connect
+    const char * seckey = "Elfrontal0";
+    
+//    Timer tyeld;
+
+    DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL);
+    i2c->frequency(400000);    
+    
+    X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c);
+    
+    pressure_sensor = mems_expansion_board->pt_sensor;
+    temp_sensor1 = mems_expansion_board->ht_sensor;  
+    humidity_sensor = mems_expansion_board->ht_sensor;  
     
     pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n");     
-    pc.printf("\r\nconnecting to AP\r\n"); 
+    pc.printf("\r\nconnecting to AP\r\n");            
+//******************************************************************
 
-    err = spwf.connect(ssid, seckey, NSAPI_SECURITY_WPA2); //WPA2
-    
-    if(err!=0)
-    {
-        pc.printf("\r\nerror connecting to AP.\r\n");
-        return -1;
-    }
-    
-    pc.printf("\r\nnow connected\r\n");
-            
-    const char *ip = spwf.get_ip_address();
-    const char *mac = spwf.get_mac_address();
-    
-    pc.printf("\r\nIP Address is: %s\r\n", (ip) ? ip : "No IP");
-    pc.printf("\r\nMAC Address is: %s\r\n", (mac) ? mac : "No MAC");    
-    
-    SocketAddress addr(&spwf, "st.com");
-    printf("\r\nst.com resolved to: %s\r\n", addr.get_ip_address());
-
-    pc.printf("\r\nconnecting to http://time-d.nist.gov\r\n");
-    //pc.printf("\r\nconnecting to https://quickstart.internetofthings.ibmcloud.com\r\n");
-    
-    TCPSocket socket(&spwf);
-    err = socket.connect("time-d.nist.gov", 37);
+// quickstartMode = (strcmp(org, "quickstart") == 0);
+ if (strcmp(org, "quickstart") == 0){quickstartMode = true;}
+ MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2);
+ MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack);
+ if (quickstartMode){
+        char mac[50];
+        char *digit=NULL;        
+        sprintf (mac,"%s",ipstack.getWiFi().get_mac_address()); 
+        strcpy (mac, ipstack.getWiFi().get_mac_address());
+        digit = strtok (mac,":");
+        while (digit != NULL)
+        {
+            strcat (id, digit);
+            digit = strtok (NULL, ":");
+        }        
+ }
+ attemptConnect(&client, &ipstack);
+ if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD)    
+ {
+    while (true)
+    wait(1.0); // Permanent failures - don't retry
+ }
+    int count = 0;    
+//    tyeld.start();
     
-    if(err!=0) 
-    {
-      pc.printf("\r\nCould not connect to Socket, err = %d!!\r\n", err); 
-      return -1;
-    }
-    char buffer[10];
-    int count = 0;
-    pc.printf("\r\nReceiving Data\r\n"); 
-    count = socket.recv(buffer, sizeof buffer);
-    
-    if(count > 0)
+    while (true)
     {
-        pc.printf("\r\nReceived: %ld bytes, 0x%02x 0x%02x 0x%02x 0x%02x\r\n", \
-                            count, buffer[0], buffer[1], buffer[2], buffer[3]);
-    }
-    else pc.printf("\r\nData not received\r\n");
-
-    pc.printf("\r\nClosing Socket\r\n");
-    socket.close();
-        
-    pc.printf("\r\ndisconnecting....\r\n");
-    spwf.disconnect();
-    pc.printf("\r\nTest complete.\r\n");
-                
-    while(1) { 
-      wait(1);
-      myled = !myled;
+        if (++count == /*100*/2)
+        {               // Publish a message every second
+            if (publish(&client, &ipstack) != 0) 
+                attemptConnect(&client, &ipstack);   // if we have lost the connection
+            count = 0;
+        }        
+//        int start = tyeld.read_ms();
+        client.yield(/*10*/1);  // allow the MQTT client to receive messages
+//        printf ("tyeld: %d\n\r",tyeld.read_ms()-start);
     }
 }