本文以C Link SDK中的Demo文件./demos/compress_basic_demo.c
为例,介绍如何调用Link SDK的API,帮助您实现设备的数据压缩功能。
背景信息
步骤一:初始化
添加头文件。
…… …… #include "aiot_compress_api.h" ……
配置底层依赖和日志输出。
aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile); aiot_state_set_logcb(demo_state_logcb);
调用aiot_compress_init,创建数据压缩模块实例,并初始化默认参数。
/* 创建1个compress客户端实例并内部初始化默认参数 */ compress_handle = aiot_compress_init(); if (compress_handle == NULL) { demo_mqtt_stop(&mqtt_handle); printf("aiot_compress_init failed\n"); return -1; }
步骤二:配置功能
调用aiot_compress_setopt, 配置以下功能。
关联MQTT连接的句柄。
/* 添加关联的MQTT句柄 */ aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_MQTT_HANDLE, mqtt_handle);
设置压缩等级。
/* 设置压缩等级,压缩等级为1~9, 压缩等级越高,压缩效果越好,但内存和时间消耗越高 */ uint8_t compress_level = 1; aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_LEVEL, &compress_level);
添加上行消息中需要压缩的Topic列表。
Topic必须为完整Topic,不支持使用带通配符的Topic列表。
列表定义。
/* TODO: 替换为自己需要压缩的上行消息topic列表 */ char *compr_list[] = { "/${YourProductKey}/${YourDeviceName}/user/update", "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post", };
配置Topic列表。
/* 添加需要压缩的上行topic */ for(int i = 0; i < sizeof(compr_list) / sizeof(char *); i++) { aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_APPEND_COMPR_TOPIC, compr_list[i]); }
添加下行消息中需要压缩的Topic列表。
列表定义。
/* TODO: 替换为自己需要压缩的下行消息topic列表 */ char *decompr_list[] = { "/${YourProductKey}/${YourDeviceName}/user/update_reply", "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post_reply", };
配置Topic列表。
/* 添加需要解压缩的下行topic */ for(int i = 0; i < sizeof(decompr_list) / sizeof(char *); i++) { aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_APPEND_DECOMPR_TOPIC, decompr_list[i]); }
设置上报列表的回调函数。
/* 向物联网平台上报压缩或解压缩topic列表,只需要上报一次,重启有效 */ uint32_t code = 0; aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_RECV_HANDLER, demo_update_reply); aiot_compress_setopt(compress_handle, AIOT_COMPRESSOPT_USERDATA, &code);
回调函数的实现,获取返回的结果。
static void demo_update_reply(void *handle, const aiot_compress_recv_t *packet, void *userdata) { uint32_t *code = (uint32_t *)userdata; *code = packet->data.update_reply.code; printf("compress update reply code %d, message %.*s\r\n", packet->data.update_reply.code, packet->data.update_reply.message_len, packet->data.update_reply.message); }
(可选)步骤三:上报压缩Topic列表
设备需要上报压缩或解压Topic列表,并等待返回结果。
说明
设备上报成功以后,重启无需再次上报。
如果需要更新Topic列表,可以再次上报更新,物联网云平台会以最新的一次上报为准。
上报压缩Topic列表。
aiot_compress_topiclist_update(compress_handle);
返回结果,code为200时表示执行成功。
if(code != 200) { demo_mqtt_stop(&mqtt_handle); aiot_compress_deinit(&compress_handle); printf("aiot_compress_topiclist_update failed\n"); return -1; }
步骤四:上报压缩列表中消息
当消息的Topic已在列表中,您可以发布消息,Link SDK会自动完成消息的压缩。
调用aiot_mqtt_pub像普通消息一样上报。
char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post";
char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0, \"message\":\"this is a test message, this is a test message, this is a test message\"}}";
aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0);
步骤五:下发压缩列表中的消息
如果下发的消息需要压缩,物联网平台会完成压缩动作,Link SDK完成消息的解压,回调函数中的数据为解压后的数据。
调用aiot_mqtt_recv处理消息接收,当有压缩消息到达时,Link SDK完成消息解压,并会执行消息回调。
/* MQTT默认消息处理回调, 当SDK从服务器收到MQTT消息时, 且无对应用户回调处理时被调用 */
void demo_mqtt_default_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)
{
switch (packet->type) {
....
case AIOT_MQTTRECV_PUB: {
printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic);
printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload);
}
break;
....
}
}
步骤六:退出程序
调用aiot_compress_deinit, 销毁实例,回收资源。
/* 销毁COMPRESS实例, 一般不会运行到这里 */
res = aiot_compress_deinit(&compress_handle);
if (res < STATE_SUCCESS) {
demo_mqtt_stop(&mqtt_handle);
printf("aiot_compress_deinit failed: -0x%04X\n", -res);
return -1;
}