1 /*
2 * Copyright (c) 2022 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 #ifndef LOG_IOCTL_H
17 #define LOG_IOCTL_H
18
19 #include <vector>
20 #include <functional>
21 #include <securec.h>
22
23 #include "hilog_common.h"
24 #include "log_utils.h"
25 #include "hilog_cmd.h"
26 #include "seq_packet_socket_client.h"
27
28 namespace OHOS {
29 namespace HiviewDFX {
30 using namespace std;
31
32 class LogIoctl {
33 public:
34 LogIoctl(IoctlCmd rqst, IoctlCmd rsp);
35 ~LogIoctl() = default;
36
37 template<typename T1, typename T2>
38 int Request(const T1& rqst, std::function<int(const T2& rsp)> handle);
39 int RequestOutput(const OutputRqst& rqst, std::function<int(const OutputRsp& rsp)> handle);
40 int RequestStatsQuery(const StatsQueryRqst& rqst, std::function<int(const StatsQueryRsp& rsp)> handle);
41
42 private:
43 SeqPacketSocketClient socket;
44 int socketInit = -1;
45 IoctlCmd rqstCmd;
46 IoctlCmd rspCmd;
47 static constexpr int DEFAULT_RECV_BUF_LEN = MAX_LOG_LEN * 2;
48
49 int SendMsgHeader(IoctlCmd cmd, size_t len);
50 int ReceiveMsgHeaer(MsgHeader& hdr);
51 int GetRsp(char* rsp, int len);
52 template<typename T1, typename T2>
53 int RequestMsgHead(const T1& rqst);
54
55 int ReceiveAndProcessOutputRsp(std::function<int(const OutputRsp& rsp)> handle);
56 int ReceiveAndProcessStatsQueryRsp(std::function<int(const StatsQueryRsp& rsp)> handle);
57 int ReceiveProcTagStats(StatsQueryRsp &rsp);
58 int ReceiveProcLogTypeStats(StatsQueryRsp &rsp);
59 int ReceiveProcStats(StatsQueryRsp &rsp);
60 int ReceiveDomainTagStats(StatsQueryRsp &rsp);
61 int ReceiveDomainStats(StatsQueryRsp &rsp);
62 int ReceiveLogTypeDomainStats(StatsQueryRsp &rsp);
63 void DeleteLogStatsInfo(StatsQueryRsp &rsp);
64 };
65
66 template<typename T1, typename T2>
RequestMsgHead(const T1 & rqst)67 int LogIoctl::RequestMsgHead(const T1& rqst)
68 {
69 // 0. Send reqeust message and process the response header
70 int ret = SendMsgHeader(rqstCmd, sizeof(T1));
71 if (ret != RET_SUCCESS) {
72 return ret;
73 }
74 ret = socket.WriteAll(reinterpret_cast<const char*>(&rqst), sizeof(T1));
75 if (ret < 0) {
76 return ERR_SOCKET_WRITE_CMD_FAIL;
77 }
78 // 1. Receive msg header
79 MsgHeader hdr = { 0 };
80 ret = ReceiveMsgHeaer(hdr);
81 if (ret != RET_SUCCESS) {
82 return ret;
83 }
84 if (hdr.cmd == static_cast<uint8_t>(IoctlCmd::RSP_ERROR)) {
85 return hdr.err;
86 }
87 if (hdr.cmd != static_cast<uint8_t>(rspCmd)) {
88 return RET_FAIL;
89 }
90 if (hdr.len != sizeof(T2)) {
91 return ERR_MSG_LEN_INVALID;
92 }
93 return RET_SUCCESS;
94 }
95
96 template<typename T1, typename T2>
Request(const T1 & rqst,std::function<int (const T2 & rsp)> handle)97 int LogIoctl::Request(const T1& rqst, std::function<int(const T2& rsp)> handle)
98 {
99 if (rqstCmd == IoctlCmd::OUTPUT_RQST || rqstCmd == IoctlCmd::STATS_QUERY_RQST) {
100 std::cout << "Request API not support this command" << endl;
101 return RET_FAIL;
102 }
103 int ret = RequestMsgHead<T1, T2>(rqst);
104 if (ret != RET_SUCCESS) {
105 return ret;
106 }
107 // common case, Get Response and callback
108 T2 rsp = { 0 };
109 ret = GetRsp(reinterpret_cast<char*>(&rsp), sizeof(T2));
110 if (ret != RET_SUCCESS) {
111 return ret;
112 }
113 return handle(rsp);
114 }
115 } // namespace HiviewDFX
116 } // namespace OHOS
117 #endif // LOG_IOCTL_H