1b049dde5Sopenharmony_ci/*
2b049dde5Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3b049dde5Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4b049dde5Sopenharmony_ci *
5b049dde5Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
6b049dde5Sopenharmony_ci * are permitted provided that the following conditions are met:
7b049dde5Sopenharmony_ci *
8b049dde5Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
9b049dde5Sopenharmony_ci *    conditions and the following disclaimer.
10b049dde5Sopenharmony_ci *
11b049dde5Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12b049dde5Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
13b049dde5Sopenharmony_ci *    provided with the distribution.
14b049dde5Sopenharmony_ci *
15b049dde5Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16b049dde5Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
17b049dde5Sopenharmony_ci *    permission.
18b049dde5Sopenharmony_ci *
19b049dde5Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20b049dde5Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21b049dde5Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b049dde5Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23b049dde5Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24b049dde5Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25b049dde5Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26b049dde5Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27b049dde5Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28b049dde5Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29b049dde5Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b049dde5Sopenharmony_ci */
31b049dde5Sopenharmony_ci
32b049dde5Sopenharmony_ci#include "hiview_hievent.h"
33b049dde5Sopenharmony_ci
34b049dde5Sopenharmony_ci#include <stdio.h>
35b049dde5Sopenharmony_ci#include <stdlib.h>
36b049dde5Sopenharmony_ci#include <errno.h>
37b049dde5Sopenharmony_ci#include <string.h>
38b049dde5Sopenharmony_ci
39b049dde5Sopenharmony_ci#include "los_memory.h"
40b049dde5Sopenharmony_ci#include "los_task_pri.h"
41b049dde5Sopenharmony_ci#include "los_process_pri.h"
42b049dde5Sopenharmony_ci#include "los_mux.h"
43b049dde5Sopenharmony_ci#include "los_mp.h"
44b049dde5Sopenharmony_ci#include "los_typedef.h"
45b049dde5Sopenharmony_ci
46b049dde5Sopenharmony_ci#include "hievent_driver.h"
47b049dde5Sopenharmony_ci
48b049dde5Sopenharmony_ci#define INT_TYPE_MAX_LEN    21
49b049dde5Sopenharmony_ci
50b049dde5Sopenharmony_ci#define MAX_PATH_LEN        256
51b049dde5Sopenharmony_ci#define MAX_STR_LEN         (10 * 1024)
52b049dde5Sopenharmony_ci
53b049dde5Sopenharmony_ci/* 64K is max length of /dev/hwlog_exception */
54b049dde5Sopenharmony_ci#define EVENT_INFO_BUF_LEN         (64 * 1024)
55b049dde5Sopenharmony_ci#define EVENT_INFO_PACK_BUF_LEN    (2 * 1024)
56b049dde5Sopenharmony_ci
57b049dde5Sopenharmony_ci#define HWLOG_ERR  PRINT_ERR
58b049dde5Sopenharmony_ci#define HWLOG_INFO PRINT_INFO
59b049dde5Sopenharmony_ci
60b049dde5Sopenharmony_ci#define BUF_POINTER_FORWARD                     \
61b049dde5Sopenharmony_ci    do {                                        \
62b049dde5Sopenharmony_ci        if (tmplen < len) {                     \
63b049dde5Sopenharmony_ci            tmp += tmplen;                      \
64b049dde5Sopenharmony_ci            len -= tmplen;                      \
65b049dde5Sopenharmony_ci        } else {                                \
66b049dde5Sopenharmony_ci            HWLOG_ERR("string over length");    \
67b049dde5Sopenharmony_ci            tmp += len;                         \
68b049dde5Sopenharmony_ci            len = 0;                            \
69b049dde5Sopenharmony_ci        }                                       \
70b049dde5Sopenharmony_ci    } while (0)
71b049dde5Sopenharmony_ci
72b049dde5Sopenharmony_cistruct HiviewHieventPayload {
73b049dde5Sopenharmony_ci    char *key;
74b049dde5Sopenharmony_ci    char *value;
75b049dde5Sopenharmony_ci    struct HiviewHieventPayload *next;
76b049dde5Sopenharmony_ci};
77b049dde5Sopenharmony_ci
78b049dde5Sopenharmony_cistatic int HiviewHieventConvertString(struct HiviewHievent *event, char **pbuf);
79b049dde5Sopenharmony_ci
80b049dde5Sopenharmony_cistatic struct HiviewHieventPayload *HiviewHieventPayloadCreate(void);
81b049dde5Sopenharmony_ci
82b049dde5Sopenharmony_cistatic void HiviewHieventPayloadDestroy(struct HiviewHieventPayload *p);
83b049dde5Sopenharmony_ci
84b049dde5Sopenharmony_cistatic struct HiviewHieventPayload *HiviewHieventGetPayload(struct HiviewHieventPayload *head,
85b049dde5Sopenharmony_ci                                                            const char *key);
86b049dde5Sopenharmony_ci
87b049dde5Sopenharmony_cistatic void HiviewHieventAddPayload(struct HiviewHievent *obj,
88b049dde5Sopenharmony_ci                                    struct HiviewHieventPayload *payload);
89b049dde5Sopenharmony_ci
90b049dde5Sopenharmony_cistatic struct HiviewHieventPayload *HiviewHieventPayloadCreate(void)
91b049dde5Sopenharmony_ci{
92b049dde5Sopenharmony_ci    struct HiviewHieventPayload *payload = NULL;
93b049dde5Sopenharmony_ci
94b049dde5Sopenharmony_ci    payload = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR,
95b049dde5Sopenharmony_ci                           sizeof(struct HiviewHieventPayload));
96b049dde5Sopenharmony_ci    if (!payload) {
97b049dde5Sopenharmony_ci        return NULL;
98b049dde5Sopenharmony_ci    }
99b049dde5Sopenharmony_ci
100b049dde5Sopenharmony_ci    payload->key = NULL;
101b049dde5Sopenharmony_ci    payload->value = NULL;
102b049dde5Sopenharmony_ci    payload->next = NULL;
103b049dde5Sopenharmony_ci
104b049dde5Sopenharmony_ci    return payload;
105b049dde5Sopenharmony_ci}
106b049dde5Sopenharmony_ci
107b049dde5Sopenharmony_cistatic void HiviewHieventPayloadDestroy(struct HiviewHieventPayload *p)
108b049dde5Sopenharmony_ci{
109b049dde5Sopenharmony_ci    if (!p) {
110b049dde5Sopenharmony_ci        return;
111b049dde5Sopenharmony_ci    }
112b049dde5Sopenharmony_ci
113b049dde5Sopenharmony_ci    if (p->value) {
114b049dde5Sopenharmony_ci        LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, p->value);
115b049dde5Sopenharmony_ci    }
116b049dde5Sopenharmony_ci
117b049dde5Sopenharmony_ci    LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, p->key);
118b049dde5Sopenharmony_ci    LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, p);
119b049dde5Sopenharmony_ci}
120b049dde5Sopenharmony_ci
121b049dde5Sopenharmony_cistatic struct HiviewHieventPayload *HiviewHieventGetPayload(struct HiviewHieventPayload *head,
122b049dde5Sopenharmony_ci                                                            const char *key)
123b049dde5Sopenharmony_ci{
124b049dde5Sopenharmony_ci    struct HiviewHieventPayload *p = head;
125b049dde5Sopenharmony_ci
126b049dde5Sopenharmony_ci    while (p) {
127b049dde5Sopenharmony_ci        if (key && p->key) {
128b049dde5Sopenharmony_ci            if (strcmp(p->key, key) == 0) {
129b049dde5Sopenharmony_ci                return p;
130b049dde5Sopenharmony_ci            }
131b049dde5Sopenharmony_ci        }
132b049dde5Sopenharmony_ci        p = p->next;
133b049dde5Sopenharmony_ci    }
134b049dde5Sopenharmony_ci
135b049dde5Sopenharmony_ci    return NULL;
136b049dde5Sopenharmony_ci}
137b049dde5Sopenharmony_ci
138b049dde5Sopenharmony_cistatic void HiviewHieventAddPayload(struct HiviewHievent *obj,
139b049dde5Sopenharmony_ci                                    struct HiviewHieventPayload *payload)
140b049dde5Sopenharmony_ci{
141b049dde5Sopenharmony_ci    if (!obj->head) {
142b049dde5Sopenharmony_ci        obj->head = payload;
143b049dde5Sopenharmony_ci    } else {
144b049dde5Sopenharmony_ci        struct HiviewHieventPayload *p = obj->head;
145b049dde5Sopenharmony_ci
146b049dde5Sopenharmony_ci        while (p->next) {
147b049dde5Sopenharmony_ci            p = p->next;
148b049dde5Sopenharmony_ci        }
149b049dde5Sopenharmony_ci        p->next = payload;
150b049dde5Sopenharmony_ci    }
151b049dde5Sopenharmony_ci}
152b049dde5Sopenharmony_ci
153b049dde5Sopenharmony_cistruct HiviewHievent *HiviewHieventCreate(unsigned int eventid)
154b049dde5Sopenharmony_ci{
155b049dde5Sopenharmony_ci    struct HiviewHievent *event = NULL;
156b049dde5Sopenharmony_ci
157b049dde5Sopenharmony_ci    /* combined event obj struct */
158b049dde5Sopenharmony_ci    event = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(*event));
159b049dde5Sopenharmony_ci    if (!event) {
160b049dde5Sopenharmony_ci        return NULL;
161b049dde5Sopenharmony_ci    }
162b049dde5Sopenharmony_ci
163b049dde5Sopenharmony_ci    (VOID)memset_s(event, sizeof(*event), 0, sizeof(*event));
164b049dde5Sopenharmony_ci    event->eventid = eventid;
165b049dde5Sopenharmony_ci    HWLOG_INFO("%s : %u\n", __func__, eventid);
166b049dde5Sopenharmony_ci
167b049dde5Sopenharmony_ci    return (void *)event;
168b049dde5Sopenharmony_ci}
169b049dde5Sopenharmony_ci
170b049dde5Sopenharmony_ciint HiviewHieventPutIntegral(struct HiviewHievent *event,
171b049dde5Sopenharmony_ci                             const char *key, long value)
172b049dde5Sopenharmony_ci{
173b049dde5Sopenharmony_ci    int ret;
174b049dde5Sopenharmony_ci    struct HiviewHieventPayload *payload = NULL;
175b049dde5Sopenharmony_ci
176b049dde5Sopenharmony_ci    if ((!event) || (!key)) {
177b049dde5Sopenharmony_ci        HWLOG_ERR("Bad input event or key for %s", __func__);
178b049dde5Sopenharmony_ci        return -EINVAL;
179b049dde5Sopenharmony_ci    }
180b049dde5Sopenharmony_ci
181b049dde5Sopenharmony_ci    payload = HiviewHieventGetPayload(event->head, key);
182b049dde5Sopenharmony_ci    if (!payload) {
183b049dde5Sopenharmony_ci        payload = HiviewHieventPayloadCreate();
184b049dde5Sopenharmony_ci        if (!payload) {
185b049dde5Sopenharmony_ci            return -ENOMEM;
186b049dde5Sopenharmony_ci        }
187b049dde5Sopenharmony_ci        payload->key = strdup(key);
188b049dde5Sopenharmony_ci        HiviewHieventAddPayload(event, payload);
189b049dde5Sopenharmony_ci    }
190b049dde5Sopenharmony_ci
191b049dde5Sopenharmony_ci    if (payload->value) {
192b049dde5Sopenharmony_ci        LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, payload->value);
193b049dde5Sopenharmony_ci    }
194b049dde5Sopenharmony_ci
195b049dde5Sopenharmony_ci    payload->value = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, INT_TYPE_MAX_LEN);
196b049dde5Sopenharmony_ci    if (!payload->value) {
197b049dde5Sopenharmony_ci        return -ENOMEM;
198b049dde5Sopenharmony_ci    }
199b049dde5Sopenharmony_ci    (VOID)memset_s(payload->value, INT_TYPE_MAX_LEN, 0, INT_TYPE_MAX_LEN);
200b049dde5Sopenharmony_ci    ret = snprintf_s(payload->value, INT_TYPE_MAX_LEN, INT_TYPE_MAX_LEN - 1,
201b049dde5Sopenharmony_ci                     "%d", (int)value);
202b049dde5Sopenharmony_ci    if (ret < 0) {
203b049dde5Sopenharmony_ci        return -ENOMEM;
204b049dde5Sopenharmony_ci    }
205b049dde5Sopenharmony_ci
206b049dde5Sopenharmony_ci    return 0;
207b049dde5Sopenharmony_ci}
208b049dde5Sopenharmony_ci
209b049dde5Sopenharmony_ciint HiviewHieventPutString(struct HiviewHievent *event,
210b049dde5Sopenharmony_ci                           const char *key, const char *value)
211b049dde5Sopenharmony_ci{
212b049dde5Sopenharmony_ci    struct HiviewHieventPayload *payload = NULL;
213b049dde5Sopenharmony_ci    int len;
214b049dde5Sopenharmony_ci
215b049dde5Sopenharmony_ci    if ((!event) || (!key) || (!value)) {
216b049dde5Sopenharmony_ci        HWLOG_ERR("Bad key for %s", __func__);
217b049dde5Sopenharmony_ci        return -EINVAL;
218b049dde5Sopenharmony_ci    }
219b049dde5Sopenharmony_ci
220b049dde5Sopenharmony_ci    payload = HiviewHieventGetPayload(event->head, key);
221b049dde5Sopenharmony_ci    if (!payload) {
222b049dde5Sopenharmony_ci        payload = HiviewHieventPayloadCreate();
223b049dde5Sopenharmony_ci        if (!payload) {
224b049dde5Sopenharmony_ci            return -ENOMEM;
225b049dde5Sopenharmony_ci        }
226b049dde5Sopenharmony_ci        payload->key = strdup(key);
227b049dde5Sopenharmony_ci        HiviewHieventAddPayload(event, payload);
228b049dde5Sopenharmony_ci    }
229b049dde5Sopenharmony_ci
230b049dde5Sopenharmony_ci    if (payload->value) {
231b049dde5Sopenharmony_ci        LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, payload->value);
232b049dde5Sopenharmony_ci    }
233b049dde5Sopenharmony_ci
234b049dde5Sopenharmony_ci    len = strlen(value);
235b049dde5Sopenharmony_ci    /* prevent length larger than MAX_STR_LEN */
236b049dde5Sopenharmony_ci    if (len > MAX_STR_LEN) {
237b049dde5Sopenharmony_ci        len = MAX_STR_LEN;
238b049dde5Sopenharmony_ci    }
239b049dde5Sopenharmony_ci    payload->value = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, len + 1);
240b049dde5Sopenharmony_ci    if (!payload->value) {
241b049dde5Sopenharmony_ci        return -ENOMEM;
242b049dde5Sopenharmony_ci    }
243b049dde5Sopenharmony_ci    (VOID)memset_s(payload->value, len + 1, 0, len + 1);
244b049dde5Sopenharmony_ci    if (EOK == strncpy_s(payload->value, len + 1, value, len)) {
245b049dde5Sopenharmony_ci        payload->value[len] = '\0';
246b049dde5Sopenharmony_ci    }
247b049dde5Sopenharmony_ci
248b049dde5Sopenharmony_ci    return 0;
249b049dde5Sopenharmony_ci}
250b049dde5Sopenharmony_ci
251b049dde5Sopenharmony_ciint HiviewHieventSetTime(struct HiviewHievent *event, long long seconds)
252b049dde5Sopenharmony_ci{
253b049dde5Sopenharmony_ci    if ((!event) || (seconds == 0)) {
254b049dde5Sopenharmony_ci        HWLOG_ERR("Bad input for %s", __func__);
255b049dde5Sopenharmony_ci        return -EINVAL;
256b049dde5Sopenharmony_ci    }
257b049dde5Sopenharmony_ci    event->time = seconds;
258b049dde5Sopenharmony_ci    return 0;
259b049dde5Sopenharmony_ci}
260b049dde5Sopenharmony_ci
261b049dde5Sopenharmony_cistatic int AppendArrayItem(char **pool, int poolLen, const char *path)
262b049dde5Sopenharmony_ci{
263b049dde5Sopenharmony_ci    int i;
264b049dde5Sopenharmony_ci
265b049dde5Sopenharmony_ci    if ((!path) || (path[0] == 0)) {
266b049dde5Sopenharmony_ci        HWLOG_ERR("Bad path %s", __func__);
267b049dde5Sopenharmony_ci        return -EINVAL;
268b049dde5Sopenharmony_ci    }
269b049dde5Sopenharmony_ci
270b049dde5Sopenharmony_ci    if (strlen(path) > MAX_PATH_LEN) {
271b049dde5Sopenharmony_ci        HWLOG_ERR("file path over max: %d", MAX_PATH_LEN);
272b049dde5Sopenharmony_ci        return -EINVAL;
273b049dde5Sopenharmony_ci    }
274b049dde5Sopenharmony_ci
275b049dde5Sopenharmony_ci    for (i = 0; i < poolLen; i++) {
276b049dde5Sopenharmony_ci        if (pool[i] != 0) {
277b049dde5Sopenharmony_ci            continue;
278b049dde5Sopenharmony_ci        }
279b049dde5Sopenharmony_ci        pool[i] = strdup(path);
280b049dde5Sopenharmony_ci        if (pool[i] == NULL) {
281b049dde5Sopenharmony_ci            return -ENOMEM;
282b049dde5Sopenharmony_ci        }
283b049dde5Sopenharmony_ci        break;
284b049dde5Sopenharmony_ci    }
285b049dde5Sopenharmony_ci
286b049dde5Sopenharmony_ci    if (i == MAX_PATH_NUMBER) {
287b049dde5Sopenharmony_ci        HWLOG_ERR("Too many paths");
288b049dde5Sopenharmony_ci        return -EINVAL;
289b049dde5Sopenharmony_ci    }
290b049dde5Sopenharmony_ci
291b049dde5Sopenharmony_ci    return 0;
292b049dde5Sopenharmony_ci}
293b049dde5Sopenharmony_ci
294b049dde5Sopenharmony_ciint HiviewHieventAddFilePath(struct HiviewHievent *event, const char *path)
295b049dde5Sopenharmony_ci{
296b049dde5Sopenharmony_ci    if (!event) {
297b049dde5Sopenharmony_ci        HWLOG_ERR("Bad path %s", __func__);
298b049dde5Sopenharmony_ci        return -EINVAL;
299b049dde5Sopenharmony_ci    }
300b049dde5Sopenharmony_ci    return AppendArrayItem(event->filePath, MAX_PATH_NUMBER, path);
301b049dde5Sopenharmony_ci}
302b049dde5Sopenharmony_ci
303b049dde5Sopenharmony_ci/* make string ":" to "::", ";" to ";;", and remove newline character
304b049dde5Sopenharmony_ci * for example: "abc:def;ghi" transfer to "abc::def;;ghi"
305b049dde5Sopenharmony_ci */
306b049dde5Sopenharmony_cistatic char *HiviewHieventMakeRegular(char *value)
307b049dde5Sopenharmony_ci{
308b049dde5Sopenharmony_ci    int count = 0;
309b049dde5Sopenharmony_ci    int len = 0;
310b049dde5Sopenharmony_ci    char *temp = value;
311b049dde5Sopenharmony_ci    char *regular = NULL;
312b049dde5Sopenharmony_ci    char *regularTemp = NULL;
313b049dde5Sopenharmony_ci
314b049dde5Sopenharmony_ci    while (*temp != '\0') {
315b049dde5Sopenharmony_ci        if (*temp == ':') {
316b049dde5Sopenharmony_ci            count++;
317b049dde5Sopenharmony_ci        } else if (*temp == ';') {
318b049dde5Sopenharmony_ci            count++;
319b049dde5Sopenharmony_ci        } else if ((*temp == '\n') || (*temp == '\r')) {
320b049dde5Sopenharmony_ci            *temp = ' ';
321b049dde5Sopenharmony_ci        }
322b049dde5Sopenharmony_ci        temp++;
323b049dde5Sopenharmony_ci        len++;
324b049dde5Sopenharmony_ci    }
325b049dde5Sopenharmony_ci
326b049dde5Sopenharmony_ci    /* no need to transfer, just return old value */
327b049dde5Sopenharmony_ci    if (count == 0) {
328b049dde5Sopenharmony_ci        return value;
329b049dde5Sopenharmony_ci    }
330b049dde5Sopenharmony_ci
331b049dde5Sopenharmony_ci    size_t regularLen = len + count * 2 + 1; // 2 char in a byte
332b049dde5Sopenharmony_ci    regular = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, regularLen);
333b049dde5Sopenharmony_ci    if (!regular) {
334b049dde5Sopenharmony_ci        return NULL;
335b049dde5Sopenharmony_ci    }
336b049dde5Sopenharmony_ci    (VOID)memset_s(regular, regularLen, 0, regularLen);
337b049dde5Sopenharmony_ci    regularTemp = regular;
338b049dde5Sopenharmony_ci    temp = value;
339b049dde5Sopenharmony_ci    while (*temp != 0) {
340b049dde5Sopenharmony_ci        if ((*temp == ':') || (*temp == ';')) {
341b049dde5Sopenharmony_ci            *regularTemp++ = *temp;
342b049dde5Sopenharmony_ci        }
343b049dde5Sopenharmony_ci        *regularTemp++ = *temp;
344b049dde5Sopenharmony_ci        temp++;
345b049dde5Sopenharmony_ci    }
346b049dde5Sopenharmony_ci    *regularTemp = '\0';
347b049dde5Sopenharmony_ci
348b049dde5Sopenharmony_ci    return regular;
349b049dde5Sopenharmony_ci}
350b049dde5Sopenharmony_ci
351b049dde5Sopenharmony_ciint LogBufToException(char category, int level, char logType,
352b049dde5Sopenharmony_ci                      char sn, const char *msg, int msglen)
353b049dde5Sopenharmony_ci{
354b049dde5Sopenharmony_ci    struct IdapHeader *hdr;
355b049dde5Sopenharmony_ci    size_t bufLen = sizeof(int) + sizeof(struct IdapHeader) + msglen;
356b049dde5Sopenharmony_ci    char *buffer = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, bufLen);
357b049dde5Sopenharmony_ci    if (!buffer) {
358b049dde5Sopenharmony_ci        return -ENOMEM;
359b049dde5Sopenharmony_ci    }
360b049dde5Sopenharmony_ci
361b049dde5Sopenharmony_ci    int *checkCode = (int *)buffer;
362b049dde5Sopenharmony_ci    *checkCode = CHECK_CODE;
363b049dde5Sopenharmony_ci
364b049dde5Sopenharmony_ci    hdr = (struct IdapHeader *)(buffer + sizeof(int));
365b049dde5Sopenharmony_ci    hdr->level = level;
366b049dde5Sopenharmony_ci    hdr->category = category;
367b049dde5Sopenharmony_ci    hdr->logType = logType;
368b049dde5Sopenharmony_ci    hdr->sn = sn;
369b049dde5Sopenharmony_ci
370b049dde5Sopenharmony_ci    int ret = memcpy_s(buffer + sizeof(int) + sizeof(struct IdapHeader),
371b049dde5Sopenharmony_ci                       msglen, msg, msglen);
372b049dde5Sopenharmony_ci    if (ret != EOK) {
373b049dde5Sopenharmony_ci        goto out;
374b049dde5Sopenharmony_ci    }
375b049dde5Sopenharmony_ci
376b049dde5Sopenharmony_ci    ret = HieventWriteInternal(buffer, bufLen);
377b049dde5Sopenharmony_ci
378b049dde5Sopenharmony_ciout:
379b049dde5Sopenharmony_ci    LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, buffer);
380b049dde5Sopenharmony_ci
381b049dde5Sopenharmony_ci    return ret;
382b049dde5Sopenharmony_ci}
383b049dde5Sopenharmony_ci
384b049dde5Sopenharmony_cistatic int HiviewHieventFillPayload(struct HiviewHievent *event, char **pbuf,
385b049dde5Sopenharmony_ci                                    char *tmp, int length)
386b049dde5Sopenharmony_ci{
387b049dde5Sopenharmony_ci    struct HiviewHieventPayload *p = event->head;
388b049dde5Sopenharmony_ci    int len = length;
389b049dde5Sopenharmony_ci    int tmplen = 0;
390b049dde5Sopenharmony_ci    unsigned int keycount = 0;
391b049dde5Sopenharmony_ci    while (p) {
392b049dde5Sopenharmony_ci        char *value = NULL;
393b049dde5Sopenharmony_ci        char *regularValue = NULL;
394b049dde5Sopenharmony_ci        int needFree = 1;
395b049dde5Sopenharmony_ci
396b049dde5Sopenharmony_ci        if (!p->value) {
397b049dde5Sopenharmony_ci            p = p->next;
398b049dde5Sopenharmony_ci            continue;
399b049dde5Sopenharmony_ci        }
400b049dde5Sopenharmony_ci        if (keycount == 0) {
401b049dde5Sopenharmony_ci            tmplen = snprintf_s(tmp, len, len - 1, " --extra ");
402b049dde5Sopenharmony_ci            BUF_POINTER_FORWARD;
403b049dde5Sopenharmony_ci        }
404b049dde5Sopenharmony_ci        keycount++;
405b049dde5Sopenharmony_ci
406b049dde5Sopenharmony_ci        /* fill key */
407b049dde5Sopenharmony_ci        if (p->key) {
408b049dde5Sopenharmony_ci            tmplen = snprintf_s(tmp, len, len - 1, "%s:", p->key);
409b049dde5Sopenharmony_ci        }
410b049dde5Sopenharmony_ci        BUF_POINTER_FORWARD;
411b049dde5Sopenharmony_ci        /* fill value */
412b049dde5Sopenharmony_ci        tmplen = 0;
413b049dde5Sopenharmony_ci
414b049dde5Sopenharmony_ci        value = p->value;
415b049dde5Sopenharmony_ci        regularValue = HiviewHieventMakeRegular(value);
416b049dde5Sopenharmony_ci        if (!regularValue) {
417b049dde5Sopenharmony_ci            regularValue = "NULL";
418b049dde5Sopenharmony_ci            needFree = 0;
419b049dde5Sopenharmony_ci        }
420b049dde5Sopenharmony_ci        tmplen = snprintf_s(tmp, len, len - 1, "%s;", regularValue);
421b049dde5Sopenharmony_ci        if ((value != regularValue) && needFree) {
422b049dde5Sopenharmony_ci            free(regularValue);
423b049dde5Sopenharmony_ci        }
424b049dde5Sopenharmony_ci        BUF_POINTER_FORWARD;
425b049dde5Sopenharmony_ci        p = p->next;
426b049dde5Sopenharmony_ci    }
427b049dde5Sopenharmony_ci    return len;
428b049dde5Sopenharmony_ci}
429b049dde5Sopenharmony_ci
430b049dde5Sopenharmony_cistatic int HiviewHieventConvertString(struct HiviewHievent *event, char **pbuf)
431b049dde5Sopenharmony_ci{
432b049dde5Sopenharmony_ci    int len;
433b049dde5Sopenharmony_ci    char *tmp = NULL;
434b049dde5Sopenharmony_ci    int tmplen = 0;
435b049dde5Sopenharmony_ci    unsigned int i;
436b049dde5Sopenharmony_ci
437b049dde5Sopenharmony_ci    char *buf = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, EVENT_INFO_BUF_LEN);
438b049dde5Sopenharmony_ci    if (!buf) {
439b049dde5Sopenharmony_ci        *pbuf = NULL;
440b049dde5Sopenharmony_ci        return 0;
441b049dde5Sopenharmony_ci    }
442b049dde5Sopenharmony_ci    (VOID)memset_s(buf, EVENT_INFO_BUF_LEN, 0, EVENT_INFO_BUF_LEN);
443b049dde5Sopenharmony_ci    len = EVENT_INFO_BUF_LEN;
444b049dde5Sopenharmony_ci    tmp = buf;
445b049dde5Sopenharmony_ci
446b049dde5Sopenharmony_ci    /* fill eventid */
447b049dde5Sopenharmony_ci    tmplen = snprintf_s(tmp, len, len - 1, "eventid %d", event->eventid);
448b049dde5Sopenharmony_ci    BUF_POINTER_FORWARD;
449b049dde5Sopenharmony_ci
450b049dde5Sopenharmony_ci    /* fill the path */
451b049dde5Sopenharmony_ci    for (i = 0; i < MAX_PATH_NUMBER; i++) {
452b049dde5Sopenharmony_ci        if (!event->filePath[i]) {
453b049dde5Sopenharmony_ci            break;
454b049dde5Sopenharmony_ci        }
455b049dde5Sopenharmony_ci        tmplen = snprintf_s(tmp, len, len - 1, " -i %s",
456b049dde5Sopenharmony_ci                            event->filePath[i]);
457b049dde5Sopenharmony_ci        BUF_POINTER_FORWARD;
458b049dde5Sopenharmony_ci    }
459b049dde5Sopenharmony_ci
460b049dde5Sopenharmony_ci    /* fill time */
461b049dde5Sopenharmony_ci    if (event->time) {
462b049dde5Sopenharmony_ci        tmplen = snprintf_s(tmp, len, len - 1, " -t %lld",  event->time);
463b049dde5Sopenharmony_ci        BUF_POINTER_FORWARD;
464b049dde5Sopenharmony_ci    }
465b049dde5Sopenharmony_ci
466b049dde5Sopenharmony_ci    /* fill the payload info */
467b049dde5Sopenharmony_ci    len = HiviewHieventFillPayload(event, pbuf, tmp, len);
468b049dde5Sopenharmony_ci    *pbuf = buf;
469b049dde5Sopenharmony_ci    return (EVENT_INFO_BUF_LEN - len);
470b049dde5Sopenharmony_ci}
471b049dde5Sopenharmony_ci
472b049dde5Sopenharmony_ci#define IDAP_LOGTYPE_CMD 1
473b049dde5Sopenharmony_cistatic int HiviewHieventWriteLogException(char *str, const int strlen)
474b049dde5Sopenharmony_ci{
475b049dde5Sopenharmony_ci    char tempchr;
476b049dde5Sopenharmony_ci    char *strptr = str;
477b049dde5Sopenharmony_ci    int leftBufLen = strlen + 1;
478b049dde5Sopenharmony_ci    int sentcnt = 0;
479b049dde5Sopenharmony_ci
480b049dde5Sopenharmony_ci    while (leftBufLen > 0) {
481b049dde5Sopenharmony_ci        if (leftBufLen > EVENT_INFO_PACK_BUF_LEN) {
482b049dde5Sopenharmony_ci            tempchr = strptr[EVENT_INFO_PACK_BUF_LEN - 1];
483b049dde5Sopenharmony_ci            strptr[EVENT_INFO_PACK_BUF_LEN - 1] = '\0';
484b049dde5Sopenharmony_ci            (void)LogBufToException(0, 0, IDAP_LOGTYPE_CMD, 1,
485b049dde5Sopenharmony_ci                                    strptr, EVENT_INFO_PACK_BUF_LEN);
486b049dde5Sopenharmony_ci            leftBufLen -= (EVENT_INFO_PACK_BUF_LEN - 1);
487b049dde5Sopenharmony_ci            strptr += (EVENT_INFO_PACK_BUF_LEN - 1);
488b049dde5Sopenharmony_ci            strptr[0] = tempchr;
489b049dde5Sopenharmony_ci            sentcnt++;
490b049dde5Sopenharmony_ci        } else {
491b049dde5Sopenharmony_ci            (void)LogBufToException(0, 0, IDAP_LOGTYPE_CMD, 0,
492b049dde5Sopenharmony_ci                                    strptr, leftBufLen);
493b049dde5Sopenharmony_ci            sentcnt++;
494b049dde5Sopenharmony_ci            break;
495b049dde5Sopenharmony_ci        }
496b049dde5Sopenharmony_ci    }
497b049dde5Sopenharmony_ci
498b049dde5Sopenharmony_ci    return sentcnt;
499b049dde5Sopenharmony_ci}
500b049dde5Sopenharmony_ci
501b049dde5Sopenharmony_ciint HiviewHieventReport(struct HiviewHievent *obj)
502b049dde5Sopenharmony_ci{
503b049dde5Sopenharmony_ci    char *str = NULL;
504b049dde5Sopenharmony_ci    int bufLen;
505b049dde5Sopenharmony_ci    int sentPacket;
506b049dde5Sopenharmony_ci
507b049dde5Sopenharmony_ci    if (!obj) {
508b049dde5Sopenharmony_ci        HWLOG_ERR("Bad event %s", __func__);
509b049dde5Sopenharmony_ci        return -EINVAL;
510b049dde5Sopenharmony_ci    }
511b049dde5Sopenharmony_ci
512b049dde5Sopenharmony_ci    bufLen = HiviewHieventConvertString(obj, &str);
513b049dde5Sopenharmony_ci    if (!str) {
514b049dde5Sopenharmony_ci        return -EINVAL;
515b049dde5Sopenharmony_ci    }
516b049dde5Sopenharmony_ci    sentPacket = HiviewHieventWriteLogException(str, bufLen);
517b049dde5Sopenharmony_ci    HWLOG_INFO("report: %s", str);
518b049dde5Sopenharmony_ci    LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, str);
519b049dde5Sopenharmony_ci
520b049dde5Sopenharmony_ci    return sentPacket;
521b049dde5Sopenharmony_ci}
522b049dde5Sopenharmony_ci
523b049dde5Sopenharmony_civoid HiviewHieventDestroy(struct HiviewHievent *event)
524b049dde5Sopenharmony_ci{
525b049dde5Sopenharmony_ci    int i;
526b049dde5Sopenharmony_ci    struct HiviewHieventPayload *p = NULL;
527b049dde5Sopenharmony_ci
528b049dde5Sopenharmony_ci    if (!event) {
529b049dde5Sopenharmony_ci        return;
530b049dde5Sopenharmony_ci    }
531b049dde5Sopenharmony_ci    p = event->head;
532b049dde5Sopenharmony_ci    while (p) {
533b049dde5Sopenharmony_ci        struct HiviewHieventPayload *del = p;
534b049dde5Sopenharmony_ci
535b049dde5Sopenharmony_ci        p = p->next;
536b049dde5Sopenharmony_ci        HiviewHieventPayloadDestroy(del);
537b049dde5Sopenharmony_ci    }
538b049dde5Sopenharmony_ci    event->head = NULL;
539b049dde5Sopenharmony_ci    for (i = 0; i < MAX_PATH_NUMBER; i++) {
540b049dde5Sopenharmony_ci        LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, event->filePath[i]);
541b049dde5Sopenharmony_ci        event->filePath[i] = NULL;
542b049dde5Sopenharmony_ci    }
543b049dde5Sopenharmony_ci    LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, event);
544b049dde5Sopenharmony_ci}
545b049dde5Sopenharmony_ci
546b049dde5Sopenharmony_civoid HiviewHieventFlush(void)
547b049dde5Sopenharmony_ci{
548b049dde5Sopenharmony_ci    // magic number 0x7BBE69BD for notify hiview to flush hievent file
549b049dde5Sopenharmony_ci    struct HiviewHievent *hievent = HiviewHieventCreate(0x7BBE69BD);
550b049dde5Sopenharmony_ci    (void)HiviewHieventReport(hievent);
551b049dde5Sopenharmony_ci    HiviewHieventDestroy(hievent);
552b049dde5Sopenharmony_ci}
553