All Products
Search
Document Center

Communication through MQTT Topics

Last Updated: Dec 28, 2021

Devices can communicate with Alibaba Cloud IoT platform through MQTT topics, this document describe how to connect to IoT platform, how to subscribe topics and publish messages to topics.

Configure MQTT site

When connecting a device to Alibaba Cloud IoT, you can specify the server site for the device. You can configure the site as follows:

In iotx-sdk-c/include/iot_export.h, the enumeration type iotx_cloud_region_types_t defines the currently available MQTT sites:

/* region type */
typedef enum IOTX_CLOUD_REGION_TYPES {
/* Shanghai */
IOTX_CLOUD_REGION_SHANGHAI,
/* Singapore */
IOTX_CLOUD_REGION_SINGAPORE,
/* Japan */
IOTX_CLOUD_REGION_JAPAN,
/* America(sillicon valley) */
IOTX_CLOUD_REGION_USA_WEST,
/* Germany */
IOTX_CLOUD_REGION_GERMANY,
/* Custom setting */
IOTX_CLOUD_REGION_CUSTOM,
/* Maximum number of domain */
IOTX_CLOUD_DOMAIN_MAX
} iotx_cloud_region_types_t;
  • First use the IOTX_IOCTL_SET_REGION option of IOT_Ioctl in combination with the above-mentioned enumeration value to set the connection site.

  • Then use IOT_MQTT_Construct or IOT_Linkkit_Connect to establish a connection between the device and Alibaba Cloud.

For example:

/* Choose Login Server */
int domain_type = IOTX_CLOUD_REGION_SHANGHAI;
IOT_Ioctl(IOTX_IOCTL_SET_REGION, (void *)&domain_type);

The SDK also supports manual configuration of the domain name of a site. For regional sites undefined in the iotx_cloud_region_types_t enumeration type, use the Other option for IOT_Ioctl to set the site.

  • Use the IOTX_IOCTL_SET_MQTT_DOMAIN option for IOT_Ioctl to manually configure the domain name of the MQTT server.

  • Use the IOTX_IOCTL_SET_HTTP_DOMAIN option for IOT_Ioctl to manually configure the domain name of the HTTP server.

For example, set the connection site to US (Virginia) by using the following method:

#define USA_EAST_DOMAIN_MQTT     "iot-as-mqtt.us-east-1.aliyuncs.com"
#define USA_EAST_DOMAIN_HTTP     "iot-auth.us-east-1.aliyuncs.com"
IOT_Ioctl(IOTX_IOCTL_SET_MQTT_DOMAIN, (void *)USA_EAST_DOMAIN_MQTT);
IOT_Ioctl(IOTX_IOCTL_SET_HTTP_DOMAIN, (void *)USA_EAST_DOMAIN_HTTP);

If the device trituple requested on the Alibaba Cloud IoT Platform console does not match the domain name used for the connection, an authentication error occurs when connecting the device to the site (error code -35).

For example: The device trituple applied for at the China (Shanghai) site on the Alibaba Cloud IoT Console is supposed to be connected to the China (Shanghai) site in the Alibaba Cloud IoT.

AOS1.3.2 Connections to Overseas Sites

The AliOS Things IoT operating system (AOS) is also integrated with the Linkkit SDK. However, different AOS versions have different configurations for connections to overseas sites. For AOS1.3.2, the connection to the Singapore site is configured differently, because the Singapore site automatically assigns the nearest acceleration point to the device.

You only need to modify the example/linkkitapp/linkkitapp.mk file, and set the default configuration:

GLOBAL_DEFINES += MQTT_DIRECT ALIOT_DEBUG IOTX_DEBUG USE_LPTHREAD HAL_ASYNC_API COAP_USE_PLATFORM_LOG

to:

GLOBAL_DEFINES += SUPPORT_SINGAPORE_DOMAIN ALIOT_DEBUG IOTX_DEBUG USE_LPTHREAD HAL_ASYNC_API COAP_USE_PLATFORM_LOG

Then recompile the firmware for programming.

Example program explanation

We describe each step of these APIs to implement an MQTT connection to the cloud by referencing the examples/mqtt/mqtt-example.c example program.

  1. In the initialization stage, if you need to use an overseas site or the dynamic registration function, first use the IOT_Ioctl() API to complete the configuration.

    /* Choose logon server */
        int domain_type = IOTX_CLOUD_DOMAIN_SH;
        IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);
        /* Choose logon method */
        int dynamic_register = 0;
        IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);
  2. Import the device trituple and initialize the connection information while preparing to establish the MQTT session.

    iotx_conn_info_pt pconn_info;
        HAL_GetProductKey(__product_key);
        HAL_GetDeviceName(__device_name);
        HAL_GetDeviceSecret(__device_secret);
        /* Device AUTH */
        if (0 != IOT_SetupConnInfo(__product_key, __device_name, __device_secret, (void **)&pconn_info)) {
            EXAMPLE_TRACE("AUTH request failed!") ;
            rc = -1;
            goto do_exit;
        }
  3. Configure MQTT parameters, establish an MQTT connection session, and establish a connection with the cloud server.

    void *pclient;
        iotx_mqtt_param_t mqtt_params;
        /* Initialize MQTT parameter */
        memset(&mqtt_params, 0x0, sizeof(mqtt_params));
        mqtt_params.port = pconn_info->port;
        mqtt_params.host = pconn_info->host_name;
        mqtt_params.client_id = pconn_info->client_id;
        mqtt_params.username = pconn_info->username;
        mqtt_params.password = pconn_info->password;
        mqtt_params.pub_key = pconn_info->pub_key;
        mqtt_params.request_timeout_ms = 2000;
        mqtt_params.clean_session = 0;
        mqtt_params.keepalive_interval_ms = 60000;
        mqtt_params.read_buf_size = MQTT_MSGLEN;
        mqtt_params.write_buf_size = MQTT_MSGLEN;
        mqtt_params.handle_event.h_fp = event_handle;
        mqtt_params.handle_event.pcontext = NULL;
        /* Construct an MQTT client with specify parameter */
        pclient = IOT_MQTT_Construct(&mqtt_params);
        if (NULL == pclient) {
            EXAMPLE_TRACE("MQTT construct failed");
            rc = -1;
            goto do_exit;
        }
  4. After successfully establishing the MQTT session, you can publish the custom topic data according to the business requirements. You need to customize this topic and grant it the publish permission at https://iot.console.aliyun.com in advance.

    #define TOPIC_DATA              "/"PRODUCT_KEY"/"DEVICE_NAME"/data"
        iotx_mqtt_topic_info_t topic_msg;
        /* Initialize topic information */
        memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
        strcpy(msg_pub, "update: hello! start!") ;
        topic_msg.qos = IOTX_MQTT_QOS1;
        topic_msg.retain = 0;
        topic_msg.dup = 0;
        topic_msg.payload = (void *)msg_pub;
        topic_msg.payload_len = strlen(msg_pub);
        /* Publish the specified topic */
        rc = IOT_MQTT_Publish(pclient, TOPIC_UPDATE, &topic_msg);
        if (rc < 0) {
            IOT_MQTT_Destroy(&pclient);
            EXAMPLE_TRACE("error occur when publish");
            rc = -1;
            goto do_exit;
        }
  5. Likewise, you can subscribe to or unsubscribe from the custom topic according to the business requirements. You need to customize this topic and grant it the subscribe permission at https://iot.console.aliyun.com in advance.

    /* Subscribe to the specified topic, and register the corresponding callback function to process messages published on the cloud */
        rc = IOT_MQTT_Subscribe(pclient, TOPIC_DATA, IOTX_MQTT_QOS1, _demo_message_arrive, NULL);
        if (rc < 0) {
            IOT_MQTT_Destroy(&pclient);
            EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc);
            rc = -1;
            goto do_exit;
        }
        /* Unsubscribe from the specified topic */
        IOT_MQTT_Unsubscribe(pclient, TOPIC_DATA);
  6. Each upstream operation (including publish, subscribe, and unsubscribe) is followed by a IOT_MQTT_Yield() function. This function is mainly used to collect and parse server downstream packets. In addition, it maintains the heartbeat. This function needs to be included in the while() loop.

    /* Handle the MQTT packet received from the TCP or SSL connection */
        IOT_MQTT_Yield(pclient, 200);
  7. The end user can terminate the session using IOT_MQTT_Destroy(), to disconnect the device and the server.

    IOT_MQTT_Destroy(&pclient);

MQTT function APIs

Function Name

Description

IOT_SetupConnInfo

Creates the username and password used for the MQTT connection based on the DeviceName, DeviceSecret, and ProductKey. Call this function before you establish MQTT connections.

IOT_MQTT_CheckStateNormal

Checks whether the persistent connection is normal. Call this function after an MQTT connection has been established.

IOT_MQTT_Construct

MQTT constructor. The input parameter is a iotx_mqtt_param_t struct type, and the output is an MQTT session handle.

IOT_MQTT_Destroy

MQTT destructor. The input parameter is an MQTT session handle returned by IOT_MQTT_Construct().

IOT_MQTT_Publish

Organizes a complete MQTT Publish packet in the MQTT session phase and sends it to the server.

IOT_MQTT_Publish_Simple

Organizes a complete MQTT Publish packet in the MQTT session phase and sends it to the server. The parameter does not contain complex data types such as structures.

IOT_MQTT_Subscribe

Organizes a complete MQTT Subscribe packet in the MQTT session phase and sends a subscription request to the server.

IOT_MQTT_Subscribe_Sync

Organizes a complete MQTT Subscribe packet in the MQTT session phase, sends a subscription request to the server, and waits for the reply.

IOT_MQTT_Unsubscribe

Organizes a complete MQTT UnSubscribe packet in the MQTT session phase and sends an unsubscribe request to the server.

IOT_MQTT_Yield

The MQTT session phase. The main cyclic function that includes the keep-alive timer and receives packets from the server.

HAL interface that needs to be implemented

The following functions are optional. If you want the SDK to provide the MQTT channel function, you need user connection.

Function Name

Description

HAL_SSL_Destroy

Destroys a TLS connection. Required for MQTT and HTTPS.

HAL_SSL_Establish

Establishes a TLS connection. Required for MQTT and HTTPS.

HAL_SSL_Read

Reads data from a TLS connection. Required for MQTT and HTTPS.

HAL_SSL_Write

Writes data to a TLS connection. Required for MQTT and HTTPS.

HAL_TCP_Destroy

Destroys a TLS connection. Required for MQTT and HTTPS.

HAL_TCP_Establish

Establishes a TCP connection, and performs domain name resolution and TCP connection establishment.

HAL_TCP_Read

Reads data streams from a TCP connection and returns the number of bytes that are read during the specified time.

HAL_TCP_Write

Sends data streams to a TCP connection and returns the number of bytes that are sent during the specified time.

HAL_Random

Takes an unsigned number as the input and returns a random unsigned number from zero to the specified unsigned number as the output.

HAL_Srandom

Sets the seed of the random number generator algorithm used by HAL_Random. For more information, see srand.

Result