This topic describes how to call the API operations of Link SDK for C to send Message Queuing Telemetry Transport (MQTT) requests to IoT Platform, dynamically register a device, and obtain the verification information that is required to activate the device. In this example, a sample code file named ./demos/dynregmq_basic_demo.c
is used.
Background information
When you customize an SDK, set Device authentication scheme to Dynamic registration on the SDK customization page. Before you use the sample code file in this topic, make sure that you are familiar with the content of the Overview topic.
Step 1: Initialize the SDK
Add header files.
#include "aiot_state_api.h" #include "aiot_sysdep_api.h" #include "aiot_dynregmq_api.h"
Add the underlying dependency and configure the log output feature.
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);
Call the aiot_dynregmq_init operation to create a client instance named
dynregmq
and initialize the default parameters.dynregmq_handle = aiot_dynregmq_init(); if (dynregmq_handle == NULL) { printf("aiot_dynregmq_init failed\n"); return -1; }
Step 2: Configure the required features
Call the aiot_dynregmq_setopt operation to configure the following items:
For more information, see MQTT-based dynamic registration.
Configure connection parameters.
Sample code:
char *product_key = "a18wP******"; char *product_secret = "CpIlPVCXI7******"; char *device_name = "LightSwitch"; char *mqtt_host = "iot-06******.mqtt.iothub.aliyuncs.com"; uint8_t skip_pre_regist =1; ... /* Specify the endpoint of the server. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_HOST, (void *)host); /* Specify the port of the server. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_PORT, (void *)&port); /* Specify the ProductKey of the device. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_PRODUCT_KEY, (void *)product_key); /* Specify the ProductSecret of the device. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_PRODUCT_SECRET, (void *)product_secret); /* Specify the DeviceName of the device. aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_DEVICE_NAME, (void *)device_name); /* Specify the security credential of the connection. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_NETWORK_CRED, (void *)&cred); /* Specify whether to use the preregistration-free verification method. */ aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_NO_WHITELIST, (void *)&skip_pre_regist); ... ...
Parameters:
Parameter
Examples
Overview
mqtt_host
iot-06******.mqtt.iothub.aliyuncs.com
The endpoint to which you want to connect the device.
Format:
${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com
.skip_pre_regist
1
Specifies whether to use the preregistration-free verification method.
0: no
1: yes
ImportantFor more information about pre-registration and preregistration-free unique-certificate-per-product verification methods, see Unique-certificate-per-product verification.
product_key
a18wP******
The ProductKey and ProductSecret that you saved when you created the product in the IoT Platform console. For more information, see Create a product.
product_secret
CpIlPVCXI7******
device_name
LightSwitch
The DeviceName of the device.
IoT Platform checks the DeviceName when a device initiates an activation request. We recommend that you use an identifier that can be obtained from the device as the DeviceName. The identifier can be the MAC address, International Mobile Equipment Identity (IMEI) number, or serial number (SN) of the device.
Configure a message callback.
Specify a message callback function.
Sample code:
int main(int argc, char *argv[]) { ... Etc. aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_RECV_HANDLER, (void *)demo_dynregmq_recv_handler); aiot_dynregmq_setopt(dynregmq_handle, AIOT_DYNREGMQOPT_USERDATA, (void *)&demo_info); ... Etc. }
Parameters:
Parameter
Example
Description
AIOT_DYNREGMQOPT_RECV_HANDLER
demo_dynregmq_recv_handler
Configures a message callback. When a message is received, the callback is called to perform the required operations.
AIOT_DYNREGMQOPT_USERDATA
&demo_info
The context. When the
demo_dynregmq_recv_handler
operation is called, the value obtained from the operation is returned.
Define the message callback function.
void demo_dynregmq_recv_handler(void *handle, const aiot_dynregmq_recv_t *packet, void *userdata) { switch (packet->type) { /* TODO: You must save the space to which the packet parameter in the callback points. After the callback returns a result, the space is released. */ case AIOT_DYNREGMQRECV_DEVICEINFO_WL: { if (strlen(packet->data.deviceinfo_wl.device_secret) >= sizeof(demo_devinfo_wl.device_secret)) { break; } /* If you use the pre-registration verification method, make sure that the device_secret parameter is persisted. */ memset(&demo_devinfo_wl, 0, sizeof(demo_devinfo_wl_t)); memcpy(demo_devinfo_wl.device_secret, packet->data.deviceinfo_wl.device_secret, strlen(packet->data.deviceinfo_wl.device_secret)); } break; /* TODO: You must save the space to which the packet parameter in the callback points. After the callback returns a result, the space is released. */ case AIOT_DYNREGMQRECV_DEVICEINFO_NWL: { if (strlen(packet->data.deviceinfo_nwl.clientid) >= sizeof(demo_devinfo_nwl.conn_clientid) || strlen(packet->data.deviceinfo_nwl.username) >= sizeof(demo_devinfo_nwl.conn_username) || strlen(packet->data.deviceinfo_nwl.password) >= sizeof(demo_devinfo_nwl.conn_password)) { break; } /* If you use the preregistration-free verification method, make sure that the clientid, username, and password parameters are persisted. */ memset(&demo_devinfo_nwl, 0, sizeof(demo_devinfo_nwl_t)); memcpy(demo_devinfo_nwl.conn_clientid, packet->data.deviceinfo_nwl.clientid, strlen(packet->data.deviceinfo_nwl.clientid)); memcpy(demo_devinfo_nwl.conn_username, packet->data.deviceinfo_nwl.username, strlen(packet->data.deviceinfo_nwl.username)); memcpy(demo_devinfo_nwl.conn_password, packet->data.deviceinfo_nwl.password, strlen(packet->data.deviceinfo_nwl.password)); } break; default: { } break; } }
Step 3: Send a request
Call the aiot_dynregmq_send_request operation to send a dynamic registration request to the server. For information about how to configure the parameters, see Configure connection parameters.
res = aiot_dynregmq_send_request(dynregmq_handle);
if (res < STATE_SUCCESS) {
printf("aiot_dynregmq_send_request failed: -0x%04X\n", -res);
return -1;
}
Step 4: Receive a response
After the registration request is sent, IoT Platform returns a response. The device calls the aiot_dynregmq_recv operation to receive the response data and process the data by using the message callback.
res = aiot_dynregmq_recv(dynregmq_handle);
if (res < STATE_SUCCESS) {
printf("aiot_dynregmq_recv failed: -0x%04X\n", -res);
return -1;
}
In this example, the response data is printed. You must specify the logic to save the returned device verification information on premises. The verification information is used when the device connects to IoT Platform.
if (skip_pre_regist == 0) {
printf("device secret: %s\n", demo_devinfo_wl.device_secret);
} else {
printf("clientid: %s\n", demo_devinfo_nwl.conn_clientid);
printf("username: %s\n", demo_devinfo_nwl.conn_username);
printf("password: %s\n", demo_devinfo_nwl.conn_password);
}
Step 5: Exit the program
Call the aiot_dynregmq_deinit operation to delete the dynregmq
client instance and release the related resources.
res = aiot_dynregmq_deinit(&dynregmq_handle);
What to do next
After you configure the sample code file, compile the file to generate an executable file. In this example, the
./output/dynregmq-basic-demo
executable file is generated.For more information, see Prepare a development environment.
For more information about the running results, see View logs.
If you use the preregistration-free unique-certificate-per-product verification method to verify the device, IoT Platform issues the ClientId, UserName, and Password instead of DeviceSecret to the device after IoT Platform verifies the device.
You can specify the ClientId, UserName, and Password for the
AIOT_MQTTOPT_USERNAME, AIOT_MQTTOPT_PASSWORD, and AIOT_MQTTOPT_CLIENTID
parameters in themqtt_basic_demo.c
file and call theaiot_mqtt_connect
operation to connect the device to IoT Platform. The following sample code provides an example on how to perform the preceding operations:char *user_name = "demo_user_name"; char *password = "demo_passwd"; char *client_id = "demo_client_id"; aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_USERNAME, user_name); aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PASSWORD, password); aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_CLIENTID, client_id); res = aiot_mqtt_connect(mqtt_handle);