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 "nstackx_dfile_dfx.h"
17 #include "securec.h"
18 #include "nstackx_dfile_session.h"
19 #include "nstackx_dfile_transfer.h"
20 #include "nstackx_dfile_log.h"
21
22 #define TAG "nStackXDFile"
23 #ifdef DFILE_ENABLE_HIDUMP
24
25 static bool g_dfileDumpFrameSwitch = 0;
26
HidumpHelp(char * message,size_t * size)27 int32_t HidumpHelp(char *message, size_t *size)
28 {
29 int32_t ret = 0;
30 ret = sprintf_s(message, DUMP_INFO_MAX,
31 "\n-h help information about the hidump dfile command.\n"
32 "-l Displays all session IDs.\n"
33 "-m signaling packet switch, 1:open, 0:close.\n"
34 "-s Displays information about the transmit end/receive end.\n"
35 " transmit end: capability, sending rate, I/O rate, send block number.\n"
36 " receive end: capability, I/O rate, retransmissions number, recev number, total number\n");
37 if (ret == -1) {
38 DFILE_LOGE(TAG, "write message failed");
39 return NSTACKX_EFAILED;
40 }
41
42 *size = strlen(message);
43 return NSTACKX_EOK;
44 }
45
HidumpList(char * message,size_t * size)46 int32_t HidumpList(char *message, size_t *size)
47 {
48 int32_t ret = 0, retTemp = 0;
49 uint16_t count = 0;
50 bool flag = 0;
51 DFileSessionNode *node = NULL;
52 if (PthreadMutexLock(&g_dFileSessionChainMutex) != 0) {
53 DFILE_LOGE(TAG, "lock g_dFileSessionChainMutex failed");
54 return 0;
55 }
56 List *pos = NULL;
57 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "\nsession id list:\n");
58 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
59 LIST_FOR_EACH(pos, &g_dFileSessionChain)
60 {
61 node = (DFileSessionNode *)pos;
62 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "index %u sessionId: %u \n", count, node->sessionId);
63 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
64 count++;
65 }
66
67 if (PthreadMutexUnlock(&g_dFileSessionChainMutex) != 0) {
68 DFILE_LOGE(TAG, "unlock g_dFileSessionChainMutex failed");
69 return 0;
70 }
71 *size = strlen(message);
72
73 if (flag == 1) {
74 DFILE_LOGE(TAG, "write message failed");
75 return NSTACKX_EFAILED;
76 }
77
78 return NSTACKX_EOK;
79 }
80
HidumpInfoClient(char * message,size_t * size,DFileSession * session)81 static int32_t HidumpInfoClient(char *message, size_t *size, DFileSession *session)
82 {
83 int32_t ret = 0, retTemp = 0;
84 bool flag = 0;
85 List *pos = NULL;
86 PeerInfo *peerInfoTemp = NULL;
87
88 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "\ncapability: %x\n", session->capability);
89 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
90 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "amendSendRate: ");
91 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
92 LIST_FOR_EACH(pos, &session->peerInfoChain)
93 {
94 peerInfoTemp = (PeerInfo *)pos;
95 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "%d ", peerInfoTemp->amendSendRate);
96 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
97 }
98 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "\nIO read rate: %u KB/s\n", session->fileManager->iorRate);
99 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
100 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "total send block num: %llu\n",
101 NSTACKX_ATOM_FETCH(&(session->totalSendBlocks)));
102 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
103
104 *size = strlen(message);
105
106 if (flag == 1) {
107 return NSTACKX_EFAILED;
108 }
109
110 return NSTACKX_EOK;
111 }
112
HidumpInfoServer(char * message,size_t * size,DFileSession * session)113 static int32_t HidumpInfoServer(char *message, size_t *size, DFileSession *session)
114 {
115 int32_t ret = 0, retTemp = 0;
116 bool flag = 0;
117 List *pos = NULL;
118 DFileTrans *transTemp = NULL;
119
120 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "\ncapability: %x\n", session->capability);
121 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
122 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "IO write rate: %u KB/s\n", session->fileManager->iowRate);
123 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
124 LIST_FOR_EACH(pos, &session->dFileTransChain)
125 {
126 transTemp = (DFileTrans *)pos;
127 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "trans id: %d\n", transTemp->transId);
128 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
129 retTemp = sprintf_s(message + ret, DUMP_INFO_MAX - ret, "allRetrySendCount:%u recev:%d all:%llu\n",
130 transTemp->allRetrySendCount, transTemp->receivedDataFrameCnt, transTemp->totalDataFrameCnt);
131 retTemp == -1 ? (flag = 1) : (ret = ret + retTemp);
132 }
133
134 *size = strlen(message);
135
136 if (flag == 1) {
137 return NSTACKX_EFAILED;
138 }
139
140 return NSTACKX_EOK;
141 }
142
HidumpInformation(char * message,size_t * size,char * opt)143 int32_t HidumpInformation(char *message, size_t *size, char *opt)
144 {
145 int32_t ret = 0;
146 int64_t sessionId = 0;
147 DFileSession *session = NULL;
148 DFileSessionNode *node = NULL;
149
150 sessionId = (int64_t)strtol(opt, NULL, DUMP_DECIMAL);
151 if (sessionId > USHRT_MAX) {
152 (void)sprintf_s(message, DUMP_INFO_MAX, "session id is overflowing");
153 *size = strlen(message);
154 return NSTACKX_EOK;
155 }
156
157 node = GetDFileSessionNodeById(sessionId);
158 if (node == NULL) {
159 ret = sprintf_s(message, DUMP_INFO_MAX, "find session by session id failed");
160 return NSTACKX_EOK;
161 }
162
163 session = node->session;
164
165 if (session->sessionType == DFILE_SESSION_TYPE_CLIENT) {
166 ret = HidumpInfoClient(message, size, session);
167 } else {
168 ret = HidumpInfoServer(message, size, session);
169 }
170
171 if (ret != NSTACKX_EOK) {
172 DFILE_LOGE(TAG, "write message failed");
173 return NSTACKX_EFAILED;
174 }
175
176 return NSTACKX_EOK;
177 }
178
SetDfileDumpFrameSwitch(bool status)179 static void SetDfileDumpFrameSwitch(bool status)
180 {
181 g_dfileDumpFrameSwitch = status;
182 }
183
GetDfileDumpFrameSwitch()184 bool GetDfileDumpFrameSwitch()
185 {
186 return g_dfileDumpFrameSwitch;
187 }
188
HidumpMessage(char * message,size_t * size,char * opt)189 int32_t HidumpMessage(char *message, size_t *size, char *opt)
190 {
191 int ret = 0;
192 int64_t input;
193 input = (int64_t)strtol(opt, NULL, DUMP_DECIMAL);
194 if (input == 1) {
195 SetDfileDumpFrameSwitch(1);
196 ret = sprintf_s(message, DUMP_INFO_MAX, "Signaling packet switch is open");
197 } else if (input == 0) {
198 SetDfileDumpFrameSwitch(0);
199 ret = sprintf_s(message, DUMP_INFO_MAX, "Signaling packet switch is close");
200 } else {
201 ret = sprintf_s(message, DUMP_INFO_MAX, "Invalid input");
202 }
203 if (ret == -1) {
204 DFILE_LOGE(TAG, "write message failed");
205 return NSTACKX_EFAILED;
206 }
207
208 *size = strlen(message);
209 return NSTACKX_EOK;
210 }
211 #endif
212
EventAssemble(char * eventName,DFileEventType eventType,DFileEventLevel eventLevel,uint32_t eventNum,DFileEventParam * transParam)213 static void EventAssemble(char *eventName, DFileEventType eventType, DFileEventLevel eventLevel, uint32_t eventNum,
214 DFileEventParam *transParam)
215 {
216 DFileEvent temp;
217 DFileEvent *msg = &temp;
218 if (strcpy_s(msg->eventName, DFile_EVENT_NAME_LEN, eventName) != NSTACKX_EOK) {
219 DFILE_LOGE(TAG, "string copy failed", 0);
220 return;
221 }
222 msg->type = eventType;
223 msg->level = eventLevel;
224 msg->paramNum = eventNum;
225 msg->params = transParam;
226 NSTACKX_DFileAssembleFunc(NULL, msg);
227 }
228
WaitFileHeaderTimeoutEvent(DFileTransErrorCode errorCode)229 void WaitFileHeaderTimeoutEvent(DFileTransErrorCode errorCode)
230 {
231 char valueStr[DFile_EVENT_NAME_LEN];
232 char eventName[DFile_EVENT_NAME_LEN] = "Header confirm timeout";
233
234 DFileEventParam temp;
235 DFileEventParam *transParam = &temp;
236 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "Errorcode: %u", errorCode);
237 transParam->type = DFile_PARAM_TYPE_STRING;
238
239 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "ERROR_CODE") != NSTACKX_EOK) {
240 DFILE_LOGE(TAG, "string copy failed");
241 return;
242 }
243 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
244 DFILE_LOGE(TAG, "string copy failed");
245 return;
246 }
247
248 EventAssemble(eventName, DFile_EVENT_TYPE_FAULT, DFile_EVENT_LEVEL_CRITICAL, 1, transParam);
249 }
250
DFileServerCreateEvent(void)251 void DFileServerCreateEvent(void)
252 {
253 char valueStr[DFile_EVENT_NAME_LEN] = "";
254 char eventName[DFile_EVENT_NAME_LEN] = "Server created";
255
256 DFileEventParam temp;
257 DFileEventParam *transParam = &temp;
258 transParam->type = DFile_PARAM_TYPE_STRING;
259
260 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "NA") != NSTACKX_EOK) {
261 DFILE_LOGE(TAG, "string copy failed");
262 return;
263 }
264 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
265 DFILE_LOGE(TAG, "string copy failed");
266 return;
267 }
268
269 EventAssemble(eventName, DFile_EVENT_TYPE_BEHAVIOR, DFile_EVENT_LEVEL_MINOR, 0, transParam);
270 }
271
DFileClientCreateEvent(void)272 void DFileClientCreateEvent(void)
273 {
274 char valueStr[DFile_EVENT_NAME_LEN];
275 char eventName[DFile_EVENT_NAME_LEN] = "Client created";
276
277 DFileEventParam temp;
278 DFileEventParam *transParam = &temp;
279 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "");
280 transParam->type = DFile_PARAM_TYPE_STRING;
281
282 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "NA") != NSTACKX_EOK) {
283 DFILE_LOGE(TAG, "string copy failed");
284 return;
285 }
286 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
287 DFILE_LOGE(TAG, "string copy failed");
288 return;
289 }
290
291 EventAssemble(eventName, DFile_EVENT_TYPE_BEHAVIOR, DFile_EVENT_LEVEL_MINOR, 0, transParam);
292 }
293
DFileSendFileBeginEvent(void)294 void DFileSendFileBeginEvent(void)
295 {
296 char valueStr[DFile_EVENT_NAME_LEN];
297 char eventName[DFile_EVENT_NAME_LEN] = "Send file begin";
298
299 DFileEventParam temp;
300 DFileEventParam *transParam = &temp;
301 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "");
302 transParam->type = DFile_PARAM_TYPE_STRING;
303
304 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "NA") != NSTACKX_EOK) {
305 DFILE_LOGE(TAG, "string copy failed", 0);
306 return;
307 }
308 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
309 DFILE_LOGE(TAG, "string copy failed", 0);
310 return;
311 }
312
313 EventAssemble(eventName, DFile_EVENT_TYPE_BEHAVIOR, DFile_EVENT_LEVEL_MINOR, 0, transParam);
314 }
315
PeerShuttedEvent(void)316 void PeerShuttedEvent(void)
317 {
318 char valueStr[DFile_EVENT_NAME_LEN];
319 char eventName[DFile_EVENT_NAME_LEN] = "Peer shutted down";
320
321 DFileEventParam temp;
322 DFileEventParam *transParam = &temp;
323 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "");
324 transParam->type = DFile_PARAM_TYPE_STRING;
325
326 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "SocketIndex") != NSTACKX_EOK) {
327 DFILE_LOGE(TAG, "string copy failed", 0);
328 return;
329 }
330 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
331 DFILE_LOGE(TAG, "string copy failed", 0);
332 return;
333 }
334
335 EventAssemble(eventName, DFile_EVENT_TYPE_FAULT, DFile_EVENT_LEVEL_CRITICAL, 1, transParam);
336 }
337
TransferCompleteEvent(const double rate)338 void TransferCompleteEvent(const double rate)
339 {
340 char valueStr[DFile_EVENT_NAME_LEN];
341 char eventName[DFile_EVENT_NAME_LEN] = "transferring completed";
342
343 DFileEventParam temp;
344 DFileEventParam *transParam = &temp;
345 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "rate: %.2f MB/s", rate);
346 transParam->type = DFile_PARAM_TYPE_STRING;
347
348 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "TRANSRATE") != NSTACKX_EOK) {
349 DFILE_LOGE(TAG, "string copy failed", 0);
350 return;
351 }
352 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
353 DFILE_LOGE(TAG, "string copy failed", 0);
354 return;
355 }
356
357 EventAssemble(eventName, DFile_EVENT_TYPE_STATISTIC, DFile_EVENT_LEVEL_MINOR, 0, transParam);
358 }
359
AcceptSocketEvent(void)360 void AcceptSocketEvent(void)
361 {
362 char valueStr[DFile_EVENT_NAME_LEN];
363 char eventName[DFile_EVENT_NAME_LEN] = "Accept socket success";
364
365 DFileEventParam temp;
366 DFileEventParam *transParam = &temp;
367 (void)sprintf_s(valueStr, DFile_EVENT_NAME_LEN, "");
368 transParam->type = DFile_PARAM_TYPE_STRING;
369
370 if (strcpy_s(transParam->name, DFile_EVENT_NAME_LEN, "NA") != NSTACKX_EOK) {
371 DFILE_LOGE(TAG, "string copy failed", 0);
372 return;
373 }
374 if (strcpy_s(transParam->value.str, DFile_EVENT_NAME_LEN, valueStr) != NSTACKX_EOK) {
375 DFILE_LOGE(TAG, "string copy failed", 0);
376 return;
377 }
378
379 EventAssemble(eventName, DFile_EVENT_TYPE_BEHAVIOR, DFile_EVENT_LEVEL_MINOR, 0, transParam);
380 }
381