This article describes how to call the API operations of Link SDK for C to distribute devices. In this example, the ./demos/bootstrap_posix_demo.c sample code file is used.
Step 1: Initialize a client
- Add header files.
...
...
#include "aiot_bootstrap_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_bootstrap_init operation to create a
bootstrap
client instance and initialize the default parameters. bootstrap_handle = aiot_bootstrap_init();
if (bootstrap_handle == NULL) {
printf("aiot_bootstrap_init failed\n");
return -1;
}
Step 2: Configure required features
Call the aiot_bootstrap_setopt operation to configure the following items:
- Set connection parameters.
Notice You must set the TLS connection type to AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA.
- Sample code
int32_t res = STATE_SUCCESS;
void *bootstrap_handle = NULL, *mqtt_handle = NULL;
aiot_sysdep_network_cred_t cred;
demo_info_t demo_info;
/* TODO: Replace the values of the following parameters with the ProductKey, DeviceName, and DeviceSecret of your device. */
char *product_key = "a18wP******";
char *device_name = "LightSwitch";
char *device_secret = "uwMTmVAMnGGHaAkqmeDY6cHxxB******";
...
...
memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* Verify the MQTT broker by using the RSA certificate. */
cred.max_tls_fragment = 16384; /* The fragment can be up to 16 KB in length. Other optional values include 4 KB, 2 KB, 1 KB, and 0.5 KB. */
cred.sni_enabled = 1; /* The server name indicator that is supported when you establish a TLS connection. */
cred.x509_server_cert = ali_ca_cert; /* The RSA root certificate that is used to verify the MQTT broker. */
cred.x509_server_cert_len = strlen(ali_ca_crt); /* The length of the RSA root certificate that is used to verify the MQTT broker. */
...
...
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_HOST, (void *)host);
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PORT, (void *)&port);
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_PRODUCT_KEY, (void *)product_key);
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_DEVICE_NAME, (void *)device_name);
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_NETWORK_CRED, (void *)&cred);
...
...
- Parameters:
Parameter |
Example |
Description |
product_key |
a18wP****** |
The device authentication information. For more information, see Obtain device authentication information.
In this example, the unique-certificate-per-device authentication method is used.
The device_secret parameter is required when you establish an MQTT connection by using the obtained
endpoint and port number.
|
device_name |
LightSwitch |
device_secret |
uwMTmVAMnGGHaAkqmeDY6cHxxB****** |
- Configure a message callback.
- Sample code
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_RECV_HANDLER, (void *)demo_bootstrap_recv_handler);
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_USERDATA, (void *)&demo_info);
- Parameters:
Parameter |
Example |
Description |
AIOT_BOOTSTRAPOPT_RECV_HANDLER |
demo_bootstrap_recv_handler |
When a device distribution message is received, this callback is called. |
AIOT_BOOTSTRAPOPT_USERDATA |
demo_info |
Sets the context. When the demo_bootstrap_recv_handler callback is called, the userdata parameter is returned. You must convert the data type before you use this parameter.
|
- Configure status monitoring.
- Define the callback to monitor status.
void demo_bootstrap_event_handler(void *handle, const aiot_bootstrap_event_t *event, void *userdata)
{
switch (event->type) {
case AIOT_BOOTSTRAPEVT_INVALID_RESPONSE: {
printf("AIOT_BOOTSTRAPEVT_INVALID_RESPONSE\n");
}
break;
case AIOT_BOOTSTRAPEVT_INVALID_CMD: {
printf("AIOT_BOOTSTRAPEVT_INVALID_CMD\n");
}
break;
default: {
}
break;
}
}
- Specify the callbacks to monitor status.
Step 3: Send a request
Notice Before you send a device distribution request, make sure that the device is distributed
in IoT Platform. Otherwise, the current endpoint and port number of the device is
returned.
Call the aiot_bootstrap_send_request operation to send an HTTPS request to the server. For more information about the
parameters in the request, see the previous step.
res = aiot_bootstrap_send_request(bootstrap_handle);
if (res < STATE_SUCCESS) {
printf("aiot_bootstrap_send_request failed, res: -0x%04X\n", -res);
return -1;
}
Step 4: Receive a response
- After the message is sent, IoT Platform returns a response message. The device calls
the aiot_bootstrap_recv operation to receive the response data and process the data by using the message
callback.
res = aiot_bootstrap_recv(bootstrap_handle);
if (res < STATE_SUCCESS) {
printf("aiot_bootstrap_recv failed, res: -0x%04X\n", -res);
return -1;
}
- Specify the processing logic of the callback.
When you specify the processing logic of the callback, take note of the following
items:
Message type |
Description |
AIOT_BOOTSTRAPRECV_STATUS_CODE |
The HTTP status code that is returned by IoT Platform. For more information, see HTTP status codes.
In this example, the logic to process received status codes is not specified. You
can specify the logic based on your business needs.
|
AIOT_BOOTSTRAPRECV_CONNECTION_INFO |
The response message that is returned by IoT Platform.
aiot_bootstrap_recv_t indicates the message type. You must save the host and port parameters on premises.
In this example, the response message is printed.
|
AIOT_BOOTSTRAPRECV_NOTIFY |
The device distribution message that is sent by IoT Platform.
After a device is distributed in IoT Platform, IoT Platform sends a message to the
device.
In this example, the message is printed. You must specify the logic to disconnect
the device and re-initiate a device distribution request.
|
void demo_bootstrap_recv_handler(void *handle, const aiot_bootstrap_recv_t *packet, void *userdata)
{
demo_info_t *demo_info = (demo_info_t *)userdata;
switch (packet->type) {
case AIOT_BOOTSTRAPRECV_STATUS_CODE: {
demo_info->code = packet->data.status_code.code;
}
break;
case AIOT_BOOTSTRAPRECV_CONNECTION_INFO: {
demo_info->host = malloc(strlen(packet->data.connection_info.host) + 1);
if (demo_info->host != NULL) {
memset(demo_info->host, 0, strlen(packet->data.connection_info.host) + 1);
/* TODO: Store the device distribution message to a specified location and release the memory space. */
memcpy(demo_info->host, packet->data.connection_info.host, strlen(packet->data.connection_info.host));
demo_info->port = packet->data.connection_info.port;
}
}
break;
case AIOT_BOOTSTRAPRECV_NOTIFY: {
printf("AIOT_BOOTSTRAPRECV_NOTIFY, cmd: %d\n", packet->data.notify.cmd);
}
default: {
}
break;
}
}
(Optional) Step 5: Establish an MQTT connection
After you obtain the required endpoint and port number, connect the device with IoT
Platform over MQTT. For more information about MQTT connections, see Overview.
After an MQTT connection is established, perform the following steps to distribute
the device.
- Associate with an MQTT connection handle. by calling the aiot_bootstrap_setopt operation.
- Log on to the IoT Platform console and distribute the device.
- After the device receives the message, the device goes offline. Re-perform Step 1 to Step 4 to obtain the endpoint and re-connect the device to IoT Platform.
Step 6: Exit the program
Call the aiot_bootstrap_deinit operation to destroy the bootstrap
client instance and release resources.
res = aiot_bootstrap_deinit(&bootstrap_handle);
if (res < 0) {
printf("demo_start_stop failed\n");
return -1;
}
What to do next
-
After you configure the sample code file, compile the file to generate an executable
file In this example, the ./demos/bootstrap-posix-demo executable file is generated.
For more information, see Compilation and running.
-
For more information about running results, see View logs.