5.5.1 Execution

This example uses Paho MQTT library for the MQTT protocol implementation.

main.c - Initialize the board, connect to an MQTT broker and chat with other devices.

  1. Code summary:
    • Configure the network parameters and the MQTT broker in main.h.
      /* Chat MQTT topic. This is only demo User can create their own topic*/
      #define MAIN_CHAT_TOPIC "atmel/sample/chat_demo/"
      /** A MQTT broker server which was connected.
       * test.mosquitto.org is public MQTT broker.*/
      static const char main_mqtt_broker[] = "test.mosquitto.org";
      
      /** Wi-Fi Settings */
      #define MAIN_WLAN_SSID        "DEMO_AP" /* < Destination SSID */
      #define MAIN_WLAN_AUTH        M2M_WIFI_SEC_WPA_PSK /* < Security manner */
      #define MAIN_WLAN_PSK         "12345678" /* < Password for Destination SSID */
    • Configure the MQTT module. When calling the configure_mqtt() function, several parameters like read/write buffers and buffer size are configured along with the callback function.
      /* Initialize the MQTT service. */
      configure_mqtt();
      static void configure_mqtt(void)
      {
          ...
          mqtt_get_config_defaults(&mqtt_conf);
          /* To use the MQTT service, it is necessary to always set the buffer and the timer. */
             mqtt_conf.read_buffer = mqtt_read_buffer;
      	mqtt_conf.read_buffer_size = MAIN_MQTT_BUFFER_SIZE;
      	mqtt_conf.send_buffer = mqtt_send_buffer;
      	mqtt_conf.send_buffer_size = MAIN_MQTT_BUFFER_SIZE;
      
          result = mqtt_init(&mqtt_inst, &mqtt_conf);
          result = mqtt_register_callback(&mqtt_inst, mqtt_callback);
    • The Paho MQTT platform implementation uses SysTick for timing. Therefore, systick must be configured before using any part of the library.
      if (SysTick_Config(system_cpu_clock_get_hz() / 1000)) 
      	{
      		puts("ERR>> Systick configuration error\r\n");
      		while (1);
      	}
    • Setup the username first and then the topic value will be set with MAIN_CHAT_TOPIC and username.
      	/* Setup username first */
      	printf("Enter the username (Max %d characters)\r\n", MAIN_CHAT_USER_NAME_SIZE);
      	scanf("%64s", mqtt_user);
      	printf("User : %s\r\n", mqtt_user);
      	sprintf(topic, "%s%s", MAIN_CHAT_TOPIC, mqtt_user);
    • Initialize the socket module and register the socket callback function.
      
      socketInit();
      registerSocketCallback(socket_cb, NULL);
    • Connect to the AP.
      /* Connect to router. */
      m2m_wifi_connect((char *)MAIN_WLAN_SSID, sizeof(MAIN_WLAN_SSID),
              MAIN_WLAN_AUTH, (char *)MAIN_WLAN_PSK, M2M_WIFI_CH_ALL);
    • After the device is connected to the AP, call the mqtt_connect() function to connect the socket.
      static void wifi_callback(uint8 msg_type, void *msg_data)
      {
          ...
          case M2M_WIFI_REQ_DHCP_CONF:
          ...
          /* Try to connect to MQTT broker when Wi-Fi was connected. */
          mqtt_connect(&mqtt_inst, main_mqtt_broker);
      }
    • The MQTT callback will receive the MQTT_CALLBACK_SOCK_CONNECTED message and then start sending a CONNECT message to the MQTT broker.
      static void mqtt_callback(struct mqtt_module *module_inst, int type, union mqtt_data *data)
      {
          ...
          case MQTT_CALLBACK_SOCK_CONNECTED:
          {
      	mqtt_connect_broker(module_inst, 1, NULL, NULL, mqtt_user, NULL, NULL, 0, 0, 0);
    • The MQTT callback will receive the MQTT_CALLBACK_CONNECTED message and then register a subscription for a specific topic. Each subscription has a separate callback function which is registered along with the subscribe call.
      static void mqtt_callback(struct mqtt_module *module_inst, int type, union mqtt_data *data)
      {
          ...
          case MQTT_CALLBACK_CONNECTED:
          {	
              mqtt_subscribe(module_inst, MAIN_CHAT_TOPIC "#", 0, SubscribeHandler)
    • If another device sends a message with this topic, then the corresponding subscribe callback is called.
      void SubscribeHandler(MessageData *msgData)
      {
      ...
      }
    • If the user inputs a string via a terminal, the MQTT will publish the following message:
      static void check_usart_buffer(char *topic)
      {
          if (uart_buffer_written >= MAIN_CHAT_BUFFER_SIZE) {
              mqtt_publish(&mqtt_inst, topic, uart_buffer,
              MAIN_CHAT_BUFFER_SIZE, 0, 0);
              uart_buffer_written = 0;
          }
    • To poll for a message in any of the subscribed topic, mqtt_yield must be called. This function must be called frequently.
      while (1) {
      		/* Handle pending events from network controller. */
      		m2m_wifi_handle_events(NULL);
      		...
      		if(mqtt_inst.isConnected)
      			mqtt_yield(&mqtt_inst, 0);
      	}
  2. Build the program and download it into the board.
  3. Start the application.
  4. On the terminal window, enter the username through the terminal window.
  5. After the initialization completes, you can chat.
    Note:
    • Initialization may take up to a few minutes depending on the network environment.
    • The application must be programmed and running. The following information will be displayed on the terminal window.
Note: The maximum message length should be shorter than 128 bytes. If the server connection is unstable, this example may not operate normally.