本文以C Link SDK中的Demo文件./demos/bootstrap_posix_demo.c为例,介绍如何调用Link SDK的API,实现设备的分发功能。
背景信息
步骤一:初始化
- 添加头文件。
…… …… #include "aiot_bootstrap_api.h"
- 配置底层依赖和日志输出。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);
- 调用aiot_bootstrap_init,创建
Bootstrap
客户端实例,并初始化默认参数。bootstrap_handle = aiot_bootstrap_init(); if (bootstrap_handle == NULL) { printf("aiot_bootstrap_init failed\n"); return -1; }
步骤二:配置功能
调用aiot_bootstrap_setopt,配置以下功能。
- 配置连接参数。重要 TLS层的安全连接类型必须为证书方式AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA。
- 示例代码:
int32_t res = STATE_SUCCESS; void *bootstrap_handle = NULL, *mqtt_handle = NULL; aiot_sysdep_network_cred_t cred; demo_info_t demo_info; /* TODO: 替换为自己设备的productKey和deviceName */ 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; /* 使用RSA证书校验MQTT服务端 */ cred.max_tls_fragment = 16384; /* 最大的分片长度为16 KB, 其它可选值还有4 KB、2 KB、1 KB、0.5 KB */ cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */ cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */ cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */ …… …… 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); …… ……
- 相关参数:
参数 示例 说明 product_key a18wP****** 设备认证信息。更多信息,请参见获取设备认证信息。
本例程的身份认证方式为一机一密。
其中,device_secret将在设备获取到接入域名和端口号以后,建立MQTT连接时,使用该参数。
device_name LightSwitch device_secret uwMTmVAMnGGHaAkqmeDY6cHxxB******
- 示例代码:
- 配置消息回调。
- 示例代码:
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);
- 相关参数:
配置项 示例值 说明 AIOT_BOOTSTRAPOPT_RECV_HANDLER demo_bootstrap_recv_handler 接收到设备分发消息时,调用该函数。 AIOT_BOOTSTRAPOPT_USERDATA demo_info 设置上下文。当触发函数 demo_bootstrap_recv_handler
时,回传userdata
,您需自行对其做类型转换后,再使用。
- 示例代码:
- 配置状态监控。
步骤三:发送请求
重要 发送设备分发请求前,请确保已在物联网平台执行设备分发操作。否则,请求后返回的接入域名为设备当前的接入域名和端口号。
调用aiot_bootstrap_send_request,根据上一步配置的参数,向服务器发送HTTPS协议的请求,请求设备分发。
关于HTTPS请求的详细说明,请参见设备分发的请求数据格式。
res = aiot_bootstrap_send_request(bootstrap_handle);
if (res < STATE_SUCCESS) {
printf("aiot_bootstrap_send_request failed, res: -0x%04X\n", -res);
return -1;
}
步骤四:接收应答
- 设备请求消息发送后,物联网平台返回应答报文。设备端调用aiot_bootstrap_recv,接收应答消息,根据消息回调函数的处理逻辑,执行对应处理。
res = aiot_bootstrap_recv(bootstrap_handle); if (res < STATE_SUCCESS) { printf("aiot_bootstrap_recv failed, res: -0x%04X\n", -res); return -1; }
- 编写回调函数的处理逻辑。您可以参考以下内容,编写回调函数的处理逻辑:
报文类型 说明 AIOT_BOOTSTRAPRECV_STATUS_CODE 服务器返回的HTTP状态码,更多信息,请参见HTTP状态码。 示例代码未对接收的状态码编写处理逻辑,您可以根据业务需要,自行编写处理逻辑。
AIOT_BOOTSTRAPRECV_CONNECTION_INFO 发起设备分发后,物联网平台返回的应答报文。 接收的消息的类型为aiot_bootstrap_recv_t,您需将其中的host和port(即设备接入的域名和端口号)保存至本地。
示例代码仅将接收的设备分发消息,做打印处理。
AIOT_BOOTSTRAPRECV_NOTIFY 物联网平台下发的设备分发通知消息。 在物联网平台执行设备分发操作后,向设备推送设备分发消息。具体操作,请参见物联网平台的设备分发。
示例代码仅做打印处理,您需编写处理逻辑,将设备断开后,在设备端重新发起设备分发请求,建立连接。
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: 回调中,将设备分发消息内容存储指定位置, 这些空间就会被SDK释放 */ 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; } }
(可选)步骤五:建立MQTT连接
获取设备所需的接入域名和端口号后,设备与物联网平台建立MQTT连接。MQTT接入的详细说明,请参见MQTT接入。
MQTT连接建立后,您可以参照以下步骤,再次实现设备分发。
- 调用aiot_bootstrap_setopt,关联MQTT连接的句柄。
- 示例代码:
aiot_bootstrap_setopt(bootstrap_handle, AIOT_BOOTSTRAPOPT_MQTT_HANDLE, (void *)mqtt_handle);
- 相关参数:
配置项 示例 说明 AIOT_BOOTSTRAPOPT_MQTT_HANDLE mqtt_handle 当设备接收到物联网平台下推的设备分发消息,触发该回调函数。
- 示例代码:
- 登录物联网平台,执行设备分发操作。具体操作,请参见物联网平台的设备分发。
- 设备端接收到下推的设备分发消息后,设备下线。然后,重新参照步骤一至步骤四,获取设备接入域名,将设备重新接入物联网平台。
步骤六:退出程序
调用aiot_bootstrap_deinit,销毁Bootstrap
客户端实例,释放资源。
res = aiot_bootstrap_deinit(&bootstrap_handle);
if (res < 0) {
printf("demo_start_stop failed\n");
return -1;
}