This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3220: Implementing MQTT in customized project

Part Number: CC3220
Other Parts Discussed in Thread: UNIFLASH

Hi,

I tried MQTT client Subscribe and Publish in "MQTT client" project, its working fine.

I am trying integrate the same MQTT  in "Out of Box" project in SDK.

So, after the device started fine I am getting print "[Provisioning task] detected device is CC3220SF" in getDeviceType() of "link_local_task.c"

Next to this step I called below task of "mqtt_client_app.c"

// Start MQTT here //
            UART_PRINT("MQTT task start\n\r");

            pthread_t MQTTThreads = (pthread_t)NULL;
            int32_t RetVal;
            pthread_attr_t pAttrs;
            struct sched_param priParam;
            pthread_attr_init(&pAttrs);
            priParam.sched_priority = 1;
            RetVal = pthread_attr_setschedparam(&pAttrs, &priParam);
            RetVal |= pthread_attr_setstacksize(&pAttrs, 4096);

            if(RetVal)
            {
                /* Handle Error */
                UART_PRINT("Unable to configure thread parameters \n");
                while(1)
                {
                    ;
                }
            }

            RetVal = pthread_create(&MQTTThreads, &pAttrs, MQTTThread, NULL);

            if(RetVal)
            {
                /* Handle Error */
                UART_PRINT("Unable to create thread \n");
                while(1)
                {
                    ;
                }
            }

and files imported from MQTT client project and edited are

/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*****************************************************************************

   Application Name     -   MQTT Client
   Application Overview -   The device is running a MQTT client which is
                           connected to the online broker. Three LEDs on the
                           device can be controlled from a web client by
                           publishing msg on appropriate topics. Similarly,
                           message can be published on pre-configured topics
                           by pressing the switch buttons on the device.

   Application Details  - Refer to 'MQTT Client' README.html

*****************************************************************************/
//*****************************************************************************
//
//! \addtogroup mqtt_server
//! @{
//
//*****************************************************************************
#include "mqtt_client_app.h"
/* Standard includes                                                         */
#include <stdlib.h>
#include <pthread.h>
#include <mqueue.h>
#include <time.h>
#include <unistd.h>

/* TI-Driver includes                                                        */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SPI.h>

/* Simplelink includes                                                       */
#include <ti/drivers/net/wifi/simplelink.h>

/* SlNetSock includes                                                        */
#include <ti/drivers/net/wifi/slnetifwifi.h>

/* MQTT Library includes                                                     */
#include <ti/net/mqtt/mqttclient.h>

/* Common interface includes                                                 */
//#include "network_if.h"
#include <Services/uart_term.h>

/* Application includes                                                      */
#include "Board.h"
#include "client_cbs.h"
#include "network_if.h"

//*****************************************************************************
//                          LOCAL DEFINES
//*****************************************************************************
/* enables secured client                                                    */
//#define SECURE_CLIENT

/* enables client authentication by the server                               */
//#define CLNT_USR_PWD

    UART_Handle tUartHndl;
#define SL_STOP_TIMEOUT         200//

#define CLIENT_INIT_STATE        (0x01)
#define MQTT_INIT_STATE          (0x04)

#define APPLICATION_VERSION      "1.1.1"
#define APPLICATION_NAME         "MQTT client"

#define SLNET_IF_WIFI_PRIO       (5)

/* Operate Lib in MQTT 3.1 mode.                                             */
#define MQTT_3_1_1               false
#define MQTT_3_1                 true

#define WILL_TOPIC               "Client"
#define WILL_MSG                 "Client Stopped"
#define WILL_QOS                 MQTT_QOS_2
#define WILL_RETAIN              false

/* Defining Broker IP address and port Number                                */
//#define SERVER_ADDRESS           "messagesight.demos.ibm.com"
#define SERVER_ADDRESS           "ntiretail.com"//"m2m.eclipse.org"
#define SERVER_IP_ADDRESS        "192.168.178.67"
#define PORT_NUMBER              1883
#define SECURED_PORT_NUMBER      8883
#define LOOPBACK_PORT            1882

/* Clean session flag                                                        */
#define CLEAN_SESSION            true

/* Retain Flag. Used in publish message.                                     */
#define RETAIN_ENABLE            1

/* Defining Number of subscription topics                                    */
#define SUBSCRIPTION_TOPIC_COUNT 1

/* Defining Subscription Topic Values                                        */
#define SUBSCRIPTION_TOPIC0      "SensorNode/StoreLight1"
//#define SUBSCRIPTION_TOPIC1      "/cc3200/ToggleLEDCmdL1"
//#define SUBSCRIPTION_TOPIC2      "/cc3200/ToggleLEDCmdL2"
//#define SUBSCRIPTION_TOPIC3      "/cc3200/ToggleLEDCmdL3"

/* Defining Publish Topic Values                                             */
#define PUBLISH_TOPIC0           "/cc32xx/ButtonPressEvtSw2"
#define PUBLISH_TOPIC0_DATA \
    "Push Button SW2 has been pressed on CC32xx device"

/* Spawn task priority and Task and Thread Stack Size                        */
#define TASKSTACKSIZE            2048
#define RXTASKSIZE               4096
#define MQTTTHREADSIZE           2048
#define SPAWN_TASK_PRIORITY      9

/* secured client requires time configuration, in order to verify server     */
/* certificate validity (date).                                              */

/* Day of month (DD format) range 1-31                                       */
#define DAY                      1
/* Month (MM format) in the range of 1-12                                    */
#define MONTH                    5
/* Year (YYYY format)                                                        */
#define YEAR                     2017
/* Hours in the range of 0-23                                                */
#define HOUR                     12
/* Minutes in the range of 0-59                                              */
#define MINUTES                  33
/* Seconds in the range of 0-59                                              */
#define SEC                      21

/* Number of files used for secure connection                                */
#define CLIENT_NUM_SECURE_FILES  1

/* Expiration value for the timer that is being used to toggle the Led.      */
#define TIMER_EXPIRATION_VALUE   100 * 1000000

//*****************************************************************************
//                      LOCAL FUNCTION PROTOTYPES
//*****************************************************************************
//void pushButtonInterruptHandler2(uint_least8_t index);
void pushButtonInterruptHandler3(uint_least8_t index);
void TimerPeriodicIntHandler(sigval val);
void LedTimerConfigNStart();
void LedTimerDeinitStop();
static void DisplayBanner(char * AppName);
void * MqttClient(void *pvParameters);
void Mqtt_ClientStop(uint8_t disconnect);
void Mqtt_ServerStop();
void Mqtt_Stop();
//void Mqtt_start();
int32_t Mqtt_IF_Connect();
int32_t MqttServer_start();
int32_t MqttClient_start();
int32_t MQTT_SendMsgToQueue(struct msgQueue *queueElement);

//*****************************************************************************
//                 GLOBAL VARIABLES
//*****************************************************************************

/* Connection state: (0) - connected, (negative) - disconnected              */
int32_t gApConnectionState = -1;
uint32_t gInitState = 0;
uint32_t memPtrCounterfree = 0;
bool gResetApplication = false;
static MQTTClient_Handle gMqttClient;
MQTTClient_Params MqttClientExmple_params;
unsigned short g_usTimerInts;

/* Receive task handle                                                       */
pthread_t g_rx_task_hndl = (pthread_t) NULL;
uint32_t gUiConnFlag = 0;

/* AP Security Parameters                                                    */
SlWlanSecParams_t SecurityParams = { 0 };

/* Client ID                                                                 */
/* If ClientId isn't set, the MAC address of the device will be copied into  */
/* the ClientID parameter.                                                   */
char ClientId[13] = {'\0'};

/* Client User Name and Password                                             */
const char *ClientUsername = "username1";
const char *ClientPassword = "pwd1";

/* Subscription topics and qos values                                        */
char *topic[SUBSCRIPTION_TOPIC_COUNT] =
{ SUBSCRIPTION_TOPIC0};//, SUBSCRIPTION_TOPIC1, \
    SUBSCRIPTION_TOPIC2, SUBSCRIPTION_TOPIC3 };

unsigned char qos[SUBSCRIPTION_TOPIC_COUNT] =
{ MQTT_QOS_2};//, MQTT_QOS_2, MQTT_QOS_2, MQTT_QOS_2 };

/* Publishing topics and messages                                            */
const char *publish_topic = { PUBLISH_TOPIC0 };
const char *publish_data = { PUBLISH_TOPIC0_DATA };

/* Message Queue                                                             */
mqd_t g_PBQueue;
pthread_t mqttThread = (pthread_t) NULL;
pthread_t appThread = (pthread_t) NULL;
timer_t g_timer;

/* Printing new line                                                         */
char lineBreak[] = "\n\r";

//*****************************************************************************
//                 Banner VARIABLES
//*****************************************************************************
#ifdef  SECURE_CLIENT

char *Mqtt_Client_secure_files[CLIENT_NUM_SECURE_FILES] = {"ca-cert.pem"};

/*Initialization structure to be used with sl_ExtMqtt_Init API. In order to  */
/*use secured socket method, the flag MQTTCLIENT_NETCONN_SEC, cipher,        */
/*n_files and secure_files must be configured.                               */
/*certificates also must be programmed  ("ca-cert.pem").                     */
/*The first parameter is a bit mask which configures server address type and */
/*security mode.                                                             */
/*Server address type: IPv4, IPv6 and URL must be declared with The          */
/*corresponding flag.                                                        */
/*Security mode: The flag MQTTCLIENT_NETCONN_SEC enables the security (TLS)  */
/*which includes domain name verification and certificate catalog            */
/*verification, those verifications can be disabled by adding to the bit mask*/
/*MQTTCLIENT_NETCONN_SKIP_DOMAIN_NAME_VERIFICATION and                       */
/*MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION flags             */
/*Example: MQTTCLIENT_NETCONN_IP6 | MQTTCLIENT_NETCONN_SEC |                 */
/*MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION                   */
/*For this bit mask, the IPv6 address type will be in use, the security      */
/*feature will be enable and the certificate catalog verification will be    */
/*skipped.                                                                   */
/*Note: The domain name verification requires URL Server address type        */
/*      otherwise, this verification will be disabled.                       */
MQTTClient_ConnParams Mqtt_ClientCtx =
{
    MQTTCLIENT_NETCONN_IP4 | MQTTCLIENT_NETCONN_SEC,
    SERVER_IP_ADDRESS,  //SERVER_ADDRESS,
    SECURED_PORT_NUMBER, //  PORT_NUMBER
    SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2,
    SLNETSOCK_SEC_CIPHER_FULL_LIST,
    CLIENT_NUM_SECURE_FILES,
    Mqtt_Client_secure_files
};

void setTime()
{
    SlDateTime_t dateTime = {0};
    dateTime.tm_day = (uint32_t)DAY;
    dateTime.tm_mon = (uint32_t)MONTH;
    dateTime.tm_year = (uint32_t)YEAR;
    dateTime.tm_hour = (uint32_t)HOUR;
    dateTime.tm_min = (uint32_t)MINUTES;
    dateTime.tm_sec = (uint32_t)SEC;
    sl_DeviceSet(SL_DEVICE_GENERAL, SL_DEVICE_GENERAL_DATE_TIME,
                 sizeof(SlDateTime_t), (uint8_t *)(&dateTime));
}

#else
MQTTClient_ConnParams Mqtt_ClientCtx =
{
    MQTTCLIENT_NETCONN_URL,
    SERVER_ADDRESS,
    PORT_NUMBER, 0, 0, 0,
    NULL
};
#endif

/* Initialize the will_param structure to the default will parameters        */
MQTTClient_Will will_param =
{
    WILL_TOPIC,
    WILL_MSG,
    WILL_QOS,
    WILL_RETAIN
};

//*****************************************************************************
//
//! MQTT_SendMsgToQueue - Utility function that receive msgQueue parameter and
//! tries to push it the queue with minimal time for timeout of 0.
//! If the queue isn't full the parameter will be stored and the function
//! will return 0.
//! If the queue is full and the timeout expired (because the timeout parameter
//! is 0 it will expire immediately), the parameter is thrown away and the
//! function will return -1 as an error for full queue.
//!
//! \param[in] struct msgQueue *queueElement
//!
//! \return 0 on success, -1 on error
//
//*****************************************************************************
int32_t MQTT_SendMsgToQueue(struct msgQueue *queueElement)
{
    struct timespec abstime = {0};

    clock_gettime(CLOCK_REALTIME, &abstime);

    if(g_PBQueue)
    {
        /* send message to the queue                                        */
        if(mq_timedsend(g_PBQueue, (char *) queueElement,
                        sizeof(struct msgQueue), 0, &abstime) == 0)
        {
            return(0);
        }
    }
    return(-1);
}

//*****************************************************************************
//
//! Push Button Handler1(GPIOSW2). Press push button1 (GPIOSW2) Whenever user
//! wants to publish a message. Write message into message queue signaling the
//! event publish messages
//!
//! \param none
//!
//! return none
//
//*****************************************************************************
//void pushButtonInterruptHandler2(uint_least8_t index)
//{
//    struct msgQueue queueElement;
//
//    /* Disable the SW2 interrupt */
//    GPIO_disableInt(Board_GPIO_BUTTON0); // SW2
//
//    queueElement.event = PUBLISH_PUSH_BUTTON_PRESSED;
//    queueElement.msgPtr = NULL;
//
//    /* write message indicating publish message                             */
//    if(MQTT_SendMsgToQueue(&queueElement))
//    {
//        UART_PRINT("\n\n\rQueue is full\n\n\r");
//    }
//}

//*****************************************************************************
//
//! Push Button Handler2(GPIOSW3). Press push button3 Whenever user wants to
//! disconnect from the remote broker. Write message into message queue
//! indicating disconnect from broker.
//!
//! \param none
//!
//! return none
//
//*****************************************************************************
void pushButtonInterruptHandler3(uint_least8_t index)
{
    struct msgQueue queueElement;
    struct msgQueue queueElemRecv;

    queueElement.event = DISC_PUSH_BUTTON_PRESSED;
    queueElement.msgPtr = NULL;

    /* write message indicating disconnect push button pressed message      */
    if(MQTT_SendMsgToQueue(&queueElement))
    {
        UART_PRINT(
            "\n\n\rQueue is full, throw first msg and send the new one\n\n\r");
        mq_receive(g_PBQueue, (char*) &queueElemRecv, sizeof(struct msgQueue),
                   NULL);
        MQTT_SendMsgToQueue(&queueElement);
    }
}

//*****************************************************************************
//
//! Periodic Timer Interrupt Handler
//!
//! \param None
//!
//! \return None
//
//*****************************************************************************
void TimerPeriodicIntHandler(sigval val)
{
    /* Increment our interrupt counter.                                      */
    g_usTimerInts++;

    if(!(g_usTimerInts & 0x1))
    {
        /* Turn Led Off                                                      */
//        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
    }
    else
    {
        /* Turn Led On                                                       */
//        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    }
}

//*****************************************************************************
//
//! Function to configure and start timer to blink the LED while device is
//! trying to connect to an AP
//!
//! \param none
//!
//! return none
//
//*****************************************************************************
void LedTimerConfigNStart()
{
    struct itimerspec value;
    sigevent sev;

    /* Create Timer                                                          */
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_notify_function = &TimerPeriodicIntHandler;
    timer_create(2, &sev, &g_timer);

    /* start timer                                                           */
    value.it_interval.tv_sec = 0;
    value.it_interval.tv_nsec = TIMER_EXPIRATION_VALUE;
    value.it_value.tv_sec = 0;
    value.it_value.tv_nsec = TIMER_EXPIRATION_VALUE;

    timer_settime(g_timer, 0, &value, NULL);
}

//*****************************************************************************
//
//! Disable the LED blinking Timer as Device is connected to AP
//!
//! \param none
//!
//! return none
//
//*****************************************************************************
void LedTimerDeinitStop()
{
    /* Disable the LED blinking Timer as Device is connected to AP.          */
    timer_delete(g_timer);
}

//*****************************************************************************
//
//! Application startup display on UART
//!
//! \param  none
//!
//! \return none
//!
//*****************************************************************************
static void DisplayBanner(char * AppName)
{
    UART_PRINT("\n\n\n\r");
    UART_PRINT("\t\t *************************************************\n\r");
    UART_PRINT("\t\t    CC32xx %s Application       \n\r", AppName);
    UART_PRINT("\t\t *************************************************\n\r");
    UART_PRINT("\n\n\n\r");
}

void * MqttClientThread(void * pvParameters)
{
    struct msgQueue queueElement;
    struct msgQueue queueElemRecv;

    MQTTClient_run((MQTTClient_Handle)pvParameters);

    queueElement.event = LOCAL_CLIENT_DISCONNECTION;
    queueElement.msgPtr = NULL;

    /*write message indicating disconnect Broker message.                   */
    if(MQTT_SendMsgToQueue(&queueElement))
    {
        UART_PRINT(
            "\n\n\rQueue is full, throw first msg and send the new one\n\n\r");
        mq_receive(g_PBQueue, (char*) &queueElemRecv, sizeof(struct msgQueue),
                   NULL);
        MQTT_SendMsgToQueue(&queueElement);
    }

    pthread_exit(0);

    return(NULL);
}

//*****************************************************************************
//
//! Task implementing MQTT Server plus client bridge
//!
//! This function
//!    1. Initializes network driver and connects to the default AP
//!    2. Initializes the mqtt client ans server libraries and set up MQTT
//!       with the remote broker.
//!    3. set up the button events and their callbacks(for publishing)
//!    4. handles the callback signals
//!
//! \param  none
//!
//! \return None
//!
//*****************************************************************************
void * MqttClient(void *pvParameters)
{
    struct msgQueue queueElemRecv;
    long lRetVal = -1;
    char *tmpBuff;

    /*Initializing Client and Subscribing to the Broker.                     */
    if(gApConnectionState >= 0)
    {
        lRetVal = MqttClient_start();
        if(lRetVal == -1)
        {
            UART_PRINT("MQTT Client lib initialization failed\n\r");
            pthread_exit(0);
            return(NULL);
        }
    }

    /*handling the signals from various callbacks including the push button  */
    /*prompting the client to publish a msg on PUB_TOPIC OR msg received by  */
    /*the server on enrolled topic(for which the on-board client ha enrolled)*/
    /*from a local client(will be published to the remote broker by the      */
    /*client) OR msg received by the client from the remote broker (need to  */
    /*be sent to the server to see if any local client has subscribed on the */
    /*same topic).                                                           */
    for(;; )
    {
        /*waiting for signals                                                */
        mq_receive(g_PBQueue, (char*) &queueElemRecv, sizeof(struct msgQueue),
                   NULL);

        switch(queueElemRecv.event)
        {
//        case PUBLISH_PUSH_BUTTON_PRESSED:
//
//            /*send publish message                                       */
//            lRetVal =
//                MQTTClient_publish(gMqttClient, (char*) publish_topic, strlen(
//                                      (char*)publish_topic),
//                                  (char*)publish_data,
//                                  strlen((char*) publish_data), MQTT_QOS_2 |
//                                  ((RETAIN_ENABLE) ? MQTT_PUBLISH_RETAIN : 0));
//
//            UART_PRINT("\n\r CC3200 Publishes the following message \n\r");
//            UART_PRINT("Topic: %s\n\r", publish_topic);
//            UART_PRINT("Data: %s\n\r", publish_data);
//
//            /* Clear and enable again the SW2 interrupt */
//            GPIO_clearInt(Board_GPIO_BUTTON0);     // SW2
//            GPIO_enableInt(Board_GPIO_BUTTON0);     // SW2
//
//            break;

        /*msg received by client from remote broker (on a topic      */
        /*subscribed by local client)                                */
        case MSG_RECV_BY_CLIENT:
            tmpBuff = (char *) ((char *) queueElemRecv.msgPtr + 12);
//            if(strncmp
//                (tmpBuff, SUBSCRIPTION_TOPIC1, queueElemRecv.topLen) == 0)
//            {
//                GPIO_toggle(Board_GPIO_LED0);
//            }
//            else if(strncmp(tmpBuff, SUBSCRIPTION_TOPIC2,
//                            queueElemRecv.topLen) == 0)
//            {
//                GPIO_toggle(Board_GPIO_LED1);
//            }
//            else if(strncmp(tmpBuff, SUBSCRIPTION_TOPIC3,
//                            queueElemRecv.topLen) == 0)
//            {
//                GPIO_toggle(Board_GPIO_LED2);
//            }

            free(queueElemRecv.msgPtr);
            break;

        /*On-board client disconnected from remote broker, only      */
        /*local MQTT network will work                               */
        case LOCAL_CLIENT_DISCONNECTION:
            UART_PRINT("\n\rOn-board Client Disconnected\n\r\r\n");
            gUiConnFlag = 0;
            break;

        /*Push button for full restart check                         */
        case DISC_PUSH_BUTTON_PRESSED:
            gResetApplication = true;
            break;

        case THREAD_TERMINATE_REQ:
            gUiConnFlag = 0;
            pthread_exit(0);
            return(NULL);

        default:
            sleep(1);
            break;
        }
    }
}

//*****************************************************************************
//
//! This function connect the MQTT device to an AP with the SSID which was
//! configured in SSID_NAME definition which can be found in Network_if.h file,
//! if the device can't connect to to this AP a request from the user for other
//! SSID will appear.
//!
//! \param  none
//!
//! \return None
//!
//*****************************************************************************
int32_t Mqtt_IF_Connect()
{
    int32_t lRetVal;
    char SSID_Remote_Name[32];
    int8_t Str_Length;

    memset(SSID_Remote_Name, '\0', sizeof(SSID_Remote_Name));
    Str_Length = strlen(SSID_NAME);

    if(Str_Length)
    {
        /*Copy the Default SSID to the local variable                        */
        strncpy(SSID_Remote_Name, SSID_NAME, Str_Length);
    }

    /*Display Application Banner                                             */
//    DisplayBanner(APPLICATION_NAME);
//
//    GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
//    GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
//    GPIO_write(Board_GPIO_LED2, Board_GPIO_LED_OFF);

    /*Reset The state of the machine                                         */
    Network_IF_ResetMCUStateMachine();

    /*Start the driver                                                       */
    lRetVal = Network_IF_InitDriver(ROLE_STA);
    if(lRetVal < 0)
    {
        UART_PRINT("Failed to start SimpleLink Device\n\r", lRetVal);
        return(-1);
    }

    /*switch on Green LED to indicate Simplelink is properly up.             */
//    GPIO_write(Board_GPIO_LED2, Board_GPIO_LED_ON);

    /*Start Timer to blink Red LED till AP connection                        */
    LedTimerConfigNStart();

    /*Initialize AP security params                                          */
    SecurityParams.Key = (signed char *) SECURITY_KEY;
    SecurityParams.KeyLen = strlen(SECURITY_KEY);
    SecurityParams.Type = SECURITY_TYPE;

    /*Connect to the Access Point                                            */
    lRetVal = Network_IF_ConnectAP(SSID_Remote_Name, SecurityParams);
    if(lRetVal < 0)
    {
        UART_PRINT("Connection to an AP failed\n\r");
        return(-1);
    }

    /*Disable the LED blinking Timer as Device is connected to AP.           */
    LedTimerDeinitStop();

    /*Switch ON RED LED to indicate that Device acquired an IP.              */
//    GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);

//    sleep(1);

//    GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
//    GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
//    GPIO_write(Board_GPIO_LED2, Board_GPIO_LED_OFF);

    return(0);
}

//*****************************************************************************
//!
//! MQTT Start - Initialize and create all the items required to run the MQTT
//! protocol
//!
//! \param  none
//!
//! \return None
//!
//*****************************************************************************
void Mqtt_start()
{
    int32_t threadArg = 100;
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int32_t retc = 0;
    mq_attr attr;
    unsigned mode = 0;

    /*sync object for inter thread communication                             */
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = sizeof(struct msgQueue);
    g_PBQueue = mq_open("g_PBQueue", O_CREAT, mode, &attr);

    if(g_PBQueue == NULL)
    {
        UART_PRINT("MQTT Message Queue create fail\n\r");
        gInitState &= ~MQTT_INIT_STATE;
        return;
    }

    /*Set priority and stack size attributes                                 */
    pthread_attr_init(&pAttrs);
    priParam.sched_priority = 2;
    retc = pthread_attr_setschedparam(&pAttrs, &priParam);
    retc |= pthread_attr_setstacksize(&pAttrs, MQTTTHREADSIZE);
    retc |= pthread_attr_setdetachstate(&pAttrs, PTHREAD_CREATE_DETACHED);

    if(retc != 0)
    {
        gInitState &= ~MQTT_INIT_STATE;
        UART_PRINT("MQTT thread create fail\n\r");
        return;
    }

    retc = pthread_create(&mqttThread, &pAttrs, MqttClient, (void *) &threadArg);
    if(retc != 0)
    {
        gInitState &= ~MQTT_INIT_STATE;
        UART_PRINT("MQTT thread create fail\n\r");
        return;
    }

    /*enable interrupt for the GPIO 13 (SW3) and GPIO 22 (SW2).              */
//    GPIO_setCallback(Board_GPIO_BUTTON0, pushButtonInterruptHandler2);
//    GPIO_enableInt(Board_GPIO_BUTTON0); // SW2
//
//    GPIO_setCallback(Board_GPIO_BUTTON1, pushButtonInterruptHandler3);
//    GPIO_enableInt(Board_GPIO_BUTTON1); // SW3

    gInitState &= ~MQTT_INIT_STATE;
}

//*****************************************************************************
//!
//! MQTT Stop - Close the client instance and free all the items required to
//! run the MQTT protocol
//!
//! \param  none
//!
//! \return None
//!
//*****************************************************************************

void Mqtt_Stop()
{
    struct msgQueue queueElement;
    struct msgQueue queueElemRecv;

    if(gApConnectionState >= 0)
    {
        Mqtt_ClientStop(1);
    }

    queueElement.event = THREAD_TERMINATE_REQ;
    queueElement.msgPtr = NULL;

    /*write message indicating publish message                               */
    if(MQTT_SendMsgToQueue(&queueElement))
    {
        UART_PRINT(
            "\n\n\rQueue is full, throw first msg and send the new one\n\n\r");
        mq_receive(g_PBQueue, (char*) &queueElemRecv, sizeof(struct msgQueue),
                   NULL);
        MQTT_SendMsgToQueue(&queueElement);
    }

    sleep(2);

    mq_close(g_PBQueue);
    g_PBQueue = NULL;

    sl_Stop(SL_STOP_TIMEOUT);
    UART_PRINT("\n\r Client Stop completed\r\n");

    /*Disable the SW2 and SW3 interrupt */
    GPIO_disableInt(Board_GPIO_BUTTON0); // SW2
    GPIO_disableInt(Board_GPIO_BUTTON1); // SW3
}

int32_t MqttClient_start()
{
    int32_t lRetVal = -1;
    int32_t iCount = 0;

    int32_t threadArg = 100;
    pthread_attr_t pAttrs;
    struct sched_param priParam;

    MqttClientExmple_params.clientId = ClientId;
    MqttClientExmple_params.connParams = &Mqtt_ClientCtx;
    MqttClientExmple_params.mqttMode31 = MQTT_3_1;
    MqttClientExmple_params.blockingSend = true;

    gInitState |= CLIENT_INIT_STATE;

    /*Initialize MQTT client lib                                             */
    gMqttClient = MQTTClient_create(MqttClientCallback,
                                    &MqttClientExmple_params);
    if(gMqttClient == NULL)
    {
        UART_PRINT("MQTTClient_create failed\n\r");
        /*lib initialization failed                                          */
        gInitState &= ~CLIENT_INIT_STATE;
        return(-1);
    }

    /*Open Client Receive Thread start the receive task. Set priority and    */
    /*stack size attributes                                                  */
    pthread_attr_init(&pAttrs);
    priParam.sched_priority = 2;
    lRetVal = pthread_attr_setschedparam(&pAttrs, &priParam);
    lRetVal |= pthread_attr_setstacksize(&pAttrs, RXTASKSIZE);
    lRetVal |= pthread_attr_setdetachstate(&pAttrs, PTHREAD_CREATE_DETACHED);
    lRetVal |=
        pthread_create(&g_rx_task_hndl, &pAttrs, MqttClientThread,
                       (void *) &threadArg);
    if(lRetVal != 0)
    {
        UART_PRINT("Client Thread Create Failed failed\n\r");
        gInitState &= ~CLIENT_INIT_STATE;
        return(-1);
    }
#ifdef SECURE_CLIENT
    setTime();
#endif

    /*setting will parameters                                                */
    MQTTClient_set(gMqttClient, MQTTClient_WILL_PARAM, &will_param,
                   sizeof(will_param));

#ifdef CLNT_USR_PWD
    /*Set user name for client connection                                    */
    MQTTClient_set(gMqttClient, MQTTClient_USER_NAME, (void *)ClientUsername,
                   strlen(
                       (char*)ClientUsername));

    /*Set password                                                           */
    MQTTClient_set(gMqttClient, MQTTClient_PASSWORD, (void *)ClientPassword,
                   strlen(
                       (char*)ClientPassword));
#endif
    /*Initiate MQTT Connect                                                  */
    if(gApConnectionState >= 0)
    {
#if CLEAN_SESSION == false
        bool clean = CLEAN_SESSION;
        MQTTClient_set(gMqttClient, MQTTClient_CLEAN_CONNECT, (void *)&clean,
                       sizeof(bool));
#endif
        /*The return code of MQTTClient_connect is the ConnACK value that
           returns from the server */
        lRetVal = MQTTClient_connect(gMqttClient);

        /*negative lRetVal means error,
           0 means connection successful without session stored by the server,
           greater than 0 means successful connection with session stored by
           the server */
        if(0 > lRetVal)
        {
            /*lib initialization failed                                      */
            UART_PRINT("Connection to broker failed, Error code: %d\n\r",
                       lRetVal);

            gUiConnFlag = 0;
        }
        else
        {
            gUiConnFlag = 1;
        }
        /*Subscribe to topics when session is not stored by the server       */
        if((gUiConnFlag == 1) && (0 == lRetVal))
        {
            uint8_t subIndex;
            MQTTClient_SubscribeParams subscriptionInfo[
                SUBSCRIPTION_TOPIC_COUNT];

            for(subIndex = 0; subIndex < SUBSCRIPTION_TOPIC_COUNT; subIndex++)
            {
                subscriptionInfo[subIndex].topic = topic[subIndex];
                subscriptionInfo[subIndex].qos = qos[subIndex];
            }

            if(MQTTClient_subscribe(gMqttClient, subscriptionInfo,
                                    SUBSCRIPTION_TOPIC_COUNT) < 0)
            {
                UART_PRINT("\n\r Subscription Error \n\r");
                MQTTClient_disconnect(gMqttClient);
                gUiConnFlag = 0;
            }
            else
            {
                for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
                {
                    UART_PRINT("Client subscribed on %s\n\r,", topic[iCount]);
                }
            }
        }
    }

    gInitState &= ~CLIENT_INIT_STATE;

    return(0);
}

//*****************************************************************************
//!
//! MQTT Client stop - Unsubscribe from the subscription topics and exit the
//! MQTT client lib.
//!
//! \param  none
//!
//! \return None
//!
//*****************************************************************************

void Mqtt_ClientStop(uint8_t disconnect)
{
    uint32_t iCount;

    MQTTClient_UnsubscribeParams subscriptionInfo[SUBSCRIPTION_TOPIC_COUNT];

    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
    {
        subscriptionInfo[iCount].topic = topic[iCount];
    }

    MQTTClient_unsubscribe(gMqttClient, subscriptionInfo,
                           SUBSCRIPTION_TOPIC_COUNT);
    for(iCount = 0; iCount < SUBSCRIPTION_TOPIC_COUNT; iCount++)
    {
        UART_PRINT("Unsubscribed from the topic %s\r\n", topic[iCount]);
    }
    gUiConnFlag = 0;

    /*exiting the Client library                                             */
    MQTTClient_delete(gMqttClient);
}

//*****************************************************************************
//!
//! Utility function which prints the borders
//!
//! \param[in] ch  -  hold the charater for the border.
//! \param[in] n   -  hold the size of the border.
//!
//! \return none.
//!
//*****************************************************************************

//void printBorder(char ch,
//                 int n)
//{
//    int i = 0;
//
//    for(i = 0; i < n; i++)
//    {
//        putch(ch);
//    }
//}

//*****************************************************************************
//!
//! Set the ClientId with its own mac address
//! This routine converts the mac address which is given
//! by an integer type variable in hexadecimal base to ASCII
//! representation, and copies it into the ClientId parameter.
//!
//! \param  macAddress  -   Points to string Hex.
//!
//! \return void.
//!
//*****************************************************************************
void SetClientIdNamefromMacAddress(uint8_t *macAddress)
{
    uint8_t Client_Mac_Name[2];
    uint8_t Index;

    /*When ClientID isn't set, use the mac address as ClientID               */
    if(ClientId[0] == '\0')
    {
        /*6 bytes is the length of the mac address                           */
        for(Index = 0; Index < SL_MAC_ADDR_LEN; Index++)
        {
            /*Each mac address byte contains two hexadecimal characters      */
            /*Copy the 4 MSB - the most significant character                */
            Client_Mac_Name[0] = (macAddress[Index] >> 4) & 0xf;
            /*Copy the 4 LSB - the least significant character               */
            Client_Mac_Name[1] = macAddress[Index] & 0xf;

            if(Client_Mac_Name[0] > 9)
            {
                /*Converts and copies from number that is greater than 9 in  */
                /*hexadecimal representation (a to f) into ascii character   */
                ClientId[2 * Index] = Client_Mac_Name[0] + 'a' - 10;
            }
            else
            {
                /*Converts and copies from number 0 - 9 in hexadecimal       */
                /*representation into ascii character                        */
                ClientId[2 * Index] = Client_Mac_Name[0] + '0';
            }
            if(Client_Mac_Name[1] > 9)
            {
                /*Converts and copies from number that is greater than 9 in  */
                /*hexadecimal representation (a to f) into ascii character   */
                ClientId[2 * Index + 1] = Client_Mac_Name[1] + 'a' - 10;
            }
            else
            {
                /*Converts and copies from number 0 - 9 in hexadecimal       */
                /*representation into ascii character                        */
                ClientId[2 * Index + 1] = Client_Mac_Name[1] + '0';
            }
        }
    }
}

//*****************************************************************************
//!
//! Utility function which Display the app banner
//!
//! \param[in] appName     -  holds the application name.
//! \param[in] appVersion  -  holds the application version.
//!
//! \return none.
//!
//*****************************************************************************

int32_t DisplayAppBanner(char* appName,
                         char* appVersion)
{
    int32_t ret = 0;
    uint8_t macAddress[SL_MAC_ADDR_LEN];
    uint16_t macAddressLen = SL_MAC_ADDR_LEN;
    uint16_t ConfigSize = 0;
    uint8_t ConfigOpt = SL_DEVICE_GENERAL_VERSION;
    SlDeviceVersion_t ver = {0};

    ConfigSize = sizeof(SlDeviceVersion_t);

    /*Print device version info. */
    ret =
        sl_DeviceGet(SL_DEVICE_GENERAL, &ConfigOpt, &ConfigSize,
                     (uint8_t*)(&ver));

    /*Print device Mac address */
    ret = sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET, 0, &macAddressLen,
                       &macAddress[0]);

    UART_PRINT(lineBreak);
    UART_PRINT("\t");
//    printBorder('=', 44);
    UART_PRINT(lineBreak);
    UART_PRINT("\t   %s Example Ver: %s",appName, appVersion);
    UART_PRINT(lineBreak);
    UART_PRINT("\t");
//    printBorder('=', 44);
    UART_PRINT(lineBreak);
    UART_PRINT(lineBreak);
    UART_PRINT("\t CHIP: 0x%x",ver.ChipId);
    UART_PRINT(lineBreak);
    UART_PRINT("\t MAC:  %d.%d.%d.%d",ver.FwVersion[0],ver.FwVersion[1],
               ver.FwVersion[2],
               ver.FwVersion[3]);
    UART_PRINT(lineBreak);
    UART_PRINT("\t PHY:  %d.%d.%d.%d",ver.PhyVersion[0],ver.PhyVersion[1],
               ver.PhyVersion[2],
               ver.PhyVersion[3]);
    UART_PRINT(lineBreak);
    UART_PRINT("\t NWP:  %d.%d.%d.%d",ver.NwpVersion[0],ver.NwpVersion[1],
               ver.NwpVersion[2],
               ver.NwpVersion[3]);
    UART_PRINT(lineBreak);
    UART_PRINT("\t ROM:  %d",ver.RomVersion);
    UART_PRINT(lineBreak);
    UART_PRINT("\t HOST: %s", SL_DRIVER_VERSION);
    UART_PRINT(lineBreak);
    UART_PRINT("\t MAC address: %02x:%02x:%02x:%02x:%02x:%02x", macAddress[0],
               macAddress[1], macAddress[2], macAddress[3], macAddress[4],
               macAddress[5]);
    UART_PRINT(lineBreak);
    UART_PRINT(lineBreak);
    UART_PRINT("\t");
//    printBorder('=', 44);
    UART_PRINT(lineBreak);
    UART_PRINT(lineBreak);

    SetClientIdNamefromMacAddress(macAddress);

    return(ret);
}

void MQTTThread(void * args)
{
    uint32_t count = 0;
//    pthread_t spawn_thread = (pthread_t) NULL;
//    pthread_attr_t pAttrs_spawn;
//    struct sched_param priParam;
    int32_t retc = 0;
//    UART_Handle tUartHndl;
//
//    /*Initialize SlNetSock layer with CC31xx/CC32xx interface */
//    SlNetIf_init(0);
//    SlNetIf_add(SLNETIF_ID_1, "CC32xx",
//                (const SlNetIf_Config_t *)&SlNetIfConfigWifi,
//                SLNET_IF_WIFI_PRIO);
//
//    SlNetSock_init(0);
//    SlNetUtil_init(0);
//
//    GPIO_init();
//    SPI_init();
//
//    /*Configure the UART                                                     */
//    tUartHndl = InitTerm();
//    /*remove uart receive from LPDS dependency                               */
//    UART_control(tUartHndl, UART_CMD_RXDISABLE, NULL);
//
//    /*Create the sl_Task                                                     */
//    pthread_attr_init(&pAttrs_spawn);
//    priParam.sched_priority = SPAWN_TASK_PRIORITY;
//    retc = pthread_attr_setschedparam(&pAttrs_spawn, &priParam);
//    retc |= pthread_attr_setstacksize(&pAttrs_spawn, TASKSTACKSIZE);
//    retc |= pthread_attr_setdetachstate
//                                    (&pAttrs_spawn, PTHREAD_CREATE_DETACHED);
//
//    retc = pthread_create(&spawn_thread, &pAttrs_spawn, sl_Task, NULL);
//
//    if(retc != 0)
//    {
//        UART_PRINT("could not create simplelink task\n\r");
//        while(1)
//        {
//            ;
//        }
//    }
//
//    retc = sl_Start(0, 0, 0);
//    if(retc < 0)
//    {
//        /*Handle Error */
//        UART_PRINT("\n sl_Start failed\n");
//        while(1)
//        {
//            ;
//        }
//    }
//
//    /*Output device information to the UART terminal */
//    retc = DisplayAppBanner(APPLICATION_NAME, APPLICATION_VERSION);
//
//    retc = sl_Stop(SL_STOP_TIMEOUT);
//    if(retc < 0)
//    {
//        /*Handle Error */
//        UART_PRINT("\n sl_Stop failed\n");
//        while(1)
//        {
//            ;
//        }
//    }
//
//    if(retc < 0)
//    {
//        /*Handle Error */
//        UART_PRINT("mqtt_client - Unable to retrieve device information \n");
//        while(1)
//        {
//            ;
//        }
//    }

    while(1)
    {
        gResetApplication = false;
        topic[0] = SUBSCRIPTION_TOPIC0;
//        topic[1] = SUBSCRIPTION_TOPIC1;
//        topic[2] = SUBSCRIPTION_TOPIC2;
//        topic[3] = SUBSCRIPTION_TOPIC3;
        gInitState = 0;

        /*Connect to AP                                                      */
        gApConnectionState = Mqtt_IF_Connect();
        gApConnectionState = 0;

        gInitState |= MQTT_INIT_STATE;
        /*Run MQTT Main Thread (it will open the Client and Server)          */
        Mqtt_start();

        /*Wait for init to be completed!!!                                   */
        while(gInitState != 0)
        {
            UART_PRINT(".");
            sleep(1);
        }
        UART_PRINT(".\r\n");

        while(gResetApplication == false)
        {
            ;
        }

        UART_PRINT("TO Complete - Closing all threads and resources\r\n");

        /*Stop the MQTT Process                                              */
        Mqtt_Stop();

        UART_PRINT("reopen MQTT # %d  \r\n", ++count);
    }
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

2376.mqtt_client_app.h

/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

//*****************************************************************************
//
//! \addtogroup mqtt_server
//! @{
//
//*****************************************************************************
/* Standard includes                                                         */
#include <stdlib.h>

/* Kernel (Non OS/Free-RTOS/TI-RTOS) includes                                */
#include "pthread.h"
#include "mqueue.h"

/* Common interface includes                                                 */
#include <Services/uart_term.h>

/* Application includes                                                      */
#include "client_cbs.h"

extern bool gResetApplication;

//*****************************************************************************
//                          LOCAL DEFINES
//*****************************************************************************
#define APP_PRINT               Report

#define OS_WAIT_FOREVER         (0xFFFFFFFF)
#define OS_NO_WAIT              (0)
#define OS_OK                   (0)

#define MQTTClientCbs_ConnackRC(data) (data & 0xff) 
/**< CONNACK: Return Code (LSB) */

//*****************************************************************************
//                 GLOBAL VARIABLES
//*****************************************************************************

/* Message Queue                                                              */
extern mqd_t g_PBQueue;
extern char *topic[];
struct client_info client_info_table[MAX_CONNECTION];

//*****************************************************************************
//                 Queue external function
//*****************************************************************************
extern int32_t MQTT_SendMsgToQueue(struct msgQueue *queueElement);

//****************************************************************************
//                      CLIENT CALLBACKS
//****************************************************************************

//*****************************************************************************
//
//! Callback in case of various event (for clients connection with remote
//! broker)
//!
//! \param[in]  event       - is a event occurred
//! \param[in]  metaData    - is the pointer for the message buffer
//!                           (for this event)
//! \param[in]  metaDateLen - is the length of the message buffer
//! \param[in]  data        - is the pointer to the buffer for data
//!                           (for this event)
//! \param[in]  dataLen     - is the length of the buffer data
//!
//! return none
//
//*****************************************************************************
void MqttClientCallback(int32_t event,
                        void * metaData,
                        uint32_t metaDateLen,
                        void *data,
                        uint32_t dataLen)
{
    int32_t i = 0;

    switch((MQTTClient_EventCB)event)
    {
    case MQTTClient_OPERATION_CB_EVENT:
    {
        switch(((MQTTClient_OperationMetaDataCB *)metaData)->messageType)
        {
        case MQTTCLIENT_OPERATION_CONNACK:
        {
            uint16_t *ConnACK = (uint16_t*) data;
            APP_PRINT("CONNACK:\n\r");
            /* Check if Conn Ack return value is Success (0) or       */
            /* Error - Negative value                                 */
            if(0 == (MQTTClientCbs_ConnackRC(*ConnACK)))
            {
                APP_PRINT("Connection Success\n\r");
            }
            else
            {
                APP_PRINT("Connection Error: %d\n\r", *ConnACK);
            }
            break;
        }

        case MQTTCLIENT_OPERATION_EVT_PUBACK:
        {
            char *PubAck = (char *) data;
            APP_PRINT("PubAck:\n\r");
            APP_PRINT("%s\n\r", PubAck);
            break;
        }

        case MQTTCLIENT_OPERATION_SUBACK:
        {
            APP_PRINT("Sub Ack:\n\r");
            APP_PRINT("Granted QoS Levels are:\n\r");
            for(i = 0; i < dataLen; i++)
            {
                APP_PRINT("%s :QoS %d\n\r", topic[i],
                          ((unsigned char*) data)[i]);
            }
            break;
        }

        case MQTTCLIENT_OPERATION_UNSUBACK:
        {
            char *UnSub = (char *) data;
            APP_PRINT("UnSub Ack \n\r");
            APP_PRINT("%s\n\r", UnSub);
            break;
        }

        default:
            break;
        }
        break;
    }
    case MQTTClient_RECV_CB_EVENT:
    {
        MQTTClient_RecvMetaDataCB *recvMetaData =
            (MQTTClient_RecvMetaDataCB *)metaData;
        uint32_t bufSizeReqd = 0;
        uint32_t topicOffset;
        uint32_t payloadOffset;

        struct publishMsgHeader msgHead;

        char *pubBuff = NULL;
        struct msgQueue queueElem;

        topicOffset = sizeof(struct publishMsgHeader);
        payloadOffset = sizeof(struct publishMsgHeader) +
                        recvMetaData->topLen + 1;

        bufSizeReqd += sizeof(struct publishMsgHeader);
        bufSizeReqd += recvMetaData->topLen + 1;
        bufSizeReqd += dataLen + 1;
        pubBuff = (char *) malloc(bufSizeReqd);

        if(pubBuff == NULL)
        {
            APP_PRINT("malloc failed: recv_cb\n\r");
            return;
        }

        msgHead.topicLen = recvMetaData->topLen;
        msgHead.payLen = dataLen;
        msgHead.retain = recvMetaData->retain;
        msgHead.dup = recvMetaData->dup;
        msgHead.qos = recvMetaData->qos;
        memcpy((void*) pubBuff, &msgHead, sizeof(struct publishMsgHeader));

        /* copying the topic name into the buffer                        */
        memcpy((void*) (pubBuff + topicOffset),
               (const void*)recvMetaData->topic,
               recvMetaData->topLen);
        memset((void*) (pubBuff + topicOffset + recvMetaData->topLen),'\0',1);

        /* copying the payload into the buffer                           */
        memcpy((void*) (pubBuff + payloadOffset), (const void*) data, dataLen);
        memset((void*) (pubBuff + payloadOffset + dataLen), '\0', 1);

        APP_PRINT("\n\rMsg Recvd. by client\n\r");
        APP_PRINT("TOPIC: %s\n\r", pubBuff + topicOffset);
        APP_PRINT("PAYLOAD: %s\n\r", pubBuff + payloadOffset);
        APP_PRINT("QOS: %d\n\r", recvMetaData->qos);

        if(recvMetaData->retain)
        {
            APP_PRINT("Retained\n\r");
        }

        if(recvMetaData->dup)
        {
            APP_PRINT("Duplicate\n\r");
        }

        /* filling the queue element details                              */
        queueElem.event = MSG_RECV_BY_CLIENT;
        queueElem.msgPtr = pubBuff;
        queueElem.topLen = recvMetaData->topLen;

        /* signal to the main task                                        */
        if(MQTT_SendMsgToQueue(&queueElem))
        {
            UART_PRINT("\n\n\rQueue is full\n\n\r");
        }
        break;
    }
    case MQTTClient_DISCONNECT_CB_EVENT:
    {
        gResetApplication = true;
        APP_PRINT("BRIDGE DISCONNECTION\n\r");
        break;
    }
    }
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

1220.client_cbs.h

/*
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

//*****************************************************************************
// network_if.c
//
// Networking interface functions for CC32xx device
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup common_interface
//! @{
//
//*****************************************************************************
/* Standard includes                                                         */
#include <string.h>
#include <stdlib.h>

/* Kernel (Non OS/Free-RTOS/TI-RTOS) includes                                */
#include <pthread.h>
#include <mqueue.h>
#include <unistd.h>

/* Simplelink includes                                                       */
#include <ti/drivers/net/wifi/simplelink.h>

/* Common interface includes                                                 */
#include "network_if.h"
#include <Services/uart_term.h>

//*****************************************************************************
//                          LOCAL DEFINES
//*****************************************************************************

/* Network App specific status/error codes which are                         */
/* used only in this file.                                                   */
typedef enum
{
    /* Choosing this number to avoid overlap with host-driver's error codes. */
    DEVICE_NOT_IN_STATION_MODE = -0x7F0,
    DEVICE_NOT_IN_AP_MODE = DEVICE_NOT_IN_STATION_MODE - 1,
    DEVICE_NOT_IN_P2P_MODE = DEVICE_NOT_IN_AP_MODE - 1,

    STATUS_CODE_MAX = -0xBB8
} e_NetAppStatusCodes;

//*****************************************************************************
//                 GLOBAL VARIABLES
//*****************************************************************************

/* Station IP address                                                        */
unsigned long g_ulStaIp = 0;
/* Network Gateway IP address                                                */
unsigned long g_ulGatewayIP = 0;
/* Connection SSID                                                           */
unsigned char g_ucConnectionSSID[SL_WLAN_SSID_MAX_LENGTH + 1];
/* Connection BSSID                                                          */
unsigned char g_ucConnectionBSSID[SL_WLAN_BSSID_LENGTH ];
/* SimpleLink Status                                                         */
volatile unsigned long g_ulStatus = 0;
/* Connection time delay index                                               */
volatile unsigned short g_usConnectIndex;

//*****************************************************************************
// SimpleLink Asynchronous Event Handlers -- Start
//*****************************************************************************
//void SimpleLinkHttpServerEventHandler(
//    SlNetAppHttpServerEvent_t *pSlHttpServerEvent,
//    SlNetAppHttpServerResponse_t *
//    pSlHttpServerResponse)
//{
//}

//void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest,
//                                         SlNetAppResponse_t *pNetAppResponse)
//{
//}
//
//void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
//{
//}

//*****************************************************************************
//!
//! On Successful completion of Wlan Connect, This function triggers connection
//! status to be set.
//!
//! \param[in]  pSlWlanEvent    - pointer indicating Event type
//!
//! \return None
//!
//*****************************************************************************
//void SimpleLinkWlanEventHandler(SlWlanEvent_t *pSlWlanEvent)
//{
//    SlWlanEventDisconnect_t* pEventData = NULL;
//
//    switch(pSlWlanEvent->Id)
//    {
//    case SL_WLAN_EVENT_CONNECT:
//        SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
//
//        memcpy(g_ucConnectionSSID, pSlWlanEvent->Data.Connect.SsidName,
//               pSlWlanEvent->Data.Connect.SsidLen);
//        memcpy(g_ucConnectionBSSID, pSlWlanEvent->Data.Connect.Bssid,
//               SL_WLAN_BSSID_LENGTH);
//
//        UART_PRINT(
//            "[WLAN EVENT] STA Connected to the AP: %s , BSSID: "
//            "%x:%x:%x:%x:%x:%x\n\r", g_ucConnectionSSID,
//            g_ucConnectionBSSID[0], g_ucConnectionBSSID[1],
//            g_ucConnectionBSSID[2],
//            g_ucConnectionBSSID[3], g_ucConnectionBSSID[4],
//            g_ucConnectionBSSID[5]);
//        break;
//
//    case SL_WLAN_EVENT_DISCONNECT:
//        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
//        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
//
//        pEventData = &pSlWlanEvent->Data.Disconnect;
//
//        /* If the user has initiated 'Disconnect' request, 'reason_code' */
//        /* is SL_WLAN_DISCONNECT_USER_INITIATED                          */
//        if(SL_WLAN_DISCONNECT_USER_INITIATED == pEventData->ReasonCode)
//        {
//            UART_PRINT("Device disconnected from the AP on application's "
//                       "request \n\r");
//        }
//        else
//        {
//            UART_PRINT("Device disconnected from the AP on an ERROR..!! \n\r");
//        }
//        break;
//
//    case SL_WLAN_EVENT_STA_ADDED:
//        /* when device is in AP mode and any client connects to it.      */
//        SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
//        break;
//
//    case SL_WLAN_EVENT_STA_REMOVED:
//        /* when device is in AP mode and any client disconnects from it. */
//        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
//        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
//        break;
//
//    default:
//        UART_PRINT("[WLAN EVENT] Unexpected event %d\n\r", pSlWlanEvent->Id);
//        break;
//    }
//}

//*****************************************************************************
//
//! The Function Handles the Fatal errors
//!
//! \param[in]  slFatalErrorEvent - Pointer to Fatal Error Event info
//!
//! \return     None
//!
//*****************************************************************************
//void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent)
//{
//    switch(slFatalErrorEvent->Id)
//    {
//    case SL_DEVICE_EVENT_FATAL_DEVICE_ABORT:
//        UART_PRINT(
//            "[ERROR] - FATAL ERROR: Abort NWP event detected: "
//            "AbortType=%d, AbortData=0x%x\n\r",
//            slFatalErrorEvent->Data.DeviceAssert.Code,
//            slFatalErrorEvent->Data.DeviceAssert.Value);
//        break;
//
//    case SL_DEVICE_EVENT_FATAL_DRIVER_ABORT:
//        UART_PRINT("[ERROR] - FATAL ERROR: Driver Abort detected. \n\r");
//        break;
//
//    case SL_DEVICE_EVENT_FATAL_NO_CMD_ACK:
//        UART_PRINT(
//            "[ERROR] - FATAL ERROR: No Cmd Ack detected "
//            "[cmd opcode = 0x%x] \n\r",
//            slFatalErrorEvent->Data.NoCmdAck.Code);
//        break;
//
//    case SL_DEVICE_EVENT_FATAL_SYNC_LOSS:
//        UART_PRINT("[ERROR] - FATAL ERROR: Sync loss detected n\r");
//        break;
//
//    case SL_DEVICE_EVENT_FATAL_CMD_TIMEOUT:
//        UART_PRINT(
//            "[ERROR] - FATAL ERROR: Async event timeout detected "
//            "[event opcode =0x%x]  \n\r",
//            slFatalErrorEvent->Data.CmdTimeout.Code);
//        break;
//
//    default:
//        UART_PRINT("[ERROR] - FATAL ERROR: Unspecified error detected \n\r");
//        break;
//    }
//}

//*****************************************************************************
//
//! This function handles network events such as IP acquisition, IP leased, IP
//! released etc.
//!
//! \param[in]  pNetAppEvent - Pointer to NetApp Event Info
//!
//! \return None
//!
//*****************************************************************************
//void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
//{
//    switch(pNetAppEvent->Id)
//    {
//    case SL_NETAPP_EVENT_IPV4_ACQUIRED:
//    case SL_NETAPP_EVENT_IPV6_ACQUIRED:
//        SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
//        UART_PRINT("[NETAPP EVENT] IP acquired by the device\n\r");
//        break;
//
//    case SL_NETAPP_EVENT_DHCPV4_LEASED:
//        SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
//        g_ulStaIp = (pNetAppEvent)->Data.IpLeased.IpAddress;
//
//        UART_PRINT("[NETAPP EVENT] IP Leased to Client: IP=%d.%d.%d.%d , ",
//                   SL_IPV4_BYTE(g_ulStaIp,
//                                3),
//                   SL_IPV4_BYTE(g_ulStaIp,
//                                2),
//                   SL_IPV4_BYTE(g_ulStaIp, 1), SL_IPV4_BYTE(g_ulStaIp, 0));
//        break;
//
//    case SL_NETAPP_EVENT_DHCPV4_RELEASED:
//        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
//
//        UART_PRINT("[NETAPP EVENT] IP Released for Client: "
//                   "IP=%d.%d.%d.%d , ", SL_IPV4_BYTE(g_ulStaIp,
//                                                     3),
//                   SL_IPV4_BYTE(g_ulStaIp,
//                                2),
//                   SL_IPV4_BYTE(g_ulStaIp, 1), SL_IPV4_BYTE(g_ulStaIp, 0));
//        break;
//
//    default:
//        UART_PRINT("[NETAPP EVENT] Unexpected event [0x%x] \n\r",
//                   pNetAppEvent->Id);
//        break;
//    }
//}

//*****************************************************************************
//
//! This function handles resource request
//!
//! \param[in]  pNetAppRequest  - Contains the resource requests
//! \param[in]  pNetAppResponse - Should be filled by the user with the
//!                               relevant response information
//!
//! \return     None
//!
//*****************************************************************************
void SimpleLinkNetAppRequestHandler(SlNetAppRequest_t *pNetAppRequest,
                                    SlNetAppResponse_t *pNetAppResponse)
{
    /* Unused in this application                                            */
}

//*****************************************************************************
//
//! This function handles HTTP server events
//!
//! \param[in]  pServerEvent     - Contains the relevant event information
//! \param[in]  pServerResponse  - Should be filled by the user with the
//!                                relevant response information
//!
//! \return None
//!
//****************************************************************************
void SimpleLinkHttpServerCallback(SlNetAppHttpServerEvent_t *pHttpEvent,
                                  SlNetAppHttpServerResponse_t *pHttpResponse)
{
    /* Unused in this application                                            */
}

//*****************************************************************************
//
//! This function handles General Events
//!
//! \param[in]  pDevEvent - Pointer to General Event Info
//!
//! \return None
//!
//*****************************************************************************
//void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
//{
//    /* Most of the general errors are not FATAL. are to be handled           */
//    /* appropriately by the application.                                     */
//    UART_PRINT("[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n",
//               pDevEvent->Data.Error.Code,
//               pDevEvent->Data.Error.Source);
//}

//*****************************************************************************
//
//! This function handles socket events indication
//!
//! \param[in]  pSock - Pointer to Socket Event Info
//!
//! \return None
//!
//*****************************************************************************
//void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
//{
//    /* This application doesn't work w/ socket - Events are not expected     */
//    switch(pSock->Event)
//    {
//    case SL_SOCKET_TX_FAILED_EVENT:
//        switch(pSock->SocketAsyncEvent.SockTxFailData.Status)
//        {
//        case SL_ERROR_BSD_ECLOSE:
//            UART_PRINT(
//                "[SOCK ERROR] - close socket (%d) operation "
//                "failed to transmit all queued packets\n\r",
//                pSock->SocketAsyncEvent.SockTxFailData.Sd);
//            break;
//        default:
//            UART_PRINT(
//                "[SOCK ERROR] - TX FAILED  :  socket %d , "
//                "reason (%d) \n\n",
//                pSock->SocketAsyncEvent.SockTxFailData.Sd,
//                pSock->SocketAsyncEvent.SockTxFailData.Status);
//            break;
//        }
//        break;
//    case SL_SOCKET_ASYNC_EVENT:
//    {
//        UART_PRINT("[SOCK ERROR] an event received on socket %d\r\n",
//                   pSock->SocketAsyncEvent.SockAsyncData.Sd);
//        switch(pSock->SocketAsyncEvent.SockAsyncData.Type)
//        {
//        case SL_SSL_NOTIFICATION_CONNECTED_SECURED:
//            UART_PRINT("[SOCK ERROR] SSL handshake done");
//            break;
//        case SL_SSL_NOTIFICATION_HANDSHAKE_FAILED:
//            UART_PRINT("[SOCK ERROR] SSL handshake failed with error %d\r\n",
//                       pSock->SocketAsyncEvent.SockAsyncData.Val);
//            break;
//        case SL_SSL_ACCEPT:
//            UART_PRINT(
//                "[SOCK ERROR] Recoverable error occurred "
//                "during the handshake %d\r\n",
//                pSock->SocketAsyncEvent.SockAsyncData.Val);
//            break;
//        case SL_OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED:
//            UART_PRINT("[SOCK ERROR] Other peer terminated the SSL layer.\r\n");
//            break;
//        case SL_SSL_NOTIFICATION_WRONG_ROOT_CA:
//            UART_PRINT("[SOCK ERROR] Used wrong CA to verify the peer.\r\n");
//            break;
//        default:
//            break;
//        }
//        break;
//    }
//    default:
//        UART_PRINT("[SOCK EVENT] - Unexpected Event [%x0x]\n\n", pSock->Event);
//        break;
//    }
//}

//*****************************************************************************
// SimpleLink Asynchronous Event Handlers -- End
//*****************************************************************************

//*****************************************************************************
//
//! This function initializes the application variables
//!
//! \param  None
//!
//! \return 0 on success, negative error-code on error
//
//*****************************************************************************
void InitializeAppVariables(void)
{
    g_ulStatus = 0;
    g_ulStaIp = 0;
    g_ulGatewayIP = 0;

    memset(g_ucConnectionSSID, 0, sizeof(g_ucConnectionSSID));
    memset(g_ucConnectionBSSID, 0, sizeof(g_ucConnectionBSSID));
}

//*****************************************************************************
//
//! The function initializes a CC32xx device and triggers it to start operation
//!
//! \param[in]  uiMode  - device mode in which device will be configured
//!
//! \return 0 : success, -ve : failure
//
//*****************************************************************************
long Network_IF_InitDriver(uint32_t uiMode)
{
    long lRetVal = 0;

    /* Reset CC32xx Network State Machine                                    */
//    InitializeAppVariables();

    /* Following function configure the device to default state by cleaning  */
    /* the persistent settings stored in NVMEM (viz. connection profiles     */
    /* & policies, power policy etc) Applications may choose to skip this    */
    /* step if the developer is sure that the device is in its default state */
    /* at start of application. Note that all profiles and persistent        */
    /* settings that were done on the device will be lost.                   */
//    lRetVal = sl_Start(NULL, NULL, NULL);

//    if(lRetVal < 0)
//    {
//        UART_PRINT("Failed to start the device \n\r");
//        LOOP_FOREVER();
//    }
//
//    switch(lRetVal)
//    {
//    case ROLE_STA:
//        UART_PRINT("Device came up in Station mode\n\r");
//        break;
//    case ROLE_AP:
//        UART_PRINT("Device came up in Access-Point mode\n\r");
//        break;
//    case ROLE_P2P:
//        UART_PRINT("Device came up in P2P mode\n\r");
//        break;
//    default:
//        UART_PRINT("Error:unknown mode\n\r");
//        break;
//    }
//
//    if(uiMode != lRetVal)
//    {
//        UART_PRINT("Switching Networking mode on application request\n\r");
//
//        /* Switch to AP role and restart                                     */
//        lRetVal = sl_WlanSetMode(uiMode);
//        ASSERT_ON_ERROR(lRetVal);
//
//        lRetVal = sl_Stop(SL_STOP_TIMEOUT);
//        lRetVal = sl_Start(0, 0, 0);
//        ASSERT_ON_ERROR(lRetVal);
//
//        if(lRetVal == uiMode)
//        {
//            switch(lRetVal)
//            {
//            case ROLE_STA:
//                UART_PRINT("Device came up in Station mode\n\r");
//                break;
//            case ROLE_AP:
//                UART_PRINT("Device came up in Access-Point mode\n\r");
//                /* If the device is in AP mode, we need to wait for this */
//                /* event before doing anything.                          */
//                while(!IS_IP_ACQUIRED(g_ulStatus))
//                {
//                    usleep(1000);
//                }
//                break;
//            case ROLE_P2P:
//                UART_PRINT("Device came up in P2P mode\n\r");
//                break;
//            default:
//                UART_PRINT("Error:unknown mode\n\r");
//                break;
//            }
//        }
//        else
//        {
//            UART_PRINT("could not configure correct networking mode\n\r");
//            LOOP_FOREVER();
//        }
//    }
//    else
//    {
//        if(lRetVal == ROLE_AP)
//        {
//            while(!IS_IP_ACQUIRED(g_ulStatus))
//            {
//                usleep(1000);
//            }
//        }
//    }
    return(0);
}

//*****************************************************************************
//
//! The function de-initializes a CC32xx device
//!
//! \param  None
//!
//! \return On success, zero is returned. On error, other
//
//*****************************************************************************
long Network_IF_DeInitDriver(void)
{
    long lRetVal = -1;

    UART_PRINT("SL Disconnect...\n\r");

    /* Disconnect from the AP                                                */
    lRetVal = Network_IF_DisconnectFromAP();

    /* Stop the simplelink host                                              */
    sl_Stop(SL_STOP_TIMEOUT);

    /* Reset the state to uninitialized                                      */
    Network_IF_ResetMCUStateMachine();
    return(lRetVal);
}

//*****************************************************************************
//
//! Connect to an Access Point using the specified SSID
//!
//! \param[in]  pcSsid          - is a string of the AP's SSID
//! \param[in]  SecurityParams  - is Security parameter for AP
//!
//! \return On success, zero is returned. On error, -ve value is returned
//
//*****************************************************************************
long Network_IF_ConnectAP(char *pcSsid,
                          SlWlanSecParams_t SecurityParams)
{
    char acCmdStore[128];
    unsigned short usConnTimeout;
    unsigned char ucRecvdAPDetails;
    long lRetVal;
    unsigned long ulIP = 0;
    unsigned long ulSubMask = 0;
    unsigned long ulDefGateway = 0;
    unsigned long ulDns = 0;

    g_usConnectIndex = 0;

    /* Disconnect from the AP                                                */
    Network_IF_DisconnectFromAP();

    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);

    /* Continue only if SSID is not empty                                    */
    if(pcSsid != NULL)
    {
        /* This triggers the CC32xx to connect to a specific AP.             */
        lRetVal =
            sl_WlanConnect((signed char *) pcSsid, strlen((const char *) pcSsid),
                           NULL, &SecurityParams, NULL);
        ASSERT_ON_ERROR(lRetVal);

        /* Wait for ~10 sec to check if connection to desire AP succeeds     */
        while(g_usConnectIndex < 10)
        {
            sleep(1);

            if(IS_CONNECTED(g_ulStatus) && IS_IP_ACQUIRED(g_ulStatus))
            {
                break;
            }
            g_usConnectIndex++;
        }
    }
    else
    {
        UART_PRINT("Empty SSID, Could not connect\n\r");
        return(-1);
    }

    /* Check and loop until AP connection successful, else ask new AP SSID   */
    while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus)))
    {
        /* Disconnect the previous attempt                                   */
        Network_IF_DisconnectFromAP();

        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
        CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
        UART_PRINT("Device could not connect to %s\n\r", pcSsid);

        do
        {
            ucRecvdAPDetails = 0;

            UART_PRINT("\n\r\n\rPlease enter the AP(open) SSID name # ");

            /* Get the AP name to connect over the UART                      */
            lRetVal = GetCmd(acCmdStore, sizeof(acCmdStore));
            if(lRetVal > 0)
            {
                /* remove start/end spaces if any                            */
                lRetVal = TrimSpace(acCmdStore);

                if(lRetVal)
                {
                    /* Parse the AP name                                     */
                    strncpy(pcSsid, acCmdStore, lRetVal);
                    if(pcSsid != NULL)
                    {
                        ucRecvdAPDetails = 1;
                        pcSsid[lRetVal] = '\0';
                    }
                }
            }
        }
        while(ucRecvdAPDetails == 0);

        /* Set Security Parameters to OPEN security type.                    */
        SecurityParams.Key = (signed char *) "";
        SecurityParams.KeyLen = 0;
        SecurityParams.Type = SL_WLAN_SEC_TYPE_OPEN;

        UART_PRINT("\n\rTrying to connect to AP: %s ...\n\r", pcSsid);

        /* Get the current timer tick and setup the timeout accordingly.     */
        usConnTimeout = g_usConnectIndex + 15;

        /* This triggers the CC32xx to connect to specific AP.               */
        lRetVal =
            sl_WlanConnect((signed char *) pcSsid, strlen((const char *) pcSsid),
                           NULL, &SecurityParams,NULL);
        ASSERT_ON_ERROR(lRetVal);

        /* Wait ~10 sec to check if connection to specified AP succeeds      */
        while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus)))
        {
            sleep(1);

            if(g_usConnectIndex >= usConnTimeout)
            {
                break;
            }
            g_usConnectIndex++;
        }
    }

    /* Put message on UART                                                   */
    UART_PRINT("\n\rDevice has connected to %s\n\r", pcSsid);

    /* Get IP address                                                        */
    lRetVal = Network_IF_IpConfigGet(&ulIP, &ulSubMask, &ulDefGateway, &ulDns);
    ASSERT_ON_ERROR(lRetVal);

    /* Send the information                                                  */
    UART_PRINT("Device IP Address is %d.%d.%d.%d \n\r\n\r",
               SL_IPV4_BYTE(ulIP, 3), SL_IPV4_BYTE(ulIP, 2), SL_IPV4_BYTE(ulIP,
                                                                          1),
               SL_IPV4_BYTE(ulIP, 0));
    return(0);
}

//*****************************************************************************
//
//! Disconnects from an Access Point
//!
//! \param  none
//!
//! \return 0 disconnected done, other already disconnected
//
//*****************************************************************************
long Network_IF_DisconnectFromAP(void)
{
    long lRetVal = 0;

    if(IS_CONNECTED(g_ulStatus))
    {
        lRetVal = sl_WlanDisconnect();
        if(0 == lRetVal)
        {
            while(IS_CONNECTED(g_ulStatus))
            {
                usleep(1000);
            }
            return(lRetVal);
        }
        else
        {
            return(lRetVal);
        }
    }
    else
    {
        return(lRetVal);
    }
}

//*****************************************************************************
//
//! Get the IP Address of the device.
//!
//! \param[in]  pulIP               - IP Address of Device
//! \param[in]  pulSubnetMask       - Subnetmask of Device
//! \param[in]  pulDefaultGateway   - Default Gateway value
//! \param[in]  pulDNSServer        - DNS Server
//!
//! \return On success, zero is returned. On error, -1 is returned
//
//*****************************************************************************
long Network_IF_IpConfigGet(unsigned long *pulIP,
                            unsigned long *pulSubnetMask,
                            unsigned long *pulDefaultGateway,
                            unsigned long *pulDNSServer)
{
    unsigned short usDHCP = 0;
    long lRetVal = -1;
    unsigned short len = sizeof(SlNetCfgIpV4Args_t);
    SlNetCfgIpV4Args_t ipV4 = { 0 };

    /* get network configuration                                             */
    lRetVal =
        sl_NetCfgGet(SL_NETCFG_IPV4_STA_ADDR_MODE, &usDHCP, &len,
                     (unsigned char *) &ipV4);
    ASSERT_ON_ERROR(lRetVal);

    *pulIP = ipV4.Ip;
    *pulSubnetMask = ipV4.IpMask;
    *pulDefaultGateway = ipV4.IpGateway;
    *pulDefaultGateway = ipV4.IpDnsServer;

    return(lRetVal);
}

//*****************************************************************************
//
//!  This function obtains the server IP address using a DNS lookup
//!
//! \param[in]  pcHostName        The server hostname
//! \param[out] pDestinationIP    This parameter is filled with host IP address
//!
//! \return On success, +ve value is returned. On error, -ve value is returned
//
//*****************************************************************************
long Network_IF_GetHostIP(char* pcHostName,
                          unsigned long * pDestinationIP)
{
    long lStatus = 0;

    lStatus =
        sl_NetAppDnsGetHostByName((signed char *) pcHostName, strlen(
                                      pcHostName), pDestinationIP, SL_AF_INET);
    ASSERT_ON_ERROR(lStatus);

    UART_PRINT("Get Host IP succeeded.\n\rHost: %s IP: %d.%d.%d.%d \n\r\n\r",
               pcHostName, SL_IPV4_BYTE(*pDestinationIP,
                                        3), SL_IPV4_BYTE(*pDestinationIP,
                                                         2),
               SL_IPV4_BYTE(*pDestinationIP, 1),
               SL_IPV4_BYTE(*pDestinationIP, 0));

    return(lStatus);
}

//*****************************************************************************
//
//! Reset state from the state machine
//!
//! \param  None
//!
//! \return none
//!
//*****************************************************************************
void Network_IF_ResetMCUStateMachine()
{
    g_ulStatus = 0;
}

//*****************************************************************************
//
//! Return the current state bits
//!
//! \param  None
//!
//! \return none
//!
//
//*****************************************************************************
unsigned long Network_IF_CurrentMCUState()
{
    return(g_ulStatus);
}

//*****************************************************************************
//
//! Sets a state from the state machine
//!
//! \param[in]  cStat   - Status of State Machine defined in e_StatusBits
//!
//! \return none
//!
//*****************************************************************************
void Network_IF_SetMCUMachineState(char cStat)
{
    SET_STATUS_BIT(g_ulStatus, cStat);
}

//*****************************************************************************
//
//! Unsets a state from the state machine
//!
//! \param[in]  cStat   - Status of State Machine defined in e_StatusBits
//!
//! \return none
//!
//*****************************************************************************
void Network_IF_UnsetMCUMachineState(char cStat)
{
    CLR_STATUS_BIT(g_ulStatus, cStat);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

3022.network_if.h

Please find the attaches to see the code changes.

cause 1: If flashed using CCS Uniflash, I am not getting print "MQTT task start", which I printing as below

switch(deviceType)
    {
        case DEV_TYPE_CC3220R:  // 3220R
            UART_PRINT("[Provisioning task] detected device is CC3220R\n\r");
            break;
        case DEV_TYPE_CC3220RS: // 3220RS
            UART_PRINT("[Provisioning task] detected device is CC3220RS\n\r");
            break;
        case DEV_TYPE_CC3220FS: // 3220FS
        {
            UART_PRINT("[Provisioning task] detected device is CC3220SF\n\r");

            // Start MQTT here //
            UART_PRINT("MQTT task start\n\r");

            pthread_t MQTTThreads = (pthread_t)NULL;
            int32_t RetVal;
            pthread_attr_t pAttrs;
            struct sched_param priParam;
            pthread_attr_init(&pAttrs);
            priParam.sched_priority = 1;
            RetVal = pthread_attr_setschedparam(&pAttrs, &priParam);
            RetVal |= pthread_attr_setstacksize(&pAttrs, 4096);

            if(RetVal)
            {
                /* Handle Error */
                UART_PRINT("Unable to configure thread parameters \n");
                while(1)
                {
                    ;
                }
            }

            RetVal = pthread_create(&MQTTThreads, &pAttrs, MQTTThread, NULL);

            if(RetVal)
            {
                /* Handle Error */
                UART_PRINT("Unable to create thread \n");
                while(1)
                {
                    ;
                }
            }
        }
            break;
        default:
            break;

Cause 2 : If I did JTAG debug, most of the time device is resetting by printing "

[Provisioning task] failed to commit new download, reverting to previous copy by reseting the device" and other some time.

Very few time "Connection to broker failed, Error code: -1"

Please let me know the solution for this,

Thank you

  • Hi,

    What is your goal with this OOB + MQTT project?
    Depending on what you're trying to do, there might be more appropriate starting points for this project that might be easier to work through and develop with. With the OOB project, you have the HTTP server, the provisioning task, the OTA functionality, and many other bits of functionality that you might not necessarily need that complicates debug.

    If you wanted to keep using your current OOB + MQTT project, there are couple things you can look at to start your debug.
    1. With the CCS uniflash case, where do you think you are getting stuck at based off of the terminal prints you can see?
    2. With the debugger case, if you step through your program or perhaps put a breakpoint right before the "failed to commit new download" message, do you observe anything unusual before that point? Any error messages?

    Regards,
    Michael
  • Hi Michael,
    I want use "Provisioning" task of the out of box project in my project.
    To the same I want to use Http get, Http post, MQTT pub and MQTT sub.
    Ho to achieve my above requirements in CC3220?
  • Hi,

    Given that you want all of that functionality, it might make sense to start with the smart lock reference design:
    www.ti.com/.../tidc-01005

    That code has provisioning and mqtt, as well as OTA which you would probably want in your product. Although it has some elock-specific functionality, that should be easily replaceable with your own product's code. Adding the HTTP functionality should be straightforward compared to adding MQTT or provisioning, and you can look at the httpget example for a guide on how to use our HTTP client library.

    Regards,
    Michael