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

View File

@@ -0,0 +1,458 @@
/**
* @file aiot_logpost_api.c
* @brief logpost模块的API接口实现, 提供设备端日志上云的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#include "logpost_private.h"
#include "core_string.h"
#include "core_log.h"
#include "core_mqtt.h"
#include "core_global.h"
#include "aiot_mqtt_api.h"
#define LOGPOST_JSON_KEY_MODE "mode"
const char *logpost_loglevel[] = {
"FATAL",
"ERROR",
"WARN",
"INFO",
"DEBUG",
};
static void _logpost_config_data_handler(void *handle, const aiot_mqtt_recv_t *msg, void *userdata)
{
logpost_handle_t *logpost_handle = (logpost_handle_t *)userdata;
aiot_logpost_event_t event;
char *value = NULL;
uint32_t value_len = 0;
uint32_t log_switch = 0;
/* construct event message */
memset(&event, 0, sizeof(aiot_logpost_event_t));
event.type = AIOT_LOGPOSTEVT_CONFIG_DATA;
core_log(logpost_handle->sysdep, STATE_LOGPOST_LOG_RECV, "LOGPOST user log config arrived\r\n");
if ((core_json_value((char *)msg->data.pub.payload, msg->data.pub.payload_len,
LOGPOST_JSON_KEY_MODE, strlen(LOGPOST_JSON_KEY_MODE), &value, &value_len)) < 0 ||
(core_str2uint(value, value_len, &log_switch)) < 0) {
core_log(logpost_handle->sysdep, SATAE_LOGPOST_LOG_PARSE_MSG_FAILED, "LOGPOST parse log config failed\r\n");
return;
}
/* update log config */
logpost_handle->user_log_switch = log_switch;
/* invoke user callback */
if (logpost_handle->event_handler != NULL) {
event.data.config_data.on_off = log_switch;
logpost_handle->event_handler(logpost_handle, &event, logpost_handle->userdata);
}
}
static void _logpost_get_config(logpost_handle_t *logpost_handle)
{
char *topic = NULL;
char *payload = NULL;
char *fmt = "{\"id\":\"%s\",\"version\":\"1.0\",\"params\":{\"getType\":\"content\",\"configScope\":\"device\"}}";
int32_t res = STATE_SUCCESS;
int32_t id = 0;
char *pk = NULL, *dn = NULL;
char id_string[11] = { 0 };
if (NULL == logpost_handle || NULL == logpost_handle->mqtt_handle) {
return;
}
if (NULL == (pk = core_mqtt_get_product_key(logpost_handle->mqtt_handle))) {
return;
}
if (NULL == (dn = core_mqtt_get_device_name(logpost_handle->mqtt_handle))) {
return;
}
core_global_alink_id_next(logpost_handle->sysdep, &id);
core_int2str(id, id_string, NULL);
/* construct topic */
{
char *src[2] = { pk, dn };
res = core_sprintf(logpost_handle->sysdep, &topic, LOGPOST_CONFIG_GET_TOPIC_FMT, src, sizeof(src) / sizeof(char *),
LOGPOST_MODULE_NAME);
if (NULL == topic) {
return;
}
}
/* construct payload */
{
char *src[1] = { id_string };
res = core_sprintf(logpost_handle->sysdep, &payload, fmt,
src, sizeof(src) / sizeof(char *), LOGPOST_MODULE_NAME);
if (res < STATE_SUCCESS) {
logpost_handle->sysdep->core_sysdep_free(topic);
return;
}
}
res = aiot_mqtt_pub(logpost_handle->mqtt_handle, topic, (uint8_t *)payload, (uint32_t)strlen(payload), 0);
logpost_handle->sysdep->core_sysdep_free(topic);
logpost_handle->sysdep->core_sysdep_free(payload);
}
int32_t _logpost_send_nwkstats_rtt(logpost_handle_t *handle)
{
int32_t res = STATE_SUCCESS;
aiot_logpost_msg_t msg;
core_mqtt_nwkstats_info_t nwkstats_info;
char *content_fmt = NWKSTAT_RTT_INFO_FMT;
char timestamp_str[22] = {0};
char rtt_str[22] = {0};
char *content = NULL;
char *content_src[] = {timestamp_str, rtt_str};
core_mqtt_get_nwkstats(handle->mqtt_handle, &nwkstats_info);
core_uint642str(nwkstats_info.rtt, rtt_str, NULL);
core_uint642str(handle->sysdep->core_sysdep_time(), timestamp_str, NULL);
res = core_sprintf(handle->sysdep, &content, content_fmt, content_src, 2, LOGPOST_MODULE_NAME);
if (res < 0) {
return res;
}
memset(&msg, 0, sizeof(aiot_logpost_msg_t));
msg.timestamp = 0; /* 单位为ms的时间戳, 填写0则SDK将使用当前的时间戳 */
msg.loglevel = AIOT_LOGPOST_LEVEL_INFO; /* 日志级别 */
msg.module_name = NWKSTAT_NET_RT; /* 日志对应的模块 */
msg.code = 200; /* 状态码 */
msg.msg_id = 0;
msg.content = content; /* 日志内容 */
res = aiot_logpost_send(handle, &msg);
handle->sysdep->core_sysdep_free(content);
return res;
}
int32_t _logpost_send_nwkstats_conn(logpost_handle_t *handle)
{
int32_t res = STATE_SUCCESS;
aiot_logpost_msg_t msg;
core_mqtt_nwkstats_info_t nwkstats_info;
char *content_fmt = NULL;
char success_time[22] = {0};
char conn_time_str[22] = {0};
char failed_time[22] = {0};
char conn_code[12] = {0};
char *content = NULL;
char *content_src[] = {success_time, NULL, conn_time_str, failed_time, NULL, conn_code};
uint8_t content_src_cnt = 0;
core_mqtt_get_nwkstats(handle->mqtt_handle, &nwkstats_info);
if (nwkstats_info.connect_time_used == 0) {
return res;
}
core_uint642str(nwkstats_info.connect_timestamp, success_time, NULL);
content_src[1] = (nwkstats_info.network_type == 0) ? "TCP" : "TLS";
content_src[4] = (nwkstats_info.network_type == 0) ? "TCP" : "TLS";
core_uint642str(nwkstats_info.connect_time_used, conn_time_str, NULL);
core_uint642str(nwkstats_info.failed_timestamp, failed_time, NULL);
core_int2str(nwkstats_info.failed_error_code, conn_code, NULL);
/* check if connect failure happened */
if (nwkstats_info.failed_error_code != 0) {
content_fmt = NWKSTAT_CONN_INFO_FMT2;
content_src_cnt = sizeof(content_src) / sizeof(content_src[0]);
} else {
content_fmt = NWKSTAT_CONN_INFO_FMT;
content_src_cnt = 3;
}
res = core_sprintf(handle->sysdep, &content, content_fmt, content_src, content_src_cnt, LOGPOST_MODULE_NAME);
if (res < 0) {
return res;
}
memset(&msg, 0, sizeof(aiot_logpost_msg_t));
msg.timestamp = 0; /* 单位为ms的时间戳, 填写0则SDK将使用当前的时间戳 */
msg.loglevel = AIOT_LOGPOST_LEVEL_INFO; /* 日志级别 */
msg.module_name = NWKSTAT_NET_CONN; /* 日志对应的模块 */
msg.code = 200; /* 状态码 */
msg.msg_id = 0;
msg.content = content; /* 日志内容 */
res = aiot_logpost_send(handle, &msg);
handle->sysdep->core_sysdep_free(content);
return res;
}
int32_t _should_report_sys_log(logpost_handle_t *logpost_handle, char *module_name)
{
int result = 0;
if (0 == logpost_handle->sys_log_switch) {
return result;
}
if (0 == memcmp(NWKSTAT_NET_CONN, module_name, strlen(NWKSTAT_NET_CONN)) ||
0 == memcmp(NWKSTAT_NET_RT, module_name, strlen(NWKSTAT_NET_RT))) {
result = 1;
core_log(logpost_handle->sysdep, STATE_LOGPOST_LOG_RECV,
"sys log config is on, toggle it using AIOT_LOGPOSTOPT_SYS_LOG.\r\n");
}
return result;
}
void _logpost_process_handler(void *context, aiot_mqtt_event_t *event, core_mqtt_event_t *core_event)
{
logpost_handle_t *logpost_handle = (logpost_handle_t *)context;
if (core_event != NULL) {
switch (core_event->type) {
case CORE_MQTTEVT_DEINIT: {
logpost_handle->mqtt_handle = NULL;
return;
}
default: {
}
break;
}
}
if (NULL == context || NULL == event) {
if (logpost_handle->sys_log_switch == 0) {
return;
}
_logpost_send_nwkstats_conn(logpost_handle);
if ((logpost_handle->sysdep->core_sysdep_time() - logpost_handle->last_post_time) \
> LOGPOST_NWKSTATS_POST_INTERVAL) {
logpost_handle->last_post_time = logpost_handle->sysdep->core_sysdep_time();
_logpost_send_nwkstats_rtt(logpost_handle);
}
return;
}
if (event->type == AIOT_MQTTEVT_CONNECT) {
_logpost_get_config(logpost_handle);
}
}
void *aiot_logpost_init(void)
{
aiot_sysdep_portfile_t *sysdep = aiot_sysdep_get_portfile();
logpost_handle_t *logpost_handle = NULL;
if (NULL == sysdep) {
return NULL;
}
logpost_handle = sysdep->core_sysdep_malloc(sizeof(logpost_handle_t), LOGPOST_MODULE_NAME);
if (NULL == logpost_handle) {
return NULL;
}
memset(logpost_handle, 0, sizeof(logpost_handle_t));
logpost_handle->sysdep = sysdep;
logpost_handle->user_log_switch = LOGPOST_DEFAULT_LOG_ONOFF;
logpost_handle->sys_log_switch = LOGPOST_DEFAULT_LOG_ONOFF;
core_global_init(sysdep);
return logpost_handle;
}
int32_t aiot_logpost_setopt(void *handle, aiot_logpost_option_t option, void *data)
{
logpost_handle_t *logpost_handle;
int32_t res = STATE_SUCCESS;
if (NULL == handle || NULL == data) {
return STATE_USER_INPUT_NULL_POINTER;
}
if (option >= AIOT_LOGPOSTOPT_MAX) {
return STATE_USER_INPUT_OUT_RANGE;
}
logpost_handle = (logpost_handle_t *)handle;
switch (option) {
case AIOT_LOGPOSTOPT_MQTT_HANDLE: {
aiot_mqtt_topic_map_t topic_mapping;
logpost_handle->mqtt_handle = data;
core_mqtt_process_data_t process_data;
/* setup mqtt topic mapping */
memset(&topic_mapping, 0, sizeof(aiot_mqtt_topic_map_t));
topic_mapping.topic = LOGPOST_CONFIG_PUSH_TOPIC;
topic_mapping.handler = _logpost_config_data_handler;
topic_mapping.userdata = handle;
res = aiot_mqtt_setopt(data, AIOT_MQTTOPT_APPEND_TOPIC_MAP, &topic_mapping);
if (res < 0) {
break;
}
topic_mapping.topic = LOGPOST_CONFIG_GET_REPLY_TOPIC;
res = aiot_mqtt_setopt(data, AIOT_MQTTOPT_APPEND_TOPIC_MAP, &topic_mapping);
if (res < 0) {
break;
}
/* setup mqtt process handler */
memset(&process_data, 0, sizeof(core_mqtt_process_data_t));
process_data.handler = _logpost_process_handler;
process_data.context = logpost_handle;
res = core_mqtt_setopt(data, CORE_MQTTOPT_APPEND_PROCESS_HANDLER, &process_data);
}
break;
case AIOT_LOGPOSTOPT_EVENT_HANDLER: {
logpost_handle->event_handler = (aiot_logpost_event_handler_t)data;
}
break;
case AIOT_LOGPOSTOPT_USERDATA: {
logpost_handle->userdata = data;
}
break;
case AIOT_LOGPOSTOPT_SYS_LOG: {
logpost_handle->sys_log_switch = *(uint8_t *)data;
}
break;
default:
break;
}
return res;
}
int32_t aiot_logpost_send(void *handle, aiot_logpost_msg_t *msg)
{
logpost_handle_t *logpost_handle = NULL;
char *topic = NULL;
char *payload = NULL;
char *fmt = "{\"id\":\"%s\",\"version\":\"1.0\",\"params\":" \
"[{\"utcTime\":\"%s\",\"logLevel\":\"%s\",\"module\":\"%s\",\"code\":\"%s\",\"traceContext\":\"%s\",\"logContent\":\"%s\"}]}";
char *pk = NULL, *dn = NULL;
int32_t id = 0;
int32_t res = STATE_SUCCESS;
if (NULL == handle || NULL == msg) {
return STATE_USER_INPUT_NULL_POINTER;
}
if (msg->loglevel > AIOT_LOGPOST_LEVEL_DEBUG) {
return STATE_LOGPOST_LOGLEVEL_ERROR;
}
if (NULL == msg->module_name) {
return STATE_LOGPOST_LOG_MODULE_NAME_IS_NULL;
}
if (NULL == msg->content) {
return STATE_LOGPOST_LOG_CONTENT_IS_NULL;
}
if (strlen(msg->content) > LOGPOST_CONTENT_MAXIMUM_LEN) {
return STATE_LOGPOST_LOG_CONTENT_TOO_LONG;
}
if (msg->timestamp > 100000000000000) {
return STATE_USER_INPUT_OUT_RANGE;
}
logpost_handle = (logpost_handle_t *)handle;
if (NULL == logpost_handle->mqtt_handle) {
return STATE_LOGPOST_MQTT_HANDLE_IS_NULL;
}
if (NULL == (pk = core_mqtt_get_product_key(logpost_handle->mqtt_handle))) {
return STATE_USER_INPUT_MISSING_PRODUCT_KEY;
}
if (NULL == (dn = core_mqtt_get_device_name(logpost_handle->mqtt_handle))) {
return STATE_USER_INPUT_MISSING_DEVICE_NAME;
}
if (1 != _should_report_sys_log(logpost_handle, msg->module_name) && logpost_handle->user_log_switch == 0) {
return STATE_LOGPOST_POST_TURN_OFF;
}
/* construct topic */
{
char *src[2] = {pk, dn};
res = core_sprintf(logpost_handle->sysdep, &topic, LOGPOST_POST_TOPIC_FMT, src, sizeof(src) / sizeof(char *),
LOGPOST_MODULE_NAME);
if (NULL == topic) {
return res;
}
}
/* construct payload */
{
char id_string[11] = { 0 };
char utc[32] = { 0 };
char code[11] = { 0 };
char msg_id[22] = { 0 };
const char *src[] = { id_string, utc, logpost_loglevel[msg->loglevel], msg->module_name, code, msg_id, msg->content };
core_global_alink_id_next(logpost_handle->sysdep, &id);
core_int2str(id, id_string, NULL);
if (msg->timestamp == 0) {
_core_log_append_date(logpost_handle->sysdep, core_log_get_timestamp(logpost_handle->sysdep), utc);
} else {
_core_log_append_date(logpost_handle->sysdep, msg->timestamp, utc);
}
core_int2str(msg->code, code, NULL);
core_uint642str(msg->msg_id, msg_id, NULL);
res = core_sprintf(logpost_handle->sysdep, &payload, fmt,
(char **)src, sizeof(src) / sizeof(char *), LOGPOST_MODULE_NAME);
if (res < STATE_SUCCESS) {
logpost_handle->sysdep->core_sysdep_free(topic);
return res;
}
}
res = aiot_mqtt_pub(logpost_handle->mqtt_handle, topic, (uint8_t *)payload, (uint32_t)strlen(payload), 0);
logpost_handle->sysdep->core_sysdep_free(topic);
logpost_handle->sysdep->core_sysdep_free(payload);
if (res >= STATE_SUCCESS) {
res = id;
}
return res;
}
int32_t aiot_logpost_deinit(void **p_handle)
{
logpost_handle_t *logpost_handle = NULL;
aiot_sysdep_portfile_t *sysdep = NULL;
aiot_mqtt_topic_map_t topic_mapping;
core_mqtt_process_data_t process_data;
if (NULL == p_handle || NULL == *p_handle) {
return STATE_USER_INPUT_NULL_POINTER;
}
logpost_handle = *p_handle;
sysdep = logpost_handle->sysdep;
*p_handle = NULL;
/* remove mqtt precess handler */
memset(&process_data, 0, sizeof(core_mqtt_process_data_t));
process_data.handler = _logpost_process_handler;
core_mqtt_setopt(logpost_handle->mqtt_handle, CORE_MQTTOPT_REMOVE_PROCESS_HANDLER, &process_data);
/* remove mqtt topic mapping */
memset(&topic_mapping, 0, sizeof(aiot_mqtt_topic_map_t));
topic_mapping.topic = LOGPOST_CONFIG_PUSH_TOPIC;
topic_mapping.handler = _logpost_config_data_handler;
aiot_mqtt_setopt(logpost_handle->mqtt_handle, AIOT_MQTTOPT_REMOVE_TOPIC_MAP, &topic_mapping);
topic_mapping.topic = LOGPOST_CONFIG_GET_REPLY_TOPIC;
aiot_mqtt_setopt(logpost_handle->mqtt_handle, AIOT_MQTTOPT_REMOVE_TOPIC_MAP, &topic_mapping);
sysdep->core_sysdep_free(logpost_handle);
core_global_deinit(sysdep);
return STATE_SUCCESS;
}

View File

@@ -0,0 +1,268 @@
/**
* @file aiot_logpost_api.h
* @brief logpost模块头文件, 提供设备端日志上云的能力
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
* @details
*
* 1. 在使用日志上云模块前, 用户应首先创建好一个MQTT实例
*
* 2. 调用`aiot_logpost_init`创建一个日志上云实例, 保存实例句柄
*
* 3. 调用`aiot_logpost_setopt`配置`AIOT_LOGPOSTOPT_MQTT_HANDLE`选项以设置MQTT句柄, 此选项为强制配置选项
*
* 4. 调用`aiot_logpost_setopt`配置`AIOT_LOGPOSTOPT_EVENT_HANDLER`和`AIOT_LOGPOSTOPT_USER_DATA`选项以注册事件接收回调函数和用户上下文数据指针
*
* 5. 在使用`aiot_logpost_send`发送日志消息前, 应先完成MQTT实例的建连
*
*/
#ifndef __AIOT_LOGPOST_API_H__
#define __AIOT_LOGPOST_API_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdint.h>
/**
* @brief -0x1500~-0x15FF表达SDK在logpost模块内的状态码
*/
#define STATE_LOGPOST_BASE (-0x1500)
/**
* @brief 用户未调用@ref aiot_logpost_setopt 配置MQTT句柄
*/
#define STATE_LOGPOST_MQTT_HANDLE_IS_NULL (-0x1501)
/**
* @brief 日志上报被云端配置为关闭状态
*/
#define STATE_LOGPOST_POST_TURN_OFF (-0x1502)
/**
* @brief 日志消息的日志级别有误
*/
#define STATE_LOGPOST_LOGLEVEL_ERROR (-0x1503)
/**
* @brief 日志消息的模块名称字段为NULL
*/
#define STATE_LOGPOST_LOG_MODULE_NAME_IS_NULL (-0x1504)
/**
* @brief 日志消息的日志内容字段为NULL
*/
#define STATE_LOGPOST_LOG_CONTENT_IS_NULL (-0x1505)
/**
* @brief 日志消息的日志内容字段字符串长度大于4096个字节
*/
#define STATE_LOGPOST_LOG_CONTENT_TOO_LONG (-0x1506)
/**
* @brief 接收到服务器下行消息时的内部日志状态码
*/
#define STATE_LOGPOST_LOG_RECV (-0x1507)
/**
* @brief 解析服务器下行消息失败时的内部日志状态码
*/
#define SATAE_LOGPOST_LOG_PARSE_MSG_FAILED (-0x1508)
/**
* @brief @ref aiot_logpost_setopt 接口的option参数可选值.
*
* @details 下文每个选项中的数据类型, 指的是@ref aiot_logpost_setopt 中, data参数的数据类型
*/
typedef enum {
/**
* @brief 模块依赖的MQTT句柄
*
* @details
*
* LOGPOST模块依赖底层的MQTT模块, 用户必需配置正确的MQTT句柄, 否则无法正常工作, 数据类型为(void *)
*/
AIOT_LOGPOSTOPT_MQTT_HANDLE,
/**
* @brief 设置回调, 它在SDK收到网络报文的时候被调用, 告知用户, 数据类型为(aiot_logpost_recv_handler_t)
*/
AIOT_LOGPOSTOPT_EVENT_HANDLER,
/**
* @brief 用户需要SDK暂存的上下文, 数据类型为(void *)
*
* @details 这个上下文指针会在 AIOT_LOGPOSTOPT_RECV_HANDLER 设置的回调被调用时, 由SDK传给用户
*/
AIOT_LOGPOSTOPT_USERDATA,
/**
* @brief 系统日志的开关.
*
* @detail 设置为1表示要上报系统日志, 设置为0表示不上报系统日志. 这里的系统日志是指建连耗时和网络延时
*/
AIOT_LOGPOSTOPT_SYS_LOG,
/**
* @brief 配置选项数量最大值, 不可用作配置参数
*/
AIOT_LOGPOSTOPT_MAX,
} aiot_logpost_option_t;
/**
* @brief 日志级别枚举类型定义
*/
typedef enum {
AIOT_LOGPOST_LEVEL_FATAL,
AIOT_LOGPOST_LEVEL_ERR,
AIOT_LOGPOST_LEVEL_WARN,
AIOT_LOGPOST_LEVEL_INFO,
AIOT_LOGPOST_LEVEL_DEBUG,
} aiot_logpost_level_t;
/**
* @brief 日志数据结构体定义
*
*/
typedef struct {
/**
* @brief utc时间戳, 单位为ms, 此数值会直接展示在云端控制台设备日志页面
*/
uint64_t timestamp;
/**
* @brief 日志级别, 请查看@ref aiot_logpost_level_t 定义
*/
aiot_logpost_level_t loglevel;
/**
* @brief 模块名称, <b>必须为以结束符'\0'结尾的字符串</b>
*/
char *module_name;
/**
* @brief 状态码, 可用于标识日志对应的状态
*/
int32_t code;
/**
* @brief 消息标示符, 用于标识云端下行消息, 可从data-module模块的消息接收回调函数中获得对应的标识符, 如果用户设置为0, 此字段将不上传。
*/
uint64_t msg_id;
/**
* @brief 日志内容, <b>必须为以结束符'\0'结尾的字符串</b>
*/
char *content;
} aiot_logpost_msg_t;
/**
* @brief logpost模块内部发生值得用户关注的状态变化时, 通知用户的事件类型
*/
typedef enum {
/**
* @brief 接受到云端下发的日志配置数据
*/
AIOT_LOGPOSTEVT_CONFIG_DATA,
} aiot_logpost_event_type_t;
/**
* @brief logpost模块内部发生值得用户关注的状态变化时, 通知用户的事件内容
*/
typedef struct {
/**
* @brief 事件内容所对应的事件类型, 更多信息请参考@ref aiot_logpost_event_type_t
*/
aiot_logpost_event_type_t type;
union {
/**
* @brief 日志配置数据结构体
*/
struct {
/**
* @brief 日志开关状态, 0: 关闭日志上传; 1: 打开日志上传
*/
uint8_t on_off;
} config_data;
} data;
} aiot_logpost_event_t;
/**
* @brief logpost模块内部发生值得用户关注的状态变化时, 通知用户所调用的事件回调函数
*
* @param[in] handle logpost会话句柄
* @param[in] event logpost模块中发生的事件的内容
* @param[in] userdata 指向用户上下文数据的指针, 这个指针由用户通过调用@ref aiot_logpost_setopt 配置@ref AIOT_LOGPOSTOPT_USERDATA 选项设置
*
* @return void
*/
typedef void (*aiot_logpost_event_handler_t)(void *handle,
const aiot_logpost_event_t *event, void *userdata);
/**
* @brief 创建logpost会话实例, 并以默认值配置会话参数
*
* @return void *
* @retval 非NULL logpost实例的句柄
* @retval NULL 初始化失败, 一般是内存分配失败导致
*/
void *aiot_logpost_init(void);
/**
* @brief 配置logpost会话
*
* @param[in] handle logpost会话句柄
* @param[in] option 配置选项, 更多信息请参考@ref aiot_logpost_option_t
* @param[in] data 配置选项数据, 更多信息请参考@ref aiot_logpost_option_t
*
* @return int32_t
* @retval <STATE_SUCCESS 参数配置失败
* @retval STATE_SUCCESS 参数配置成功
* @retval STATE_USER_INPUT_NULL_POINTER 入参handle或data为NULL
* @retval STATE_USER_INPUT_OUT_RANGE 入参optioin的枚举值>=AIOT_LOGPOSTOPT_MAX
* @retval others 参考@ref aiot_state_api.h
*/
int32_t aiot_logpost_setopt(void *handle, aiot_logpost_option_t option, void *data);
/**
* @brief 向服务器发送日志消息
*
* @param[in] handle logpost会话句柄
* @param[in] msg 消息结构体, 可指定日志对应模块, 日志级别等, 更多信息请参考@ref aiot_logpost_msg_t
*
* @return int32_t
* @retval STATE_SUCCESS 请求发送成功
* @retval STATE_USER_INPUT_NULL_POINTER 入参<i>handle</i>或<i>msg</i>为NULL
* @retval STATE_SYS_DEPEND_MALLOC_FAILED 内存分配失败
* @retval STATE_LOGPOST_MQTT_HANDLE_IS_NULL 用户未调用@ref aiot_logpost_setopt 配置MQTT句柄
* @retval others 参考@ref aiot_state_api.h 或@ref STATE_SHADOW_BASE 中对应的错误码说明
*
*/
int32_t aiot_logpost_send(void *handle, aiot_logpost_msg_t *msg);
/**
* @brief 结束logpost会话, 销毁实例并回收资源
*
* @param[in] handle 指向logpost会话句柄的指针
*
* @return int32_t
* @retval <STATE_SUCCESS 执行失败
* @retval >=STATE_SUCCESS 执行成功
*/
int32_t aiot_logpost_deinit(void **handle);
#if defined(__cplusplus)
}
#endif
#endif /* __AIOT_LOGPOST_API_H__ */

View File

@@ -0,0 +1,64 @@
/**
* @file logpost_private.h
* @brief logpost模块内部的宏定义和数据结构声明, 不面向其它模块, 更不面向用户
*
* @copyright Copyright (C) 2015-2020 Alibaba Group Holding Limited
*
*/
#ifndef __LOGPOST_PRIVATE_H__
#define __LOGPOST_PRIVATE_H__
#if defined(__cplusplus)
extern "C" {
#endif
#include "core_stdinc.h"
#include "aiot_state_api.h"
#include "aiot_sysdep_api.h"
#include "aiot_mqtt_api.h"
#include "aiot_logpost_api.h"
/* logpost模块内部的会话句柄结构体, SDK用户不可见, 只能得到void *handle类型的指针 */
typedef struct {
aiot_sysdep_portfile_t *sysdep;
void *mqtt_handle;
uint8_t user_log_switch;
uint8_t sys_log_switch;
aiot_logpost_event_handler_t event_handler;
void *userdata;
/* network info stats */
uint64_t last_post_time;
} logpost_handle_t;
#define LOGPOST_MODULE_NAME "logpost" /* 用于内存统计的模块名字符串 */
#define LOGPOST_DEFAULT_LOG_ONOFF (0)
#define LOGPOST_CONTENT_MAXIMUM_LEN (4096)
#define LOGPOST_NWKSTATS_POST_INTERVAL (1800000)
/* 上下行topic定义 */
#define LOGPOST_POST_TOPIC_FMT "/sys/%s/%s/thing/log/post"
#define LOGPOST_CONFIG_GET_TOPIC_FMT "/sys/%s/%s/thing/config/log/get"
#define LOGPOST_CONFIG_PUSH_TOPIC "/sys/+/+/thing/config/log/push"
#define LOGPOST_CONFIG_GET_REPLY_TOPIC "/sys/+/+/thing/config/log/get_reply"
#define NWKSTAT_RTT_INFO_FMT "time=%s^rtt=%s"
#define NWKSTAT_CONN_INFO_FMT "time=%s^conn_type=%s^conn_cost=%s^conn_ret=0"
#define NWKSTAT_CONN_INFO_FMT2 "time=%s^conn_type=%s^conn_cost=%s^conn_ret=0,time=%s^conn_type=%s^conn_cost=0^conn_ret=%s"
#define NWKSTAT_NET_RT "net_rt"
#define NWKSTAT_NET_CONN "net_conn"
#if defined(__cplusplus)
}
#endif
#endif /* __LOGPOST_PRIVATE_H__ */