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.

Problem while using MQTT client example and MQTT lib

Other Parts Discussed in Thread: CC3200

Hi,

I am using CC3200 to implement applicant which use MQTT client lib provided by SDK.

By doing some experiment on SDK MQTT client example, I found some weird case.

Please note I already patch SDK know issues for MQTT lib.

Followings is my experiment:

In MQTT client example, rewrite it to let it not enter main while loop but just repeat  to connect and disconnect from broker

==================================================

repeat2:
//
// Initialze MQTT client lib
//
lRetVal = sl_ExtLib_MqttClientInit(&Mqtt_Client);
if(lRetVal != 0)
{
// lib initialization failed
UART_PRINT("MQTT Client lib initialization failed\n\r");
LOOP_FOREVER();
}

repeat1:

/******************* connection to the broker ***************************/
iNumBroker = sizeof(usr_connect_config)/sizeof(connect_config);
if(iNumBroker > MAX_BROKER_CONN)
{
UART_PRINT("Num of brokers are more then max num of brokers\n\r");
LOOP_FOREVER();
}

while(iCount < iNumBroker)
{
//create client context
local_con_conf[iCount].clt_ctx =
sl_ExtLib_MqttClientCtxCreate(&local_con_conf[iCount].broker_config,
&local_con_conf[iCount].CallBAcks,
&(local_con_conf[iCount]));
UART_PRINT("Johnson 01\n\r");
//
// Set Client ID
//
sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
SL_MQTT_PARAM_CLIENT_ID,
local_con_conf[iCount].client_id,
strlen((char*)(local_con_conf[iCount].client_id)));

//
// Set will Params
//
if(local_con_conf[iCount].will_params.will_topic != NULL)
{
sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
SL_MQTT_PARAM_WILL_PARAM,
&(local_con_conf[iCount].will_params),
sizeof(SlMqttWill_t));
}

//
// setting username and password
//
if(local_con_conf[iCount].usr_name != NULL)
{
sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
SL_MQTT_PARAM_USER_NAME,
local_con_conf[iCount].usr_name,
strlen((char*)local_con_conf[iCount].usr_name));

if(local_con_conf[iCount].usr_pwd != NULL)
{
sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
SL_MQTT_PARAM_PASS_WORD,
local_con_conf[iCount].usr_pwd,
strlen((char*)local_con_conf[iCount].usr_pwd));
}
}
UART_PRINT("Johnson 02\n\r");
//
// connectin to the broker
//
if((sl_ExtLib_MqttClientConnect((void*)local_con_conf[iCount].clt_ctx,
local_con_conf[iCount].is_clean,
local_con_conf[iCount].keep_alive_time) & 0xFF) != 0)
{
UART_PRINT("\n\rBroker connect fail for conn no. %d \n\r",iCount+1);

//delete the context for this connection
sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);

break;
}
else
{
UART_PRINT("\n\rSuccess: conn to Broker no. %d\n\r ", iCount+1);
local_con_conf[iCount].is_connected = true;
iConnBroker++;
}
UART_PRINT("Johnson 03\n\r");
//
// Subscribe to topics
//

if(sl_ExtLib_MqttClientSub((void*)local_con_conf[iCount].clt_ctx,
local_con_conf[iCount].topic,
local_con_conf[iCount].qos, TOPIC_COUNT) < 0)
{
UART_PRINT("\n\r Subscription Error for conn no. %d\n\r", iCount+1);
UART_PRINT("Disconnecting from the broker\r\n");
sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
local_con_conf[iCount].is_connected = false;

//delete the context for this connection
sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
iConnBroker--;
break;
}
else
{
int iSub;
UART_PRINT("Client subscribed on following topics:\n\r");
for(iSub = 0; iSub < local_con_conf[iCount].num_topics; iSub++)
{
UART_PRINT("%s\n\r", local_con_conf[iCount].topic[iSub]);
}
}
iCount++;
}

if(iConnBroker < 1)
{
//
// no succesful connection to broker
//
goto end;
}

iCount = 0;

iNumBroker = 0;
iConnBroker = 0;

osi_Sleep(5);

sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
local_con_conf[iCount].is_connected = false;

//delete the context for this connection
sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
osi_Sleep(5);

goto repeat1;

lRetVal = sl_ExtLib_MqttClientExit();
if (lRetVal != 0)
UART_PRINT("MQTT exit failed\n\r");
osi_Sleep(5);


goto repeat2;

=================================================

So far, every thing is good, CC3200 will connect to desired AP and connect to desired broker, and then disconnect and then connect.

However, if I comment out the "goto repeat1" line in the code, and run into repeat2 loop, this time, it will blocked while it is trying to reconnect

to broker after doing sl_ExtLib_MqttClientExit(). The sl_ExtLib_MqttClientConnect function is never return.

Is there something not clean in sl_ExtLib_MqttClientExit() ? 

I also encounter the same behavior while I am following experiment:

1. Connect to desired AP

2. Connect to desired broker

3. unplug the power supply of the AP to cause a wlan disconnect.

4. My code will then take recover procedure and reconnect to AP (by repeat the exactly same procedure in step 1)

5. MQTT client then try to reconnect to broker without doing sl_ExtLib_MqttClientExit (the same procedure in previous repeat1 loop)

6. dada, sl_ExtLib_MqttClientConnect is no return like repeat2 case.

 

Please point out if there is any thing I am missed to build such kind of application.

By the way, the client example will also hang after broker connection is drop and it receive disconnect callback.

Maybe this is caused by doing sl_ExtLib_MqttClientCtxDelete in mqtt lib's context.

  • Hi Johnson,

    Allow me to check and get back.

    Regards,
    Ankur
  • I'm having the same issue as Johnson Mo. Is there an issue with sl_ExtLib_MqttClientExit()?

    Thanks
  • Hi Ankur,

    Any solution now?
    I got the same problem.
    And sl_ExtLib_MqttClientExit() will only return failure.
  • Hi Ankur1,

    Any update on this issue?
  • Hi Ankur,

    I think this is a critical issue on MQTT library.
    Any solution now?

    Thanks.
  • I had the same issue

    Anyway, for those maybe reading this and struggling with same issue, if you did apply the fix in the SDK, you need to make sure you are not using any function from MQTT library before you exit the callback. There is MUTEX_LOCKIN() in the function: proc_ctx_data_recv

    proc_ctx_data_recv will actually call do_net_close_rx, which in turn will call your callback function for disconnect.

    so if your disconnect function has anything to do MQTT library while the routine not finished, you will get locked. 

    just to make it short, I found the best way to handle this by just applying the fixes in the SDK knows issues wiki, but change from the application side your call back function:

    as an example:

    static void
    sl_MqttDisconnect(void *app_hndl)
    {
      
      connect_config *local_con_conf;
    
      local_con_conf = app_hndl;
      local_con_conf->is_connected = false;
      UART_PRINT("disconnect from broker %s\r\n",
                 (local_con_conf->broker_config).server_info.server_addr);
      local_con_conf->is_connected = false;
    
      //
      // write message indicating publish message
      //
      //osi_MsgQWrite(&g_PBQueue,&var,OSI_NO_WAIT);
       unsigned char ucQueueMsg = 1;
      
      osi_MsgQWrite(&g_tWkupSignalQueue, &ucQueueMsg, OSI_NO_WAIT);
        return; //we have to return so the main routine in MQTT library can remove the mutex lock
      
    }

    and then in your main loop or task where you are reading g_tWkupSignalQueue queue, you can do the following for clean disconnection:

    osi_MsgQRead(&g_tWkupSignalQueue, &ucQueueMsg, OSI_WAIT_FOREVER);
    switch(ucQueueMsg){
    case 1:{ //MQTT Client Disconnected
    UART_PRINT("MQTT Client Has been disconnected");
    osi_Sleep(100);  //just some delay so the MQTT library routine can finish and unlock
    
    sl_ExtLib_MqttClientDisconnect(MQTT_CLIENT_SESSION.clt_ctx);
    sl_ExtLib_MqttClientCtxDelete(MQTT_CLIENT_SESSION.clt_ctx);
    sl_ExtLib_MqttClientExit();
    
    
    //reconnect
    MqttClient_Connect();
    break;
    }
    

    For me this worked, maybe someone can come up with a better solution

    Best

    Khalefa

  • Hi Khaleefa ,

    Can you please explain this sentence you mentioned.

    "so if your disconnect function has anything to do MQTT library while the routine not finished, you will get locked. "

    I didn't get which is routine you are are referring to , while the sl_ExtLib_MqttDisconn() is running.

    Cheers

  • To properly understand this, you need to go into mqtt_client.c in the netapps folder

    I assume you were trying same as me, to disconnect the Client from server side, or some other way which will send the client notification about the disconnection

    I'll try to briefly explain it

    if you apply the fix from the SDK 1.1.0 knows issues for MQTT_client:

    Function: process_disconn_cb in File: sl_mqtt_client.c

    client_ctx->app_cbs.sl_ExtLib_MqttDisconn(client_ctx->app_hndl);

    if the client receive disconnection, this routine in the library will be executed as follow:

    static
    i32 proc_ctx_data_recv(struct client_ctx *cl_ctx, struct mqtt_packet *mqp,
                           u32 wait_secs, void **app)
    {
            i32 rv  = MQP_ERR_NOTCONN;
            i32 net = cl_ctx->net;
    
            *app = cl_ctx->usr;
    
            rv = net_recv(net, mqp, wait_secs, (void*)cl_ctx);
    
            MUTEX_LOCKIN();
    
            if(rv > 0)
                    if(false == process_recv(cl_ctx, mqp))
                            rv = MQP_ERR_CONTENT;
    
            /* RX: close the network connection to the server for this context, if
               (a) there is a processing / protocol error other than time-out
               (b) A good MQTT CONNACK has a return code - connection refused
            */
            if(((rv < 0) && (rv != MQP_ERR_TIMEOUT)) ||
               ((MQTT_CONNACK == mqp->msg_type) &&
                MQP_CONNACK_RC(mqp)))
                    do_net_close_rx(cl_ctx, rv);
    
            MUTEX_UNLOCK();
    
            return rv;
    }

    function: proc_ctx_data_recv in File: mqtt_client.c

    
    

    As you can see, there is MUTEX_LOCKIN();

    Then this function will call the following before returning:

    function: do_net_close_rx (Showing Part of it) in File: mqtt_client.c

    static void do_net_close_rx(struct client_ctx *cl_ctx, i32 cause)
    {
            struct mqtt_client_ctx_cbs *ctx_cbs = CTX_CBS_PTR(cl_ctx);
    
            DBG_INFO("C: RX closing Net %d [%d]\n\r", cl_ctx->net, cause);
    
            do_net_close(cl_ctx);
            if(ctx_cbs->disconn_cb)
                    ctx_cbs->disconn_cb(CLIENT(cl_ctx)->app, cause);
    
            if(A_GROUP_MEMBER(cl_ctx))
                    cl_ctx_remove(&used_ctxs, cl_ctx);
    
            return;
    }

    The last line is the one that will call the following (which we modified according to the SDK known issues)

    Function: process_disconn_cb in File: sl_mqtt_client.c

    static void process_disconn_cb(void *app, _i32 cause)
    {
            struct sl_client_ctx *client_ctx = (struct sl_client_ctx *)app;
    
            if(client_ctx->awaited_ack != 0) {
                    client_ctx->awaited_ack = MQTT_DISCONNECT;
                    ACK_RX_SIGNAL_POST(&client_ctx->ack_sync_obj);
            } else 
                client_ctx->app_cbs.sl_ExtLib_MqttDisconn(client_ctx->app_hndl);
                    
            
            return;
    }

    Now let go to the Application (mqtt_client in the examples folder for the SDK) not the Library, 

    so the routine will initiate the call back in the application, lets assume you are using the default example in the sdk, MQTT_client

    Function: static void sl_MqttDisconnect in main.c

    static void
    sl_MqttDisconnect(void *app_hndl)
    {
        connect_config *local_con_conf;
        osi_messages var = BROKER_DISCONNECTION;
        local_con_conf = app_hndl;
        sl_ExtLib_MqttClientUnsub(local_con_conf->clt_ctx, local_con_conf->topic,
                                  TOPIC_COUNT);
        UART_PRINT("disconnect from broker %s\r\n",
               (local_con_conf->broker_config).server_info.server_addr);
        local_con_conf->is_connected = false;
        sl_ExtLib_MqttClientCtxDelete(local_con_conf->clt_ctx);
    
        //
        // write message indicating publish message
        //
        osi_MsgQWrite(&g_PBQueue,&var,OSI_NO_WAIT);
    
    }

    As you can see in the code above, there is a call to: 

    sl_ExtLib_MqttClientCtxDelete

    which if you go back to MQTT_Library, you will see that it will call another function in MQTT_client Library:

    i32 mqtt_client_ctx_delete(void *ctx)
    {
            struct client_ctx  *cl_ctx = (struct client_ctx*) ctx;
            i32 rv = -1; /* Not sure about deletion as yet */
    
            MUTEX_LOCKIN();
            if((NULL == cl_ctx)          ||
               (-1   != cl_ctx->net)     ||
               (awaits_pkts(cl_ctx)))
                    goto mqtt_client_ctx_delete_exit1;
    
            rv = 0; /* OK to delete ctx */
            client_reset(CLIENT(cl_ctx));
            cl_ctx_freeup(cl_ctx);
    
     mqtt_client_ctx_delete_exit1:
            MUTEX_UNLOCK();
            return rv;
    }

    I know that was really not briefly ;P, but you can see this function is trying to do Mutex_locking while the lock has not yet been released

    Thats why the code gets stuck

    Maybe I'm wrong, because its weird that TI has not mention that we need to modify from the application side if we apply the fix from the SDK 1.1.0 knows issues

    but for me it worked when I changed in my application (or the default mqtt_clinet) application in the SDK the function 

    sl_MqttDisconnect

     

    by not doing anything related to the socket or the library, just publishing a message in the queue that a disconnection happened, and returning from the function.

    So the first lock will be released

    hope this help to understand

    Best

    Khalefa

  • Hi Khalefa ,

    Thank you for the brief explanation ;) , I now understand by what you mean about the locking. I was able to reconnect by using the following :

    <code>

    ////////////////////////////////connecting to MQTT ////////////////////////////////////////////////////
    for(;;)
    {
    if((local_con_conf[iCount].is_connected == false) )
    {
    if(sl_ExtLib_MqttClientConnect((void*)local_con_conf[iCount].clt_ctx,true,0) < 0)
    {
    UART_PRINT("\n\rBroker connect fail for conn no. %d \n\r",iCount+1);
    UART_PRINT("\n\riCount = %d\n\r",iCount);
    }
    else
    {
    UART_PRINT("\n\rSuccess: conn to Broker no. %d\n\r ", iCount+1);
    local_con_conf[iCount].is_connected = true;
    UART_PRINT("\n\riCount = %d\n\r",iCount);
    }
    }

    /////////////////////////////////////////Random Code begin/////////////////////////////////////////////////////////////


    /////////////////////////////////////////Random Code end/////////////////////////////////////////////////////////////

    /////////////////////disconnecting to MQTT ////////////////////////////////////////////////////////////////////////
    if(local_con_conf[iCount].is_connected == true)
    {
    sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
    local_con_conf[iCount].is_connected = false;
    }
    }
    </code>

    This loop works fine as long as the wifi network is on with internet connectivity , it connects and disconnects to the mqtt server seamlessly but once the internet goes down , all hell breaks loose.

    In the case where I switch off the internet , the connect to broker fails as expected but added to that I get the "MQP alloc failed - msg type 0x01" error and it fails to reconnect to mqtt server once I switch on the internet.
  • Hi Zyxmn Jes,

    I've reading and the issu of "MQP alloc failed - msg type 0x01" is a bug that is solved in the next wiki processors.wiki.ti.com/.../CC32xx_Summary_of_Known_Issues

    Iguess everytime it tries a connection the function reseved memory but doesn't free it after a fail, so after a lot of tries all the memory is occupied and prints the error.

    Regards, Juan.
  • Hi,

    I still cannot fix this issue.
    If the AP connection is lost, CC3200 can return back to connect the AP
    but it does not allow to re-init the MQTT again.
    I am using the following to delete MQTT
    sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
    sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
    sl_ExtLib_MqttClientExit();
    and init AP connection again.
    After CC3200 connect to AP again, I tried to use sl_ExtLib_MqttClientInit... (Like the example of MQTT)
    But CC3200 failed and dead.
    Is there any way to restart MQTT now?
    It is very stupid that I am using software reset if the connection is lost.
    It affects my main application if CC3200 is reset.

    Thank you.
  • Hi Bryan

    I solved that issue of the reconnection after and AP disconnection. I solved it as it follows:

    This is my function to connect to the broker:

    MQTT_States ConnectToBroker(connect_config *local_con_conf)
    {    
        int iConnBroker = 0;     
      
     /******************* connection to the broker ***************************/
        iNumBroker = sizeof(usr_connect_config)/sizeof(connect_config);
        if(iNumBroker > MAX_BROKER_CONN)
        {
            UART_PRINT("Num of brokers are more then max num of brokers\n\r");
            LOOP_FOREVER();
        }
    
        while(iCount < iNumBroker)
        {
            //create client context
            local_con_conf[iCount].clt_ctx =
            sl_ExtLib_MqttClientCtxCreate(&local_con_conf[iCount].broker_config,
                                          &local_con_conf[iCount].CallBAcks,
                                          &(local_con_conf[iCount]));
    
            //
            // Set Client ID
            //
            sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                SL_MQTT_PARAM_CLIENT_ID,
                                local_con_conf[iCount].client_id,
                                strlen((char*)(local_con_conf[iCount].client_id)));
    
            //
            // Set will Params
            //
            if(local_con_conf[iCount].will_params.will_topic != NULL)
            {
                sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                        SL_MQTT_PARAM_WILL_PARAM,
                                        &(local_con_conf[iCount].will_params),
                                        sizeof(SlMqttWill_t));
            }
    
            //
            // setting username and password
            //
            if(local_con_conf[iCount].usr_name != NULL)
            {
                sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                    SL_MQTT_PARAM_USER_NAME,
                                    local_con_conf[iCount].usr_name,
                                    strlen((char*)local_con_conf[iCount].usr_name));
    
                if(local_con_conf[iCount].usr_pwd != NULL)
                {
                    sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                    SL_MQTT_PARAM_PASS_WORD,
                                    local_con_conf[iCount].usr_pwd,
                                    strlen((char*)local_con_conf[iCount].usr_pwd));
                }
            }
    
            //
            // connectin to the broker
            //
            if((sl_ExtLib_MqttClientConnect((void*)local_con_conf[iCount].clt_ctx,
                                local_con_conf[iCount].is_clean,
                                local_con_conf[iCount].keep_alive_time) & 0xFF) != 0)
            {
                UART_PRINT("\n\rBroker connect fail for conn no. %d \n\r",iCount+1);
                
                //delete the context for this connection
                sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
                
                iConnBroker--;
                
                break;
            }
            else
            {
                UART_PRINT("\n\rSuccess: conn to Broker no. %d\n\r ", iCount+1);
                local_con_conf[iCount].is_connected = true;
                iConnBroker++;
            }
    
            //
            // Subscribe to topics
            //
            if(sl_ExtLib_MqttClientSub((void*)local_con_conf[iCount].clt_ctx,
                                       local_con_conf[iCount].topic,
                                       local_con_conf[iCount].qos, TOPIC_COUNT) < 0)
            {
                UART_PRINT("\n\r Subscription Error for conn no. %d\n\r", iCount+1);
                UART_PRINT("Disconnecting from the broker\r\n");
                sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
                local_con_conf[iCount].is_connected = false;
                
                //delete the context for this connection
                sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
                iConnBroker--;
                break;
            }
            else
            {
                int iSub;
                UART_PRINT("Client subscribed on following topics:\n\r");
                for(iSub = 0; iSub < local_con_conf[iCount].num_topics; iSub++)
                {
                    UART_PRINT("%s\n\r", local_con_conf[iCount].topic[iSub]);
                }
            }
            iCount++;
        }
    
        if(iConnBroker < 1)
        {
            //
            // no succesful connection to broker
            //
            sl_ExtLib_MqttClientExit();
            UART_PRINT("\n\r Broker Disconnected \n\r");
            
            StateMessage = MQTT_DISCONNECTED;    
            osi_MsgQWrite(&MQTTState,&StateMessage,OSI_NO_WAIT);
            
            iCount = 0; 
            
            return MQTT_DISCONNECTED;
        } 
        else
        {
        
        StateMessage = MQTT_CONNECTED;    
        osi_MsgQWrite(&MQTTState,&StateMessage,OSI_NO_WAIT);    
        
        iCount = 0; 
        
        return MQTT_CONNECTED;
        }       
    }

    As you see is exactly the same from the example of the SDK, excepts for the call to sl_ExtLib_MqttClientInit(); I call this function just once (before enter the main) and never call to sl_ExtLib_MqttClientExit();

    Just in case before I call the function to connect to the broker I use the next function:

    MQTT_States CleanBeforeConnect(connect_config *local_con_conf)
    { 
     
     local_con_conf->is_connected = false;
     sl_ExtLib_MqttClientCtxDelete(local_con_conf->clt_ctx);           
         
     return MQTT_DISCONNECTED;
    }

    Also I have a flag to check the connection to the AP, I set it in the Handler where it gives the message that the Ip has been acquired (the function is one of the simplelink asynchronous handlers SimpleLinkNetAppEventHandler();) and clean it in the hanlder where it gives the message of the WLAN disconnection (in the hanlder SimpleLinkWlanEventHandler).

    So I constantly check that flag and if I see it clean I try to reconnect to the broker. But at the same time I don't call the connect function until the WLAN flag is set.

    I don't know if I make it clear but any doubt you can ask.

    Regards, Juan.

  • juanquique_22 said:

    Hi Bryan

    I solved that issue of the reconnection after and AP disconnection. I solved it as it follows:

    This is my function to connect to the broker:

    MQTT_States ConnectToBroker(connect_config *local_con_conf)
    {    
        int iConnBroker = 0;     
      
     /******************* connection to the broker ***************************/
        iNumBroker = sizeof(usr_connect_config)/sizeof(connect_config);
        if(iNumBroker > MAX_BROKER_CONN)
        {
            UART_PRINT("Num of brokers are more then max num of brokers\n\r");
            LOOP_FOREVER();
        }
    
        while(iCount < iNumBroker)
        {
            //create client context
            local_con_conf[iCount].clt_ctx =
            sl_ExtLib_MqttClientCtxCreate(&local_con_conf[iCount].broker_config,
                                          &local_con_conf[iCount].CallBAcks,
                                          &(local_con_conf[iCount]));
    
            //
            // Set Client ID
            //
            sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                SL_MQTT_PARAM_CLIENT_ID,
                                local_con_conf[iCount].client_id,
                                strlen((char*)(local_con_conf[iCount].client_id)));
    
            //
            // Set will Params
            //
            if(local_con_conf[iCount].will_params.will_topic != NULL)
            {
                sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                        SL_MQTT_PARAM_WILL_PARAM,
                                        &(local_con_conf[iCount].will_params),
                                        sizeof(SlMqttWill_t));
            }
    
            //
            // setting username and password
            //
            if(local_con_conf[iCount].usr_name != NULL)
            {
                sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                    SL_MQTT_PARAM_USER_NAME,
                                    local_con_conf[iCount].usr_name,
                                    strlen((char*)local_con_conf[iCount].usr_name));
    
                if(local_con_conf[iCount].usr_pwd != NULL)
                {
                    sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx,
                                    SL_MQTT_PARAM_PASS_WORD,
                                    local_con_conf[iCount].usr_pwd,
                                    strlen((char*)local_con_conf[iCount].usr_pwd));
                }
            }
    
            //
            // connectin to the broker
            //
            if((sl_ExtLib_MqttClientConnect((void*)local_con_conf[iCount].clt_ctx,
                                local_con_conf[iCount].is_clean,
                                local_con_conf[iCount].keep_alive_time) & 0xFF) != 0)
            {
                UART_PRINT("\n\rBroker connect fail for conn no. %d \n\r",iCount+1);
                
                //delete the context for this connection
                sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
                
                iConnBroker--;
                
                break;
            }
            else
            {
                UART_PRINT("\n\rSuccess: conn to Broker no. %d\n\r ", iCount+1);
                local_con_conf[iCount].is_connected = true;
                iConnBroker++;
            }
    
            //
            // Subscribe to topics
            //
            if(sl_ExtLib_MqttClientSub((void*)local_con_conf[iCount].clt_ctx,
                                       local_con_conf[iCount].topic,
                                       local_con_conf[iCount].qos, TOPIC_COUNT) < 0)
            {
                UART_PRINT("\n\r Subscription Error for conn no. %d\n\r", iCount+1);
                UART_PRINT("Disconnecting from the broker\r\n");
                sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx);
                local_con_conf[iCount].is_connected = false;
                
                //delete the context for this connection
                sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx);
                iConnBroker--;
                break;
            }
            else
            {
                int iSub;
                UART_PRINT("Client subscribed on following topics:\n\r");
                for(iSub = 0; iSub < local_con_conf[iCount].num_topics; iSub++)
                {
                    UART_PRINT("%s\n\r", local_con_conf[iCount].topic[iSub]);
                }
            }
            iCount++;
        }
    
        if(iConnBroker < 1)
        {
            //
            // no succesful connection to broker
            //
            sl_ExtLib_MqttClientExit();
            UART_PRINT("\n\r Broker Disconnected \n\r");
            
            StateMessage = MQTT_DISCONNECTED;    
            osi_MsgQWrite(&MQTTState,&StateMessage,OSI_NO_WAIT);
            
            iCount = 0; 
            
            return MQTT_DISCONNECTED;
        } 
        else
        {
        
        StateMessage = MQTT_CONNECTED;    
        osi_MsgQWrite(&MQTTState,&StateMessage,OSI_NO_WAIT);    
        
        iCount = 0; 
        
        return MQTT_CONNECTED;
        }       
    }

    As you see is exactly the same from the example of the SDK, excepts for the call to sl_ExtLib_MqttClientInit(); I call this function just once (before enter the main) and never call to sl_ExtLib_MqttClientExit();

    Just in case before I call the function to connect to the broker I use the next function:

    MQTT_States CleanBeforeConnect(connect_config *local_con_conf)
    { 
     
     local_con_conf->is_connected = false;
     sl_ExtLib_MqttClientCtxDelete(local_con_conf->clt_ctx);           
         
     return MQTT_DISCONNECTED;
    }

    Also I have a flag to check the connection to the AP, I set it in the Handler where it gives the message that the Ip has been acquired (the function is one of the simplelink asynchronous handlers SimpleLinkNetAppEventHandler();) and clean it in the hanlder where it gives the message of the WLAN disconnection (in the hanlder SimpleLinkWlanEventHandler).

    So I constantly check that flag and if I see it clean I try to reconnect to the broker. But at the same time I don't call the connect function until the WLAN flag is set.

    I don't know if I make it clear but any doubt you can ask.

    Regards, Juan.

    Hi Juan,

    Thank you very much. 

    It solves my problem.

    Best Regards.

    Bryan

  • Hi Juan,

    I found that CC3200 can reconnect to router and start the MQTT function.
    But it now stuck on "C: FH-B1 0x10 to net 16, Sent (48 Bytes) [@ 540]"
    And it go into dead loop again.
    Did you come across this situation?

    Thank you.
    Bryan
  • Hi Juan,

    I tried to turn CC3200 to auto connect.
    And the problem is gone.
    Thank you very much.
    I now need not stupidly restart CC3200.
    Thank you.

    Best Regards,
    Bryan
  • Hi Bryan,

    I forget to mention that I'm using the autoconnect function, sorry. But I glad to hear that you solve your problem.
    Don't worry, I'm new with the CC3200 too and I'm tring to use it in the most efficient way too.

    Regards, Juan