9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
270 lines
7.0 KiB
C
270 lines
7.0 KiB
C
/*
|
|
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
|
|
*/
|
|
|
|
#include "iotx_dm_internal.h"
|
|
|
|
#if defined(LOG_REPORT_TO_CLOUD) && !defined(DEVICE_MODEL_RAWDATA_SOLO)
|
|
|
|
#include "dev_model_api.h"
|
|
|
|
const char THING_LOG_POST_PARAMS_HEAD[] =
|
|
"\"%.*s %s %ld ";
|
|
const char THING_LOG_POST_PARAMS_BODY[] =
|
|
"%s %ld ";
|
|
const char THING_LOG_POST_PARAMS_END[] =
|
|
"%s %ld\",";
|
|
|
|
char *g_log_poll = NULL;
|
|
static char *current_log_pos = NULL;
|
|
|
|
int remove_log_poll()
|
|
{
|
|
if (NULL != g_log_poll) {
|
|
HAL_Free(g_log_poll);
|
|
g_log_poll = NULL;
|
|
current_log_pos = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
unsigned int push_log(const char *input_log, int input_log_size)
|
|
{
|
|
if (NULL == current_log_pos || NULL == input_log || input_log_size <= 0) {
|
|
return -1;
|
|
}
|
|
memcpy(current_log_pos, input_log, input_log_size);
|
|
current_log_pos += input_log_size;
|
|
return (current_log_pos - g_log_poll);
|
|
}
|
|
|
|
unsigned int add_tail()
|
|
{
|
|
const char *tail = "]}";
|
|
current_log_pos -= 1;
|
|
return push_log(tail, strlen(tail));
|
|
}
|
|
|
|
void add_log_header()
|
|
{
|
|
const char *subprefix = "{\"template\": \"traceContext logContent\",\"contents\":[";
|
|
int sublen = strlen(subprefix);
|
|
push_log(subprefix, sublen);
|
|
}
|
|
|
|
int reset_log_poll()
|
|
{
|
|
if (NULL == g_log_poll) {
|
|
return -1;
|
|
}
|
|
memset(g_log_poll, 0, LOG_POLL_SIZE);
|
|
current_log_pos = g_log_poll;
|
|
add_log_header();
|
|
return 0;
|
|
}
|
|
|
|
int create_log_poll()
|
|
{
|
|
int ret;
|
|
remove_log_poll();
|
|
g_log_poll = HAL_Malloc(LOG_POLL_SIZE);
|
|
ret = reset_log_poll();
|
|
return ret;
|
|
}
|
|
|
|
static int switch_status = 0; /* 0 for switch off; 1 for switch on */
|
|
static unsigned int sample_interval = 5;
|
|
static unsigned int sample_count = 1000;
|
|
|
|
#define MSG_ID_LEN (64)
|
|
char msg_array[MSG_ID_LEN] = {0};
|
|
int check_target_msg(const char *input, int len)
|
|
{
|
|
/* do not upload log when swith is off */
|
|
if (0 == switch_status) {
|
|
return -1;
|
|
}
|
|
if (NULL == input || len <= 0) {
|
|
return -1;
|
|
}
|
|
return strncmp(input, msg_array, len);
|
|
}
|
|
|
|
static unsigned int msg_num = 0;
|
|
/* return 0 for success; -1 for failure */
|
|
int set_target_msg(const char *input, int len)
|
|
{
|
|
if (0 == switch_status) {
|
|
return -1;
|
|
}
|
|
if ((msg_num % sample_interval == 0) && (msg_num < sample_count)) {
|
|
if (NULL == input || len <= 0) {
|
|
return -1;
|
|
}
|
|
strncpy(msg_array, input, len);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void parse_msg_id(_IN_ char *payload, _IN_ int payload_len, _OU_ dm_msg_request_payload_t *request)
|
|
{
|
|
lite_cjson_t lite;
|
|
|
|
if (payload == NULL || payload_len <= 0 || request == NULL) {
|
|
return;
|
|
}
|
|
|
|
dm_utils_json_parse(payload, payload_len, cJSON_Object, &lite);
|
|
dm_utils_json_object_item(&lite, DM_MSG_KEY_ID, strlen(DM_MSG_KEY_ID), cJSON_String, &request->id);
|
|
}
|
|
|
|
int stop_sample()
|
|
{
|
|
if (current_log_pos > g_log_poll) {
|
|
dm_mgr_upstream_thing_log_post(0, NULL, 0, 1);
|
|
}
|
|
switch_status = 0;
|
|
|
|
iotx_state_event(ITE_STATE_DEV_MODEL, STATE_DEV_MODLE_LOG_REPORT_STOP, "log report stop");
|
|
return remove_log_poll();
|
|
}
|
|
|
|
void parse_switch_info(_IN_ char *payload, _IN_ int payload_len)
|
|
{
|
|
lite_cjson_t lite, lite_sample_count, lite_sample_interval, lite_sample_target;
|
|
const char *c1 = "Count";
|
|
const char *c2 = "Interval";
|
|
const char *c3 = "ProfileTarget";
|
|
char *sample_target;
|
|
int sample_target_len;
|
|
const char *target = "propSet";
|
|
int ret = -1;
|
|
|
|
if (payload == NULL || payload_len <= 0) {
|
|
return;
|
|
}
|
|
dm_utils_json_parse(payload, payload_len, cJSON_Object, &lite);
|
|
ret = lite_cjson_object_item(&lite, c1, strlen(c1), &lite_sample_count);
|
|
if (ret < SUCCESS_RETURN) {
|
|
return;
|
|
}
|
|
|
|
ret = lite_cjson_object_item(&lite, c2, strlen(c2), &lite_sample_interval);
|
|
if (ret < SUCCESS_RETURN) {
|
|
return;
|
|
}
|
|
|
|
ret = lite_cjson_object_item(&lite, c3, strlen(c3), &lite_sample_target);
|
|
if (ret < SUCCESS_RETURN) {
|
|
return;
|
|
}
|
|
|
|
sample_count = lite_sample_count.value_int;
|
|
sample_interval = lite_sample_interval.value_int;
|
|
sample_target = lite_sample_target.value;
|
|
sample_target_len = lite_sample_target.value_length;
|
|
|
|
iotx_state_event(ITE_STATE_DEV_MODEL, STATE_DEV_MODLE_LOG_REPORT_SWITCH, "switch count is %d, interval is %d, target is %.*s\n",
|
|
sample_count, sample_interval, sample_target_len, sample_target);
|
|
/* if the target is not property set, return */
|
|
if (0 != strncmp(sample_target, target, sample_target_len)) {
|
|
return;
|
|
}
|
|
if (sample_interval <= 0) {
|
|
return;
|
|
}
|
|
msg_num = 0;
|
|
/* when it switch off, force upload the remaining log */
|
|
if (0 == sample_count) {
|
|
ret = stop_sample();
|
|
} else {
|
|
switch_status = 1;
|
|
ret = create_log_poll();
|
|
}
|
|
}
|
|
|
|
REPORT_STATE g_report_status = READY;
|
|
|
|
void send_permance_info(char *input, int input_len, char *comments, int report_format)
|
|
{
|
|
#define LOCAL_POST_LEN (150)
|
|
char data[LOCAL_POST_LEN] = {0};
|
|
const char *format = NULL;
|
|
if (0 == switch_status) {
|
|
return;
|
|
}
|
|
|
|
switch (report_format) {
|
|
case 0:
|
|
if (NULL == input || input_len <= 0) {
|
|
return;
|
|
}
|
|
format = THING_LOG_POST_PARAMS_HEAD;
|
|
HAL_Snprintf(data, sizeof(data), format, input_len, input,
|
|
comments, (long)HAL_UptimeMs());
|
|
break;
|
|
case 1:
|
|
format = THING_LOG_POST_PARAMS_BODY;
|
|
HAL_Snprintf(data, sizeof(data), format,
|
|
comments, (long)HAL_UptimeMs());
|
|
break;
|
|
case 2:
|
|
format = THING_LOG_POST_PARAMS_END;
|
|
HAL_Snprintf(data, sizeof(data), format,
|
|
comments, (long)HAL_UptimeMs());
|
|
g_report_status = DONE;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
iotx_dm_log_post(0, data, strlen((const char *)data));
|
|
if (2 == report_format) {
|
|
g_report_status = READY;
|
|
}
|
|
}
|
|
|
|
void get_msgid(char *payload, int is_cloud)
|
|
{
|
|
const char *interest = "\"method\":\"thing.service.property.set";
|
|
char *found;
|
|
dm_msg_request_payload_t request;
|
|
if (0 == switch_status || NULL == payload) {
|
|
return;
|
|
}
|
|
|
|
found = strstr(payload, interest);
|
|
if (NULL == found) {
|
|
return;
|
|
}
|
|
found = strstr(payload, "{");
|
|
if (NULL == found) {
|
|
return;
|
|
}
|
|
msg_num++;
|
|
parse_msg_id(found, strlen(found), &request);
|
|
if (RUNNING == g_report_status) {
|
|
return;
|
|
}
|
|
|
|
if (sample_count <= msg_num) {
|
|
stop_sample();
|
|
return;
|
|
}
|
|
|
|
/* if it does not meet the sample conditions, do NOT take sample */
|
|
if (SUCCESS_RETURN != set_target_msg(request.id.value, request.id.value_length)) {
|
|
return;
|
|
}
|
|
|
|
g_report_status = RUNNING;
|
|
|
|
if (1 == is_cloud) {
|
|
send_permance_info(request.id.value, request.id.value_length, "1_cloud", 0);
|
|
} else if (0 == is_cloud) {
|
|
send_permance_info(request.id.value, request.id.value_length, "1_alcs", 0);
|
|
}
|
|
}
|
|
#endif
|