更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
Name: 设备标签模块
DEVINFO Component for Link SDK V4.0.0

View File

@@ -0,0 +1,424 @@
/**
* @file aiot_devinfo_api.c
* @brief devinfo模块的API接口实现, 提供更新和删除设备标签的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#include "devinfo_private.h"
#include "core_string.h"
#include "core_log.h"
#include "core_global.h"
#include "core_mqtt.h"
static void _core_devinfo_exec_inc(devinfo_handle_t *devinfo_handle)
{
devinfo_handle->sysdep->core_sysdep_mutex_lock(devinfo_handle->data_mutex);
devinfo_handle->exec_count++;
devinfo_handle->sysdep->core_sysdep_mutex_unlock(devinfo_handle->data_mutex);
}
static void _core_devinfo_exec_dec(devinfo_handle_t *devinfo_handle)
{
devinfo_handle->sysdep->core_sysdep_mutex_lock(devinfo_handle->data_mutex);
devinfo_handle->exec_count--;
devinfo_handle->sysdep->core_sysdep_mutex_unlock(devinfo_handle->data_mutex);
}
static void _devinfo_find_pk_dn(devinfo_handle_t *devinfo_handle, char *topic, uint16_t topic_len, char **product_key,
char **device_name)
{
uint16_t idx = 0, prev_slash = 0, slash = 0, pk_len = 0, dn_len = 0;
char *pk_pos = NULL, *dn_pos = NULL, *tmp_pk = NULL, *tmp_dn = NULL;
for (idx = 0; idx < topic_len; idx++) {
if (topic[idx] == '/') {
slash++;
if (slash == 2) {
pk_pos = &topic[idx + 1];
prev_slash = idx;
} else if (slash == 3) {
dn_pos = &topic[idx + 1];
pk_len = idx - prev_slash - 1;
prev_slash = idx;
} else if (slash == 4) {
dn_len = idx - prev_slash - 1;
break;
}
}
}
if (pk_len == 0 || dn_len == 0) {
return;
}
tmp_pk = devinfo_handle->sysdep->core_sysdep_malloc(pk_len + 1, DEVINFO_MODULE_NAME);
if (tmp_pk == NULL) {
return;
}
memset(tmp_pk, 0, pk_len + 1);
memcpy(tmp_pk, pk_pos, pk_len);
tmp_dn = devinfo_handle->sysdep->core_sysdep_malloc(dn_len + 1, DEVINFO_MODULE_NAME);
if (tmp_dn == NULL) {
devinfo_handle->sysdep->core_sysdep_free(tmp_pk);
return;
}
memset(tmp_dn, 0, dn_len + 1);
memcpy(tmp_dn, dn_pos, dn_len);
*product_key = tmp_pk;
*device_name = tmp_dn;
}
static void _devinfo_mqtt_recv_handler(void *handle, const aiot_mqtt_recv_t *packet, void *userdata)
{
devinfo_handle_t *devinfo_handle = (devinfo_handle_t *)userdata;
aiot_devinfo_event_t event;
char *product_key = NULL, *device_name = NULL;
char *code_key = "code", *id_key = "id", *data_key = "data", *message_key = "message";
char *code_value = NULL, *id_value = NULL, *data_value = NULL, *message_value = NULL;
uint32_t code_value_len = 0, id_value_len = 0, data_value_len = 0, message_value_len = 0;
if (devinfo_handle->recv_handler == NULL) {
return;
}
_devinfo_find_pk_dn(devinfo_handle, packet->data.pub.topic, packet->data.pub.topic_len, &product_key, &device_name);
if (product_key == NULL || device_name == NULL) {
if (devinfo_handle->event_handler != NULL) {
memset(&event, 0, sizeof(aiot_devinfo_event_t));
event.type = AIOT_DEVINFOEVT_INVALID_DEVINFO;
devinfo_handle->event_handler(devinfo_handle, &event, devinfo_handle->userdata);
}
return;
}
if (core_json_value((char *)packet->data.pub.payload, packet->data.pub.payload_len,
code_key, (uint32_t)strlen(code_key), &code_value, &code_value_len) == STATE_SUCCESS &&
core_json_value((char *)packet->data.pub.payload, packet->data.pub.payload_len,
id_key, (uint32_t)strlen(id_key), &id_value, &id_value_len) == STATE_SUCCESS &&
core_json_value((char *)packet->data.pub.payload, packet->data.pub.payload_len,
data_key, (uint32_t)strlen(data_key), &data_value, &data_value_len) == STATE_SUCCESS &&
core_json_value((char *)packet->data.pub.payload, packet->data.pub.payload_len,
message_key, (uint32_t)strlen(message_key), &message_value, &message_value_len) == STATE_SUCCESS) {
uint32_t code = 0, id = 0;
if (core_str2uint(code_value, code_value_len, &code) == STATE_SUCCESS &&
core_str2uint(id_value, id_value_len, &id) == STATE_SUCCESS) {
aiot_devinfo_recv_t recv;
memset(&recv, 0, sizeof(aiot_devinfo_recv_t));
recv.product_key = product_key;
recv.device_name = device_name;
recv.type = AIOT_DEVINFORECV_GENERIC_REPLY;
recv.data.generic_reply.code = code;
recv.data.generic_reply.msg_id = id;
recv.data.generic_reply.data = data_value;
recv.data.generic_reply.data_len = data_value_len;
recv.data.generic_reply.message = message_value;
recv.data.generic_reply.message_len = message_value_len;
devinfo_handle->recv_handler(devinfo_handle, &recv, devinfo_handle->userdata);
} else {
if (devinfo_handle->event_handler != NULL) {
memset(&event, 0, sizeof(aiot_devinfo_event_t));
event.type = AIOT_DEVINFOEVT_INVALID_RESPONSE_FORMAT;
devinfo_handle->event_handler(devinfo_handle, &event, devinfo_handle->userdata);
}
}
} else {
if (devinfo_handle->event_handler != NULL) {
memset(&event, 0, sizeof(aiot_devinfo_event_t));
event.type = AIOT_DEVINFOEVT_INVALID_RESPONSE;
devinfo_handle->event_handler(devinfo_handle, &event, devinfo_handle->userdata);
}
}
devinfo_handle->sysdep->core_sysdep_free(product_key);
devinfo_handle->sysdep->core_sysdep_free(device_name);
}
static int32_t _devinfo_operate_topic_map(devinfo_handle_t *devinfo_handle, aiot_mqtt_option_t option)
{
int32_t res = STATE_SUCCESS;
aiot_mqtt_topic_map_t map;
if (option != AIOT_MQTTOPT_APPEND_TOPIC_MAP && option != AIOT_MQTTOPT_REMOVE_TOPIC_MAP) {
return STATE_USER_INPUT_OUT_RANGE;
}
memset(&map, 0, sizeof(aiot_mqtt_topic_map_t));
map.topic = DEVINFO_UPDATE_REPLY_TOPIC;
map.handler = _devinfo_mqtt_recv_handler;
map.userdata = devinfo_handle;
res = aiot_mqtt_setopt(devinfo_handle->mqtt_handle, option, &map);
if (res < STATE_SUCCESS) {
return res;
}
map.topic = DEVINFO_DELETE_REPLY_TOPIC;
map.handler = _devinfo_mqtt_recv_handler;
map.userdata = devinfo_handle;
res = aiot_mqtt_setopt(devinfo_handle->mqtt_handle, option, &map);
if (res < STATE_SUCCESS) {
return res;
}
return STATE_SUCCESS;
}
static int32_t _devinfo_send(devinfo_handle_t *devinfo_handle, char *product_key, char *device_name,
aiot_devinfo_msg_data_t *data, char *topic_fmt)
{
int32_t res = STATE_SUCCESS, alink_id = 0;
char *topic = NULL, *payload = NULL;
char *topic_src[] = { product_key, device_name };
char alink_id_str[11] = {0}, *payload_src[] = { alink_id_str, data->params };
char *payload_fmt = "{\"id\":\"%s\",\"version\":\"1.0\",\"params\":%s}";
res = core_global_alink_id_next(devinfo_handle->sysdep, &alink_id);
if (res < STATE_SUCCESS) {
return res;
}
res = core_int2str(alink_id, alink_id_str, NULL);
if (res < STATE_SUCCESS) {
return res;
}
res = core_sprintf(devinfo_handle->sysdep, &topic, topic_fmt, topic_src, sizeof(topic_src) / sizeof(char *),
DEVINFO_MODULE_NAME);
if (res < STATE_SUCCESS) {
return res;
}
res = core_sprintf(devinfo_handle->sysdep, &payload, payload_fmt, payload_src, sizeof(payload_src) / sizeof(char *),
DEVINFO_MODULE_NAME);
if (res < STATE_SUCCESS) {
devinfo_handle->sysdep->core_sysdep_free(topic);
return res;
}
res = aiot_mqtt_pub(devinfo_handle->mqtt_handle, topic, (uint8_t *)payload, (uint32_t)strlen(payload), 0);
devinfo_handle->sysdep->core_sysdep_free(topic);
devinfo_handle->sysdep->core_sysdep_free(payload);
if (res >= STATE_SUCCESS) {
res = alink_id;
}
return res;
}
static void _devinfo_core_mqtt_process_handler(void *context, aiot_mqtt_event_t *event, core_mqtt_event_t *core_event)
{
devinfo_handle_t *devinfo_handle = (devinfo_handle_t *)context;
if (core_event != NULL) {
switch (core_event->type) {
case CORE_MQTTEVT_DEINIT: {
devinfo_handle->mqtt_handle = NULL;
return;
}
break;
default: {
}
break;
}
}
}
static int32_t _devinfo_core_mqtt_operate_process_handler(devinfo_handle_t *devinfo_handle, core_mqtt_option_t option)
{
core_mqtt_process_data_t process_data;
memset(&process_data, 0, sizeof(core_mqtt_process_data_t));
process_data.handler = _devinfo_core_mqtt_process_handler;
process_data.context = devinfo_handle;
return core_mqtt_setopt(devinfo_handle->mqtt_handle, option, &process_data);
}
void *aiot_devinfo_init(void)
{
int32_t res = STATE_SUCCESS;
devinfo_handle_t *devinfo_handle = NULL;
aiot_sysdep_portfile_t *sysdep = NULL;
sysdep = aiot_sysdep_get_portfile();
if (sysdep == NULL) {
return NULL;
}
res = core_global_init(sysdep);
if (res < STATE_SUCCESS) {
return NULL;
}
devinfo_handle = sysdep->core_sysdep_malloc(sizeof(devinfo_handle_t), DEVINFO_MODULE_NAME);
if (devinfo_handle == NULL) {
core_global_deinit(sysdep);
return NULL;
}
memset(devinfo_handle, 0, sizeof(devinfo_handle_t));
devinfo_handle->sysdep = sysdep;
devinfo_handle->deinit_timeout_ms = DEVINFO_DEFAULT_DEINIT_TIMEOUT_MS;
devinfo_handle->data_mutex = sysdep->core_sysdep_mutex_init();
devinfo_handle->exec_enabled = 1;
return devinfo_handle;
}
int32_t aiot_devinfo_setopt(void *handle, aiot_devinfo_option_t option, void *data)
{
int32_t res = STATE_SUCCESS;
devinfo_handle_t *devinfo_handle = (devinfo_handle_t *)handle;
if (handle == NULL || data == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
if (option >= AIOT_DEVINFOOPT_MAX) {
return STATE_USER_INPUT_OUT_RANGE;
}
if (devinfo_handle->exec_enabled == 0) {
return STATE_USER_INPUT_EXEC_DISABLED;
}
_core_devinfo_exec_inc(devinfo_handle);
devinfo_handle->sysdep->core_sysdep_mutex_lock(devinfo_handle->data_mutex);
switch (option) {
case AIOT_DEVINFOOPT_MQTT_HANDLE: {
devinfo_handle->mqtt_handle = data;
devinfo_handle->sysdep->core_sysdep_mutex_unlock(devinfo_handle->data_mutex);
res = _devinfo_operate_topic_map(devinfo_handle, AIOT_MQTTOPT_APPEND_TOPIC_MAP);
if (res >= STATE_SUCCESS) {
res = _devinfo_core_mqtt_operate_process_handler(devinfo_handle, CORE_MQTTOPT_APPEND_PROCESS_HANDLER);
}
devinfo_handle->sysdep->core_sysdep_mutex_lock(devinfo_handle->data_mutex);
}
break;
case AIOT_DEVINFOOPT_RECV_HANDLER: {
devinfo_handle->recv_handler = (aiot_devinfo_recv_handler_t)data;
}
break;
case AIOT_DEVINFOOPT_EVENT_HANDLER: {
devinfo_handle->event_handler = (aiot_devinfo_event_handler_t)data;
}
break;
case AIOT_DEVINFOOPT_USERDATA: {
devinfo_handle->userdata = data;
}
break;
case AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS: {
devinfo_handle->deinit_timeout_ms = *(uint32_t *)data;
}
break;
default: {
res = STATE_USER_INPUT_UNKNOWN_OPTION;
}
}
devinfo_handle->sysdep->core_sysdep_mutex_unlock(devinfo_handle->data_mutex);
_core_devinfo_exec_dec(devinfo_handle);
return res;
}
int32_t aiot_devinfo_deinit(void **handle)
{
uint64_t deinit_timestart = 0;
devinfo_handle_t *devinfo_handle = NULL;
if (handle == NULL || *handle == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
devinfo_handle = *(devinfo_handle_t **)handle;
if (devinfo_handle->exec_enabled == 0) {
return STATE_USER_INPUT_EXEC_DISABLED;
}
devinfo_handle->exec_enabled = 0;
_devinfo_core_mqtt_operate_process_handler(devinfo_handle, CORE_MQTTOPT_REMOVE_PROCESS_HANDLER);
_devinfo_operate_topic_map(devinfo_handle, AIOT_MQTTOPT_REMOVE_TOPIC_MAP);
deinit_timestart = devinfo_handle->sysdep->core_sysdep_time();
do {
if (devinfo_handle->exec_count == 0) {
break;
}
devinfo_handle->sysdep->core_sysdep_sleep(DEVINFO_DEINIT_INTERVAL_MS);
} while ((devinfo_handle->sysdep->core_sysdep_time() - deinit_timestart) < devinfo_handle->deinit_timeout_ms);
if (devinfo_handle->exec_count != 0) {
return STATE_MQTT_DEINIT_TIMEOUT;
}
*handle = NULL;
devinfo_handle->sysdep->core_sysdep_mutex_deinit(&devinfo_handle->data_mutex);
core_global_deinit(devinfo_handle->sysdep);
devinfo_handle->sysdep->core_sysdep_free(devinfo_handle);
return STATE_SUCCESS;
}
int32_t aiot_devinfo_send(void *handle, aiot_devinfo_msg_t *msg)
{
int32_t res = STATE_SUCCESS;
devinfo_handle_t *devinfo_handle = (devinfo_handle_t *)handle;
if (handle == NULL || msg == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
if (devinfo_handle->mqtt_handle == NULL) {
return STATE_DEVINFO_MISSING_MQTT_HANDLE;
}
if (msg->product_key == NULL) {
return STATE_USER_INPUT_MISSING_PRODUCT_KEY;
}
if (msg->device_name == NULL) {
return STATE_USER_INPUT_MISSING_DEVICE_NAME;
}
switch (msg->type) {
case AIOT_DEVINFO_MSG_UPDATE: {
if (msg->data.update.params == NULL) {
res = STATE_USER_INPUT_NULL_POINTER;
} else {
res = _devinfo_send(devinfo_handle, msg->product_key, msg->device_name, &msg->data.update, DEVINFO_UPDATE_TOPIC_FMT);
}
}
break;
case AIOT_DEVINFO_MSG_DELETE: {
if (msg->data.delete.params == NULL) {
res = STATE_USER_INPUT_NULL_POINTER;
} else {
res = _devinfo_send(devinfo_handle, msg->product_key, msg->device_name, &msg->data.delete, DEVINFO_DELETE_TOPIC_FMT);
}
}
break;
default: {
res = STATE_USER_INPUT_UNKNOWN_OPTION;
}
}
return res;
}

View File

@@ -0,0 +1,315 @@
/**
* @file aiot_devinfo_api.h
* @brief devinfo模块头文件, 提供更新和删除设备标签的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
* @details
*
* Devinfo模块用于向阿里云物联网平台更新或删除设备的标签, API的使用流程如下:
*
* 1. 首先参考 @ref aiot_mqtt_api.h 的说明, 保证成功建立与物联网平台的`MQTT`连接
*
* 2. 调用 @ref aiot_devinfo_init 初始化devinfo会话, 获取会话句柄
*
* 3. 调用 @ref aiot_devinfo_setopt 配置devinfo会话的参数, 常用配置项见 @ref aiot_devinfo_setopt 的说明
*
* 4. 调用 @ref aiot_devinfo_send 发送标签变更的请求, 比如更新或删除
*
* 5. 收到的应答经SDK处理后会调用由 @ref aiot_devinfo_setopt 配置的 @ref AIOT_DEVINFOOPT_RECV_HANDLER 回调函数, 通知用户云端的应答
*
*/
#ifndef __AIOT_DEVINFO_API_H__
#define __AIOT_DEVINFO_API_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdint.h>
/**
* @brief -0x1200~-0x12FF表达SDK在devinfo模块内的状态码
*/
#define STATE_DEVINFO_BASE (-0x1200)
/**
* @brief MQTT会话句柄未设置, 请通过 @ref aiot_devinfo_setopt 设置MQTT会话句柄
*/
#define STATE_DEVINFO_MISSING_MQTT_HANDLE (-0x1201)
/**
* @brief devinfo模块收到从网络上来的报文时, 通知用户的报文类型
*/
typedef enum {
AIOT_DEVINFORECV_GENERIC_REPLY,
} aiot_devinfo_recv_type_t;
typedef struct {
/**
* @brief 消息标识符, uint64_t类型的整数, 与属性上报或事件上报的消息标示符一致
*/
uint32_t msg_id;
/**
* @brief 设备端错误码, 200-请求成功, 更多错误码码查看<a href="https://help.aliyun.com/document_detail/120329.html">设备端错误码</a>
*/
uint32_t code;
/**
* @brief 指向云端应答数据的指针
*/
char *data;
/**
* @brief 云端应答数据的长度
*/
uint32_t data_len;
/**
* @brief 指向状态消息字符串的指针, 当设备端上报请求成功时对应的应答消息为"success", 若请求失败则应答消息中包含错误信息
*/
char *message;
/**
* @brief 消息字符串的长度
*/
uint32_t message_len;
} aiot_devinfo_recv_generic_reply_t;
/**
* @brief devinfo模块收到从网络上来的报文时, 通知用户的报文内容
*/
typedef struct {
char *product_key;
char *device_name;
/**
* @brief 报文内容所对应的报文类型, 更多信息请参考@ref aiot_devinfo_recv_type_t
*/
aiot_devinfo_recv_type_t type;
union {
/**
* @brief 从云端收到的更新或删除设备标签的应答
*/
aiot_devinfo_recv_generic_reply_t generic_reply;
} data;
} aiot_devinfo_recv_t;
/**
* @brief devinfo模块收到从网络上来的报文时, 通知用户所调用的数据回调函数
*
* @param[in] handle devinfo会话句柄
* @param[in] packet devinfo消息结构体, 存放收到的devinfo报文内容
* @param[in] userdata 用户上下文
*
* @return void
*/
typedef void (* aiot_devinfo_recv_handler_t)(void *handle, const aiot_devinfo_recv_t *packet, void *userdata);
/**
* @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户的事件类型
*/
typedef enum {
/**
* @brief 收到的应答中设备信息不合法, 无法获取product key和device name
*/
AIOT_DEVINFOEVT_INVALID_DEVINFO,
/**
* @brief 收到的应答中字段不合法
*/
AIOT_DEVINFOEVT_INVALID_RESPONSE,
/**
* @brief 收到的应答中字段格式错误
*/
AIOT_DEVINFOEVT_INVALID_RESPONSE_FORMAT,
} aiot_devinfo_event_type_t;
/**
* @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户的事件内容
*/
typedef struct {
/**
* @brief 事件内容所对应的事件类型, 更多信息请参考@ref aiot_devinfo_event_type_t
*/
aiot_devinfo_event_type_t type;
} aiot_devinfo_event_t;
/**
* @brief devinfo模块内部发生值得用户关注的状态变化时, 通知用户所调用的事件回调函数
*
* @param[in] handle, devinfo会话句柄
* @param[in] event, devinfo模块中发生的事件的内容
* @param[in] userdata, 用户上下文
*
* @return void
*/
typedef void (*aiot_devinfo_event_handler_t)(void *handle, const aiot_devinfo_event_t *event, void *userdata);
/**
* @brief @ref aiot_devinfo_msg_t 中的发送消息类型
*
* @details
*
* 消息类型有两个, 分别是更新设备标签和删除设备标签
*/
typedef enum {
/**
* @brief 更新设备标签
*/
AIOT_DEVINFO_MSG_UPDATE,
/**
* @brief 删除设备标签
*/
AIOT_DEVINFO_MSG_DELETE
} aiot_devinfo_msg_type_t;
/**
* @brief 更新或删除设备标签的params内容
*/
typedef struct {
char *params;
} aiot_devinfo_msg_data_t;
typedef struct {
/**
* @brief 设备的product key
*/
char *product_key;
/**
* @brief 设备的device name
*/
char *device_name;
/**
* @brief 消息类型, 更多信息请参考@ref aiot_devinfo_msg_type_t
*/
aiot_devinfo_msg_type_t type;
union {
/**
* @brief 更新设备标签, 格式:"[{\"attrKey\":\"xxx\",\"attrValue\":\"yyy\"}]"
*
* @details
*
* 从上述格式可以看出更新设备标签的格式是一个JSON数组一次可按attrKey和attrValue上报多组设备标签
*/
aiot_devinfo_msg_data_t update;
/**
* @brief 删除设备标签, 格式:"[{\"attrKey\":\"xxx\"}]"
*
* @details
*
* 从上述格式可以看出删除设备标签的格式是一个JSON数组一次可按attrKey删除多组设备标签
*/
aiot_devinfo_msg_data_t delete;
} data;
} aiot_devinfo_msg_t;
/**
* @brief @ref aiot_devinfo_setopt 接口的option参数可选值.
*
* @details 下文每个选项中的数据类型, 指的是@ref aiot_devinfo_setopt 中, data参数的数据类型
*
* 1. data的数据类型是void *时, 以配置@ref AIOT_DEVINFOOPT_MQTT_HANDLE 为例:
*
* void *mqtt_handle = aiot_mqtt_init();
* aiot_devinfo_setopt(devinfo_handle, AIOT_DEVINFOOPT_MQTT_HANDLE, mqtt_handle);
*
* 2. data的数据类型是其他数据类型时, 以配置@ref AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS 为例:
*
* uint32_t deinit_timeout_ms = 443;
* aiot_devinfo_setopt(devinfo_handle, AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS, (void *)&deinit_timeout_ms);
*/
typedef enum {
/**
* @brief devinfo会话 需要的MQTT句柄, 需要先建立MQTT连接, 再设置MQTT句柄
*/
AIOT_DEVINFOOPT_MQTT_HANDLE,
/**
* @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户
*
* @details
*
* 数据类型: ( @ref aiot_devinfo_recv_handler_t)
*/
AIOT_DEVINFOOPT_RECV_HANDLER,
/**
* @brief 设置回调, 它在SDK发生内部状态变更时被调用, 告知用户
*
* @details
*
* 数据类型: ( @ref aiot_devinfo_event_handler_t)
*/
AIOT_DEVINFOOPT_EVENT_HANDLER,
/**
* @brief 用户需要SDK暂存的上下文, 数据类型为(void *)
*
* @details 这个上下文指针会在 AIOT_DEVINFOOPT_RECV_HANDLER 和 AIOT_DEVINFOOPT_EVENT_HANDLER 设置的回调被调用时, 由SDK传给用户
*/
AIOT_DEVINFOOPT_USERDATA,
/**
* @brief 销毁devinfo实例时, 等待其他api执行完毕的时间
*
* @details
*
* 当调用@ref aiot_devinfo_deinit 销毁devinfo实例时, 若继续调用其他aiot_devinfo_xxx API, API会返回@ref STATE_USER_INPUT_EXEC_DISABLED 错误
*
* 此时, 用户应该停止调用其他aiot_devinfo_xxx API
*
* 数据类型: (uint32_t *) 默认值: (2 * 1000) ms
*/
AIOT_DEVINFOOPT_DEINIT_TIMEOUT_MS,
AIOT_DEVINFOOPT_MAX
} aiot_devinfo_option_t;
/**
* @brief 创建devinfo会话实例, 并以默认值配置会话参数
*
* @return void *
* @retval 非NULL devinfo实例的句柄
* @retval NULL 初始化失败, 一般是内存分配失败导致
*
*/
void *aiot_devinfo_init(void);
/**
* @brief 配置devinfo会话
*
* @param[in] handle devinfo会话句柄
* @param[in] option 配置选项, 更多信息请参考@ref aiot_devinfo_option_t
* @param[in] data 配置选项数据, 更多信息请参考@ref aiot_devinfo_option_t
*
* @return int32_t
* @retval <STATE_SUCCESS 参数配置失败
* @retval >=STATE_SUCCESS 参数配置成功
*
*/
int32_t aiot_devinfo_setopt(void *handle, aiot_devinfo_option_t option, void *data);
/**
* @brief 结束devinfo会话, 销毁实例并回收资源
*
* @param[in] handle 指向devinfo会话句柄的指针
*
* @return int32_t
* @retval <STATE_SUCCESS 执行失败
* @retval >=STATE_SUCCESS 执行成功
*
*/
int32_t aiot_devinfo_deinit(void **handle);
/**
* @brief 向devinfo服务器发送devinfo消息请求
*
* @param handle devinfo会话句柄
* @param msg devinfo发送给云端的删除/更新设备标签信息的报文
*
* @return int32_t
* @retval <STATE_SUCCESS 请求发送失败
* @retval >=STATE_SUCCESS 请求发送成功
*/
int32_t aiot_devinfo_send(void *handle, aiot_devinfo_msg_t *msg);
#if defined(__cplusplus)
}
#endif
#endif /* __AIOT_DEVINFO_API_H__ */

View File

@@ -0,0 +1,57 @@
/**
* @file devinfo_private.h
* @brief devinfo模块内部的宏定义和数据结构声明, 不面向其它模块, 更不面向用户
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#ifndef __DEVINFO_PRIVATE_H__
#define __DEVINFO_PRIVATE_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include "core_stdinc.h"
/* TODO: 这一段列出需要包含SDK其它模块头文件, 与上一段落以1个空行隔开 */
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"
#include "aiot_devinfo_api.h" /* 内部头文件是用户可见头文件的超集 */
typedef struct {
aiot_sysdep_portfile_t *sysdep; /* 底层依赖回调合集的引用指针 */
void *mqtt_handle;
aiot_devinfo_event_handler_t event_handler; /* 组件内部运行状态变更时, 通知用户的回调 */
aiot_devinfo_recv_handler_t recv_handler; /* 组件从协议栈读到内容时, 通知用户的回调 */
void *userdata; /* 组件调用以上2个 devinfo_handler 时的入参之一 */
uint32_t deinit_timeout_ms;
/*---- 以上都是用户在API可配 ----*/
/*---- 以下都是DEVINFO在内部使用, 用户无感知 ----*/
void *data_mutex; /* 保护本地的数据结构 */
uint8_t exec_enabled;
uint32_t exec_count;
} devinfo_handle_t;
#define DEVINFO_MODULE_NAME "devinfo" /* 用于内存统计的模块名字符串 */
#define DEVINFO_DEFAULT_DEINIT_TIMEOUT_MS (2 * 1000)
#define DEVINFO_UPDATE_TOPIC_FMT "/sys/%s/%s/thing/deviceinfo/update"
#define DEVINFO_UPDATE_REPLY_TOPIC "/sys/+/+/thing/deviceinfo/update_reply"
#define DEVINFO_DELETE_TOPIC_FMT "/sys/%s/%s/thing/deviceinfo/delete"
#define DEVINFO_DELETE_REPLY_TOPIC "/sys/+/+/thing/deviceinfo/delete_reply"
#define DEVINFO_DEINIT_INTERVAL_MS (100)
#if defined(__cplusplus)
}
#endif
#endif /* __DEVINFO_PRIVATE_H__ */