1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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 */
15
16#include "kmsg_parser.h"
17#include "hilog/log.h"
18
19#include <cstdlib>
20#include <cinttypes>
21#include <iostream>
22#include <string>
23#include <thread>
24#include <chrono>
25#include <fstream>
26#include <regex>
27#include <sys/time.h>
28#include <unistd.h>
29#include <fcntl.h>
30#include <sys/types.h>
31#include <string_view>
32
33namespace OHOS {
34namespace HiviewDFX {
35using namespace std::chrono;
36using namespace std::literals;
37
38// Avoid name collision between sys/syslog.h and our log_c.h
39#undef LOG_FATAL
40#undef LOG_ERR
41#undef LOG_WARN
42#undef LOG_INFO
43#undef LOG_DEBUG
44
45using Priority = enum {
46    PV0 = 0,
47    PV1,
48    PV2,
49    PV3,
50    PV4,
51    PV5,
52    PV6
53};
54
55// Log levels are different in syslog.h and hilog log_c.h
56static uint16_t KmsgLevelMap(uint16_t prio)
57{
58    uint16_t level;
59    switch (prio) {
60        case Priority::PV0:
61        case Priority::PV1:
62        case Priority::PV2:
63            level = LOG_FATAL;
64            break;
65        case Priority::PV3:
66            level = LOG_ERROR;
67            break;
68        case Priority::PV4:
69        case Priority::PV5:
70            level = LOG_WARN;
71            break;
72        case Priority::PV6:
73            level = LOG_INFO;
74            break;
75        default:
76            level = LOG_DEBUG;
77            break;
78    }
79    return level;
80}
81
82std::optional<HilogMsgWrapper> KmsgParser::ParseKmsg(const std::vector<char>& kmsgBuffer)
83{
84    std::string kmsgStr(kmsgBuffer.data());
85    std::string tagStr = "";
86    size_t tagLen = tagStr.size();
87    // Now build HilogMsg and insert it into buffer
88    auto len = kmsgStr.size() + 1;
89    auto msgLen = sizeof(HilogMsg) + tagLen + len + 1;
90    HilogMsgWrapper msgWrap((std::vector<char>(msgLen, '\0')));
91    HilogMsg& msg = msgWrap.GetHilogMsg();
92    msg.len = msgLen;
93    msg.tagLen = tagLen + 1;
94    msg.type = LOG_KMSG;
95    msg.level = KmsgLevelMap(LOG_INFO);
96    struct timespec ts = {0};
97    (void)clock_gettime(CLOCK_REALTIME, &ts);
98    msg.tv_sec = static_cast<uint32_t>(ts.tv_sec);
99    msg.tv_nsec = static_cast<uint32_t>(ts.tv_nsec);
100    if (strncpy_s(msg.tag, tagLen + 1, tagStr.c_str(), tagLen) != 0) {
101        return {};
102    }
103    if (strncpy_s(CONTENT_PTR((&msg)), MAX_LOG_LEN, kmsgStr.c_str(), len) != 0) {
104        return {};
105    }
106    return msgWrap;
107}
108} // namespace HiviewDFX
109} // namespace OHOS
110