• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: diag oam log
15  * This file should be changed only infrequently and with great care.
16  */
17 #include "securec.h"
18 #include "log_oam_msg.h"
19 #include "log_oam_logger.h"
20 #include "log_oam_status.h"
21 #include "log_oam_ota.h"
22 #include "log_oam_pcm.h"
23 #include "log_oml_exception.h"
24 #include "diag.h"
25 #include "soc_diag_util.h"
26 #include "diag_common.h"
27 #include "diag_filter.h"
28 #include "diag_adapt_layer.h"
29 #include "sample_data_adapt.h"
30 #include "log_common.h"
31 #include "diag_adapt_sdt.h"
32 
33 #ifdef SUPPORT_CONNECTIVITY
34 #include "connectivity_log.h"
35 #endif
36 
37 enum {
38     LOG_STATUS_MODULE = MODULEID_BUTT,
39     LOG_OTA_MODULE,
40 } log_adapt_module;
41 
42 typedef enum {
43     SDT_MSG_STEP_HEAD, /* sdt msg head */
44     SDT_MSG_STEP_BODY, /* sdt msg body */
45     STD_MSG_STEP_TAIL, /* sdt msg tail */
46 } sdt_msg_pack_step_t;
47 
48 typedef struct {
49     uint8_t *msg;
50     uint32_t len;
51 } zdiag_adapt_sdt_msg_t;
52 
53 typedef struct diag_msg_para {
54     uint32_t module_id;
55     uint32_t msg_id;
56     uint32_t no;
57     uint8_t *buf;
58     uint16_t buf_size;
59     uint8_t level;
60 } diag_msg_para_t;
61 
62 oam_cmd_handle_callback g_diag_debug_proc = NULL;
63 uint8_t g_recv_msg_step = SDT_MSG_STEP_HEAD;
64 uint8_t *g_recv_buf = NULL;          /* 组包buf */
65 
log_level_trans(uint32_t sdt_level)66 static uint32_t log_level_trans(uint32_t sdt_level)
67 {
68     /* sdt 日志等级4种, hso日志等级8种,需要转换一次 */
69     uint32_t level[LOG_LEVEL_MAX] = {
70         DIAG_LOG_LEVEL_ALERT,
71         DIAG_LOG_LEVEL_ERROR,
72         DIAG_LOG_LEVEL_WARN,
73         DIAG_LOG_LEVEL_INFO,
74         DIAG_LOG_LEVEL_DBG,
75     };
76 
77     if (sdt_level < LOG_LEVEL_MAX) {
78         return level[sdt_level];
79     } else {
80         return LOG_LEVEL_NONE;
81     }
82 }
83 
84 /*
85 For std log:
86 1bit        | 4bit   | 10bit   | 14bit   | 3bit  |
87 logFlag = 1 | mod_id | file_id | line_no | level |
88 for other:
89 1bit        | 7bit     | 8bit  | 16bit  |
90 logFlag = 0 | resv = 0 | type  | msg_id |
91 */
92 
zdiag_adapt_sdt_om_log_parse(uint8_t * sdt_buf,uint16_t sdt_buf_size,diag_msg_para_t * para)93 static void zdiag_adapt_sdt_om_log_parse(uint8_t *sdt_buf, uint16_t sdt_buf_size, diag_msg_para_t *para)
94 {
95     om_log_header_t* om_log = (om_log_header_t*)sdt_buf;
96 
97     uint32_t file_id = (om_log->file_idx_high << 2) + om_log->bit2_file_idx_low;
98     uint32_t line_no = (om_log->bit6_line_no_high << 8) + om_log->line_no_low;
99     uint32_t sdt_level = (uint32_t)om_log->mod_print_lev_info >> 6;   /* level 2 bit */
100     uint32_t mod_id = om_log->header.prime_id >> 4; /* 高4 bit 为mod_id */
101 
102     para->module_id = mod_id;
103 
104     para->msg_id = (1 << 31);                    /* bit31 为logFlag */
105     para->msg_id += mod_id << 27;                /* bit27 ~ bit30 为mod_id */
106     para->msg_id += (file_id & 0x3FF) << 17;     /* bit17 ~ bit26 为file_id */
107     para->msg_id += (line_no & 0x3FFF) << 3;     /* bit3 ~ bit16 为line_no */
108     para->msg_id += log_level_trans(sdt_level);
109 
110     para->no = om_log->header.sn;
111     para->buf = sdt_buf + sizeof(om_log_header_t);
112     para->buf_size = (uint16_t)(sdt_buf_size - sizeof(om_log_header_t) - sizeof(uint8_t));
113     para->level = (uint8_t)log_level_trans(sdt_level);
114 }
115 
zdiag_adapt_sdt_om_status_parse(uint8_t * sdt_buf,uint16_t sdt_buf_size,diag_msg_para_t * para)116 static void zdiag_adapt_sdt_om_status_parse(uint8_t *sdt_buf, uint16_t sdt_buf_size, diag_msg_para_t *para)
117 {
118     om_status_data_stru_t *om_status = (om_status_data_stru_t*)sdt_buf;
119 
120     unused(sdt_buf_size);
121     para->module_id = LOG_STATUS_MODULE;
122     para->msg_id = (OM_MSG_TYPE_STATUS << 16) | om_status->msg_id; /* 高16 bit 为MSG_TYPE */
123     para->no = om_status->header.sn;
124     para->buf = om_status->data;
125     para->buf_size = om_status->data_len;
126     para->level = DIAG_LOG_LEVEL_INFO;
127 }
128 
zdiag_adapt_sdt_om_ota_parse(uint8_t * sdt_buf,uint16_t sdt_buf_size,diag_msg_para_t * para)129 static void zdiag_adapt_sdt_om_ota_parse(uint8_t *sdt_buf, uint16_t sdt_buf_size, diag_msg_para_t *para)
130 {
131     om_ota_header_t *om_ota = (om_ota_header_t*)sdt_buf;
132     para->module_id = LOG_OTA_MODULE;
133     para->msg_id = (OM_MSG_TYPE_OTA << 16) | om_ota->msg_id; /* 高16 bit 为MSG_TYPE */
134     para->no = om_ota->header.sn;
135     para->buf = sdt_buf + sizeof(om_ota_header_t);
136     para->buf_size = (uint16_t)(sdt_buf_size - sizeof(om_ota_header_t) - sizeof(uint8_t));
137     para->level = DIAG_LOG_LEVEL_INFO;
138 }
139 
zdiag_adapt_sdt_om_last_parse(uint8_t * sdt_buf,uint16_t sdt_buf_size,diag_msg_para_t * para)140 static void zdiag_adapt_sdt_om_last_parse(uint8_t *sdt_buf, uint16_t sdt_buf_size, diag_msg_para_t *para)
141 {
142     om_exception_info_stru_t *om_last = (om_exception_info_stru_t*)sdt_buf;
143     para->module_id = LOG_BTMODULE;
144     para->msg_id = (OM_MSG_TYPE_LAST << 16) | om_last->msg_header.prime_id; /* 高16 bit 为MSG_TYPE */
145     para->no = om_last->msg_header.sn;
146     para->buf = sdt_buf + sizeof(om_msg_header_stru_t);
147     para->buf_size = (uint16_t)(sdt_buf_size - sizeof(om_msg_header_stru_t) - sizeof(uint8_t));
148     para->level = DIAG_LOG_LEVEL_INFO;
149 }
150 
zdiag_adapt_sdt_msg_report(uint8_t * sdt_buf,uint16_t sdt_buf_size)151 static void zdiag_adapt_sdt_msg_report(uint8_t *sdt_buf, uint16_t sdt_buf_size)
152 {
153     om_msg_header_stru_t *om_msg_header;
154     diag_msg_para_t para;
155 
156     om_msg_header = (om_msg_header_stru_t*)sdt_buf;
157     if (om_msg_header->func_type == OM_MSG_TYPE_OTA) {
158         zdiag_adapt_sdt_om_ota_parse(sdt_buf, sdt_buf_size, &para);
159         uapi_diag_report_sys_msg(para.module_id, para.msg_id, para.buf, para.buf_size, para.level);
160     } else if (om_msg_header->func_type == OM_BT_SAMPLE_DATA) {
161         zdiag_adapt_sample_data_report(sdt_buf, sdt_buf_size);
162     } else {
163         return;
164     }
165 }
166 
zdiag_adapt_msg_pack_check(uint8_t * data,uint32_t data_len)167 static errcode_t zdiag_adapt_msg_pack_check(uint8_t *data, uint32_t data_len)
168 {
169     om_msg_header_stru_t *om_msg_header = (om_msg_header_stru_t*)data;
170     if (data_len < sizeof(om_msg_header_stru_t)) {
171         return ERRCODE_FAIL;
172     }
173 
174     if (om_msg_header->frame_start != OM_FRAME_DELIMITER) {
175         return ERRCODE_FAIL;
176     }
177 
178     if (om_msg_header->func_type == OM_MSG_TYPE_OTA) {
179         if (om_msg_header->frame_len > OTA_DATA_MAX_SIZE + sizeof(om_msg_header_stru_t) + 1) {
180             return ERRCODE_FAIL;
181         }
182     } else if (om_msg_header->func_type == OM_BT_SAMPLE_DATA) {
183         if (om_msg_header->frame_len > BT_SAMPLE_DATA_MAX_SIZE + sizeof(om_pcm_header_t) + 1) {
184             return ERRCODE_FAIL;
185         }
186     } else {
187         return ERRCODE_FAIL;
188     }
189 
190     return ERRCODE_SUCC;
191 }
zdiag_adapt_msg_pack_para_reinit(void)192 static void zdiag_adapt_msg_pack_para_reinit(void)
193 {
194     g_recv_msg_step = SDT_MSG_STEP_HEAD;
195     if (g_recv_buf != NULL) {
196         dfx_free(0, g_recv_buf);
197         g_recv_buf = NULL;
198     }
199 }
200 
zdiag_adapt_sdt_msg_dispatch(uint32_t msg_id,uint8_t * data,uint32_t data_len)201 errcode_t zdiag_adapt_sdt_msg_dispatch(uint32_t msg_id, uint8_t *data, uint32_t data_len)
202 {
203     zdiag_adapt_sdt_msg_t *msg = (zdiag_adapt_sdt_msg_t*)data;
204     uint32_t check_valid;
205     unused(msg_id);
206     unused(data_len);
207     uint32_t frame_len = 0;          /* om包长度 */
208     uint32_t recv_len = 0;
209 
210     if (g_recv_msg_step == SDT_MSG_STEP_HEAD) {
211         check_valid = zdiag_adapt_msg_pack_check(msg->msg, msg->len);
212         if (check_valid == ERRCODE_SUCC) {
213             frame_len = ((om_msg_header_stru_t *)msg->msg)->frame_len;
214             g_recv_buf = dfx_malloc(0, frame_len);
215             if (g_recv_buf != NULL) {
216                 (void)memcpy_s(g_recv_buf, frame_len, msg->msg, msg->len);
217                 recv_len = msg->len;
218                 g_recv_msg_step = SDT_MSG_STEP_BODY;
219             }
220         }
221     } else if (g_recv_msg_step == SDT_MSG_STEP_BODY) {
222         if (frame_len - recv_len > 0) {
223             (void)memcpy_s(g_recv_buf + recv_len, frame_len - recv_len, msg->msg, msg->len);
224         }
225         recv_len += msg->len;
226         g_recv_msg_step = STD_MSG_STEP_TAIL;
227     } else {
228         if (frame_len - recv_len > 0) {
229             (void)memcpy_s(g_recv_buf + recv_len, frame_len - recv_len, msg->msg, msg->len);
230         }
231         zdiag_adapt_sdt_msg_report(g_recv_buf, (uint16_t)frame_len);
232         zdiag_adapt_msg_pack_para_reinit();
233     }
234     dfx_free(0, msg->msg);
235     return ERRCODE_SUCC;
236 }
237 
zdiag_adapt_sdt_short_msg_report(uint8_t * data,uint32_t data_len)238 static bool zdiag_adapt_sdt_short_msg_report(uint8_t *data, uint32_t data_len)
239 {
240     om_msg_header_stru_t *om_msg_header = NULL;
241     diag_msg_para_t para;
242     bool pack = true;
243     bool report = false;
244 
245     if (data_len >= sizeof(om_msg_header_stru_t)) {
246         om_msg_header = (om_msg_header_stru_t*)data;
247         if ((om_msg_header->frame_start == OM_FRAME_DELIMITER) &&
248             (om_msg_header->frame_len == data_len) &&
249             (data[data_len - 1] == OM_FRAME_DELIMITER)) {
250             if (om_msg_header->func_type ==  OM_MSG_TYPE_LOG) {
251                 zdiag_adapt_sdt_om_log_parse(data, (uint16_t)data_len, &para);
252                 report = true;
253             } else if (om_msg_header->func_type == OM_MSG_TYPE_STATUS) {
254                 zdiag_adapt_sdt_om_status_parse(data, (uint16_t)data_len, &para);
255                 report = true;
256             } else if (om_msg_header->func_type == OM_MSG_TYPE_LAST) {
257                 zdiag_adapt_sdt_om_last_parse(data, (uint16_t)data_len, &para);
258                 report = true;
259             }
260             pack = false;
261             /* OTA, BT SAMPLE 三包数据一起写buffer,不会夹杂其他数据,若出现丢弃已pack的部分包 */
262             zdiag_adapt_msg_pack_para_reinit();
263         }
264     }
265 
266     if (report) {
267         uapi_diag_report_sys_msg(para.module_id, para.msg_id, para.buf, para.buf_size, para.level);
268     }
269 
270     return pack;
271 }
272 
zdiag_adapt_sdt_msg_proc(uint8_t * buf1,uint32_t len1,uint8_t * buf2,uint32_t len2)273 void zdiag_adapt_sdt_msg_proc(uint8_t *buf1, uint32_t len1, uint8_t *buf2, uint32_t len2)
274 {
275     zdiag_adapt_sdt_msg_t msg;
276     uint32_t len = len1 + len2;
277     uint8_t *buf = NULL;
278     uint32_t pos = 0;
279     uint32_t ret;
280     bool pack;
281 
282     if (zdiag_is_enable() == false) {
283         return;
284     }
285 
286     if (len > 0) {
287         buf = dfx_malloc(0, len);
288     }
289 
290     if (buf == NULL) {
291         return;
292     }
293 
294     if (len1 > 0) {
295         (void)memcpy_s(buf + pos, len1, buf1, len1);
296         pos += len1;
297     }
298 
299     if (len2 > 0) {
300         (void)memcpy_s(buf + pos, len2, buf2, len2);
301     }
302 
303     /* 如果是非整包数据,入队列,做pack处理 */
304     pack = zdiag_adapt_sdt_short_msg_report(buf, len);
305     if (pack) {
306         msg.msg = buf;
307         msg.len = len;
308         ret = dfx_msg_write(DFX_MSG_ID_SDT_MSG, (uint8_t *)&msg, sizeof(zdiag_adapt_sdt_msg_t), false);
309         if (ret != ERRCODE_SUCC) {
310             dfx_log_err("sdt msg write to queue error\r\n");
311             dfx_free(0, buf);
312         }
313     } else {
314         dfx_free(0, buf);
315     }
316 }
317 
diag_register_debug_cmd_callback(oam_cmd_handle_callback func)318 void diag_register_debug_cmd_callback(oam_cmd_handle_callback func)
319 {
320     g_diag_debug_proc =  func;
321 }
322 
diag_debug_cmd_proc(uint8_t * data,uint32_t len)323 void diag_debug_cmd_proc(uint8_t *data, uint32_t len)
324 {
325     if (g_diag_debug_proc != NULL) {
326         g_diag_debug_proc(data, (uint16_t)len);
327     }
328 }
329 
330 #ifndef FORBID_AUTO_LOG_REPORT
diag_auto_log_report_enable(void)331 void diag_auto_log_report_enable(void)
332 {
333     uint8_t level[] = {
334         DIAG_LOG_LEVEL_ERROR,
335         DIAG_LOG_LEVEL_WARN,
336         DIAG_LOG_LEVEL_INFO,
337         DIAG_LOG_LEVEL_DBG,
338     };
339     uint32_t mod_id[] = {
340         LOG_WIFIMODULE,
341         LOG_BTMODULE,
342         LOG_PFMODULE,
343         LOG_NFCMODULE,
344         LOG_STATUS_MODULE,
345         LOG_OTA_MODULE,
346     };
347 
348     /* module 使能 */
349     for (uint32_t i = 0; i < sizeof(mod_id) / sizeof(uint32_t); i++) {
350         zdiag_set_id_enable(mod_id[i], 1);
351     }
352 
353     /* 未连接hso时,不上报所有 level   */
354     for (uint32_t i = 0; i < sizeof(level) / sizeof(uint32_t); i++) {
355         zdiag_set_level_enable(level[i], 0);
356     }
357 }
358 #endif
359 
zdiag_level_proc(uint8_t level)360 void zdiag_level_proc(uint8_t level)
361 {
362     log_level_e core_level = LOG_LEVEL_NONE;
363 
364     if ((level & (1 << DIAG_LOG_LEVEL_INFO)) != 0) {
365         core_level = LOG_LEVEL_INFO;
366     } else if ((level & (1 << DIAG_LOG_LEVEL_WARN)) != 0) {
367         core_level = LOG_LEVEL_WARNING;
368     } else if ((level & (1 << DIAG_LOG_LEVEL_ERROR)) != 0) {
369         core_level = LOG_LEVEL_ERROR;
370     }
371 
372     log_set_local_log_level(core_level);
373 }
374