mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-21 10:25:54 +08:00
更新硬件SDK
This commit is contained in:
2
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/README.md
vendored
Normal file
2
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/README.md
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Name: 物模型模块
|
||||
Data-Model Component for Link SDK V4.0.0
|
||||
834
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/aiot_dm_api.c
vendored
Normal file
834
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/aiot_dm_api.c
vendored
Normal file
@@ -0,0 +1,834 @@
|
||||
/**
|
||||
* @file aiot_dm_api.c
|
||||
* @brief 数据模型模块接口实现文件, 包含了支持物模型数据格式通信的所有接口实现
|
||||
* @date 2020-01-20
|
||||
*
|
||||
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dm_private.h"
|
||||
|
||||
|
||||
static int32_t _dm_send_property_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_event_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_property_set_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_async_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_sync_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_raw_data(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_raw_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_desired_get(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_desired_delete(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
static int32_t _dm_send_property_batch_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
|
||||
static void _dm_recv_generic_reply_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_property_set_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_async_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_sync_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_raw_data_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_raw_sync_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
static void _dm_recv_up_raw_reply_data_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata);
|
||||
|
||||
static const dm_send_topic_map_t g_dm_send_topic_mapping[AIOT_DMMSG_MAX] = {
|
||||
{
|
||||
"/sys/%s/%s/thing/event/property/post",
|
||||
_dm_send_property_post
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/event/%s/post",
|
||||
_dm_send_event_post
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/service/property/set_reply",
|
||||
_dm_send_property_set_reply
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/service/%s_reply",
|
||||
_dm_send_async_service_reply
|
||||
},
|
||||
{
|
||||
"/ext/rrpc/%s/sys/%s/%s/thing/service/%s",
|
||||
_dm_send_sync_service_reply
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/model/up_raw",
|
||||
_dm_send_raw_data
|
||||
},
|
||||
{
|
||||
"/ext/rrpc/%s/sys/%s/%s/thing/model/down_raw",
|
||||
_dm_send_raw_service_reply
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/property/desired/get",
|
||||
_dm_send_desired_get
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/property/desired/delete",
|
||||
_dm_send_desired_delete
|
||||
},
|
||||
{
|
||||
"/sys/%s/%s/thing/event/property/batch/post",
|
||||
_dm_send_property_batch_post
|
||||
},
|
||||
};
|
||||
|
||||
static const dm_recv_topic_map_t g_dm_recv_topic_mapping[] = {
|
||||
{
|
||||
"/sys/+/+/thing/event/+/post_reply",
|
||||
_dm_recv_generic_reply_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/service/property/set",
|
||||
_dm_recv_property_set_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/service/+",
|
||||
_dm_recv_async_service_invoke_handler,
|
||||
},
|
||||
{
|
||||
"/ext/rrpc/+/sys/+/+/thing/service/+",
|
||||
_dm_recv_sync_service_invoke_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/model/down_raw",
|
||||
_dm_recv_raw_data_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/model/up_raw_reply",
|
||||
_dm_recv_up_raw_reply_data_handler,
|
||||
},
|
||||
{
|
||||
"/ext/rrpc/+/sys/+/+/thing/model/down_raw",
|
||||
_dm_recv_raw_sync_service_invoke_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/property/desired/get_reply",
|
||||
_dm_recv_generic_reply_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/property/desired/delete_reply",
|
||||
_dm_recv_generic_reply_handler,
|
||||
},
|
||||
{
|
||||
"/sys/+/+/thing/event/property/batch/post_reply",
|
||||
_dm_recv_generic_reply_handler,
|
||||
},
|
||||
};
|
||||
|
||||
static void _append_diag_data(dm_handle_t *dm_handle, uint8_t msg_type, int32_t msg_id)
|
||||
{
|
||||
/* append diagnose data */
|
||||
uint8_t diag_data[] = { 0x00, 0x30, 0x01, 0x00, 0x00, 0x31, 0x04, 0x00, 0x00, 0x00, 0x00 };
|
||||
diag_data[3] = msg_type;
|
||||
diag_data[7] = (msg_id >> 24) & 0xFF;
|
||||
diag_data[8] = (msg_id >> 16) & 0xFF;
|
||||
diag_data[9] = (msg_id >> 8) & 0xFF;
|
||||
diag_data[10] = msg_id & 0xFF;
|
||||
core_diag(dm_handle->sysdep, STATE_DM_BASE, diag_data, sizeof(diag_data));
|
||||
}
|
||||
|
||||
static int32_t _dm_setup_topic_mapping(void *mqtt_handle, void *dm_handle)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
for (i = 0; i < sizeof(g_dm_recv_topic_mapping) / sizeof(dm_recv_topic_map_t); i++) {
|
||||
aiot_mqtt_topic_map_t topic_mapping;
|
||||
topic_mapping.topic = g_dm_recv_topic_mapping[i].topic;
|
||||
topic_mapping.handler = g_dm_recv_topic_mapping[i].func;
|
||||
topic_mapping.userdata = dm_handle;
|
||||
|
||||
res = aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_APPEND_TOPIC_MAP, &topic_mapping);
|
||||
if (res < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t _dm_prepare_send_topic(dm_handle_t *dm_handle, const aiot_dm_msg_t *msg, char **topic)
|
||||
{
|
||||
char *src[4];
|
||||
uint8_t src_count = 0;
|
||||
char *pk = NULL;
|
||||
char *dn = NULL;
|
||||
|
||||
if (NULL == msg->product_key && NULL == core_mqtt_get_product_key(dm_handle->mqtt_handle)) {
|
||||
return STATE_USER_INPUT_MISSING_PRODUCT_KEY;
|
||||
}
|
||||
if (NULL == msg->device_name && NULL == core_mqtt_get_device_name(dm_handle->mqtt_handle)) {
|
||||
return STATE_USER_INPUT_MISSING_DEVICE_NAME;
|
||||
}
|
||||
|
||||
pk = (msg->product_key != NULL) ? msg->product_key : core_mqtt_get_product_key(dm_handle->mqtt_handle);
|
||||
dn = (msg->device_name != NULL) ? msg->device_name : core_mqtt_get_device_name(dm_handle->mqtt_handle);
|
||||
|
||||
switch (msg->type) {
|
||||
case AIOT_DMMSG_PROPERTY_POST:
|
||||
case AIOT_DMMSG_PROPERTY_BATCH_POST:
|
||||
case AIOT_DMMSG_PROPERTY_SET_REPLY:
|
||||
case AIOT_DMMSG_GET_DESIRED:
|
||||
case AIOT_DMMSG_DELETE_DESIRED:
|
||||
case AIOT_DMMSG_RAW_DATA: {
|
||||
src[0] = pk;
|
||||
src[1] = dn;
|
||||
src_count = 2;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMMSG_EVENT_POST: {
|
||||
if (msg->data.event_post.event_id == NULL) {
|
||||
return STATE_DM_EVENT_ID_IS_NULL;
|
||||
}
|
||||
src[0] = pk;
|
||||
src[1] = dn;
|
||||
src[2] = msg->data.event_post.event_id;
|
||||
src_count = 3;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMMSG_ASYNC_SERVICE_REPLY: {
|
||||
if (msg->data.async_service_reply.service_id == NULL) {
|
||||
return STATE_DM_SERVICE_ID_IS_NULL;
|
||||
}
|
||||
src[0] = pk;
|
||||
src[1] = dn;
|
||||
src[2] = msg->data.async_service_reply.service_id;
|
||||
src_count = 3;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMMSG_SYNC_SERVICE_REPLY: {
|
||||
if (msg->data.sync_service_reply.rrpc_id == NULL) {
|
||||
return STATE_DM_RRPC_ID_IS_NULL;
|
||||
}
|
||||
if (msg->data.sync_service_reply.service_id == NULL) {
|
||||
return STATE_DM_SERVICE_ID_IS_NULL;
|
||||
}
|
||||
src[0] = msg->data.sync_service_reply.rrpc_id;
|
||||
src[1] = pk;
|
||||
src[2] = dn;
|
||||
src[3] = msg->data.sync_service_reply.service_id;
|
||||
src_count = 4;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMMSG_RAW_SERVICE_REPLY: {
|
||||
if (msg->data.raw_service_reply.rrpc_id == NULL) {
|
||||
return STATE_DM_RRPC_ID_IS_NULL;
|
||||
}
|
||||
src[0] = msg->data.raw_service_reply.rrpc_id;
|
||||
src[1] = pk;
|
||||
src[2] = dn;
|
||||
src_count = 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return STATE_USER_INPUT_OUT_RANGE;
|
||||
}
|
||||
|
||||
return core_sprintf(dm_handle->sysdep, topic, g_dm_send_topic_mapping[msg->type].topic, src, src_count,
|
||||
DATA_MODEL_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
static int32_t _dm_send_alink_req(dm_handle_t *handle, const char *topic, char *params)
|
||||
{
|
||||
char *payload = NULL;
|
||||
int32_t id = 0;
|
||||
char id_string[11] = { 0 };
|
||||
char *src[3] = { NULL };
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
if (NULL == params) {
|
||||
return STATE_DM_MSG_PARAMS_IS_NULL;
|
||||
}
|
||||
|
||||
core_global_alink_id_next(handle->sysdep, &id);
|
||||
core_int2str(id, id_string, NULL);
|
||||
|
||||
_append_diag_data(handle, DM_DIAG_MSG_TYPE_REQ, id);
|
||||
|
||||
src[0] = id_string;
|
||||
src[1] = params;
|
||||
src[2] = (0 == handle->post_reply) ? "0" : "1";
|
||||
|
||||
res = core_sprintf(handle->sysdep, &payload, ALINK_REQUEST_FMT, src, sizeof(src) / sizeof(char *),
|
||||
DATA_MODEL_MODULE_NAME);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = aiot_mqtt_pub(handle->mqtt_handle, (char *)topic, (uint8_t *)payload, strlen(payload), 0);
|
||||
handle->sysdep->core_sysdep_free(payload);
|
||||
|
||||
if (STATE_SUCCESS == res) {
|
||||
return id;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int32_t _dm_send_alink_rsp(dm_handle_t *handle, const char *topic, uint64_t msg_id, uint32_t code,
|
||||
char *data)
|
||||
{
|
||||
char *payload = NULL;
|
||||
char id_string[21] = { 0 };
|
||||
char code_string[11] = { 0 };
|
||||
char *src[3] = { NULL };
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
if (NULL == data) {
|
||||
return STATE_DM_MSG_DATA_IS_NULL;
|
||||
}
|
||||
|
||||
core_uint642str(msg_id, id_string, NULL);
|
||||
core_uint2str(code, code_string, NULL);
|
||||
|
||||
src[0] = id_string;
|
||||
src[1] = code_string;
|
||||
src[2] = data;
|
||||
|
||||
res = core_sprintf(handle->sysdep, &payload, ALINK_RESPONSE_FMT, src, sizeof(src) / sizeof(char *),
|
||||
DATA_MODEL_MODULE_NAME);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = aiot_mqtt_pub(handle->mqtt_handle, (char *)topic, (uint8_t *)payload, strlen(payload), 0);
|
||||
handle->sysdep->core_sysdep_free(payload);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*** dm send function start ***/
|
||||
static int32_t _dm_send_property_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_req(handle, topic, msg->data.property_post.params);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_event_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_req(handle, topic, msg->data.event_post.params);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_property_set_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_rsp(handle, topic, msg->data.property_set_reply.msg_id,
|
||||
msg->data.property_set_reply.code,
|
||||
msg->data.property_set_reply.data);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_async_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_rsp(handle, topic, msg->data.async_service_reply.msg_id,
|
||||
msg->data.async_service_reply.code,
|
||||
msg->data.async_service_reply.data);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_sync_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_rsp(handle, topic, msg->data.sync_service_reply.msg_id,
|
||||
msg->data.sync_service_reply.code,
|
||||
msg->data.sync_service_reply.data);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_raw_data(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return aiot_mqtt_pub(handle->mqtt_handle, (char *)topic, msg->data.raw_data.data, msg->data.raw_data.data_len, 0);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_raw_service_reply(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return aiot_mqtt_pub(handle->mqtt_handle, (char *)topic, msg->data.raw_service_reply.data,
|
||||
msg->data.raw_service_reply.data_len, 0);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_desired_get(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_req(handle, topic, msg->data.get_desired.params);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_desired_delete(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_req(handle, topic, msg->data.delete_desired.params);
|
||||
}
|
||||
|
||||
static int32_t _dm_send_property_batch_post(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
return _dm_send_alink_req(handle, topic, msg->data.property_post.params);
|
||||
}
|
||||
/*** dm send function end ***/
|
||||
|
||||
/*** dm recv handler functions start ***/
|
||||
static int32_t _dm_get_topic_level(aiot_sysdep_portfile_t *sysdep, char *topic, uint32_t topic_len, uint8_t level,
|
||||
char **level_name)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint16_t level_curr = 0;
|
||||
char *p_open = NULL;
|
||||
char *p_close = NULL;
|
||||
char *p_name = NULL;
|
||||
uint16_t name_len = 0;
|
||||
|
||||
for (i = 0; i < (topic_len - 1); i++) {
|
||||
if (topic[i] == '/') {
|
||||
level_curr++;
|
||||
if (level_curr == level && p_open == NULL) {
|
||||
p_open = topic + i + 1;
|
||||
}
|
||||
|
||||
if (level_curr == (level + 1) && p_close == NULL) {
|
||||
p_close = topic + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_open == NULL) {
|
||||
return STATE_DM_INTERNAL_TOPIC_ERROR;
|
||||
}
|
||||
if (p_close == NULL) {
|
||||
p_close = topic + topic_len;
|
||||
}
|
||||
|
||||
name_len = p_close - p_open;
|
||||
p_name = sysdep->core_sysdep_malloc(name_len + 1, DATA_MODEL_MODULE_NAME);
|
||||
if (p_name == NULL) {
|
||||
return STATE_SYS_DEPEND_MALLOC_FAILED;
|
||||
}
|
||||
memset(p_name, 0, name_len + 1);
|
||||
memcpy(p_name, p_open, name_len);
|
||||
*level_name = p_name;
|
||||
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t _dm_parse_alink_request(const char *payload, uint32_t payload_len, uint64_t *msg_id, char **params,
|
||||
uint32_t *params_len)
|
||||
{
|
||||
char *value = NULL;
|
||||
uint32_t value_len = 0;
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
if ((res = core_json_value((char *)payload, payload_len, ALINK_JSON_KEY_ID, strlen(ALINK_JSON_KEY_ID),
|
||||
&value, &value_len)) < 0 ||
|
||||
((res = core_str2uint64(value, value_len, msg_id)) < 0)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if ((res = core_json_value((char *)payload, payload_len, ALINK_JSON_KEY_PARAMS, strlen(ALINK_JSON_KEY_PARAMS),
|
||||
&value, &value_len)) < 0) {
|
||||
return res;
|
||||
}
|
||||
*params = value;
|
||||
*params_len = value_len;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _dm_recv_generic_reply_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
char *value = NULL;
|
||||
uint32_t value_len = 0;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* construct recv message */
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_GENERIC_REPLY;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv generic reply\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 2, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3, &recv.device_name) < 0) {
|
||||
break; /* must be malloc failed */
|
||||
}
|
||||
|
||||
if ((core_json_value((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
ALINK_JSON_KEY_ID, strlen(ALINK_JSON_KEY_ID), &value, &value_len)) < 0 ||
|
||||
(core_str2uint(value, value_len, &recv.data.generic_reply.msg_id)) < 0 ||
|
||||
(core_json_value((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
ALINK_JSON_KEY_CODE, strlen(ALINK_JSON_KEY_CODE), &value, &value_len)) < 0 ||
|
||||
(core_str2uint(value, value_len, &recv.data.generic_reply.code)) < 0 ||
|
||||
(core_json_value((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
ALINK_JSON_KEY_DATA, strlen(ALINK_JSON_KEY_DATA),
|
||||
&recv.data.generic_reply.data,
|
||||
&recv.data.generic_reply.data_len)) < 0) {
|
||||
|
||||
core_log(dm_handle->sysdep, SATAE_DM_LOG_PARSE_RECV_MSG_FAILED, "DM parse generic reply failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
core_json_value((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
ALINK_JSON_KEY_MESSAGE, strlen(ALINK_JSON_KEY_MESSAGE),
|
||||
&recv.data.generic_reply.message,
|
||||
&recv.data.generic_reply.message_len);
|
||||
|
||||
_append_diag_data(dm_handle, DM_DIAG_MSG_TYPE_RSP, recv.data.generic_reply.msg_id);
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
}
|
||||
|
||||
static void _dm_recv_property_set_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* construct recv message */
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_PROPERTY_SET;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv property set\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 2, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3, &recv.device_name) < 0) {
|
||||
break; /* must be malloc failed */
|
||||
}
|
||||
|
||||
if ((_dm_parse_alink_request((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
&recv.data.property_set.msg_id,
|
||||
&recv.data.property_set.params,
|
||||
&recv.data.property_set.params_len)) < 0) {
|
||||
|
||||
core_log(dm_handle->sysdep, SATAE_DM_LOG_PARSE_RECV_MSG_FAILED, "DM parse property set failed\r\n");
|
||||
break;
|
||||
}
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
}
|
||||
|
||||
static void _dm_recv_async_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_ASYNC_SERVICE_INVOKE;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv async service invoke\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 2, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3, &recv.device_name) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 6,
|
||||
&recv.data.async_service_invoke.service_id) < 0) {
|
||||
break;
|
||||
}
|
||||
if ((_dm_parse_alink_request((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
&recv.data.async_service_invoke.msg_id,
|
||||
&recv.data.async_service_invoke.params,
|
||||
&recv.data.async_service_invoke.params_len)) < 0) {
|
||||
|
||||
/* core_log(dm_handle->sysdep, SATAE_DM_LOG_PARSE_RECV_MSG_FAILED, "DM parse async servicey failed\r\n"); */
|
||||
break;
|
||||
}
|
||||
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
DM_FREE(recv.data.async_service_invoke.service_id);
|
||||
}
|
||||
|
||||
static void _dm_recv_sync_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_SYNC_SERVICE_INVOKE;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv sync service invoke\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 5, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 6, &recv.device_name) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3,
|
||||
&recv.data.sync_service_invoke.rrpc_id) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 9,
|
||||
&recv.data.sync_service_invoke.service_id) < 0) {
|
||||
break;
|
||||
}
|
||||
if ((_dm_parse_alink_request((char *)msg->data.pub.payload, msg->data.pub.payload_len,
|
||||
&recv.data.sync_service_invoke.msg_id,
|
||||
&recv.data.sync_service_invoke.params,
|
||||
&recv.data.sync_service_invoke.params_len)) < 0) {
|
||||
|
||||
core_log(dm_handle->sysdep, SATAE_DM_LOG_PARSE_RECV_MSG_FAILED, "DM parse sync service failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.data.sync_service_invoke.rrpc_id);
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
DM_FREE(recv.data.sync_service_invoke.service_id);
|
||||
}
|
||||
|
||||
static void _dm_recv_raw_data_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_RAW_DATA;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv raw data\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 2, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3, &recv.device_name) < 0) {
|
||||
break;
|
||||
}
|
||||
recv.data.raw_data.data = msg->data.pub.payload;
|
||||
recv.data.raw_data.data_len = msg->data.pub.payload_len;
|
||||
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
}
|
||||
|
||||
static void _dm_recv_up_raw_reply_data_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_RAW_DATA_REPLY;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv raw data\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 2, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3, &recv.device_name) < 0) {
|
||||
break;
|
||||
}
|
||||
recv.data.raw_data.data = msg->data.pub.payload;
|
||||
recv.data.raw_data.data_len = msg->data.pub.payload_len;
|
||||
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
}
|
||||
|
||||
static void _dm_recv_raw_sync_service_invoke_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)userdata;
|
||||
aiot_dm_recv_t recv;
|
||||
|
||||
if (NULL == dm_handle->recv_handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&recv, 0, sizeof(aiot_dm_recv_t));
|
||||
recv.type = AIOT_DMRECV_RAW_SYNC_SERVICE_INVOKE;
|
||||
|
||||
core_log(dm_handle->sysdep, STATE_DM_LOG_RECV, "DM recv raw sync service invoke\r\n");
|
||||
|
||||
do {
|
||||
if (_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 3,
|
||||
&recv.data.raw_service_invoke.rrpc_id) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 5, &recv.product_key) < 0 ||
|
||||
_dm_get_topic_level(dm_handle->sysdep, msg->data.pub.topic, msg->data.pub.topic_len, 6, &recv.device_name) < 0) {
|
||||
break;
|
||||
}
|
||||
recv.data.raw_service_invoke.data = msg->data.pub.payload;
|
||||
recv.data.raw_service_invoke.data_len = msg->data.pub.payload_len;
|
||||
|
||||
dm_handle->recv_handler(dm_handle, &recv, dm_handle->userdata);
|
||||
} while (0);
|
||||
|
||||
DM_FREE(recv.data.raw_service_invoke.rrpc_id);
|
||||
DM_FREE(recv.product_key);
|
||||
DM_FREE(recv.device_name);
|
||||
}
|
||||
|
||||
static void _dm_core_mqtt_process_handler(void *context, aiot_mqtt_event_t *event, core_mqtt_event_t *core_event)
|
||||
{
|
||||
dm_handle_t *dm_handle = (dm_handle_t *)context;
|
||||
|
||||
if (core_event != NULL) {
|
||||
switch (core_event->type) {
|
||||
case CORE_MQTTEVT_DEINIT: {
|
||||
dm_handle->mqtt_handle = NULL;
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t _dm_core_mqtt_operate_process_handler(dm_handle_t *dm_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 = _dm_core_mqtt_process_handler;
|
||||
process_data.context = dm_handle;
|
||||
|
||||
return core_mqtt_setopt(dm_handle->mqtt_handle, option, &process_data);
|
||||
}
|
||||
|
||||
void *aiot_dm_init(void)
|
||||
{
|
||||
aiot_sysdep_portfile_t *sysdep = aiot_sysdep_get_portfile();
|
||||
dm_handle_t *dm_handle = NULL;
|
||||
|
||||
if (NULL == sysdep) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dm_handle = sysdep->core_sysdep_malloc(sizeof(dm_handle_t), DATA_MODEL_MODULE_NAME);
|
||||
if (NULL == dm_handle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(dm_handle, 0, sizeof(dm_handle_t));
|
||||
dm_handle->sysdep = sysdep;
|
||||
dm_handle->post_reply = 1;
|
||||
|
||||
core_global_init(sysdep);
|
||||
return dm_handle;
|
||||
}
|
||||
|
||||
int32_t aiot_dm_setopt(void *handle, aiot_dm_option_t option, void *data)
|
||||
{
|
||||
dm_handle_t *dm_handle;
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
if (NULL == handle || NULL == data) {
|
||||
return STATE_USER_INPUT_NULL_POINTER;
|
||||
}
|
||||
if (option >= AIOT_DMOPT_MAX) {
|
||||
return STATE_USER_INPUT_OUT_RANGE;
|
||||
}
|
||||
|
||||
dm_handle = (dm_handle_t *)handle;
|
||||
|
||||
switch (option) {
|
||||
case AIOT_DMOPT_MQTT_HANDLE: {
|
||||
dm_handle->mqtt_handle = data;
|
||||
/* setup mqtt topic mapping */
|
||||
res = _dm_setup_topic_mapping(data, dm_handle);
|
||||
if (res >= STATE_SUCCESS) {
|
||||
res = _dm_core_mqtt_operate_process_handler(dm_handle, CORE_MQTTOPT_APPEND_PROCESS_HANDLER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AIOT_DMOPT_RECV_HANDLER: {
|
||||
dm_handle->recv_handler = (aiot_dm_recv_handler_t)data;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMOPT_USERDATA: {
|
||||
dm_handle->userdata = data;
|
||||
}
|
||||
break;
|
||||
case AIOT_DMOPT_POST_REPLY: {
|
||||
dm_handle->post_reply = *(uint8_t *)data;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t aiot_dm_send(void *handle, const aiot_dm_msg_t *msg)
|
||||
{
|
||||
dm_handle_t *dm_handle = NULL;
|
||||
char *topic = NULL;
|
||||
int32_t res = STATE_SUCCESS;
|
||||
|
||||
if (NULL == handle || NULL == msg) {
|
||||
return STATE_USER_INPUT_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (msg->type >= AIOT_DMMSG_MAX) {
|
||||
return STATE_USER_INPUT_OUT_RANGE;
|
||||
}
|
||||
|
||||
dm_handle = (dm_handle_t *)handle;
|
||||
if (NULL == dm_handle->mqtt_handle) {
|
||||
return STATE_DM_MQTT_HANDLE_IS_NULL;
|
||||
}
|
||||
|
||||
res = _dm_prepare_send_topic(dm_handle, msg, &topic);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = g_dm_send_topic_mapping[msg->type].func(dm_handle, topic, msg);
|
||||
dm_handle->sysdep->core_sysdep_free(topic);
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t aiot_dm_deinit(void **p_handle)
|
||||
{
|
||||
dm_handle_t *dm_handle = NULL;
|
||||
aiot_sysdep_portfile_t *sysdep = NULL;
|
||||
uint8_t i = 0;
|
||||
|
||||
if (NULL == p_handle || NULL == *p_handle) {
|
||||
return STATE_USER_INPUT_NULL_POINTER;
|
||||
}
|
||||
|
||||
dm_handle = *p_handle;
|
||||
sysdep = dm_handle->sysdep;
|
||||
*p_handle = NULL;
|
||||
|
||||
_dm_core_mqtt_operate_process_handler(dm_handle, CORE_MQTTOPT_REMOVE_PROCESS_HANDLER);
|
||||
|
||||
/* remove mqtt topic mapping */
|
||||
for (i = 0; i < sizeof(g_dm_recv_topic_mapping) / sizeof(dm_recv_topic_map_t); i++) {
|
||||
aiot_mqtt_topic_map_t topic_mapping;
|
||||
memset(&topic_mapping, 0, sizeof(aiot_mqtt_topic_map_t));
|
||||
topic_mapping.topic = g_dm_recv_topic_mapping[i].topic;
|
||||
topic_mapping.handler = g_dm_recv_topic_mapping[i].func;
|
||||
|
||||
aiot_mqtt_setopt(dm_handle->mqtt_handle, AIOT_MQTTOPT_REMOVE_TOPIC_MAP, &topic_mapping);
|
||||
}
|
||||
|
||||
sysdep->core_sysdep_free(dm_handle);
|
||||
|
||||
core_global_deinit(sysdep);
|
||||
return STATE_SUCCESS;
|
||||
}
|
||||
|
||||
681
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/aiot_dm_api.h
vendored
Normal file
681
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/aiot_dm_api.h
vendored
Normal file
@@ -0,0 +1,681 @@
|
||||
/**
|
||||
* @file aiot_dm_api.h
|
||||
* @brief 数据模型模块头文件, 提供了物模型数据格式的上云能力, 包括属性, 事件, 服务和物模型二进制格式的数据上下行能力
|
||||
* @date 2020-01-20
|
||||
*
|
||||
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 请按照以下流程使用API
|
||||
*
|
||||
* 1. 在使用物模型模块前, 用户应首先创建好一个MQTT实例
|
||||
*
|
||||
* 2. 调用`aiot_dm_init`创建一个物模型实例, 保存实例句柄
|
||||
*
|
||||
* 3. 调用`aiot_dm_setopt`配置`AIOT_DMOPT_MQTT_HANDLE`选项以设置MQTT句柄, 此选项为强制配置选项
|
||||
*
|
||||
* 4. 调用`aiot_dm_setopt`配置`AIOT_DMOPT_RECV_HANDLER`和`AIOT_DMOPT_USERDATA`选项以注册数据接受回调函数和用户上下文数据指针
|
||||
*
|
||||
* 5. 在使用`aiot_dm_send`发送消息前, 应先完成MQTT实例的建连
|
||||
*
|
||||
* 6. 调动`aiot_dm_send`发送不同类型的消息到云平台, 在注册的回调函数中处理各种类型的云平台下行消息
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AIOT_DM_API_H__
|
||||
#define __AIOT_DM_API_H__
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief -0x0A00~-0x0AFF表达SDK在data-model模块内的状态码
|
||||
*/
|
||||
#define STATE_DM_BASE (-0x0A00)
|
||||
|
||||
/**
|
||||
* @brief 用户发送@ref AIOT_DMMSG_EVENT_POST 消息时, 消息数据中的event_id为NULL
|
||||
*/
|
||||
#define STATE_DM_EVENT_ID_IS_NULL (-0x0A01)
|
||||
|
||||
/**
|
||||
* @brief 用户发送@ref AIOT_DMMSG_ASYNC_SERVICE_REPLY 或@ref AIOT_DMMSG_SYNC_SERVICE_REPLY 消息时, 消息数据中的event_id为NULL
|
||||
*/
|
||||
#define STATE_DM_SERVICE_ID_IS_NULL (-0x0A02)
|
||||
|
||||
/**
|
||||
* @brief 用户发送@ref AIOT_DMMSG_SYNC_SERVICE_REPLY 消息时, 消息数据中的rrpc_id为NULL
|
||||
*/
|
||||
#define STATE_DM_RRPC_ID_IS_NULL (-0x0A03)
|
||||
|
||||
/**
|
||||
* @brief 用户发送请求类消息时, 消息数据中的param为NULL
|
||||
*/
|
||||
#define STATE_DM_MSG_PARAMS_IS_NULL (-0X0A04)
|
||||
|
||||
/**
|
||||
* @brief 用户发送应答类消息时, 消息数据中的data为NULL
|
||||
*/
|
||||
#define STATE_DM_MSG_DATA_IS_NULL (-0X0A05)
|
||||
|
||||
/**
|
||||
* @brief 解析下行数据对应的topic时发生错误
|
||||
*/
|
||||
#define STATE_DM_INTERNAL_TOPIC_ERROR (-0x0A06)
|
||||
|
||||
/**
|
||||
* @brief 用户未调用@ref aiot_dm_setopt 配置MQTT句柄
|
||||
*/
|
||||
#define STATE_DM_MQTT_HANDLE_IS_NULL (-0x0A07)
|
||||
|
||||
/**
|
||||
* @brief 接收到服务器下行消息时的日志状态码
|
||||
*/
|
||||
#define STATE_DM_LOG_RECV (-0x0A08)
|
||||
|
||||
/**
|
||||
* @brief 解析服务器下行消息失败时的日志状态码
|
||||
*/
|
||||
#define SATAE_DM_LOG_PARSE_RECV_MSG_FAILED (-0x0A09)
|
||||
|
||||
|
||||
/**
|
||||
* @brief data-model模块的配置选项枚举类型定义. @ref aiot_dm_setopt 函数入数data的数据类型根据不同的选项而不同
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief 模块依赖的MQTT句柄
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* data-model模块依赖底层的MQTT模块, 用户必需配置正确的MQTT句柄, 否则无法正常工作
|
||||
*
|
||||
* 数据类型: (void *)
|
||||
*/
|
||||
AIOT_DMOPT_MQTT_HANDLE,
|
||||
|
||||
/**
|
||||
* @brief 数据接收回调函数, data-model接收物联网平台的下行消息后调用此回调函数
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 数据类型: (aiot_dm_recv_handler_t), 详细查看@ref aiot_dm_recv_handler_t 回调函数原型
|
||||
*/
|
||||
AIOT_DMOPT_RECV_HANDLER,
|
||||
|
||||
/**
|
||||
* @brief 指向用户上下文数据的指针
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 在用户注册的@ref aiot_dm_recv_handler_t 数据接收回调函数中会同过userdata参数将此指针返回给用户
|
||||
*
|
||||
* 数据类型: (void *)
|
||||
*/
|
||||
AIOT_DMOPT_USERDATA,
|
||||
|
||||
/**
|
||||
* @brief 用户是否希望接收post消息后的reply
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 是否要接收云端的reply消息. 1表示要接收, 0表示不要.
|
||||
*
|
||||
* 数据类型: (uint8_t) *)
|
||||
*/
|
||||
AIOT_DMOPT_POST_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 配置选项数量最大值, 不可用作配置参数
|
||||
*/
|
||||
AIOT_DMOPT_MAX,
|
||||
} aiot_dm_option_t;
|
||||
|
||||
/**
|
||||
* @brief data-model模块发送消息类型
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 这个枚举类型包括了dm模块支持发送的所有数据类型, 不同的消息类型将对于不同的消息结构体
|
||||
* 用户可查看网页文档<a href="https://help.aliyun.com/document_detail/89301.html">设备属性/事件/服务</a>进一步了解各种数据类型
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief 属性上报, 消息结构体参考@ref aiot_dm_msg_property_post_t \n
|
||||
* 成功发送此消息后, 将会收到@ref AIOT_DMRECV_GENERIC_REPLY 类型的应答消息
|
||||
*/
|
||||
AIOT_DMMSG_PROPERTY_POST,
|
||||
|
||||
/**
|
||||
* @brief 事件上报, 消息结构体参考@ref aiot_dm_msg_event_post_t \n
|
||||
* 成功发送此消息后, 将会收到@ref AIOT_DMRECV_GENERIC_REPLY 类型的应答消息
|
||||
*/
|
||||
AIOT_DMMSG_EVENT_POST,
|
||||
|
||||
/**
|
||||
* @brief 属性设置应答, 消息结构体参考@ref aiot_dm_msg_property_set_reply_t
|
||||
*/
|
||||
AIOT_DMMSG_PROPERTY_SET_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 异步服务应答, 消息结构体参考@ref aiot_dm_msg_async_service_reply_t
|
||||
*/
|
||||
AIOT_DMMSG_ASYNC_SERVICE_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 同步服务应答, 消息结构体参考@ref aiot_dm_msg_sync_service_reply_t
|
||||
*/
|
||||
AIOT_DMMSG_SYNC_SERVICE_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 二进制格式的物模型上行数据, 消息结构体参考@ref aiot_dm_msg_raw_data_t
|
||||
*/
|
||||
AIOT_DMMSG_RAW_DATA,
|
||||
|
||||
/**
|
||||
* @brief 二进制格式的同步服务应答, 消息结构体参考@ref aiot_dm_msg_raw_service_reply_t
|
||||
*/
|
||||
AIOT_DMMSG_RAW_SERVICE_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 获取期望属性值, 消息结构体请参考@ref aiot_dm_msg_get_desired_t, \n
|
||||
* 成功发送此消息后, 将会收到@ref AIOT_DMRECV_GENERIC_REPLY 类型的应答消息
|
||||
*/
|
||||
AIOT_DMMSG_GET_DESIRED,
|
||||
|
||||
/**
|
||||
* @brief 清除指定的期望值, 消息结构体请参考@ref aiot_dm_msg_delete_desired_t \n
|
||||
* 成功发送此消息后, 将会收到@ref AIOT_DMRECV_GENERIC_REPLY 类型的应答消息
|
||||
*/
|
||||
AIOT_DMMSG_DELETE_DESIRED,
|
||||
|
||||
/**
|
||||
* @brief 清除指定的期望值, 消息结构体请参考@ref aiot_dm_msg_delete_desired_t \n
|
||||
* 成功发送此消息后, 将会收到@ref AIOT_DMRECV_GENERIC_REPLY 类型的应答消息
|
||||
*/
|
||||
AIOT_DMMSG_PROPERTY_BATCH_POST,
|
||||
|
||||
/**
|
||||
* @brief 消息数量最大值, 不可用作消息类型
|
||||
*/
|
||||
AIOT_DMMSG_MAX,
|
||||
} aiot_dm_msg_type_t;
|
||||
|
||||
/**
|
||||
* @brief <b>物模型属性上报</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>. 包含用户要上报的属性数据, 如<i>"{\"LightSwitch\":0}"</i>
|
||||
*/
|
||||
char *params;
|
||||
} aiot_dm_msg_property_post_t;
|
||||
|
||||
/**
|
||||
* @brief <b>物模型事件上报</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 事件标示符, <b>必须为以结束符'\0'结尾的字符串</b>
|
||||
*/
|
||||
char *event_id;
|
||||
/**
|
||||
* @brief 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>. 包含用户要上报的事件数据, 如<i>"{\"ErrorNum\":0}"</i>
|
||||
*/
|
||||
char *params;
|
||||
} aiot_dm_msg_event_post_t;
|
||||
|
||||
/**
|
||||
* @brief <b>属性设置应答</b>消息结构体, 用户在收到@ref AIOT_DMRECV_PROPERTY_SET 类型的属性设置后, 可发送此消息进行回复
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数, <b>必须与属性设置的消息标示符一致</b>
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief 设备端状态码, 200-请求成功, 更多状态码查看<a href="https://help.aliyun.com/document_detail/89309.html">设备端通用code</a>
|
||||
*/
|
||||
uint32_t code;
|
||||
/**
|
||||
* @brief 设备端应答数据, 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>, 如<i>"{}"</i>表示应答数据为空
|
||||
*/
|
||||
char *data;
|
||||
} aiot_dm_msg_property_set_reply_t;
|
||||
|
||||
/**
|
||||
* @brief <b>异步服务应答</b>消息结构体, 用户在收到@ref AIOT_DMRECV_ASYNC_SERVICE_INVOKE 类型的异步服务调用消息后, 应发送此消息进行应答
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数, <b>必须与异步服务调用的消息标示符一致</b>
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief 服务标示符, 标识了要响应服务
|
||||
*/
|
||||
char *service_id;
|
||||
/**
|
||||
* @brief 设备端状态码, 200-请求成功, 更多状态码查看<a href="https://help.aliyun.com/document_detail/89309.html">设备端通用code</a>
|
||||
*/
|
||||
uint32_t code;
|
||||
/**
|
||||
* @brief 设备端应答数据, 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>, 如<i>"{}"</i>表示应答数据为空
|
||||
*/
|
||||
char *data;
|
||||
} aiot_dm_msg_async_service_reply_t;
|
||||
|
||||
/**
|
||||
* @brief <b>同步服务应答</b>消息结构体, 用户在收到@ref AIOT_DMRECV_SYNC_SERVICE_INVOKE 类型的同步服务调用消息后, 应在超时时间(默认7s)内进行应答
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数, <b>必须与同步服务调用的消息标示符一致</b>
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief RRPC标示符, 用于唯一标识每一个同步服务的字符串, <b>必须与同步服务调用消息的RRPC标示符一致</b>
|
||||
*/
|
||||
char *rrpc_id;
|
||||
/**
|
||||
* @brief 服务标示符, 标识了要响应服务
|
||||
*/
|
||||
char *service_id;
|
||||
/**
|
||||
* @brief 设备端状态码, 200-请求成功, 更多状态码查看<a href="https://help.aliyun.com/document_detail/89309.html">设备端通用code</a>
|
||||
*/
|
||||
uint32_t code;
|
||||
/**
|
||||
* @brief 设备端应答数据, 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>, 如<i>"{}"</i>表示应答数据为空
|
||||
*/
|
||||
char *data;
|
||||
} aiot_dm_msg_sync_service_reply_t;
|
||||
|
||||
/**
|
||||
* @brief <b>物模型二进制数据</b>消息结构体, 发送的二进制数据将通过物联网平台的JavaScript脚本转化为JSON格式数据, 用户发送此消息前应确保已正确启用云端解析脚本
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 指向待发送二进制数据的指针
|
||||
*/
|
||||
uint8_t *data;
|
||||
/**
|
||||
* @brief 待发送数据的长度
|
||||
*/
|
||||
uint32_t data_len;
|
||||
} aiot_dm_msg_raw_data_t;
|
||||
|
||||
/**
|
||||
* @brief <b>二进制格式的同步服务应答</b>消息结构体, 用户在收到@ref AIOT_DMRECV_RAW_SYNC_SERVICE_INVOKE 类型消息后, 应在超时时间(默认7s)内进行应答\n
|
||||
* 用户在使用此消息前应确保已启用云端解析脚本, 并且脚本工作正常
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief RRPC标示符, 特殊字符串, <b>必须与同步服务调用消息的RRPC标示符一致</b>
|
||||
*/
|
||||
char *rrpc_id;
|
||||
/**
|
||||
* @brief 指向待发送二进制数据的指针
|
||||
*/
|
||||
uint8_t *data;
|
||||
/**
|
||||
* @brief 待发送数据的长度
|
||||
*/
|
||||
uint32_t data_len;
|
||||
} aiot_dm_msg_raw_service_reply_t;
|
||||
|
||||
/**
|
||||
* @brief <b>获取期望属性值</b>消息结构体, 发送
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 字符串形式的JSON<b>数组</b>, <b>必须以结束符'\0'结尾</b>. 应包含用户要获取的期望属性的ID, 如<i>"[\"LightSwitch\"]"</i>
|
||||
*/
|
||||
char *params;
|
||||
} aiot_dm_msg_get_desired_t;
|
||||
|
||||
/**
|
||||
* @brief <b>删除指定期望值</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>. 应包含用户要删除的期望属性的ID和期望值版本号, 如<i>"{\"LightSwitch\":{\"version\":1},\"Color\":{}}"</i>
|
||||
*/
|
||||
char *params;
|
||||
} aiot_dm_msg_delete_desired_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief <b>物模型属性上报</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 字符串形式的JSON结构体, <b>必须以结束符'\0'结尾</b>. 包含用户要批量上报的属性和事件数据, 如 {"properties":{"Power": [ { "value": "on", "time": 1524448722000 },
|
||||
* { "value": "off", "time": 1524448722001 } ], "WF": [ { "value": 3, "time": 1524448722000 }]}, "events": {"alarmEvent": [{ "value": { "Power": "on", "WF": "2"},
|
||||
* "time": 1524448722000}]}}
|
||||
*/
|
||||
char *params;
|
||||
} aiot_dm_msg_property_batch_post_t;
|
||||
|
||||
/**
|
||||
* @brief data-model模块发送消息的消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息所属设备的product_key, 若为NULL则使用通过aiot_dm_setopt配置的product_key\n
|
||||
* 在网关子设备场景下, 可通过指定为子设备的product_key来发送子设备的消息到云端
|
||||
*/
|
||||
char *product_key;
|
||||
/**
|
||||
* @brief 消息所属设备的device_name, 若为NULL则使用通过aiot_dm_setopt配置的device_name\n
|
||||
* 在网关子设备场景下, 可通过指定为子设备的product_key来发送子设备的消息到云端
|
||||
*/
|
||||
char *device_name;
|
||||
/**
|
||||
* @brief 消息类型, 可参考@ref aiot_dm_msg_type_t
|
||||
*/
|
||||
aiot_dm_msg_type_t type;
|
||||
/**
|
||||
* @brief 消息数据联合体, 不同的消息类型将使用不同的消息结构体
|
||||
*/
|
||||
union {
|
||||
aiot_dm_msg_property_post_t property_post;
|
||||
aiot_dm_msg_event_post_t event_post;
|
||||
aiot_dm_msg_property_set_reply_t property_set_reply;
|
||||
aiot_dm_msg_sync_service_reply_t sync_service_reply;
|
||||
aiot_dm_msg_async_service_reply_t async_service_reply;
|
||||
aiot_dm_msg_raw_data_t raw_data;
|
||||
aiot_dm_msg_raw_service_reply_t raw_service_reply;
|
||||
aiot_dm_msg_get_desired_t get_desired;
|
||||
aiot_dm_msg_delete_desired_t delete_desired;
|
||||
} data;
|
||||
} aiot_dm_msg_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief data-model模块接受消息类型枚举
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* 这个枚举类型包括了dm模块支持接收的所有数据类型, 不同的消息类型将对于不同的消息结构体
|
||||
* 用户可查看网页文档<a href="https://help.aliyun.com/document_detail/89301.html">设备属性/事件/服务</a>进一步了解各种数据类型
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief 上报属性/实践后服务器返回的应答消息, 消息数据结构体参考@ref aiot_dm_recv_generic_reply_t
|
||||
*/
|
||||
AIOT_DMRECV_GENERIC_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 服务器下发的属性设置消息, 消息数据结构体参考@ref aiot_dm_recv_property_set_t
|
||||
*/
|
||||
AIOT_DMRECV_PROPERTY_SET,
|
||||
|
||||
/**
|
||||
* @brief 服务器下发的异步服务调用消息, 消息数据结构体参考@ref aiot_dm_recv_async_service_invoke_t
|
||||
*/
|
||||
AIOT_DMRECV_ASYNC_SERVICE_INVOKE,
|
||||
|
||||
/**
|
||||
* @brief 服务器下发的同步服务调用消息, 消息数据结构体参考@ref aiot_dm_recv_sync_service_invoke_t
|
||||
*/
|
||||
AIOT_DMRECV_SYNC_SERVICE_INVOKE,
|
||||
|
||||
/**
|
||||
* @brief 服务器对设备上报的二进制数据应答, 消息数据结构体参考@ref aiot_dm_recv_raw_data_t
|
||||
*/
|
||||
AIOT_DMRECV_RAW_DATA_REPLY,
|
||||
|
||||
/**
|
||||
* @brief 服务器下发的物模型二进制数据, 消息数据结构体参考@ref aiot_dm_recv_raw_data_t
|
||||
*/
|
||||
AIOT_DMRECV_RAW_DATA,
|
||||
|
||||
/**
|
||||
* @brief 服务器下发的二进制格式的同步服务调用消息, 消息数据结构体参考@ref aiot_dm_recv_raw_service_invoke_t
|
||||
*/
|
||||
AIOT_DMRECV_RAW_SYNC_SERVICE_INVOKE,
|
||||
|
||||
/**
|
||||
* @brief 消息数量最大值, 不可用作消息类型
|
||||
*/
|
||||
AIOT_DMRECV_MAX,
|
||||
} aiot_dm_recv_type_t;
|
||||
|
||||
/**
|
||||
* @brief <b>云端通用应答</b>消息结构体, 设备端上报@ref AIOT_DMMSG_PROPERTY_POST, @ref AIOT_DMMSG_EVENT_POST 或者@ref AIOT_DMMSG_GET_DESIRED 等消息后, 服务器会应答此消息
|
||||
*/
|
||||
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_dm_recv_generic_reply_t;
|
||||
|
||||
/**
|
||||
* @brief <b>属性设置</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief 服务器下发的属性数据, 为字符串形式的JSON结构体, 此字符串<b>不</b>以结束符'\0'结尾, 如<i>"{\"LightSwitch\":0}"</i>
|
||||
*/
|
||||
char *params;
|
||||
/**
|
||||
* @brief 属性数据的字符串长度
|
||||
*/
|
||||
uint32_t params_len;
|
||||
} aiot_dm_recv_property_set_t;
|
||||
|
||||
/**
|
||||
* @brief <b>同步服务调用</b>消息结构体, 用户收到同步服务后, 必须在超时时间(默认7s)内进行应答
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief RRPC标识符, 用于唯一标识每一个同步服务的特殊字符串
|
||||
*/
|
||||
char *rrpc_id;
|
||||
/**
|
||||
* @brief 服务标示符, 字符串内容由用户定义的物模型决定
|
||||
*/
|
||||
char *service_id;
|
||||
/**
|
||||
* @brief 服务调用的输入参数数据, 为字符串形式的JSON结构体, 此字符串<b>不</b>以结束符'\0'结尾, 如<i>"{\"LightSwitch\":0}"</i>
|
||||
*/
|
||||
char *params;
|
||||
/**
|
||||
* @brief 输入参数的字符串长度
|
||||
*/
|
||||
uint32_t params_len;
|
||||
} aiot_dm_recv_sync_service_invoke_t;
|
||||
|
||||
/**
|
||||
* @brief <b>同步服务调用</b>消息结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息标识符, uint64_t类型的整数
|
||||
*/
|
||||
uint64_t msg_id;
|
||||
/**
|
||||
* @brief 服务标示符, 字符串内容由用户定义的物模型决定
|
||||
*/
|
||||
char *service_id;
|
||||
/**
|
||||
* @brief 服务调用的输入参数数据, 为字符串形式的JSON结构体, 此字符串<b>不</b>以结束符'\0'结尾, 如<i>"{\"LightSwitch\":0}"</i>
|
||||
*/
|
||||
char *params;
|
||||
/**
|
||||
* @brief 输入参数的字符串长度
|
||||
*/
|
||||
uint32_t params_len;
|
||||
} aiot_dm_recv_async_service_invoke_t;
|
||||
|
||||
/**
|
||||
* @brief <b>物模型二进制数据</b>消息结构体, 服务器的JSON格式物模型数据将通过物联网平台的JavaScript脚本转化为二进制数据, 用户在接收此消息前应确保已正确启用云端解析脚本
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 指向接受数据缓冲区的指针
|
||||
*/
|
||||
uint8_t *data;
|
||||
/**
|
||||
* @brief 二进制数据的长度
|
||||
*/
|
||||
uint32_t data_len;
|
||||
} aiot_dm_recv_raw_data_t;
|
||||
|
||||
/**
|
||||
* @brief <b>二进制数据的同步服务调用</b>消息结构体, 服务器的JSON格式物模型数据将通过物联网平台的JavaScript脚本转化为二进制数据, 用户在接收此消息前应确保已正确启用云端解析脚本
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief RRPC标识符, 用于唯一标识每一个同步服务的特殊字符串
|
||||
*/
|
||||
char *rrpc_id;
|
||||
/**
|
||||
* @brief 指向接受数据缓冲区的指针
|
||||
*/
|
||||
uint8_t *data;
|
||||
/**
|
||||
* @brief 二进制数据的长度
|
||||
*/
|
||||
uint32_t data_len;
|
||||
} aiot_dm_recv_raw_service_invoke_t;
|
||||
|
||||
/**
|
||||
* @brief data-model模块接收消息的结构体
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief 消息所属设备的product_key, 不配置则默认使用MQTT模块配置的product_key
|
||||
*/
|
||||
char *product_key;
|
||||
/**
|
||||
* @brief 消息所属设备的device_name, 不配置则默认使用MQTT模块配置的device_name
|
||||
*/
|
||||
char *device_name;
|
||||
/**
|
||||
* @brief 接收消息的类型, 可参考@ref aiot_dm_recv_type_t
|
||||
*/
|
||||
aiot_dm_recv_type_t type;
|
||||
/**
|
||||
* @brief 消息数据联合体, 不同的消息类型将使用不同的消息结构体
|
||||
*/
|
||||
union {
|
||||
aiot_dm_recv_generic_reply_t generic_reply;
|
||||
aiot_dm_recv_property_set_t property_set;
|
||||
aiot_dm_recv_async_service_invoke_t async_service_invoke;
|
||||
aiot_dm_recv_sync_service_invoke_t sync_service_invoke;
|
||||
aiot_dm_recv_raw_data_t raw_data;
|
||||
aiot_dm_recv_raw_service_invoke_t raw_service_invoke;
|
||||
} data;
|
||||
} aiot_dm_recv_t;
|
||||
|
||||
/**
|
||||
* @brief data-model模块消息接收回调函数的函数原型定义, 当模块接收到服务器下行数据后将调用此回调函数, 并将消息数据通过<i>recv</i>参数输入给用户, \n
|
||||
* 同时将用户上下文数据指针通过<i>userdata</i>参数返回给用户
|
||||
*
|
||||
* @param[in] handle data-model实例句柄
|
||||
* @param[in] recv 服务下发的消息数据, <b>消息结构体中的所有数据指针在离开回调函数后将失效, 保存消息数据必须使用内存复制的方式</b>
|
||||
* @param[in] userdata 指向用户上下文数据的指针, 这个指针由用户通过调用@ref aiot_dm_setopt 配置@ref AIOT_DMOPT_USERDATA 选项设置
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
typedef void (*aiot_dm_recv_handler_t)(void *handle, const aiot_dm_recv_t *recv, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief 初始化data-model实例
|
||||
*
|
||||
* @return void*
|
||||
* @retval 非NULL data-model实例句柄
|
||||
* @retval NULL 初始化失败, 一般是内存分配失败导致
|
||||
*/
|
||||
void *aiot_dm_init(void);
|
||||
|
||||
/**
|
||||
* @brief 设置data-model参数
|
||||
*
|
||||
* @param[in] handle data-model实例句柄
|
||||
* @param[in] option 配置选项, 更多信息请查看@ref aiot_dm_option_t
|
||||
* @param[in] data 配置数据, 更多信息请查看@ref aiot_dm_option_t
|
||||
*
|
||||
* @return int32_t
|
||||
* @retval STATE_SUCCESS 参数配置成功
|
||||
* @retval STATE_USER_INPUT_NULL_POINTER 入参handle或data为NULL
|
||||
* @retval STATE_USER_INPUT_OUT_RANGE 入参optioin的枚举值>=AIOT_DMOPT_MAX
|
||||
* @retval others 参考@ref aiot_state_api.h
|
||||
*
|
||||
*/
|
||||
int32_t aiot_dm_setopt(void *handle, aiot_dm_option_t option, void *data);
|
||||
|
||||
/**
|
||||
* @brief 发送一条data-model消息到物联网平台, 消息类型和消息数据由msg入参决定
|
||||
*
|
||||
* @param[in] handle data-model实例句柄
|
||||
* @param[in] msg 消息结构体, 可指定发送消息的设备<i>productKey</i>, <i>deviceName</i>; 消息类型, 消息数据等, 更多信息请参考@ref aiot_dm_msg_t
|
||||
*
|
||||
* @return int32_t
|
||||
* @retval >=STATE_SUCCESS 消息发送成功, 对于@ref AIOT_DMMSG_PROPERTY_POST, @ref AIOT_DMMSG_EVENT_POST, @ref AIOT_DMMSG_GET_DESIRED 和@ref AIOT_DMMSG_DELETE_DESIRED 消息, \n
|
||||
* 发送成功返回值为>STATE_SUCCESS的消息标示符<i>msg_id</i>值
|
||||
* @retval STATE_USER_INPUT_NULL_POINTER 入参<i>handle</i>或<i>msg</i>为NULL
|
||||
* @retval STATE_USER_INPUT_OUT_RANGE 入参<i>msg</i>的结构体成员<i>type</i> >= AIOT_DMMSG_MAX
|
||||
* @retval STATE_SYS_DEPEND_MALLOC_FAILED 内存分配失败
|
||||
* @retval STATE_DM_MQTT_HANDLE_IS_NULL 用户未调用@ref aiot_dm_setopt 配置MQTT句柄
|
||||
* @retval others 参考@ref aiot_state_api.h 或@ref STATE_DM_BASE 中对应的错误码说明
|
||||
*
|
||||
*/
|
||||
int32_t aiot_dm_send(void *handle, const aiot_dm_msg_t *msg);
|
||||
|
||||
/**
|
||||
* @brief 销毁data-model实例, 释放资源
|
||||
*
|
||||
* @param[in] p_handle 指向data-model实例句柄的指针
|
||||
* @return int32_t
|
||||
* @retval STATE_SUCCESS 执行成功
|
||||
* @retval <STATE_SUCCESS 执行失败
|
||||
*
|
||||
*/
|
||||
int32_t aiot_dm_deinit(void **p_handle);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef __AIOT_DM_API_H__ */
|
||||
|
||||
78
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/dm_private.h
vendored
Normal file
78
sdk/合宙/air780e/csdk/luatos-soc-2022/thirdparty/linksdk/components/data-model/dm_private.h
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file dm_private.h
|
||||
* @brief 数据模型模块内部头文件
|
||||
* @date 2020-01-20
|
||||
*
|
||||
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DM_PRIVATE_H__
|
||||
#define __DM_PRIVATE_H__
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "core_stdinc.h"
|
||||
#include "core_string.h"
|
||||
#include "core_log.h"
|
||||
#include "core_diag.h"
|
||||
#include "core_global.h"
|
||||
#include "core_mqtt.h"
|
||||
|
||||
#include "aiot_sysdep_api.h"
|
||||
#include "aiot_state_api.h"
|
||||
#include "aiot_mqtt_api.h"
|
||||
#include "aiot_dm_api.h"
|
||||
|
||||
/* 模块内部名 */
|
||||
#define DATA_MODEL_MODULE_NAME "dm"
|
||||
|
||||
/* ALINK请求的JSON格式 */
|
||||
#define ALINK_REQUEST_FMT "{\"id\":\"%s\",\"version\":\"1.0\",\"params\":%s,\"sys\":{\"ack\":%s}}"
|
||||
/* ALINK应答的JSON格式 */
|
||||
#define ALINK_RESPONSE_FMT "{\"id\":\"%s\",\"code\":%s,\"data\":%s}"
|
||||
#define ALINK_JSON_KEY_ID "id"
|
||||
#define ALINK_JSON_KEY_CODE "code"
|
||||
#define ALINK_JSON_KEY_PARAMS "params"
|
||||
#define ALINK_JSON_KEY_DATA "data"
|
||||
#define ALINK_JSON_KEY_MESSAGE "message"
|
||||
|
||||
/* 诊断消息类型 */
|
||||
#define DM_DIAG_MSG_TYPE_REQ (0x00)
|
||||
#define DM_DIAG_MSG_TYPE_RSP (0x01)
|
||||
|
||||
#define DM_FREE(ptr) do {if (ptr) {dm_handle->sysdep->core_sysdep_free(ptr); ptr = NULL;}} while (0)
|
||||
|
||||
/* data-model模块的上下文结构体定义 */
|
||||
typedef struct {
|
||||
aiot_sysdep_portfile_t *sysdep;
|
||||
void *mqtt_handle;
|
||||
|
||||
aiot_dm_recv_handler_t recv_handler;
|
||||
void *userdata;
|
||||
uint8_t post_reply;
|
||||
} dm_handle_t;
|
||||
|
||||
/* data-model内部发送函数原型定义 */
|
||||
typedef int32_t (*dm_msg_send_func_t)(dm_handle_t *handle, const char *topic, const aiot_dm_msg_t *msg);
|
||||
|
||||
/* 包含上行topic和对应处理函数的结构体定义 */
|
||||
typedef struct {
|
||||
char *topic;
|
||||
dm_msg_send_func_t func;
|
||||
} dm_send_topic_map_t;
|
||||
|
||||
/* 包含下行topic和对应处理函数的结构体定义 */
|
||||
typedef struct {
|
||||
char *topic;
|
||||
aiot_mqtt_recv_handler_t func;
|
||||
} dm_recv_topic_map_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef __DM_PRIVATE_H__ */
|
||||
|
||||
Reference in New Issue
Block a user