V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

main.cpp

Committer:
jilee
Date:
2017-11-03
Revision:
29:f71a0be59b99
Parent:
28:54d9a550adf1

File content as of revision 29:f71a0be59b99:

/*
 *  AT&T IoT Starter Kit example using Amazon Web Service 
 */
#include "mbed.h"

//TFT
#include "SPI_TFT_ILI9341.h"
#include "FT6206.h"
#include "Arial12x12.h"
#include "Arial28x28.h"
#include "BookAntiqua19x19-14.h"

#include "logo.h"

// SD File System
#include "SDFileSystem.h"

// Serial extension
#include "MODSERIAL.h"

// Network includes
#include "WNCInterface.h"
#include "network_interface.h"

// AWS includes
#include "aws_iot_log.h"
#include "aws_iot_version.h"
#include "aws_iot_shadow_interface.h"
#include "aws_iot_shadow_json_data.h"
#include "aws_iot_config.h"
#include "aws_iot_mqtt_interface.h"

#include "mbedtls/net.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "mbedtls/timing.h"
#include "mbedtls/net_sockets.h"
#include "pem.h"


// Sensors
#include "HTS221.h"

#if DEBUG_LEVEL > 0
#include "mbedtls/debug.h"
#endif



//=====================================================================================================================
//
// Defines
//
//=====================================================================================================================
// LED Colors
#define COLOR_OFF    0x00
#define COLOR_RED    0x01
#define COLOR_GREEN  0x02
#define COLOR_BLUE   0x04
#define COLOR_WHITE  0x07
#define NUM_COLORS   5

// AWS defines
#define PATH_MAX    1024
#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200 // NOTE: Be wary of this if your JSON doc grows
#define SHADOW_SYNC_INTERVAL 6.0             // How often we sync with AWS Shadow (in seconds)

// Comment out the following line if color is not supported on the terminal
//#define USE_COLOR
#ifdef USE_COLOR
 #define BLK "\033[30m"
 #define RED "\033[31m"
 #define GRN "\033[32m"
 #define YEL "\033[33m"
 #define BLU "\033[34m"
 #define MAG "\033[35m"
 #define CYN "\033[36m"
 #define WHT "\033[37m"
 #define DEF "\033[39m"
#else
 #define BLK
 #define RED
 #define GRN
 #define YEL
 #define BLU
 #define MAG
 #define CYN
 #define WHT
 #define DEF
#endif

// Sensor defines
#define CTOF(x)  ((x)*1.8+32) // Temperature

//TFT
#define PIN_SCLK        PTD5
#define PIN_MISO        PTD7
#define PIN_MOSI        PTD6
#define PIN_CS_TFT      PTD4  // chip select pin
#define PIN_DC_TFT      PTB20  // data/command select pin.
#define PIN_RESET_TFT   PTB20  //we don't need reset so just use DC instead. Could modify library

#define PORTRAIT        0
#define LANDSCAPE       1
#define LANDSCAPE_R     3

//#if 0
/*
#define PIN_SCL_FT6206  PTE24
#define PIN_SDA_FT6206  PTE25
//#define PIN_INT_FT6206  PTC6
#define PIN_INT_FT6206  PTC3
*/
//#else

#define PIN_SCL_FT6206  D15
#define PIN_SDA_FT6206  D14
#define PIN_INT_FT6206  PTC3

//#endif



SPI_TFT_ILI9341 TFT(PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "TFT"); // mosi, miso, sclk, cs, reset, dc 
FT6206 ft6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int

//=====================================================================================================================
//
// Globals
//
//=====================================================================================================================
// Controls LED color
unsigned char ledColor = COLOR_OFF;

// Color cycle array (used with SW3 button presses)
unsigned char colorCycle[NUM_COLORS] = {COLOR_OFF, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_WHITE};

// Button interrupts
bool buttonOverride = false;
InterruptIn Interrupt(SW3);

// These defines are pulled from aws_iot_config.h
char HostAddress[255] = AWS_IOT_MQTT_HOST1;
char MqttClientID[32] = AWS_IOT_MQTT_CLIENT_ID;
char ThingName[32] = AWS_IOT_MY_THING_NAME;
char PortString[5] = "8883";
uint32_t port = AWS_IOT_MQTT_PORT;
char iccidName[21] = "12345678901234567890";

// Sensor data
float temperature = 0.0;
int   humidity    = 0;
unsigned int count = 1;

char iccid[] = "89011702278124165220";

//mqqt host name
char *aws_iot_mqtt_host;

//certificate
static mbedtls_x509_crt clicert;

// Temp/humidity object
HTS221 hts221; 



//=====================================================================================================================
//
// Devices
//
//=====================================================================================================================
// GPIOs for RGB LED
DigitalOut led_green(LED_GREEN);
DigitalOut led_red(LED_RED);
DigitalOut led_blue(LED_BLUE);

// USB Serial port (to PC)
MODSERIAL pc(USBTX,USBRX,256,256);

// SD card access (MOSI, MISO, SCK, CS)
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");

// I2C bus (SDA, SCL)
I2C i2c(PTC11, PTC10);

extern unsigned char cSubject[100];

int16_t dbm;
unsigned char cUpdateStatus = 0x00;

//=====================================================================================================================
//
// Functions
//
//=====================================================================================================================
//*********************************************************************************************************************
//* Prints the given format to the PC serial port.  Exposed to all files via aws_iot_log.h
//*********************************************************************************************************************
void pc_print(const char * format, ...)
{
    va_list vl;
    va_start(vl, format);
    pc.vprintf(format, vl);
    va_end(vl);
}

//*********************************************************************************************************************
//* Set the RGB LED's Color
//* LED Color 0=Off to 7=White.  3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) 
//*********************************************************************************************************************
void SetLedColor(unsigned char ucColor)
{    
    //Note that when an LED is on, you write a 0 to it:
    led_red = !(ucColor & 0x1); //bit 0
    led_green = !(ucColor & 0x2); //bit 1
    led_blue = !(ucColor & 0x4); //bit 2
}

//*********************************************************************************************************************
//* SW3 Button handler.  Finds the current LED color and sets the button to the next color in colorCycle[]
//*********************************************************************************************************************
void sw3ButtonHandler()
{
    int i;
    for(i=0; i < NUM_COLORS; i++) {
        if (ledColor == colorCycle[i])
            break;
    }
    
    // (circular-queue)
    if (++i == NUM_COLORS)
        i = 0;
        
    ledColor = colorCycle[i];
    SetLedColor(ledColor);
    buttonOverride = true;
}

//*********************************************************************************************************************
//* Print LED and sensor data
//*********************************************************************************************************************
void printData()
{
    INFO("Temperature is: %0.2f F", temperature);
    INFO("Humidity    is: %02d", humidity);    
    
    switch (ledColor) {
         case COLOR_OFF:
             INFO("LED: Off");
             
             break;
         case COLOR_RED:
             INFO("LED: Red");
             
             break;
         case COLOR_GREEN:
             INFO("LED: Green");
             break;
         case COLOR_BLUE:
             INFO("LED: Blue");
             break;
         case COLOR_WHITE:
             INFO("LED: White");
             break;
    }
    
}

/*
void printDatatoTFT()
{
    //TFT.cls();
    TFT.locate(0,10);
    TFT.printf("ATT LTE: %d dBm      AWS: Connected\n\n", dbm);
    //TFT.line (0,21, 320,21, White);
    TFT.printf("Certificate Name: %s\n\n", cSubject);
    //TFT.printf("Sending Device Data...\n\n");
    TFT.printf("ICCID:      %s\n", iccidName);
    TFT.printf("Temperature: %0.2f F    \n", temperature);
    TFT.printf("Humidity:    %02d %%\n", humidity);
    TFT.printf("LED:       ");
    
    switch (ledColor) {
         case COLOR_OFF:
             TFT.foreground(White);
             TFT.printf("OFF     \n");
             TFT.fillcircle (240,160, 25, Black);
             TFT.circle (240,160, 25, White);
             break;
         case COLOR_RED:
             TFT.foreground(Red);
             TFT.printf("RED     \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Red);
             break;
         case COLOR_GREEN:
             TFT.foreground(Green);
             TFT.printf("GREEN   \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Green);
             break;
         case COLOR_BLUE:
             TFT.foreground(Blue);
             TFT.printf("BLUE   \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Blue);
             break;
         case COLOR_WHITE:
             TFT.foreground(White);
             TFT.printf("WHITE   \n");
             TFT.fillcircle (240,160, 25, White);
             break;
    }
    TFT.printf("\nUpdate Count: %d\n", count++);
}
*/

void printDatatoTFT()
{
    //TFT.cls();
    TFT.locate(0,10);
    TFT.printf("ATT LTE: %d dBm AWS: %d\n\n", dbm, count++);
    //TFT.line (0,21, 320,21, White);
    TFT.printf("CN: %s\n", cSubject);
    //TFT.printf("Sending Device Data...\n\n");
    TFT.printf("ICCID: %s\n", iccidName);
    TFT.printf("TEMPERATURE: %0.2f F    \n", temperature);
    TFT.printf("HUMIDITY: %02d %%\n", humidity);
    TFT.printf("LED: ");
    
    switch (ledColor) {
         case COLOR_OFF:
             TFT.foreground(White);
             TFT.printf("OFF     \n");
             TFT.fillcircle (240,160, 25, Black);
             TFT.circle (240,160, 25, White);
             break;
         case COLOR_RED:
             TFT.foreground(Red);
             TFT.printf("RED     \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Red);
             break;
         case COLOR_GREEN:
             TFT.foreground(Green);
             TFT.printf("GREEN   \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Green);
             break;
         case COLOR_BLUE:
             TFT.foreground(Blue);
             TFT.printf("BLUE   \n");
             TFT.foreground(White);
             TFT.fillcircle (240,160, 25, Blue);
             break;
         case COLOR_WHITE:
             TFT.foreground(White);
             TFT.printf("WHITE   \n");
             TFT.fillcircle (240,160, 25, White);
             break;
    }
    //TFT.printf("\nUpdate Count: %d\n", count++);
}

void ShowINFO(const char *sInfo)
{
    INFO(sInfo);
    TFT.printf(sInfo);
    TFT.printf("\n");
}
   

//=====================================================================================================================
//
// AWS Shadow Callbacks
//
//=====================================================================================================================
//*********************************************************************************************************************
//* This is the callback function that fires when an update is sent.  It will print the update response status.
//*********************************************************************************************************************
void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
        const char *pReceivedJsonDocument, void *pContextData) {

    INFO("Shadow Update Status Callback");
    TFT.printf("\n");
    if (status == SHADOW_ACK_TIMEOUT) {
        INFO("Update Timeout");
    } else if (status == SHADOW_ACK_REJECTED) {
        INFO("Update Rejected");
    } else if (status == SHADOW_ACK_ACCEPTED) {
        INFO("Update Accepted"); // Good
    }
    
}

//*********************************************************************************************************************
//* This is the callback function that fires when AWS has sends out a shadow update. 
//*********************************************************************************************************************
void ledControl_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
    
    INFO("LED Callback Detected.");
    
    if (pContext != NULL) {
        switch (*(unsigned char *)(pContext->pData)){   
            case COLOR_OFF:
                INFO("LED -> OFF (%d)", *(unsigned char *)(pContext->pData));
                break;
            case COLOR_RED:
                INFO("LED -> RED (%d)", *(unsigned char *)(pContext->pData));
                break;
            case COLOR_GREEN:
                INFO("LED -> GREEN (%d)", *(unsigned char *)(pContext->pData));
                break;
            case COLOR_BLUE:
                INFO("LED -> BLUE (%d)", *(unsigned char *)(pContext->pData));
                break;
            case COLOR_WHITE:
                INFO("LED -> WHITE (%d)", *(unsigned char *)(pContext->pData));
                break;    
        }
    }
    else {
        INFO("pContext was detected as NULL");
    }
}
 
//*********************************************************************************************************************
//* Subscribe callback (used with alternate demo)
//*********************************************************************************************************************
int MQTTcallbackHandler(MQTTCallbackParams params) {

    INFO("Subscribe callback");
    INFO("%.*s\t%.*s",
            (int)params.TopicNameLen, params.pTopicName,
            (int)params.MessageParams.PayloadLen, (char*)params.MessageParams.pPayload);

    return 0;
}

//*********************************************************************************************************************
//* Disconnect handling (used with alternate demo)
//*********************************************************************************************************************
void disconnectCallbackHandler(void) {
    WARN("MQTT Disconnect");
    IoT_Error_t rc = NONE_ERROR;
    if(aws_iot_is_autoreconnect_enabled()){
        INFO("Auto Reconnect is enabled, Reconnecting attempt will start now");
    }else{
        WARN("Auto Reconnect not enabled. Starting manual reconnect...");
        rc = aws_iot_mqtt_attempt_reconnect();
        if(RECONNECT_SUCCESSFUL == rc){
            WARN("Manual Reconnect Successful");
        }else{
            WARN("Manual Reconnect Failed - %d", rc);
        }
    }
}

//=====================================================================================================================
//
// Out-of-Box Demo: This function is used as part of the binary that comes with the Starter Kit.  Instead of using an
//                  AWS device shadow, it publishes to an AWS Rule. The Rule is setup to store data to a DynamoDB, and
//                  the demo S3 website pulls that data from the DynamoDB and displays it.
//
//=====================================================================================================================
int outOfBoxDemo() {
    INFO("Running Out-of-Box Function (alternate demo).");
    
    IoT_Error_t rc = NONE_ERROR;
    int32_t i = 0;
    int publishCount = 0;
    bool infinitePublishFlag = true;
    char cPayload[100];
    char cTopic[100];
    const string colorStrings[] = {"Off", "Red", "Green", "", "Blue", "", "", "White"};
    float updateInterval = 1.0; // seconds

    MQTTConnectParams connectParams = MQTTConnectParamsDefault;
    connectParams.KeepAliveInterval_sec = 10;
    connectParams.isCleansession = true;
    connectParams.MQTTVersion = MQTT_3_1_1;
    connectParams.pClientID = iccidName;  // Using ICCID for unique Client ID
    connectParams.pHostURL = HostAddress;
    connectParams.port = port;
    connectParams.isWillMsgPresent = false;
    connectParams.pRootCALocation = AWS_IOT_ROOT_CA_FILENAME;
    connectParams.pDeviceCertLocation = AWS_IOT_CERTIFICATE_FILENAME;
    connectParams.pDevicePrivateKeyLocation = AWS_IOT_PRIVATE_KEY_FILENAME;
    connectParams.mqttCommandTimeout_ms = 10000;
    connectParams.tlsHandshakeTimeout_ms = 10000;
    connectParams.isSSLHostnameVerify = true; // ensure this is set to true for production
    connectParams.disconnectHandler = disconnectCallbackHandler;

    INFO("Connecting...");
    rc = aws_iot_mqtt_connect(&connectParams);
    if (NONE_ERROR != rc) {
        ERROR("Error(%d) connecting to %s:%d", rc, connectParams.pHostURL, connectParams.port);
    }
    
    /*
     * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
     *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
     *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
     */
    INFO("Set Auto Reconnect...");
    rc = aws_iot_mqtt_autoreconnect_set_status(true);
    if (NONE_ERROR != rc) {
        ERROR("Unable to set Auto Reconnect to true - %d", rc);
        return rc;
    }

    // Comment this in if you want to subscribe
    /*MQTTSubscribeParams subParams = MQTTSubscribeParamsDefault;
    subParams.mHandler = MQTTcallbackHandler;
    subParams.pTopic = "sdkTest/sub";
    subParams.qos = QOS_0;

    if (NONE_ERROR == rc) {
        INFO("Subscribing...");
        rc = aws_iot_mqtt_subscribe(&subParams);
        if (NONE_ERROR != rc) {
            ERROR("Error subscribing");
        }
    }*/

    // Initializ the payload
    MQTTMessageParams Msg = MQTTMessageParamsDefault;
    Msg.qos = QOS_0;
    Msg.pPayload = (void *) cPayload;

    MQTTPublishParams Params = MQTTPublishParamsDefault;
    
    // Sets up the topic to publish to
    sprintf(cTopic, AWS_IOT_MY_TOPIC, iccidName);
    Params.pTopic = cTopic;

    if (publishCount != 0) {
        infinitePublishFlag = false;
    }
      
    INFO("READY TO PUBLISH! Press SW3 button to publish current data.");
    while ((NETWORK_ATTEMPTING_RECONNECT == rc || RECONNECT_SUCCESSFUL == rc || NONE_ERROR == rc)
            && (publishCount > 0 || infinitePublishFlag)) {

        // Max time the yield function will wait for read messages
        rc = aws_iot_mqtt_yield(100);
        if(NETWORK_ATTEMPTING_RECONNECT == rc){
            INFO("--> sleep (attempting to reconnect)");
            wait(1);
            // If the client is attempting to reconnect we will skip the rest of the loop.
            continue;
        }
        
        // Whenever the software button (SW3) is pressed the LED will changes color and this will
        // trigger a publish to the AWS topic specified.
        if (buttonOverride) {
            buttonOverride = false;
            
            // Get temp/humidity values
            temperature = CTOF(hts221.readTemperature());
            humidity = hts221.readHumidity();
    
            // Loading data into JSON format
            sprintf(cPayload, "{\"color\":\"%s\",\"temperature\":%f,\"humidity\":%d}", colorStrings[ledColor], temperature, humidity);
            Msg.PayloadLen = strlen(cPayload) + 1;
            Params.MessageParams = Msg;
            
            // Publish
            rc = aws_iot_mqtt_publish(&Params);
            if (publishCount > 0) {
                publishCount--;
            }
                      
            printData();
            INFO("--> Update sent. Sleep for %f seconds", updateInterval);
            wait(updateInterval-.02);
        }
        else {
            wait(.3); // 300 ms
        }
    }

    if (NONE_ERROR != rc) {
        ERROR("An error occurred in the loop.\n");
    } else {
        INFO("Publish done\n");
    }

    return rc;
}

void InitTFT()
{
    //Configure the display driver
    TFT.claim(stdout);
    TFT.background(Black);
    TFT.foreground(White);
    TFT.set_orientation(LANDSCAPE_R);
    TFT.cls();
    TFT.set_font((unsigned char*) Arial12x12);
    //TFT.set_font((unsigned char*) Courier10x13-12B);
    TFT.locate(0,0);
}

void TFTStuff()
{
    INFO("DBG> main\r\n");
    
    //FT6206 ft6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int

    //Configure the display driver
    TFT.claim(stdout);
    TFT.background(Black);
    TFT.foreground(White);
    
    //TFT.background(White);
    //TFT.foreground(Black);

    
    TFT.set_orientation(LANDSCAPE_R);
    TFT.cls();

    //Print a welcome message
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(0,0);
    TFT.printf("Hello mbed!\n");
    TFT.printf("Touch Screen to Continue!\n");
    INFO("Hello mbed!\r\n");
    INFO("Touch Screen to Continue!!\r\n");
    
    int X1, Y1, X2, Y2;
    TS_Point p;
    
    while(1) {
        
        if(ft6206.touched())
        {
            INFO("Touched\r\n");
            p = ft6206.getPoint();
            
            
            X1 = TFT.width()-p.x;
            Y1 = TFT.height()-p.y;
            pc.printf("Touched at x=%3d y=%3d\n", p.x, p.y);
            pc.printf("Touched actual at x=%3d y=%3d\n", X1, Y1);
            
            //ft6206.clearPoint();
            //return;
        }
/*
        if (ft6206.getTouchPoint(p)) {
            X1 = X2;
            Y1 = Y2;
            X2 = TFT.width()-p.x;
            Y2 = TFT.height()-p.y;
            TFT.locate(0,12);
            INFO("Touch %3d %3d\n", p.x, p.y);
            return;
            if ((X1 > 0) && (Y1 > 0) && (X2 > 0) && (Y2 > 0)) {
                TFT.line(X1, Y1, X2, Y2, RGB(255,128,255));
            }
        }
*/
    }
    
}
/*
//=====================================================================================================================
// setupShield
// setup the Adrafruit 1947
//=====================================================================================================================
void setupShield(bool touch) {
    //Configure the display driver
    TFT.claim(stdout);
    TFT.background(Black);
    TFT.foreground(White);
    TFT.set_orientation(LANDSCAPE);
        
    TFT.cls();
    INFO("TFT.cls()");
    
    TFT.circle(120, 120, 50, Red);

    //Print a welcome message
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(120,160);
    TFT.printf("Hello G+D!\n");

   if (touch) {
       while (0)
        if(pc.readable())
                pc.putc(pc.getc());    

       int X1, Y1, X2, Y2 = 0;
        X2 = -100;
        while(1) {
            if (FT6206.touched()) {
    //        if (FT6206.dataReceived()) {
    //            led1 = !led1;
                // Retrieve a point  
                TS_Point p = FT6206.getPoint();
                X1 = X2;
                Y1 = Y2;
                X2 = p.x;
                Y2 = p.y;
    //            printf("Touch %3d %3d\n", p.x, p.y);
                if ((X1 > 0) && (Y1 > 0) && (X2 > 0) && (Y2 > 0)) {
                    TFT.line(X1, Y1, X2, Y2, Green);
                }
            }
    //        TFT.printf("Count: %d\n", count++);
            wait(0.05);
        }
    }
}
*/

int DoAWSThingMenu()
{
    
    //FT6206 ft6206(PIN_SDA_FT6206, PIN_SCL_FT6206, PIN_INT_FT6206); // sda, scl, int
    
    TFT.cls();
    TFT.locate(0,3);
    INFO ("AWS Host Selection\n");
    TFT.set_font((unsigned char*) Book_Antiqua19x19);
    TFT.printf ("     SELECT AWS HOST\n");
    
    TFT.set_font((unsigned char*) Arial28x28);
    //TFT.circle (160,65, 40, Blue);
    TFT.fillcircle (160,75, 40, Blue);
    TFT.locate(130,63);
    //TFT.foreground(Blue);
    TFT.background(Blue);
    TFT.foreground(Red);
    TFT.printf("ATT");
    //TFT.line (0,39, 319, 39, White);
    //TFT.circle (160,150, 40, Green);
    TFT.fillcircle (160,160, 40, Green);
    TFT.locate(137, 148);
    //TFT.foreground(Green);
    TFT.background(Green);
    TFT.foreground(Black);
    TFT.printf("GD");
    //TFT.line (0,79, 319, 79, White);   
    
    int X1, Y1, X2, Y2;
    TS_Point p;
    
    
    while(1) 
    {
         if(ft6206.touched())
         {
            p = ft6206.getPoint();
            X1 = TFT.width()-p.x;
            Y1 = TFT.height()-p.y;

            //pc.printf("Touched at x=%3d y=%3d\n", p.x, p.y);
            //pc.printf("Touched actual at x=%3d y=%3d\n", X1, Y1);

            if ((X1 > 120) && (X1 < 200) && (Y1 > 35) && (Y1 <115))
            {
                INFO("ATT selected\r\n");
                return 1;
            }
            
            if ((X1 > 120) && (X1 < 200) && (Y1 > 120) && (Y1 < 200))
            {
                INFO ("GD selected\n");
                return 2;
            }
         
            //ft6206.clearPoint();
        }
        
    }
    pc.printf ("leaving menu\n"); 
    wait (10.0);
    //TFT.set_font((unsigned char*) Arial12x12);
    TFT.set_font((unsigned char*) Book_Antiqua19x19);
    TFT.foreground(White);
    return 0;    
}

//=====================================================================================================================
//
// Main
//
//=====================================================================================================================
int main() 
{
    bool bFirstTime = true;
    
    //Init Screen
    InitTFT();
    
    // Set baud rate for PC Serial
    pc.baud(115200);
    ShowINFO("AT&T AWS IoT Demo V.06");
    
    TFT.drawBitmap(43, 10, att, 234, 96);
    TFT.drawBitmap(0, 150, gd, 320, 56);  

               
    int i;          
    IoT_Error_t rc = NONE_ERROR;  
    char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
    size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);

    // JSON struct for LED control
    jsonStruct_t ledController;
    ledController.cb = ledControl_Callback;
    ledController.pData = &ledColor;
    ledController.pKey = "ledColor";
    ledController.type = SHADOW_JSON_UINT8;

    // JSON struct for temperature\humidity readings
    jsonStruct_t temperatureHandler;
    temperatureHandler.cb = NULL;
    temperatureHandler.pKey = "temperature";
    temperatureHandler.pData = &temperature;
    temperatureHandler.type = SHADOW_JSON_FLOAT;
    
    jsonStruct_t humidityHandler;
    humidityHandler.cb = NULL;
    humidityHandler.pKey = "humidity";
    humidityHandler.pData = &humidity;
    humidityHandler.type = SHADOW_JSON_INT16;
    
    jsonStruct_t iccidHandler;
    iccidHandler.cb = NULL;
    iccidHandler.pKey = "iccid";
    iccidHandler.pData = iccidName;
    iccidHandler.type = SHADOW_JSON_STRING;
    
    
    INFO("AWS IoT SDK Version(dev) %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
    

#ifdef USING_SD_CARD
    // Paths for certs from SD card
    INFO("Using SD card files for AWS config.");  
    DEBUG("- mqtt config path: %s", AWS_MQTT_CONFIG_FILENAME);
    DEBUG("- rootCA path: %s", AWS_IOT_ROOT_CA_FILENAME);
    DEBUG("- clientCRT path: %s", AWS_IOT_CERTIFICATE_FILENAME);
    DEBUG("- clientKey path: %s", AWS_IOT_PRIVATE_KEY_FILENAME);
#else
    //INFO("Using #defines in aws_iot_config.h and certs from certs.cpp for AWS config.");      
#endif
    
    // Startup signal - blinks through RGBW then turns off
    SetLedColor(COLOR_RED);
    wait(.5);
    SetLedColor(COLOR_GREEN);
    wait(.5);
    SetLedColor(COLOR_BLUE);
    wait(.5);
    SetLedColor(COLOR_WHITE);
    wait(.5);
    SetLedColor(COLOR_OFF);
    
    //TFTStuff();
    
    // Initialize sensors
    INFO("Init sensors...");
    void hts221_init(void);
    i = hts221.begin();  
    if(!i) {
        WARN(RED "HTS221 NOT DETECTED!!\n\r");
    }
    
    //TFTStuff();
    wait (2.0);
    int iSelection = 0;
    string sMQTTHostName;
    
    iSelection = DoAWSThingMenu();
    
    TFT.locate(0,0);
    //TFT.set_font((unsigned char*) Arial12x12);
    TFT.set_font((unsigned char*) Book_Antiqua19x19);
    TFT.background(Black);
    TFT.foreground(White);
    TFT.cls();
    switch (iSelection)
    {
        case 1:
            aws_iot_mqtt_host = AWS_IOT_MQTT_HOST1;
            sMQTTHostName = "ATT";
            TFT.printf ("ATT AWS Host Selected\n");
            break;
        case 2:
            aws_iot_mqtt_host = AWS_IOT_MQTT_HOST2;
            sMQTTHostName = "GD";
            TFT.printf ("GD AWS Host Selected\n");
            break;
        default:
            ShowINFO ("Unknown MQTT HOST\n");
            break;
            
    }
      
    // Setup SW3 button to falling edge interrupt
    
    INFO("Init interrupts...");
    Interrupt.fall(&sw3ButtonHandler);
    
    //TFTStuff();
          
    // Boot the Avnet Shield before any other operations
    INFO("Net Boot...");
    TFT.printf ("Connecting to ATT LTE Network....\n");
    if (net_modem_boot() != 0)
    {
        TFT.printf ("Unable to Connect to ATT LTE Network. Please try again by rebooting the device.\n");
        return 0;
    }
    TFT.printf ("Connected to ATT LTE Network.\n");
    wait (3.0);
    
    
    if (GetSignalStrength(&dbm) != 0)
    {
        TFT.printf ("Unable to Signal Strength. Please try again by rebooting the device.\n");
        return 0;
    }
    
        
    //==========================================================================
    // NOTE:  You can comment in the following line for an alternate demo that
    // is used as the out-of-box demo binary that comes with the  AT&T IoT 
    // Starter Kit.  It loops instead of the rest of Main()
    //return outOfBoxDemo();
    //==========================================================================

 restart1:   

          
    // Intialize MQTT/Cert parameters
    ShadowParameters_t sp = ShadowParametersDefault;
#ifdef USING_SD_CARD
    rc = (IoT_Error_t)mbedtls_mqtt_config_parse_file(&sp, AWS_MQTT_CONFIG_FILENAME);
    if (NONE_ERROR != rc) {
        ERROR("Failed to initialize mqtt parameters %d", rc);
        return rc;
    }   
    sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
    sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
    sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
#else
    sp.pMyThingName = AWS_IOT_MY_THING_NAME;
    sp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
    //sp.pHost = HostAddress;
    INFO ("Host Name:");
    INFO (aws_iot_mqtt_host);
    sp.pHost = aws_iot_mqtt_host;
    INFO (sp.pHost);
    sp.port = port;
    
    sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
    sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
    sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
#endif
/*
    char cBlockOffset[7];
    string sObject;
    pc.printf ("Length = %d\n", AWS_IOT_CERTIFICATE_LENGTH );
    for (int i = 0; i < AWS_IOT_CERTIFICATE_LENGTH; i++)
    {
        sprintf (cBlockOffset, "%02X", AWS_IOT_CERTIFICATE[i]);
        sObject += string (cBlockOffset);
        
    }
    pc.printf(sObject.c_str());
    pc.printf("\n");
*/
    int ret = 0;
    mbedtls_x509_crt_init(&clicert);
    ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *)AWS_IOT_CERTIFICATE, AWS_IOT_CERTIFICATE_LENGTH);
    if (ret != 0) {
        ERROR(" failed\n  !  mbedtls_x509_crt_parse IOT returned 1 -0x%x,  %d\n\n", -ret, AWS_IOT_CERTIFICATE_LENGTH);
        TFT.printf ("Invalid Certificate. Please check the certificate and reboot the device.");
        return ret;
    }
    else
    {
        for (int i = 0; i < clicert.subject_raw.len; i++)
        {
            if (clicert.subject_raw.p[i] == 0x0C)
            {
                i++;
                unsigned char cLength = clicert.subject_raw.p[i];
                DEBUG ("subject length = %d", cLength);
                i++;
                for (int j = 0; j < (int) cLength; j++)
                {
                    cSubject[j] = clicert.subject_raw.p[i];
                    i++;
                }
                cSubject[cLength] = 0x00;
                break;
            }
        }
    }   
    
    TFT.printf("Logging into %s AWS\n", sMQTTHostName); 
    TFT.printf("CN: %s\n", cSubject);     
    INFO("Initialize the MQTT client...");
    MQTTClient_t mqttClient;
    aws_iot_mqtt_init(&mqttClient);

    string sAWSError = "\nUnable to Log into AWS. Invalid certificate. Please make sure the certificates in the SIM card are valid and reboot the device.\n";
    TFT.printf(".");
    INFO("Shadow Init...");
    rc = aws_iot_shadow_init(&mqttClient);
    if (NONE_ERROR != rc) {
        ERROR("Shadow Init Error %d", rc);
        TFT.printf(sAWSError.c_str()); 
        return rc;
    }
    
    INFO("Shadow Connect...");   
    TFT.printf(".");
    rc = aws_iot_shadow_connect(&mqttClient, &sp);
    if (NONE_ERROR != rc) {
        ERROR("Shadow Connection Error %d", rc);
        TFT.printf(sAWSError.c_str()); 
        return rc;
    }

    // Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
    // #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
    // #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
    rc = mqttClient.setAutoReconnectStatus(true);
    if (NONE_ERROR != rc) {
        ERROR("Unable to set Auto Reconnect to true - %d", rc);
        TFT.printf(sAWSError.c_str()); 
        return rc;
    }
    
    // Example line of how to delete a shadow (not used in this demo)
    //aws_iot_shadow_delete(&mqttClient, AWS_IOT_MY_THING_NAME, ShadowUpdateStatusCallback, NULL, 8, true);

    INFO("Shadow Register Delta...");
    TFT.printf(".");
    rc = aws_iot_shadow_register_delta(&mqttClient, &ledController);
    if (NONE_ERROR != rc) {
        ERROR("Shadow Register Delta Error");
        TFT.printf(sAWSError.c_str()); 
        return rc;
    }
    
    INFO("Will attempt to sync with device shadow every %f seconds.", SHADOW_SYNC_INTERVAL);
    // Loop and publish changes from the FRDM board
    
    while (NETWORK_ATTEMPTING_RECONNECT == rc || RECONNECT_SUCCESSFUL == rc || NONE_ERROR == rc) 
    {
        
        // Looks for incoming socket messages
        rc = aws_iot_shadow_yield(&mqttClient, 200);
        if (NETWORK_ATTEMPTING_RECONNECT == rc) 
        {
            // If the client is attempting to reconnect we will skip the rest of the loop.
            ShowINFO("Attempting to reconnect...");
            wait(1);
            bFirstTime = true;
            //TFT.cls();
            continue;
        }
        
        // Read sensor data
        temperature = CTOF(hts221.readTemperature());
        humidity = hts221.readHumidity();
                                
        INFO("\n=======================================================================================\n");             
        // Initialize JSON shadow document          
        rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
        if (rc == NONE_ERROR) 
        {
            
            // If there has been a SW3 button press update the 'desired' color
            if (buttonOverride) 
            {
                rc = aws_iot_shadow_add_desired(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 1, &ledController);               
                buttonOverride = false;
            }
                  
            // Updates the 'reported' color/temp/humidity
            rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 4, &ledController,
                                                                                              &temperatureHandler,
                                                                                              &humidityHandler, &iccidHandler);
                 
            if (rc == NONE_ERROR) 
            {               
                rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);   
                            
                if (rc == NONE_ERROR) 
                {
                    INFO("Update Shadow: %s", JsonDocumentBuffer);
                    rc = aws_iot_shadow_update(&mqttClient, sp.pMyThingName, JsonDocumentBuffer,
                            ShadowUpdateStatusCallback, NULL, 8, true);
                }
            }
        }  
        
        //get signal strength
        GetSignalStrength(&dbm);
        
        //check if certificate is updated
        
        if (GetUpdateStatus(&cUpdateStatus) != 0)
        {
            ERROR("Get Update Status Error");
        }
        else
        {
            if (cUpdateStatus == 0xFF)
            {
                TFT.cls();
                TFT.locate(0,10);
                ShowINFO ("Certifcate Update Detected.");   
                ShowINFO("Disconnecting AWS");
                rc = aws_iot_shadow_disconnect(&mqttClient);
                if (NONE_ERROR != rc) 
                {
                    ERROR("Disconnect error %d. Please reboot the device", rc);
                    return rc;
                }
                
                if (GetAllObjects() != 0)
                {
                    ShowINFO ("Read Certficate Error. Check hardware and Reboot the device..");
                    return 0;   
                }
                
                wait(3.0);
                bFirstTime = true;
                goto restart1;
            }   
        }
        
        
        // Print data
        if (bFirstTime == true)
        {
            TFT.cls();   
            bFirstTime = false;
        }
        printDatatoTFT(); 
        printData();
        INFO("*****************************************************************************************");
         
        // Set the LED color    
        SetLedColor(ledColor);
        wait(SHADOW_SYNC_INTERVAL);
        
        if (count > 50)
        {
            INFO ("Max Upload reached. Please reset the device to start again");
            TFT.printf ("Max upload reached. Please reset the device to continue.");
            return rc;
        }
            
    }

    if (NONE_ERROR != rc) 
    {
        ERROR("An error occurred in the loop %d", rc);
        TFT.printf("Fatal Error. Please reboot the device.\n");
    }

    INFO("Disconnecting");
    rc = aws_iot_shadow_disconnect(&mqttClient);

    if (NONE_ERROR != rc) {
        ERROR("Disconnect error %d", rc);
    }

    return rc;   
}