更新硬件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: 设备诊断模块
DIAG Component for Link SDK V4.0.0

View File

@@ -0,0 +1,763 @@
/**
* @file aiot_diag_api.c
* @brief diag模块的API接口实现, 提供诊断SDK的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#include "diag_private.h"
#include "core_string.h"
#include "core_log.h"
#include "core_global.h"
#include "core_mqtt.h"
#include "core_diag.h"
static void _diag_mqtt_conn_hb_extra_clean(void *handle, void *extra_data);
static int32_t _diag_mqtt_conn_hb_extra_stop(void *handle, diag_running_state_node_t *node, uint32_t stat_idx,
uint32_t stat_number, void *extra_data);
static int32_t _diag_mqtt_conn_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc);
static int32_t _diag_mqtt_hb_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc);
static void _diag_alink_uplink_extra_clean(void *handle, void *extra_data);
static int32_t _diag_alink_uplink_extra_stop(void *handle, diag_running_state_node_t *node, uint32_t stat_idx,
uint32_t stat_number, void *extra_data);
static int32_t _diag_alink_uplink_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc);
static diag_config_t g_diag_config[] = {
{
DIAG_MQTT_CONNECTION_STAT_INDEX,
DIAG_MQTT_CONNECTION_NAME_STR,
DIAG_TLV_MQTT_CONNECTION,
{
DIAG_DEFAULT_MQTT_CONN_ENABLED,
DIAG_DEFAULT_MQTT_CONN_INTERVAL_MS,
DIAG_DEFAULT_MQTT_CONN_WARNING_THRESHOLD,
DIAG_DEFAULT_MQTT_CONN_FATAL_THRESHOLD,
},
DIAG_DEFAULT_MQTT_CONN_MAX_STAT_NUMBER,
{
_diag_mqtt_conn_hb_extra_clean,
_diag_mqtt_conn_hb_extra_stop,
_diag_mqtt_conn_report_desc_append
},
1
},
{
DIAG_MQTT_HEARTBEAT_STAT_INDEX,
DIAG_MQTT_HEARTBEAT_NAME_STR,
DIAG_TLV_MQTT_HEARTBEAT,
{
DIAG_DEFAULT_MQTT_HB_ENABLED,
DIAG_DEFAULT_MQTT_HB_INTERVAL_MS,
DIAG_DEFAULT_MQTT_HB_WARNING_THRESHOLD,
DIAG_DEFAULT_MQTT_HB_FATAL_THRESHOLD
},
DIAG_DEFAULT_MQTT_HB_MAX_STAT_NUMBER,
{
_diag_mqtt_conn_hb_extra_clean,
_diag_mqtt_conn_hb_extra_stop,
_diag_mqtt_hb_report_desc_append,
},
0
},
{
DIAG_ALINK_UPLINK_STAT_INDEX,
DIAG_ALINK_UPLINK_NAME_STR,
DIAG_TLV_ALINK_UPLINK,
{
DIAG_DEFAULT_ALINK_UPLINK_ENABLED,
DIAG_DEFAULT_ALINK_UPLINK_INTERVAL_MS,
DIAG_DEFAULT_ALINK_UPLINK_WARNING_THRESHOLD,
DIAG_DEFAULT_ALINK_UPLINK_FATAL_THRESHOLD
},
DIAG_DEFAULT_ALINK_UPLINK_MAX_STAT_NUMBER,
{
_diag_alink_uplink_extra_clean,
_diag_alink_uplink_extra_stop,
_diag_alink_uplink_report_desc_append
},
0
}
};
static void _core_diag_exec_inc(diag_handle_t *diag_handle)
{
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
diag_handle->exec_count++;
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
}
static void _core_diag_exec_dec(diag_handle_t *diag_handle)
{
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
diag_handle->exec_count--;
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
}
static void _diag_desc_list_append(diag_handle_t *diag_handle, diag_stat_t *stat,
diag_running_state_node_t *running_state_node, struct core_list_head *desc_list)
{
int32_t res = STATE_SUCCESS;
char *desc = NULL;
diag_desc_node_t *node = NULL;
res = stat->stat_cb.desc_append_cb(diag_handle, &stat->running_state, running_state_node, &desc);
if (res < STATE_SUCCESS) {
return;
}
node = diag_handle->sysdep->core_sysdep_malloc(sizeof(diag_desc_node_t), DIAG_MODULE_NAME);
if (node == NULL) {
diag_handle->sysdep->core_sysdep_free(desc);
return;
}
memset(node, 0, sizeof(diag_desc_node_t));
node->timestamp = core_log_get_timestamp(diag_handle->sysdep);
node->code = stat->running_state.code;
node->module_name = stat->running_state.name;
node->level = (stat->running_state.is_reported == 0) ? (running_state_node->level) : (DIAG_REPORT_LEVEL_WARNING_STR);
node->desc = desc;
node->qos = stat->running_state.qos;
CORE_INIT_LIST_HEAD(&node->linked_node);
core_list_add_tail(&node->linked_node, desc_list);
}
static void _diag_desc_list_send(diag_handle_t *diag_handle, struct core_list_head *desc_list)
{
diag_desc_node_t *node = NULL;
core_list_for_each_entry(node, desc_list, linked_node, diag_desc_node_t) {
/* local event notify */
if ((diag_handle->event_handler != NULL) && (diag_handle->local_report_enabled == 1)) {
aiot_diag_event_t event;
memset(&event, 0, sizeof(aiot_diag_event_t));
event.type = AIOT_DIAGEVT_ALERT;
event.data.alert.module_name = node->module_name;
event.data.alert.level = node->level;
event.data.alert.desc = node->desc;
diag_handle->event_handler(diag_handle, &event, diag_handle->userdata);
}
/* cloud event report */
if (diag_handle->cloud_report_enabled == 1) {
int32_t res = STATE_SUCCESS;
char *topic = NULL, *topic_fmt = DIAG_REPORT_TOPIC_FMT;
char *topic_src[] = { core_mqtt_get_product_key(diag_handle->mqtt_handle), core_mqtt_get_device_name(diag_handle->mqtt_handle) };
int32_t alink_id = 0;
char alink_id_str[11] = {0}, utc_time_str[21] = {0}, code_str[11] = {0};
char *payload = NULL, *payload_fmt = DIAG_REPORT_PAYLOAD_FMT;
char *payload_src[] = { alink_id_str, utc_time_str, node->level, node->module_name, code_str, alink_id_str, node->desc };
res = core_sprintf(diag_handle->sysdep, &topic, topic_fmt, topic_src, sizeof(topic_src) / sizeof(char *),
DIAG_MODULE_NAME);
if (res < STATE_SUCCESS) {
continue;
}
core_global_alink_id_next(diag_handle->sysdep, &alink_id);
core_int2str(alink_id, alink_id_str, NULL);
core_uint642str(node->timestamp, utc_time_str, NULL);
core_uint2str(node->code, code_str, NULL);
res = core_sprintf(diag_handle->sysdep, &payload, payload_fmt, payload_src, sizeof(payload_src) / sizeof(char *),
DIAG_MODULE_NAME);
if (res < STATE_SUCCESS) {
diag_handle->sysdep->core_sysdep_free(topic);
continue;
}
res = aiot_mqtt_pub(diag_handle->mqtt_handle, topic, (uint8_t *)payload, (uint32_t)strlen(payload), node->qos);
if (res < STATE_SUCCESS) {
core_log(diag_handle->sysdep, STATE_DIAG_PUB_FAILED, "pub failed\r\n");
}
diag_handle->sysdep->core_sysdep_free(topic);
diag_handle->sysdep->core_sysdep_free(payload);
}
}
}
static void _diag_desc_list_destroy(diag_handle_t *diag_handle, struct core_list_head *desc_list)
{
diag_desc_node_t *node = NULL, *next = NULL;
core_list_for_each_entry_safe(node, next, desc_list, linked_node, diag_desc_node_t) {
core_list_del(&node->linked_node);
diag_handle->sysdep->core_sysdep_free(node->desc);
diag_handle->sysdep->core_sysdep_free(node);
}
}
static void _diag_core_mqtt_process_handler(void *context, aiot_mqtt_event_t *event, core_mqtt_event_t *core_event)
{
uint32_t stat_idx = 0;
diag_handle_t *diag_handle = (diag_handle_t *)context;
uint64_t timenow_ms = core_log_get_timestamp(diag_handle->sysdep);
if (core_event != NULL) {
switch (core_event->type) {
case CORE_MQTTEVT_DEINIT: {
diag_handle->mqtt_handle = NULL;
return;
}
break;
default: {
}
break;
}
}
if (diag_handle->mqtt_process.last_check_time > timenow_ms) {
diag_handle->mqtt_process.last_check_time = timenow_ms;
}
if (timenow_ms - diag_handle->mqtt_process.last_check_time >= DIAG_MQTT_PROCESS_CHECK_INTERVAL_MS) {
diag_running_state_node_t *node = NULL;
struct core_list_head desc_list;
CORE_INIT_LIST_HEAD(&desc_list);
for (stat_idx = 0; stat_idx < DIAG_STAT_ITEM_NUMBER; stat_idx++) {
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->diag_stat[stat_idx].running_state.mutex);
diag_handle->diag_stat[stat_idx].running_state.alert_counts = 0;
core_list_for_each_entry(node, &diag_handle->diag_stat[stat_idx].running_state.linked_list,
linked_node, diag_running_state_node_t) {
if ((node->stop_time != 0) && (node->start_time > node->stop_time)) {
node->start_time = node->stop_time;
}
if (node->is_diag == 1) {
if (node->start_time > timenow_ms) {
node->start_time = timenow_ms;
}
if (node->stop_time == 0
&& (timenow_ms - node->start_time >= diag_handle->diag_stat[stat_idx].config.fatal_threshold)) {
node->stop_time = node->start_time + diag_handle->diag_stat[stat_idx].config.fatal_threshold;
}
if (node->stop_time != 0) {
if ((node->stop_time - node->start_time >= diag_handle->diag_stat[stat_idx].config.warning_threashold) &&
(node->stop_time - node->start_time < diag_handle->diag_stat[stat_idx].config.fatal_threshold)) {
node->level = DIAG_REPORT_LEVEL_WARNING_STR;
} else if (node->stop_time - node->start_time >= diag_handle->diag_stat[stat_idx].config.fatal_threshold) {
node->level = DIAG_REPORT_LEVEL_FATAL_STR;
}
node->is_diag = 0;
}
if ((diag_handle->diag_stat[stat_idx].running_state.is_reported == 0) && (node->level != NULL)) {
/* report first in current period*/
_diag_desc_list_append(diag_handle, &diag_handle->diag_stat[stat_idx], node, &desc_list);
diag_handle->diag_stat[stat_idx].running_state.is_reported = 1;
diag_handle->diag_stat[stat_idx].running_state.report_start_time = timenow_ms;
}
}
if ((node->start_time >= diag_handle->diag_stat[stat_idx].running_state.report_start_time) && node->level != NULL) {
diag_handle->diag_stat[stat_idx].running_state.alert_counts++;
}
if (diag_handle->diag_stat[stat_idx].running_state.report_start_time > timenow_ms) {
diag_handle->diag_stat[stat_idx].running_state.report_start_time = timenow_ms;
}
if ((diag_handle->diag_stat[stat_idx].running_state.is_reported == 1) &&
(timenow_ms - diag_handle->diag_stat[stat_idx].running_state.report_start_time >=
diag_handle->diag_stat[stat_idx].config.interval_ms) &&
(node->linked_node.next == &diag_handle->diag_stat[stat_idx].running_state.linked_list)) {
/* report alert counts in this period */
if (diag_handle->diag_stat[stat_idx].running_state.alert_counts > 0) {
_diag_desc_list_append(diag_handle, &diag_handle->diag_stat[stat_idx], node, &desc_list);
}
diag_handle->diag_stat[stat_idx].running_state.is_reported = 0;
diag_handle->diag_stat[stat_idx].running_state.report_start_time = timenow_ms;
}
}
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->diag_stat[stat_idx].running_state.mutex);
}
_diag_desc_list_send(diag_handle, &desc_list);
_diag_desc_list_destroy(diag_handle, &desc_list);
diag_handle->mqtt_process.last_check_time = timenow_ms;
}
}
static int32_t _diag_core_mqtt_operate_process_handler(diag_handle_t *diag_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 = _diag_core_mqtt_process_handler;
process_data.context = diag_handle;
return core_mqtt_setopt(diag_handle->mqtt_handle, option, &process_data);
}
static void _diag_mqtt_conn_hb_extra_clean(void *handle, void *extra_data)
{
}
static int32_t _diag_mqtt_conn_hb_extra_stop(void *handle, diag_running_state_node_t *node, uint32_t stat_idx,
uint32_t stat_number, void *extra_data)
{
if (node->stop_time != 0) {
return STATE_DIAG_STOP_NODE_NOT_MATCH;
}
return STATE_SUCCESS;
}
static int32_t _diag_mqtt_conn_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc)
{
char *tmp_desc = NULL;
diag_handle_t *diag_handle = (diag_handle_t *)handle;
uint64_t timenow_ms = core_log_get_timestamp(diag_handle->sysdep);
if (running_state->is_reported == 0) {
/* report first time */
uint64_t time_elapsed = node->stop_time - node->start_time;
char time_elapsed_str[21] = {0};
char *desc_fmt = "MQTT connection establish time %s ms";
char *desc_src[] = { time_elapsed_str };
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
} else if (running_state->is_reported == 1) {
/* report period stat data */
uint64_t time_elapsed = timenow_ms - running_state->report_start_time;
char time_elapsed_str[21] = {0};
char alert_counts_str[11] = {0};
char *desc_fmt = "MQTT connection has been alert extra %s times in past %s ms";
char *desc_src[] = { alert_counts_str, time_elapsed_str };
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_uint2str(running_state->alert_counts, alert_counts_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
}
if (tmp_desc == NULL) {
return STATE_SYS_DEPEND_MALLOC_FAILED;
}
*desc = tmp_desc;
return STATE_SUCCESS;
}
static int32_t _diag_mqtt_hb_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc)
{
char *tmp_desc = NULL;
diag_handle_t *diag_handle = (diag_handle_t *)handle;
uint64_t timenow_ms = core_log_get_timestamp(diag_handle->sysdep);
if (running_state->is_reported == 0) {
/* report first time */
uint64_t time_elapsed = node->stop_time - node->start_time;
char time_elapsed_str[21] = {0};
char *desc_fmt = "MQTT lost heartbeat 1 times in %s ms";
char *desc_src[] = { time_elapsed_str };
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
} else if (running_state->is_reported == 1) {
/* report period stat data */
uint64_t time_elapsed = timenow_ms - running_state->report_start_time;
char time_elapsed_str[21] = {0};
char alert_counts_str[11] = {0};
char *desc_fmt = "MQTT lost heartbeat has been alert extra %s times in past %s ms";
char *desc_src[] = { alert_counts_str, time_elapsed_str };
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_uint2str(running_state->alert_counts, alert_counts_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
}
if (tmp_desc == NULL) {
return STATE_SYS_DEPEND_MALLOC_FAILED;
}
*desc = tmp_desc;
return STATE_SUCCESS;
}
static void _diag_alink_uplink_extra_clean(void *handle, void *extra_data)
{
diag_handle_t *diag_handle = (diag_handle_t *)handle;
diag_handle->sysdep->core_sysdep_free(extra_data);
}
static int32_t _diag_alink_uplink_extra_stop(void *handle, diag_running_state_node_t *node, uint32_t stat_idx,
uint32_t stat_number, void *extra_data)
{
if (*(uint32_t *)node->extra_data != *(uint32_t *)extra_data) {
return STATE_DIAG_STOP_NODE_NOT_MATCH;
}
return STATE_SUCCESS;
}
static int32_t _diag_alink_uplink_report_desc_append(void *handle, diag_running_state_t *running_state,
diag_running_state_node_t *node, char **desc)
{
char *tmp_desc = NULL;
diag_handle_t *diag_handle = (diag_handle_t *)handle;
uint64_t timenow_ms = core_log_get_timestamp(diag_handle->sysdep);
if (running_state->is_reported == 0) {
/* report first time */
char alink_id_str[11] = {0};
uint64_t time_elapsed = node->stop_time - node->start_time;
char time_elapsed_str[21] = {0};
char *desc_fmt = "Alink message %s waiting for reply has already exceed %s ms";
char *desc_src[] = { alink_id_str, time_elapsed_str };
core_uint2str(*(uint32_t *)node->extra_data, alink_id_str, NULL);
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
} else if (running_state->is_reported == 1) {
/* report period stat data */
uint64_t time_elapsed = timenow_ms - running_state->report_start_time;
char time_elapsed_str[21] = {0};
char alert_counts_str[11] = {0};
char *desc_fmt = "Alink message reply too slow has been alert extra %s times in past %s ms";
char *desc_src[] = { alert_counts_str, time_elapsed_str };
core_uint642str(time_elapsed, time_elapsed_str, NULL);
core_uint2str(running_state->alert_counts, alert_counts_str, NULL);
core_sprintf(diag_handle->sysdep, &tmp_desc, desc_fmt, desc_src, sizeof(desc_src) / sizeof(char *), DIAG_MODULE_NAME);
}
if (tmp_desc == NULL) {
return STATE_SYS_DEPEND_MALLOC_FAILED;
}
*desc = tmp_desc;
return STATE_SUCCESS;
}
static void _diag_running_state_start(diag_handle_t *diag_handle, diag_stat_t *stat, uint64_t timestamp,
void *extra_data)
{
diag_running_state_node_t *node = NULL;
diag_handle->sysdep->core_sysdep_mutex_lock(stat->running_state.mutex);
if (stat->running_state.stat_number == stat->running_state.max_stat_number) {
node = core_list_entry(stat->running_state.linked_list.next, diag_running_state_node_t, linked_node);
core_list_del(&node->linked_node);
stat->running_state.stat_number--;
stat->stat_cb.extra_clean_cb(diag_handle, node->extra_data);
diag_handle->sysdep->core_sysdep_free(node);
}
node = diag_handle->sysdep->core_sysdep_malloc(sizeof(diag_running_state_node_t), DIAG_MODULE_NAME);
if (node == NULL) {
diag_handle->sysdep->core_sysdep_mutex_unlock(stat->running_state.mutex);
return;
}
memset(node, 0, sizeof(diag_running_state_node_t));
node->is_diag = 1;
node->start_time = timestamp;
node->extra_data = extra_data;
CORE_INIT_LIST_HEAD(&node->linked_node);
core_list_add_tail(&node->linked_node, &stat->running_state.linked_list);
stat->running_state.stat_number++;
diag_handle->sysdep->core_sysdep_mutex_unlock(stat->running_state.mutex);
}
static void _diag_running_state_stop(diag_handle_t *diag_handle, diag_stat_t *stat, uint64_t timestamp,
void *extra_data)
{
uint32_t stat_idx = 0;
diag_running_state_node_t *node = NULL;
diag_handle->sysdep->core_sysdep_mutex_lock(stat->running_state.mutex);
core_list_for_each_entry(node, &stat->running_state.linked_list,
linked_node, diag_running_state_node_t) {
if (stat->stat_cb.extra_stop_cb(diag_handle, node,
stat_idx, stat->running_state.stat_number, extra_data) >= STATE_SUCCESS) {
node->stop_time = timestamp;
break;
}
stat_idx++;
}
stat->stat_cb.extra_clean_cb(diag_handle, extra_data);
diag_handle->sysdep->core_sysdep_mutex_unlock(stat->running_state.mutex);
}
static int32_t _diag_get_extra_data(diag_handle_t *diag_handle, diag_raw_data_t *raw_data, uint32_t code,
void **out_extra_data)
{
if (code == DIAG_TLV_ALINK_UPLINK) {
uint32_t tlv_sub_type1 = (raw_data->data[4] << 8) | (raw_data->data[5]);
if (tlv_sub_type1 == DIAG_TLV_ALINK_MSGID) {
uint32_t *extra_data = NULL;
extra_data = diag_handle->sysdep->core_sysdep_malloc(sizeof(uint32_t), DIAG_MODULE_NAME);
if (extra_data == NULL) {
return STATE_SYS_DEPEND_MALLOC_FAILED;
}
memset(extra_data, 0, sizeof(uint32_t));
*extra_data = ((raw_data->data[7] << 24) | (raw_data->data[8] << 16) | (raw_data->data[9] << 8) | (raw_data->data[10]));
*(uint32_t **)out_extra_data = extra_data;
}
}
return STATE_SUCCESS;
}
static void _diag_raw_data(diag_handle_t *diag_handle, diag_raw_data_t *raw_data)
{
uint32_t code = (raw_data->data[0] << 8) | (raw_data->data[1]);
uint32_t stat_idx = 0;
void *extra_data = NULL;
for (stat_idx = 0; stat_idx < DIAG_STAT_ITEM_NUMBER; stat_idx++) {
if (g_diag_config[stat_idx].code == code) {
if (_diag_get_extra_data(diag_handle, raw_data, code, &extra_data) < STATE_SUCCESS) {
return;
}
if (raw_data->data[3] == 0x00) {
_diag_running_state_start(diag_handle, &diag_handle->diag_stat[stat_idx], raw_data->timestamp, extra_data);
} else if (raw_data->data[3] == 0x01) {
_diag_running_state_stop(diag_handle, &diag_handle->diag_stat[stat_idx], raw_data->timestamp, extra_data);
}
}
}
}
static void _diag_core_diag_callback(void *handle, uint64_t timestamp, int32_t code, uint8_t *data, uint32_t data_len)
{
diag_raw_data_t raw_data;
memset(&raw_data, 0, sizeof(diag_raw_data_t));
raw_data.timestamp = timestamp;
raw_data.code = code;
raw_data.data = data;
raw_data.data_len = data_len;
_diag_raw_data((diag_handle_t *)handle, &raw_data);
}
static void _diag_running_state_clean(diag_handle_t *diag_handle)
{
uint32_t stat_idx = 0;
diag_running_state_node_t *node = NULL, *next = NULL;
for (stat_idx = 0; stat_idx < DIAG_STAT_ITEM_NUMBER; stat_idx++) {
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->diag_stat[stat_idx].running_state.mutex);
core_list_for_each_entry_safe(node, next, &diag_handle->diag_stat[stat_idx].running_state.linked_list,
linked_node, diag_running_state_node_t) {
core_list_del(&node->linked_node);
diag_handle->diag_stat[stat_idx].stat_cb.extra_clean_cb(diag_handle, node->extra_data);
diag_handle->sysdep->core_sysdep_free(node);
}
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->diag_stat[stat_idx].running_state.mutex);
diag_handle->sysdep->core_sysdep_mutex_deinit(&diag_handle->diag_stat[stat_idx].running_state.mutex);
}
}
void *aiot_diag_init(void)
{
int32_t res = STATE_SUCCESS;
uint32_t stat_idx = 0;
diag_handle_t *diag_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;
}
diag_handle = sysdep->core_sysdep_malloc(sizeof(diag_handle_t), DIAG_MODULE_NAME);
if (diag_handle == NULL) {
return NULL;
}
memset(diag_handle, 0, sizeof(diag_handle_t));
diag_handle->sysdep = sysdep;
diag_handle->local_report_enabled = DIAG_DAFAULT_LOCAL_REPORT_ENABLED;
diag_handle->cloud_report_enabled = DIAG_DAFAULT_CLOUD_REPORT_ENABLED;
for (stat_idx = 0; stat_idx < DIAG_STAT_ITEM_NUMBER; stat_idx++) {
diag_handle->diag_stat[stat_idx].running_state.code = g_diag_config[stat_idx].code;
diag_handle->diag_stat[stat_idx].running_state.name = g_diag_config[stat_idx].name;
memcpy(&diag_handle->diag_stat[stat_idx].config, &g_diag_config[stat_idx].def_config, sizeof(aiot_diag_config_t));
diag_handle->diag_stat[stat_idx].running_state.max_stat_number = g_diag_config[stat_idx].def_max_stat_number;
memcpy(&diag_handle->diag_stat[stat_idx].stat_cb, &g_diag_config[stat_idx].def_stat_cb, sizeof(diag_stat_callback_t));
diag_handle->diag_stat[stat_idx].running_state.qos = g_diag_config[stat_idx].qos;
CORE_INIT_LIST_HEAD(&diag_handle->diag_stat[stat_idx].running_state.linked_list);
diag_handle->diag_stat[stat_idx].running_state.mutex = diag_handle->sysdep->core_sysdep_mutex_init();
}
diag_handle->deinit_timeout_ms = DIAG_DEFAULT_DEINIT_TIMEOUT_MS;
diag_handle->data_mutex = sysdep->core_sysdep_mutex_init();
diag_handle->exec_enabled = 1;
core_diag_set_cb(diag_handle, _diag_core_diag_callback);
return diag_handle;
}
int32_t aiot_diag_setopt(void *handle, aiot_diag_option_t option, void *data)
{
int32_t res = STATE_SUCCESS;
diag_handle_t *diag_handle = (diag_handle_t *)handle;
if (diag_handle == NULL || data == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
if (option >= AIOT_DIAGOPT_MAX) {
return STATE_USER_INPUT_OUT_RANGE;
}
if (diag_handle->exec_enabled == 0) {
return STATE_USER_INPUT_EXEC_DISABLED;
}
_core_diag_exec_inc(diag_handle);
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
switch (option) {
case AIOT_DIAGOPT_MQTT_HANDLE: {
diag_handle->mqtt_handle = data;
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
res = _diag_core_mqtt_operate_process_handler(diag_handle, CORE_MQTTOPT_APPEND_PROCESS_HANDLER);
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
}
break;
case AIOT_DIAGOPT_LOCAL_REPORT_ENABLED: {
diag_handle->local_report_enabled = *(uint8_t *)data;
}
break;
case AIOT_DIAGOPT_CLOUD_REPORT_ENABLED: {
diag_handle->cloud_report_enabled = *(uint8_t *)data;
}
break;
case AIOT_DIAGOPT_MQTT_CONNECTION: {
memcpy(&diag_handle->diag_stat[DIAG_MQTT_CONNECTION_STAT_INDEX].config, (aiot_diag_config_t *)data,
sizeof(aiot_diag_config_t));
}
break;
case AIOT_DIAGOPT_MQTT_HEARTBEAT: {
memcpy(&diag_handle->diag_stat[DIAG_MQTT_HEARTBEAT_STAT_INDEX].config, (aiot_diag_config_t *)data,
sizeof(aiot_diag_config_t));
}
break;
case AIOT_DIAGOPT_ALINK_UPLINK: {
memcpy(&diag_handle->diag_stat[DIAG_ALINK_UPLINK_STAT_INDEX].config, (aiot_diag_config_t *)data,
sizeof(aiot_diag_config_t));
}
break;
case AIOT_DIAGOPT_RECV_HANDLER: {
diag_handle->recv_handler = (aiot_diag_recv_handler_t)data;
}
break;
case AIOT_DIAGOPT_EVENT_HANDLER: {
diag_handle->event_handler = (aiot_diag_event_handler_t)data;
}
break;
case AIOT_DIAGOPT_USERDATA: {
diag_handle->userdata = data;
}
break;
default: {
res = STATE_USER_INPUT_UNKNOWN_OPTION;
}
break;
}
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
_core_diag_exec_dec(diag_handle);
return res;
}
int32_t aiot_diag_deinit(void **handle)
{
uint64_t deinit_timestart = 0;
diag_handle_t *diag_handle = NULL;
if (handle == NULL || *handle == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
diag_handle = *(diag_handle_t **)handle;
if (diag_handle->exec_enabled == 0) {
return STATE_USER_INPUT_EXEC_DISABLED;
}
core_diag_set_cb(diag_handle, NULL);
_diag_core_mqtt_operate_process_handler(diag_handle, CORE_MQTTOPT_REMOVE_PROCESS_HANDLER);
diag_handle->exec_enabled = 0;
deinit_timestart = diag_handle->sysdep->core_sysdep_time();
do {
if (diag_handle->exec_count == 0) {
break;
}
diag_handle->sysdep->core_sysdep_sleep(DIAG_DEINIT_INTERVAL_MS);
} while ((diag_handle->sysdep->core_sysdep_time() - deinit_timestart) < diag_handle->deinit_timeout_ms);
if (diag_handle->exec_count != 0) {
return STATE_MQTT_DEINIT_TIMEOUT;
}
*handle = NULL;
_diag_running_state_clean(diag_handle);
diag_handle->sysdep->core_sysdep_mutex_deinit(&diag_handle->data_mutex);
core_global_deinit(diag_handle->sysdep);
diag_handle->sysdep->core_sysdep_free(diag_handle);
return STATE_SUCCESS;
}
int32_t aiot_diag_start(void *handle)
{
diag_handle_t *diag_handle = (diag_handle_t *)handle;
if (diag_handle == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
diag_handle->diag_status = 1;
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
return STATE_SUCCESS;
}
int32_t aiot_diag_stop(void *handle)
{
diag_handle_t *diag_handle = (diag_handle_t *)handle;
if (diag_handle == NULL) {
return STATE_USER_INPUT_NULL_POINTER;
}
diag_handle->sysdep->core_sysdep_mutex_lock(diag_handle->data_mutex);
diag_handle->diag_status = 0;
diag_handle->sysdep->core_sysdep_mutex_unlock(diag_handle->data_mutex);
return STATE_SUCCESS;
}

View File

@@ -0,0 +1,315 @@
/**
* @file aiot_diag_api.h
* @brief diag模块头文件, 提供诊断SDK的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#ifndef __AIOT_DIAG_API_H__
#define __AIOT_DIAG_API_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdint.h>
/**
* @brief -0x0.00~-0x0.FF表达SDK在diag模块内的状态码
*/
#define STATE_DIAG_BASE (-0x1400)
/**
* @brief STATE_DIAG_CODE1的说明
*/
#define STATE_DIAG_LOG_UNKNOWN_STATE_CODE_BASE (-0x1401)
/**
* @brief STATE_DIAG_CODE2的说明
*/
#define STATE_DIAG_CODE2 (-0x1402)
/**
* @brief STATE_DIAG_PUB_FAILED的说明
*/
#define STATE_DIAG_PUB_FAILED (-0x1403)
/**
* @brief diag模块收到从网络上来的报文时, 通知用户的报文类型
*/
typedef enum {
AIOT_DIAGRECV_DIAG_CONTROL
} aiot_diag_recv_type_t;
/**
* @brief diag模块收到从网络上来的报文时, 通知用户的报文内容
*/
typedef struct {
/**
* @brief 报文内容所对应的报文类型, 更多信息请参考@ref aiot_diag_recv_type_t
*/
aiot_diag_recv_type_t type;
union {
/**
* @brief 收到的云端控制指令
*/
struct {
/**
* @brief 0: 关闭诊断功能1: 打开诊断功能
*/
uint32_t data;
} diag_control;
} data;
} aiot_diag_recv_t;
/**
* @brief diag模块收到从网络上来的报文时, 通知用户所调用的数据回调函数
*
* @param[in] handle diag会话句柄
* @param[in] packet diag消息结构体, 存放收到的diag报文内容
* @param[in] userdata 用户上下文
*
* @return void
*/
typedef void (* aiot_diag_recv_handler_t)(void *handle, const aiot_diag_recv_t *packet, void *userdata);
/**
* @brief diag模块内部发生值得用户关注的状态变化时, 通知用户的事件类型
*/
typedef enum {
/**
* @brief 诊断模块产生的告警信息
*/
AIOT_DIAGEVT_ALERT
} aiot_diag_event_type_t;
/**
* @brief diag模块内部发生值得用户关注的状态变化时, 通知用户的事件内容
*/
typedef struct {
/**
* @brief 事件内容所对应的事件类型, 更多信息请参考@ref aiot_diag_event_type_t
*/
aiot_diag_event_type_t type;
union {
struct {
/**
* @brief 告警模块名
*/
char *module_name;
/**
* @brief 告警级别
*/
char *level;
/**
* @brief 告警信息描述字符串
*/
char *desc;
} alert;
} data;
} aiot_diag_event_t;
/**
* @brief diag模块内部发生值得用户关注的状态变化时, 通知用户所调用的事件回调函数
*
* @param[in] handle, diag会话句柄
* @param[in] event, diag模块中发生的事件的内容
* @param[in] userdata, 用户上下文
*
* @return void
*/
typedef void (*aiot_diag_event_handler_t)(void *handle, const aiot_diag_event_t *event, void *userdata);
/**
* @brief 诊断项的配置参数
*/
typedef struct {
/**
* @brief 对当前诊断项是否进行诊断的开关
*
* @details
*
* 0: 关闭对当前诊断项的诊断, 1: 打开对当前诊断项的诊断
*/
uint8_t enabled;
/**
* @brief 对当前诊断项连续两次告警的最小时间间隔
*/
uint32_t interval_ms;
/**
* @brief warning级别告警的阈值
*/
int64_t warning_threashold;
/**
* @brief fatal级别告警的阈值
*/
int64_t fatal_threshold;
} aiot_diag_config_t;
/**
* @brief @ref aiot_diag_setopt 接口的option参数可选值.
*
* @details 下文每个选项中的数据类型, 指的是@ref aiot_diag_setopt 中, data参数的数据类型
*
* 1. data的数据类型是void *时, 以配置@ref AIOT_DIAGOPT_MQTT_HANDLE 为例:
*
* void *mqtt_handle = aiot_mqtt_init();
* aiot_diag_setopt(diag_handle, AIOT_DIAGOPT_MQTT_HANDLE, mqtt_handle);
*
* 2. data的数据类型是其他数据类型时, 以配置@ref AIOT_DIAGOPT_LOCAL_REPORT_ENABLED 为例:
*
* uint8_t local_report_enabled = 1;
* aiot_mqtt_setopt(diag_handle, AIOT_DIAGOPT_LOCAL_REPORT_ENABLED, (void *)&local_report_enabled);
*/
typedef enum {
/**
* @brief diag会话 需要的MQTT句柄, 需要先建立MQTT连接, 再设置MQTT句柄
*
* @details
*
* 数据类型: (void *)
*/
AIOT_DIAGOPT_MQTT_HANDLE,
/**
* @brief 是否需要从事件回调函数中输出告警信息
*
* @details
*
* 0: 不从事件回调函数中输出告警信息, 1: 从事件回调函数中输出告警信息
*
* 数据类型: (uint8_t *)
*/
AIOT_DIAGOPT_LOCAL_REPORT_ENABLED,
/**
* @brief 是否需要上报告警信息至云端
*
* @details
*
* 0: 不上报告警信息至云端, 1: 上报告警信息至云端
*
* 数据类型: (uint8_t *)
*/
AIOT_DIAGOPT_CLOUD_REPORT_ENABLED,
/**
* @brief MQTT建联时长告警配置
*
* @details
*
* 数据类型: ( @ref aiot_diag_config_t )
*/
AIOT_DIAGOPT_MQTT_CONNECTION,
/**
* @brief MQTT心跳丢失告警配置
*
* @details
*
* 数据类型: ( @ref aiot_diag_config_t )
*/
AIOT_DIAGOPT_MQTT_HEARTBEAT,
/**
* @brief Alink协议上行报文的回复速度告警配置
*
* @details
*
* 数据类型: ( @ref aiot_diag_config_t )
*/
AIOT_DIAGOPT_ALINK_UPLINK,
/**
* @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户
*
* @details
*
* 数据类型: ( @ref aiot_diag_recv_handler_t )
*/
AIOT_DIAGOPT_RECV_HANDLER,
/**
* @brief diag内部发生的事件会从此回调函数进行通知
*
* @details
*
* 数据类型: ( @ref aiot_diag_event_handler_t )
*/
AIOT_DIAGOPT_EVENT_HANDLER,
/**
* @brief 用户需要SDK暂存的上下文
*
* @details 这个上下文指针会在 AIOT_DIAGOPT_RECV_HANDLER 和 AIOT_DIAGOPT_EVENT_HANDLER 设置的回调被调用时, 由SDK传给用户
*
* 数据类型: (void *)
*/
AIOT_DIAGOPT_USERDATA,
AIOT_DIAGOPT_MAX
} aiot_diag_option_t;
/**
* @brief 创建diag会话实例, 并以默认值配置会话参数
*
* @return void *
* @retval 非NULL diag实例的句柄
* @retval NULL 初始化失败, 一般是内存分配失败导致
*
*/
void *aiot_diag_init(void);
/**
* @brief 配置diag会话
*
* @param[in] handle diag会话句柄
* @param[in] option 配置选项, 更多信息请参考@ref aiot_diag_option_t
* @param[in] data 配置选项数据, 更多信息请参考@ref aiot_diag_option_t
*
* @return int32_t
* @retval <STATE_SUCCESS 参数配置失败
* @retval >=STATE_SUCCESS 参数配置成功
*
*/
int32_t aiot_diag_setopt(void *handle, aiot_diag_option_t option, void *data);
/**
* @brief 结束diag会话, 销毁实例并回收资源
*
* @param[in] handle 指向diag会话句柄的指针
*
* @return int32_t
* @retval <STATE_SUCCESS 执行失败
* @retval >=STATE_SUCCESS 执行成功
*
*/
int32_t aiot_diag_deinit(void **handle);
/**
* @brief 开始诊断SDK内部信息
*
* @param handle diag会话句柄
*
* @return int32_t
* @retval <STATE_SUCCESS 请求发送失败
* @retval >=STATE_SUCCESS 请求发送成功
*/
int32_t aiot_diag_start(void *handle);
/**
* @brief 停止诊断SDK内部信息
*
* @param handle diag会话句柄
*
* @return int32_t
* @retval <STATE_SUCCESS 数据接收失败
* @retval >=STATE_SUCCESS 数据接收成功
*/
int32_t aiot_diag_stop(void *handle);
#if defined(__cplusplus)
}
#endif
#endif /* __AIOT_DIAG_API_H__ */

View File

@@ -0,0 +1,191 @@
/**
* @file diag_private.h
* @brief diag模块内部的宏定义和数据结构声明, 不面向其它模块, 更不面向用户
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#ifndef __DIAG_PRIVATE_H__
#define __DIAG_PRIVATE_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include "core_stdinc.h"
#include "core_list.h"
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_diag_api.h"
typedef struct {
uint64_t last_check_time;
} diag_mqtt_process_t;
typedef struct {
uint64_t timestamp;
int32_t code;
uint8_t *data;
uint32_t data_len;
} diag_raw_data_t;
typedef struct {
uint64_t timestamp;
uint16_t code;
char *module_name;
char *level;
char *desc;
uint8_t qos;
struct core_list_head linked_node;
} diag_desc_node_t;
typedef struct {
uint8_t is_diag; /* 该诊断项是否处于诊断状态 */
char *level; /* 告警级别 */
uint64_t start_time; /* 统计开始时间 */
uint64_t stop_time; /* 统计结束时间 */
void *extra_data; /* 统计节点附加数据 */
struct core_list_head linked_node;
} diag_running_state_node_t;
typedef struct {
uint32_t code; /* 诊断项代号 */
char *name; /* 诊断项名 */
uint8_t is_reported; /* 当前统计周期内是否上报过 */
uint64_t report_start_time; /* 当前统计周期开始时间 */
uint32_t alert_counts; /* 当前统计周期累计产生告警次数 */
uint32_t stat_number; /* 当前节点数量 */
uint32_t max_stat_number; /* 统计节点最大数量 */
uint8_t qos; /* 使用MQTT发送告警报文至云端时使用的QoS值 */
void *mutex; /* 数据保护锁 */
struct core_list_head linked_list;
} diag_running_state_t;
typedef void (*diag_running_state_node_extra_clean_t)(void *handle, void *extra_data);
typedef int32_t (*diag_running_state_node_extra_stop_t)(void *handle, diag_running_state_node_t *node, uint32_t stat_idx, uint32_t stat_number, void *extra_data);
typedef int32_t (*diag_report_desc_append_t)(void *handle, diag_running_state_t *running_state, diag_running_state_node_t *node, char **desc);
typedef struct {
diag_running_state_node_extra_clean_t extra_clean_cb;
diag_running_state_node_extra_stop_t extra_stop_cb;
diag_report_desc_append_t desc_append_cb;
} diag_stat_callback_t;
typedef struct {
aiot_diag_config_t config;
diag_running_state_t running_state;
diag_stat_callback_t stat_cb;
} diag_stat_t;
typedef struct {
uint32_t msgid;
} diag_alink_uplink_extra_data_t;
#define DIAG_STAT_ITEM_NUMBER (3)
typedef struct {
aiot_sysdep_portfile_t *sysdep; /* 底层依赖回调合集的引用指针 */
void *mqtt_handle;
uint8_t local_report_enabled;
uint8_t cloud_report_enabled;
diag_stat_t diag_stat[DIAG_STAT_ITEM_NUMBER];
uint32_t deinit_timeout_ms;
aiot_diag_event_handler_t event_handler; /* 组件内部运行状态变更时, 通知用户的回调 */
aiot_diag_recv_handler_t recv_handler; /* 组件从协议栈读到内容时, 通知用户的回调 */
void *userdata; /* 组件调用以上2个 diag_handler 时的入参之一 */
/*---- 以上都是用户在API可配 ----*/
/*---- 以下都是DIAG在内部使用, 用户无感知 ----*/
void *data_mutex; /* 保护本地的数据结构 */
uint8_t diag_status; /* 本地诊断模块状态, 0: stop, 1: start */
uint8_t cloud_switch;
diag_mqtt_process_t mqtt_process;
uint8_t exec_enabled;
uint32_t exec_count;
} diag_handle_t;
typedef struct {
uint32_t stat_idx;
char *name;
uint32_t code;
aiot_diag_config_t def_config;
uint32_t def_max_stat_number;
diag_stat_callback_t def_stat_cb;
uint8_t qos;
} diag_config_t;
#define DIAG_MODULE_NAME "diag" /* 用于内存统计的模块名字符串 */
#define DIAG_DAFAULT_LOCAL_REPORT_ENABLED (1)
#define DIAG_DAFAULT_CLOUD_REPORT_ENABLED (1)
#define DIAG_DEFAULT_DEINIT_TIMEOUT_MS (2 * 1000)
/* MQTT connection diag default configuration */
#define DIAG_DEFAULT_MQTT_CONN_ENABLED (1)
#define DIAG_DEFAULT_MQTT_CONN_INTERVAL_MS (30 * 1000)
#define DIAG_DEFAULT_MQTT_CONN_WARNING_THRESHOLD (200)
#define DIAG_DEFAULT_MQTT_CONN_FATAL_THRESHOLD (500)
#define DIAG_DEFAULT_MQTT_CONN_MAX_STAT_NUMBER (20)
/* MQTT heartbeag diag default configuration */
#define DIAG_DEFAULT_MQTT_HB_ENABLED (1)
#define DIAG_DEFAULT_MQTT_HB_INTERVAL_MS (30 * 1000)
#define DIAG_DEFAULT_MQTT_HB_WARNING_THRESHOLD (800)
#define DIAG_DEFAULT_MQTT_HB_FATAL_THRESHOLD (1500)
#define DIAG_DEFAULT_MQTT_HB_MAX_STAT_NUMBER (20)
/* MQTT alink uplink default configuration */
#define DIAG_DEFAULT_ALINK_UPLINK_ENABLED (1)
#define DIAG_DEFAULT_ALINK_UPLINK_INTERVAL_MS (30 * 1000)
#define DIAG_DEFAULT_ALINK_UPLINK_WARNING_THRESHOLD (600)
#define DIAG_DEFAULT_ALINK_UPLINK_FATAL_THRESHOLD (1000)
#define DIAG_DEFAULT_ALINK_UPLINK_MAX_STAT_NUMBER (20)
#define DIAG_REPORT_TOPIC_FMT "/sys/%s/%s/thing/log/post"
#define DIAG_REPORT_PAYLOAD_FMT "{\"id\":\"%s\",\"version\":\"1.0\",\"params\":[{\"utcTime\":\"%s\"," \
"\"logLevel\":\"%s\",\"module\":\"%s\",\"code\":\"%s\",\"traceContext\":\"%s\",\"logContent\":\"%s\"}]}"
#define DIAG_DEINIT_INTERVAL_MS (100)
#define DIAG_MQTT_PROCESS_CHECK_INTERVAL_MS (2000)
#define DIAG_REPORT_LEVEL_WARNING_STR "WARN"
#define DIAG_REPORT_LEVEL_FATAL_STR "FATAL"
#define DIAG_STATE_MQTT_BASE (STATE_MQTT_BASE)
#define DIAG_STATE_DM_BASE (-0x0A00)
/* MQTT connection diag constant */
#define DIAG_MQTT_CONNECTION_STAT_INDEX (0)
#define DIAG_MQTT_CONNECTION_NAME_STR "DiagMqttConnection"
#define DIAG_TLV_MQTT_CONNECTION (0x0010)
/* MQTT heartbeat diag constant */
#define DIAG_MQTT_HEARTBEAT_STAT_INDEX (1)
#define DIAG_MQTT_HEARTBEAT_NAME_STR "DiagMqttHeartbeat"
#define DIAG_TLV_MQTT_HEARTBEAT (0x0020)
/* MQTT alink uplink diag constant */
#define DIAG_ALINK_UPLINK_STAT_INDEX (2)
#define DIAG_ALINK_UPLINK_NAME_STR "DiagAlinkUplink"
#define DIAG_TLV_ALINK_UPLINK (0x0030)
#define DIAG_TLV_ALINK_MSGID (0x0031)
/* internal state code */
#define STATE_DIAG_STOP_NODE_NOT_MATCH (-0x14FF)
#if defined(__cplusplus)
}
#endif
#endif /* __DIAG_PRIVATE_H__ */