9 Replies Latest reply on Oct 13, 2016 8:42 PM by xavier@candyhouse

    MQTT deinit

    mkochhal

      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 );

       

      }

        • 2. Re: MQTT deinit
          xavier@candyhouse

          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......

          • 3. Re: MQTT deinit
            rcnmartell

            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 )

            • 4. Re: MQTT deinit
              mifo

              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.

              • 5. Re: MQTT deinit
                vikr

                rcnmartell xavier@candyhouse mkochhal

                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 ?

                3 of 3 people found this helpful
                • 6. Re: MQTT deinit
                  rcnmartell

                  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

                  • 7. Re: MQTT deinit
                    rcnmartell

                    vikr

                     

                    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

                    • 8. Re: MQTT deinit
                      rcnmartell

                      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

                      1 of 1 people found this helpful
                      • 9. Re: MQTT deinit
                        xavier@candyhouse

                        Hi vikr

                         

                        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?