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 420 : STATIC TraStatus AtraceClientCreatePacket(int32_t devId, const char *value, uint32_t valueLen,
20 : void **buf, uint32_t *bufLen)
21 : {
22 420 : if (value == NULL || buf == NULL || bufLen == NULL) {
23 0 : ADIAG_ERR("input invalid parameter");
24 0 : return TRACE_FAILURE;
25 : }
26 :
27 420 : 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 420 : uint32_t mallocValueLen = valueLen + 1U;
33 420 : uint32_t sendLen = (uint32_t)sizeof(struct tlv_req) + mallocValueLen;
34 420 : char *sendBuf = (char *)AdiagMalloc(sendLen);
35 420 : if (sendBuf == NULL) {
36 0 : ADIAG_ERR("malloc memory failed");
37 0 : return TRACE_FAILURE;
38 : }
39 420 : IdeTlvReq req = (IdeTlvReq)sendBuf;
40 420 : req->type = IDE_TRACE_REQ;
41 420 : req->dev_id = devId;
42 420 : req->len = (int32_t)valueLen;
43 420 : int32_t err = memcpy_s(req->value, mallocValueLen, value, valueLen);
44 420 : 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 420 : *buf = (void *)sendBuf;
51 420 : *bufLen = (uint32_t)sizeof(struct tlv_req) + valueLen;
52 :
53 420 : return TRACE_SUCCESS;
54 : }
55 :
56 220 : STATIC TraStatus AtraceClientSendMsg(const struct tlv_req *req, char *result, uint32_t resultLen)
57 : {
58 220 : char *resultBuf = (char *)AdiagMalloc(MSG_MAX_LEN);
59 220 : if (resultBuf == NULL) {
60 0 : ADIAG_ERR("malloc failed, strerr=%s.", strerror(AdiagGetErrorCode()));
61 0 : return TRACE_FAILURE;
62 : }
63 220 : ADIAG_INF("send msg by adx[begin], resultLen=%u bytes.", resultLen);
64 220 : int32_t err = AdxSendMsgAndGetResultByType(HDC_SERVICE_TYPE_BBOX, req, resultBuf, MSG_MAX_LEN);
65 220 : ADIAG_INF("send msg by adx[finish], ret=%d.", err);
66 :
67 220 : TraStatus ret = TRACE_SUCCESS;
68 220 : if (err != IDE_DAEMON_OK) {
69 20 : ADIAG_WAR("can not receive server message, ret=%d.", err);
70 20 : ret = TRACE_FAILURE;
71 : } else {
72 200 : err = memcpy_s(result, resultLen, resultBuf, resultLen);
73 200 : if (err != EOK) {
74 0 : ADIAG_ERR("memcpy failed, ret=%d.", err);
75 0 : ret = TRACE_FAILURE;
76 : }
77 : }
78 :
79 : // release resource
80 220 : ADIAG_SAFE_FREE(resultBuf);
81 220 : return ret;
82 : }
83 :
84 200 : STATIC TraStatus AtraceClientCheckHelloMsg(char *buffer, uint32_t len)
85 : {
86 200 : 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 200 : TraceHelloMsg *msg = (TraceHelloMsg *)buffer;
91 200 : if ((msg->msgType != TRACE_HELLO_MSG) ||
92 200 : (msg->magic != TRACE_HEAD_MAGIC) ||
93 200 : (msg->version != TRACE_HEAD_VERSION)) {
94 0 : ADIAG_ERR("msgType=%hhu, magic=%hu, version=%hu.", msg->msgType, msg->magic, msg->version);
95 0 : return TRACE_FAILURE;
96 : }
97 200 : ADIAG_INF("msgType=%hhu, magic=%hu, version=%hu.", msg->msgType, msg->magic, msg->version);
98 200 : return TRACE_SUCCESS;
99 : }
100 :
101 220 : TraStatus AtraceClientSendHello(int32_t devId)
102 : {
103 220 : ADIAG_INF("send [hello] msg.");
104 220 : TraceHelloMsg msg = { 0 };
105 220 : msg.msgType = TRACE_HELLO_MSG;
106 220 : msg.magic = TRACE_HEAD_MAGIC;
107 220 : msg.version = TRACE_HEAD_VERSION;
108 :
109 220 : uint32_t sendLen = 0;
110 220 : void *reqBuf = NULL;
111 :
112 220 : TraStatus ret = AtraceClientCreatePacket(devId, (const char *)&msg, (uint32_t)sizeof(msg), &reqBuf, &sendLen);
113 220 : if (ret != TRACE_SUCCESS) {
114 0 : ADIAG_ERR("create [hello] msg failed, ret=%d", ret);
115 0 : ADIAG_SAFE_FREE(reqBuf);
116 0 : return TRACE_FAILURE;
117 : }
118 :
119 220 : struct tlv_req *req = (struct tlv_req *)reqBuf;
120 220 : char result[MSG_MAX_LEN] = { 0 };
121 220 : ret = AtraceClientSendMsg(req, result, MSG_MAX_LEN);
122 220 : if (ret != TRACE_SUCCESS) {
123 20 : ADIAG_WAR("can not send [hello] msg, ret=%d", ret);
124 20 : ADIAG_SAFE_FREE(reqBuf);
125 20 : return TRACE_FAILURE;
126 : }
127 : // check result pkg
128 200 : ret = AtraceClientCheckHelloMsg(result, MSG_MAX_LEN);
129 200 : if (ret != TRACE_SUCCESS) {
130 0 : ADIAG_ERR("check [hello] msg failed, ret=%d", ret);
131 0 : ADIAG_SAFE_FREE(reqBuf);
132 0 : return TRACE_SUCCESS;
133 : }
134 200 : ADIAG_SAFE_FREE(reqBuf);
135 200 : ADIAG_INF("send [hello] msg successfully.");
136 200 : return TRACE_SUCCESS;
137 : }
138 :
139 200 : TraStatus AtraceClientSendEnd(int32_t devId)
140 : {
141 200 : ADIAG_INF("send [end] msg.");
142 200 : TraceEndMsg msg = { 0 };
143 200 : msg.msgType = TRACE_END_MSG;
144 :
145 200 : uint32_t sendLen = 0;
146 200 : void *reqBuf = NULL;
147 :
148 200 : TraStatus ret = AtraceClientCreatePacket(devId, (const char *)&msg, (uint32_t)sizeof(msg), &reqBuf, &sendLen);
149 200 : if (ret != TRACE_SUCCESS) {
150 0 : ADIAG_ERR("create [end] msg failed, ret=%d", ret);
151 0 : ADIAG_SAFE_FREE(reqBuf);
152 0 : return TRACE_FAILURE;
153 : }
154 :
155 200 : struct tlv_req *req = (struct tlv_req *)reqBuf;
156 200 : int32_t err = AdxSendMsgAndNoResultByType(HDC_SERVICE_TYPE_BBOX, req);
157 200 : if (err != IDE_DAEMON_OK) {
158 20 : ADIAG_WAR("can not send [end] message, ret=%d.", err);
159 20 : ADIAG_SAFE_FREE(reqBuf);
160 20 : return TRACE_FAILURE;
161 : }
162 :
163 180 : ADIAG_SAFE_FREE(reqBuf);
164 180 : ADIAG_INF("send [end] msg successfully.");
165 180 : return TRACE_SUCCESS;
166 : }
167 :
168 200 : TraStatus AtraceClientCreateLongLink(int32_t devId, int32_t timeout, void **handle)
169 : {
170 200 : AdxCommHandle adxHandle = AdxCreateCommHandle(HDC_SERVICE_TYPE_BBOX, devId, COMPONENT_TRACE);
171 200 : int32_t ret = AdxIsCommHandleValid(adxHandle);
172 200 : if (ret != IDE_DAEMON_OK) {
173 0 : ADIAG_ERR("adx create handle failed, ret=%d", ret);
174 0 : return TRACE_FAILURE;
175 : }
176 :
177 200 : ADIAG_INF("send [start] msg.");
178 200 : TraceStartMsg msg = { 0 };
179 200 : msg.msgType = TRACE_START_MSG;
180 200 : msg.timeout = timeout;
181 200 : ret = AdxSendMsg(adxHandle, (const char*)&msg, (uint32_t)sizeof(TraceStartMsg));
182 200 : if (ret != IDE_DAEMON_OK) {
183 20 : AdxDestroyCommHandle(adxHandle);
184 20 : ADIAG_ERR("send [start] messages failed, ret=%d", ret);
185 20 : return TRACE_FAILURE;
186 : }
187 :
188 180 : *handle = (void *)adxHandle;
189 180 : ADIAG_INF("send [start] msg successfully.");
190 180 : return TRACE_SUCCESS;
191 : }
192 :
193 16540 : bool AtraceClientIsHandleValid(void *handle)
194 : {
195 16540 : AdxCommHandle adxHandle = (AdxCommHandle)handle;
196 16540 : if (AdxIsCommHandleValid(adxHandle) == IDE_DAEMON_OK) {
197 16540 : return true;
198 : }
199 0 : return false;
200 : }
201 16540 : TraStatus AtraceClientRecv(void *handle, char **data, uint32_t *len, int32_t timeout)
202 : {
203 16540 : int32_t ret = AdxRecvMsg((AdxCommHandle)handle, data, len, (uint32_t)timeout);
204 16540 : if (ret != IDE_DAEMON_OK) {
205 16440 : return TRACE_FAILURE;
206 : }
207 100 : return TRACE_SUCCESS;
208 : }
209 :
210 180 : void AtraceClientReleaseHandle(void **handle)
211 : {
212 180 : AdxDestroyCommHandle((AdxCommHandle)(*handle));
213 180 : *handle = NULL;
214 180 : }
215 :
216 80 : bool AtraceClientIsEventMsg(char *data, uint32_t len)
217 : {
218 80 : if (len < sizeof(TraceEventMsg)) {
219 20 : return false;
220 : }
221 60 : TraceEventMsg *msg = (TraceEventMsg *)data;
222 60 : if (msg->msgType == TRACE_EVENT_MSG) {
223 40 : return true;
224 : }
225 20 : return false;
226 : }
227 :
228 40 : bool AtraceClientIsEndMsg(char *data, uint32_t len)
229 : {
230 40 : if (len < sizeof(TraceEndMsg)) {
231 0 : return false;
232 : }
233 40 : TraceEndMsg *msg = (TraceEndMsg *)data;
234 40 : if (msg->msgType == TRACE_END_MSG) {
235 20 : return true;
236 : }
237 20 : return false;
238 : }
239 :
240 40 : TraStatus AtraceClientParseEventMsg(char *data, uint32_t len, TraceMsgInfo *info)
241 : {
242 40 : if (len < sizeof(TraceEventMsg)) {
243 0 : ADIAG_ERR("AtraceClientParseEventMsg receive length(%u bytes) < msg min length(%zu bytes).",
244 : len, sizeof(TraceEventMsg));
245 0 : return TRACE_FAILURE;
246 : }
247 40 : TraceEventMsg *msg = (TraceEventMsg *)data;
248 40 : info->eventName = msg->eventName;
249 40 : info->eventTime = msg->eventTime;
250 40 : info->buf = msg->buf;
251 40 : info->bufLen = msg->bufLen;
252 40 : info->devPid = msg->pid;
253 40 : info->saveType = msg->saveType;
254 40 : if ((msg->seqFlag == TRACE_MSG_SEQFLAG_END) || (msg->seqFlag == TRACE_MSG_SEQFLAG_SINGLE)) {
255 20 : info->endFlag = true;
256 : } else {
257 20 : info->endFlag = false;
258 : }
259 40 : ADIAG_DBG("AtraceClientParseEventMsg: info->eventName=%s, info->eventTime=%s, info->saveType=%u.",
260 : info->eventName, info->eventTime, (uint32_t)info->saveType);
261 40 : return TRACE_SUCCESS;
262 : }
|