MQTT deinit

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi.

I am having problems reconnecting upon an disconnect.

I am using WICED_SDK_3.5.1 and using secure MQTT (i.e. over TLS).

static wiced_result_t mqtt_connection_event_cb( wiced_mqtt_object_t mqtt_object, wiced_mqtt_event_info_t *event )

{

    switch ( event->type )

    {

       :

        case WICED_MQTT_EVENT_TYPE_DISCONNECTED:

        {

            if(reconnecting != WICED_TRUE) {

                printf("Uh-Oh, I got disconnected in %s...\n", __FUNCTION__);

                expected_event = event->type;

                wiced_rtos_set_semaphore( &msg_semaphore );

                reconnecting = WICED_TRUE;

                iot_mqtt_connect();

            }

        }

        break;

    :

    :

}

static void iot_aws_mqtt_reconnect()

{

    mqtt_conn_close( mqtt_object );

    mqtt_app_unsubscribe( mqtt_object, DELTA_TOPIC );

    wiced_rtos_deinit_semaphore( &msg_semaphore );

    WPRINT_APP_INFO(("[MQTT] Deinit connection in %s...\n", __FUNCTION__));

    wiced_mqtt_deinit( mqtt_object );

    wiced_rtos_deinit_semaphore( &wake_semaphore );

    free( mqtt_object );

    mqtt_object = NULL;

    iot_mqtt_connect();

}

void iot_mqtt_connect( void )

{

    wiced_result_t        ret = WICED_SUCCESS;

    uint32_t              size_out = 0;

    int                   connection_retries = 0;

    int                   retries = 0;

    int                   count = 0;

    char*                 msg = SHADOW_PUBLISH_INVERTER_OFF;

    /* Get AWS root certificate, client certificate and private key respectively */

    ret = resource_get_readonly_buffer( &resources_apps_DIR_secure_mqtt_DIR_TestSolPadThing_DIR_rootCA_pem, 0, MQTT_MAX_RESOURCE_SIZE, &size_out, (const void **) &security.ca_cert );

    ret = resource_get_readonly_buffer( &resources_apps_DIR_secure_mqtt_DIR_TestSolPadThing_DIR_cert_pem, 0, MQTT_MAX_RESOURCE_SIZE, &size_out, (const void **) &security.cert );

    if(size_out < 64)

    {

        WPRINT_APP_INFO( ( "\nNot a valid Certificate! Please replace the dummy certificate file 'resources/app/aws_iot/client.cer' with the one got from AWS\n\n" ) );

        return;

    }

    ret = resource_get_readonly_buffer( &resources_apps_DIR_secure_mqtt_DIR_TestSolPadThing_DIR_privKey_pem, 0, MQTT_MAX_RESOURCE_SIZE, &size_out, (const void **) &security.key );

    if(size_out < 64)

    {

        WPRINT_APP_INFO( ( "\nNot a valid Private Key! Please replace the dummy private key file 'resources/app/aws_iot/privkey.cer' with the one got from AWS\n\n" ) );

        return;

    }

    /* Disable roaming to other access points */

    wiced_wifi_set_roam_trigger( -99 ); /* -99dBm ie. extremely low signal level */

    /* Bring up the network interface */

    ret = wiced_network_up( WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL );

    if ( ret != WICED_SUCCESS )

    {

        WPRINT_APP_INFO( ( "\nNot able to join the requested AP in %s...\n", __FUNCTION__));

       return;

    }

    /* json register parser */

    wiced_JSON_parser_register_callback(parse_json_control_message);

    /* Allocate memory for MQTT object*/

    mqtt_object = (wiced_mqtt_object_t) malloc( WICED_MQTT_OBJECT_MEMORY_SIZE_REQUIREMENT );

    if ( mqtt_object == NULL )

    {

        WPRINT_APP_ERROR(("Dont have memory to allocate for mqtt objectin %s...\n", __FUNCTION__));

       return;

    }

    WPRINT_APP_INFO( ( "Resolving IP address of MQTT broker in %s...\n", __FUNCTION__));

    ret = resolve_dns_to_ip(MQTT_BROKER_ADDRESS, &broker_address);

    if ( ret == WICED_ERROR || broker_address.ip.v4 == 0 )

    {

        WPRINT_APP_INFO(("Error in resolving DNS in %s...\n", __FUNCTION__));

       return;

    }

    wiced_rtos_init_semaphore( &wake_semaphore );

    wiced_mqtt_init( mqtt_object );

    wiced_rtos_init_semaphore( &msg_semaphore );

    do

    {

        WPRINT_APP_INFO(("[MQTT] Opening connection in %s...\n", __FUNCTION__));

        do

        {

            ret = mqtt_conn_open( mqtt_object, &broker_address, WICED_STA_INTERFACE, mqtt_connection_event_cb, &security );

            connection_retries++ ;

        } while ( ( ret != WICED_SUCCESS ) && ( connection_retries < WICED_MQTT_CONNECTION_NUMBER_OF_RETRIES ) );

        if ( ret != WICED_SUCCESS )

        {

            WPRINT_APP_INFO(("Failed in %s...\n", __FUNCTION__));

            reconnecting = WICED_TRUE;

            return;

        }

        WPRINT_APP_INFO(("Success in %s...\n", __FUNCTION__));

       

        reconnecting = WICED_FALSE;

        WPRINT_APP_INFO(("[MQTT] Subscribing in %s...\n", __FUNCTION__));

        do

        {

           ret = mqtt_app_subscribe( mqtt_object,  DELTA_TOPIC, WICED_MQTT_QOS_DELIVER_AT_MOST_ONCE );

           retries++ ;

        } while ( ( ret != WICED_SUCCESS ) && ( retries < MQTT_SUBSCRIBE_RETRY_COUNT ) );

        if ( ret != WICED_SUCCESS )

        {

           failed_subscribe = WICED_TRUE;

           return;

        }

        /* configure push button to publish a message */

        wiced_gpio_input_irq_enable( WICED_BUTTON1, IRQ_TRIGGER_RISING_EDGE, publish_callback, NULL );

        while ( reconnecting != WICED_TRUE )

        {

            wiced_rtos_get_semaphore( &wake_semaphore, WICED_NEVER_TIMEOUT );

            if ( pub_in_progress == 1 )

            {

                WPRINT_APP_INFO(("[MQTT] Publishing in %s...\n", __FUNCTION__));

                if ( count % 2 )

                {

                    msg = SHADOW_PUBLISH_INVERTER_ON;

                }

                else

                {

                    msg = SHADOW_PUBLISH_INVERTER_OFF;

                }

                do

                {

                    ret = mqtt_app_publish( mqtt_object, WICED_MQTT_QOS_DELIVER_AT_LEAST_ONCE, (uint8_t*) STATE_TOPIC, (uint8_t*) msg, strlen( msg ) );

                    retries++ ;

                } while ( ( ret != WICED_SUCCESS ) && ( retries < MQTT_PUBLISH_RETRY_COUNT ) );

                if ( ret != WICED_SUCCESS )

                {

                    WPRINT_APP_INFO((" Failed in %s...\n", __FUNCTION__));

                    failed_publish = WICED_TRUE;

                    return;

                }

                else

                {

                    WPRINT_APP_INFO((" Success in %s...\n", __FUNCTION__));

                }

                pub_in_progress = 0;

                count++ ;

            }

            wiced_rtos_delay_milliseconds( 100 );

        }

        wiced_rtos_delay_milliseconds( MQTT_DELAY_IN_MILLISECONDS * 2 );

    } while ( reconnecting != WICED_TRUE );

}

0 Likes
1 Solution

rcnmartellxavier@candyhousemkochhal

I just tried this

aws_mqtt_app_subscribe( app_info.mqtt_object, app_info.shadow_delta_topic , WICED_MQTT_QOS_DELIVER_AT_MOST_ONCE );

Change the subscribe QoS to 0 .

It works fine.

Also make sure to clean to and then download.

Let me know if this resolves ?

View solution in original post

9 Replies
Anonymous
Not applicable
0 Likes

Let me briefly describe my ideas on SDK 3.5.2, maybe some of them may help.

(I'm not very confident for my workaround, don't doubt if anything here is against your understanding. And please kindly share with me. Thank you.)

1. Heartbeat usually won't be stopped when WIFI is down, so modify stock MQTT library for this.

2. MQTT_DISCONNECTED_EVENT comes from two sources:

   a. heartbeat (runs in network_worker_thread w/ priority = 3)

   b. popped from queue in MQTT main thread (thread priority = 5, I guess it's network-related thread put this event into queue)

3. Stock MQTT lib sets a semaphore at the end of "mqtt_manager()", but I can't find anyone getting it.

4. for MQTT_EVENT_CONNECTION_CLOSE event, the above semaphore is call at the same place after deinit...... weird.

In my opinion stock MQTT lib doesn't look like as high-quality as other part in WICED SDK.

I'll be very appreciated if anyone can share information / experience on the forum......

Anonymous
Not applicable

did you resolve this. I am having an issue with the application stopping when it recieves just one published message from the Shadow AWS topic. After some debugging, after recieving the publish message, it gets a disconnect message and just stopping working ( no IRQs working, no MQTT messages )

0 Likes

The level 2 applications team is looking into this and we should be able to provide an update soon.

Thanks in advance for your patience.

0 Likes

rcnmartellxavier@candyhousemkochhal

I just tried this

aws_mqtt_app_subscribe( app_info.mqtt_object, app_info.shadow_delta_topic , WICED_MQTT_QOS_DELIVER_AT_MOST_ONCE );

Change the subscribe QoS to 0 .

It works fine.

Also make sure to clean to and then download.

Let me know if this resolves ?

Anonymous
Not applicable

Will try today. Thanks. And will let you know. I tried the other code but need Shadow functions. Was trying to hook the two up

Rob

0 Likes
Anonymous
Not applicable

vik86

Another note.

As I was de bugging deeper yesterday  , I found that the 4343w firmware system was generating a Mqtt disconnect after  losing connection - so it thought ( even tho I have no connection issues )

It was like the system was just terminating the connection after a receipt of published ( or AWS IOT system was closing it )

Rob

0 Likes
Anonymous
Not applicable

Wow.. after weeks of debugging... Works like a charm..

Setting QoS to the other value

aws_mqtt_app_subscribe( app_info.mqtt_object, app_info.shadow_delta_topic , WICED_MQTT_QOS_DELIVER_AT_MOST_ONCE

thank you so much

Hi vik86

There are some WICED users who work with other MQTT brokers and really need MQTT exactly once delivery.

(According to Protocols - AWS IoT​, they don't support pos=2. We use mosquito)

What can we do?

0 Likes