Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "atrace_client_communication.h"
12 : #include "adcore_api.h"
13 : #include "adiag_print.h"
14 : #include "securec.h"
15 : #include "trace_msg.h"
16 :
17 : #define MSG_MAX_LEN 1024U
18 :
19 : STATIC TraStatus
20 462 : AtraceClientCreatePacket(int32_t devId, const char* value, uint32_t valueLen, void** buf, uint32_t* bufLen)
21 : {
22 462 : if (value == NULL || buf == NULL || bufLen == NULL) {
23 0 : ADIAG_ERR("input invalid parameter");
24 0 : return TRACE_FAILURE;
25 : }
26 :
27 462 : if (valueLen + sizeof(struct tlv_req) + 1U > INT32_MAX) {
28 0 : ADIAG_ERR("bigger than INT32_MAX, value_len: %u bytes, tlv_len: %zu bytes", valueLen, sizeof(struct tlv_req));
29 0 : return TRACE_FAILURE;
30 : }
31 :
32 462 : uint32_t mallocValueLen = valueLen + 1U;
33 462 : uint32_t sendLen = (uint32_t)sizeof(struct tlv_req) + mallocValueLen;
34 462 : char* sendBuf = (char*)AdiagMalloc(sendLen);
35 462 : if (sendBuf == NULL) {
36 0 : ADIAG_ERR("malloc memory failed");
37 0 : return TRACE_FAILURE;
38 : }
39 462 : IdeTlvReq req = (IdeTlvReq)sendBuf;
40 462 : req->type = IDE_TRACE_REQ;
41 462 : req->dev_id = devId;
42 462 : req->len = (int32_t)valueLen;
43 462 : int32_t err = memcpy_s(req->value, mallocValueLen, value, valueLen);
44 462 : if (err != EOK) {
45 0 : ADIAG_ERR("memory copy failed, err: %d", err);
46 0 : ADIAG_SAFE_FREE(req);
47 0 : return TRACE_FAILURE;
48 : }
49 :
50 462 : *buf = (void*)sendBuf;
51 462 : *bufLen = (uint32_t)sizeof(struct tlv_req) + valueLen;
52 :
53 462 : return TRACE_SUCCESS;
54 : }
55 :
56 242 : STATIC TraStatus AtraceClientSendMsg(const struct tlv_req* req, char* result, uint32_t resultLen)
57 : {
58 242 : char* resultBuf = (char*)AdiagMalloc(MSG_MAX_LEN);
59 242 : if (resultBuf == NULL) {
60 0 : ADIAG_ERR("malloc failed, strerr=%s.", strerror(AdiagGetErrorCode()));
61 0 : return TRACE_FAILURE;
62 : }
63 242 : ADIAG_INF("send msg by adx[begin], resultLen=%u bytes.", resultLen);
64 242 : int32_t err = AdxSendMsgAndGetResultByType(HDC_SERVICE_TYPE_BBOX, req, resultBuf, MSG_MAX_LEN);
65 242 : ADIAG_INF("send msg by adx[finish], ret=%d.", err);
66 :
67 242 : TraStatus ret = TRACE_SUCCESS;
68 242 : if (err != IDE_DAEMON_OK) {
69 22 : ADIAG_WAR("can not receive server message, ret=%d.", err);
70 22 : ret = TRACE_FAILURE;
71 : } else {
72 220 : err = memcpy_s(result, resultLen, resultBuf, resultLen);
73 220 : if (err != EOK) {
74 0 : ADIAG_ERR("memcpy failed, ret=%d.", err);
75 0 : ret = TRACE_FAILURE;
76 : }
77 : }
78 :
79 : // release resource
80 242 : ADIAG_SAFE_FREE(resultBuf);
81 242 : return ret;
82 : }
83 :
84 220 : STATIC TraStatus AtraceClientCheckHelloMsg(char* buffer, uint32_t len)
85 : {
86 220 : if (len < sizeof(TraceHelloMsg)) {
87 0 : ADIAG_ERR("check hello msg failed, len=%u bytes, size=%zu bytes.", len, sizeof(TraceHelloMsg));
88 0 : return TRACE_FAILURE;
89 : }
90 220 : TraceHelloMsg* msg = (TraceHelloMsg*)buffer;
91 220 : if ((msg->msgType != TRACE_HELLO_MSG) || (msg->magic != TRACE_HEAD_MAGIC) || (msg->version != TRACE_HEAD_VERSION)) {
92 0 : ADIAG_ERR("msgType=%hhu, magic=%hu, version=%hu.", msg->msgType, msg->magic, msg->version);
93 0 : return TRACE_FAILURE;
94 : }
95 220 : ADIAG_INF("msgType=%hhu, magic=%hu, version=%hu.", msg->msgType, msg->magic, msg->version);
96 220 : return TRACE_SUCCESS;
97 : }
98 :
99 242 : TraStatus AtraceClientSendHello(int32_t devId)
100 : {
101 242 : ADIAG_INF("send [hello] msg.");
102 242 : TraceHelloMsg msg = {0};
103 242 : msg.msgType = TRACE_HELLO_MSG;
104 242 : msg.magic = TRACE_HEAD_MAGIC;
105 242 : msg.version = TRACE_HEAD_VERSION;
106 :
107 242 : uint32_t sendLen = 0;
108 242 : void* reqBuf = NULL;
109 :
110 242 : TraStatus ret = AtraceClientCreatePacket(devId, (const char*)&msg, (uint32_t)sizeof(msg), &reqBuf, &sendLen);
111 242 : if (ret != TRACE_SUCCESS) {
112 0 : ADIAG_ERR("create [hello] msg failed, ret=%d", ret);
113 0 : ADIAG_SAFE_FREE(reqBuf);
114 0 : return TRACE_FAILURE;
115 : }
116 :
117 242 : struct tlv_req* req = (struct tlv_req*)reqBuf;
118 242 : char result[MSG_MAX_LEN] = {0};
119 242 : ret = AtraceClientSendMsg(req, result, MSG_MAX_LEN);
120 242 : if (ret != TRACE_SUCCESS) {
121 22 : ADIAG_WAR("can not send [hello] msg, ret=%d", ret);
122 22 : ADIAG_SAFE_FREE(reqBuf);
123 22 : return TRACE_FAILURE;
124 : }
125 : // check result pkg
126 220 : ret = AtraceClientCheckHelloMsg(result, MSG_MAX_LEN);
127 220 : if (ret != TRACE_SUCCESS) {
128 0 : ADIAG_ERR("check [hello] msg failed, ret=%d", ret);
129 0 : ADIAG_SAFE_FREE(reqBuf);
130 0 : return TRACE_SUCCESS;
131 : }
132 220 : ADIAG_SAFE_FREE(reqBuf);
133 220 : ADIAG_INF("send [hello] msg successfully.");
134 220 : return TRACE_SUCCESS;
135 : }
136 :
137 220 : TraStatus AtraceClientSendEnd(int32_t devId)
138 : {
139 220 : ADIAG_INF("send [end] msg.");
140 220 : TraceEndMsg msg = {0};
141 220 : msg.msgType = TRACE_END_MSG;
142 :
143 220 : uint32_t sendLen = 0;
144 220 : void* reqBuf = NULL;
145 :
146 220 : TraStatus ret = AtraceClientCreatePacket(devId, (const char*)&msg, (uint32_t)sizeof(msg), &reqBuf, &sendLen);
147 220 : if (ret != TRACE_SUCCESS) {
148 0 : ADIAG_ERR("create [end] msg failed, ret=%d", ret);
149 0 : ADIAG_SAFE_FREE(reqBuf);
150 0 : return TRACE_FAILURE;
151 : }
152 :
153 220 : struct tlv_req* req = (struct tlv_req*)reqBuf;
154 220 : int32_t err = AdxSendMsgAndNoResultByType(HDC_SERVICE_TYPE_BBOX, req);
155 220 : if (err != IDE_DAEMON_OK) {
156 22 : ADIAG_WAR("can not send [end] message, ret=%d.", err);
157 22 : ADIAG_SAFE_FREE(reqBuf);
158 22 : return TRACE_FAILURE;
159 : }
160 :
161 198 : ADIAG_SAFE_FREE(reqBuf);
162 198 : ADIAG_INF("send [end] msg successfully.");
163 198 : return TRACE_SUCCESS;
164 : }
165 :
166 220 : TraStatus AtraceClientCreateLongLink(int32_t devId, int32_t timeout, void** handle)
167 : {
168 220 : AdxCommHandle adxHandle = AdxCreateCommHandle(HDC_SERVICE_TYPE_BBOX, devId, COMPONENT_TRACE);
169 220 : int32_t ret = AdxIsCommHandleValid(adxHandle);
170 220 : if (ret != IDE_DAEMON_OK) {
171 0 : ADIAG_WAR("adx create handle failed, ret=%d", ret);
172 0 : return TRACE_FAILURE;
173 : }
174 :
175 220 : ADIAG_INF("send [start] msg.");
176 220 : TraceStartMsg msg = {0};
177 220 : msg.msgType = TRACE_START_MSG;
178 220 : msg.timeout = timeout;
179 220 : ret = AdxSendMsg(adxHandle, (const char*)&msg, (uint32_t)sizeof(TraceStartMsg));
180 220 : if (ret != IDE_DAEMON_OK) {
181 22 : AdxDestroyCommHandle(adxHandle);
182 22 : ADIAG_ERR("send [start] messages failed, ret=%d", ret);
183 22 : return TRACE_FAILURE;
184 : }
185 :
186 198 : *handle = (void*)adxHandle;
187 198 : ADIAG_INF("send [start] msg successfully.");
188 198 : return TRACE_SUCCESS;
189 : }
190 :
191 18238 : bool AtraceClientIsHandleValid(void* handle)
192 : {
193 18238 : AdxCommHandle adxHandle = (AdxCommHandle)handle;
194 18238 : if (AdxIsCommHandleValid(adxHandle) == IDE_DAEMON_OK) {
195 18238 : return true;
196 : }
197 0 : return false;
198 : }
199 18238 : TraStatus AtraceClientRecv(void* handle, char** data, uint32_t* len, int32_t timeout)
200 : {
201 18238 : int32_t ret = AdxRecvMsg((AdxCommHandle)handle, data, len, (uint32_t)timeout);
202 18238 : if (ret != IDE_DAEMON_OK) {
203 18128 : return TRACE_FAILURE;
204 : }
205 110 : return TRACE_SUCCESS;
206 : }
207 :
208 198 : void AtraceClientReleaseHandle(void** handle)
209 : {
210 198 : AdxDestroyCommHandle((AdxCommHandle)(*handle));
211 198 : *handle = NULL;
212 198 : }
213 :
214 88 : bool AtraceClientIsEventMsg(char* data, uint32_t len)
215 : {
216 88 : if (len < sizeof(TraceEventMsg)) {
217 22 : return false;
218 : }
219 66 : TraceEventMsg* msg = (TraceEventMsg*)data;
220 66 : if (msg->msgType == TRACE_EVENT_MSG) {
221 44 : return true;
222 : }
223 22 : return false;
224 : }
225 :
226 44 : bool AtraceClientIsEndMsg(char* data, uint32_t len)
227 : {
228 44 : if (len < sizeof(TraceEndMsg)) {
229 0 : return false;
230 : }
231 44 : TraceEndMsg* msg = (TraceEndMsg*)data;
232 44 : if (msg->msgType == TRACE_END_MSG) {
233 22 : return true;
234 : }
235 22 : return false;
236 : }
237 :
238 44 : TraStatus AtraceClientParseEventMsg(char* data, uint32_t len, TraceMsgInfo* info)
239 : {
240 44 : if (len < sizeof(TraceEventMsg)) {
241 0 : ADIAG_ERR(
242 : "AtraceClientParseEventMsg receive length(%u bytes) < msg min length(%zu bytes).", len,
243 : sizeof(TraceEventMsg));
244 0 : return TRACE_FAILURE;
245 : }
246 44 : TraceEventMsg* msg = (TraceEventMsg*)data;
247 44 : info->eventName = msg->eventName;
248 44 : info->eventTime = msg->eventTime;
249 44 : info->buf = msg->buf;
250 44 : info->bufLen = msg->bufLen;
251 44 : info->devPid = msg->pid;
252 44 : info->saveType = msg->saveType;
253 44 : if ((msg->seqFlag == TRACE_MSG_SEQFLAG_END) || (msg->seqFlag == TRACE_MSG_SEQFLAG_SINGLE)) {
254 22 : info->endFlag = true;
255 : } else {
256 22 : info->endFlag = false;
257 : }
258 44 : ADIAG_DBG(
259 : "AtraceClientParseEventMsg: info->eventName=%s, info->eventTime=%s, info->saveType=%u.", info->eventName,
260 : info->eventTime, (uint32_t)info->saveType);
261 44 : return TRACE_SUCCESS;
262 : }
|