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