1 /*
2  * Copyright (c) 2022-2024 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 #include "softbus_hidumper.h"
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <securec.h>
20 
21 #include "comm_log.h"
22 #include "common_list.h"
23 #include "softbus_errcode.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_hidumper_bc_mgr.h"
26 #include "softbus_hidumper_broadcast.h"
27 #include "softbus_hidumper_buscenter.h"
28 #include "softbus_hidumper_conn.h"
29 #include "softbus_hidumper_disc.h"
30 #include "softbus_hidumper_nstack.h"
31 #include "softbus_hidumper_trans.h"
32 
33 static LIST_HEAD(g_hidumperhander_list);
34 
SoftBusDumpShowHelp(int fd)35 void SoftBusDumpShowHelp(int fd)
36 {
37     if (fd < 0) {
38         COMM_LOGE(COMM_DFX, "fd is invalid.");
39         return;
40     }
41 
42     SOFTBUS_DPRINTF(fd, "Usage: hidumper -s 4700 -a \"[Option]\" \n");
43     SOFTBUS_DPRINTF(fd, "  Option: [-h] ");
44     ListNode *item = NULL;
45     LIST_FOR_EACH(item, &g_hidumperhander_list) {
46         HandlerNode *itemNode = LIST_ENTRY(item, HandlerNode, node);
47         SOFTBUS_DPRINTF(fd, "| [");
48         SOFTBUS_DPRINTF(fd, "%s", itemNode->moduleName);
49         SOFTBUS_DPRINTF(fd, "]");
50     }
51     SOFTBUS_DPRINTF(fd, "\n");
52 
53     item = NULL;
54     LIST_FOR_EACH(item, &g_hidumperhander_list) {
55         HandlerNode *itemNode = LIST_ENTRY(item, HandlerNode, node);
56         SOFTBUS_DPRINTF(fd, "\t\t");
57         SOFTBUS_DPRINTF(fd, "%s", itemNode->moduleName);
58         SOFTBUS_DPRINTF(fd, "\t\t");
59         SOFTBUS_DPRINTF(fd, "%s", itemNode->helpInfo);
60         SOFTBUS_DPRINTF(fd, "\n");
61     }
62 }
63 
SoftBusDumpErrInfo(int fd,const char * argv)64 void SoftBusDumpErrInfo(int fd, const char *argv)
65 {
66     if (fd < 0 || argv == NULL) {
67         COMM_LOGE(COMM_DFX, "param is invalid.");
68         return;
69     }
70     SOFTBUS_DPRINTF(fd, "the command %s is invalid, please input again!\n", argv);
71 }
72 
SoftBusDumpSubModuleHelp(int fd,char * moduleName,ListNode * varList)73 void SoftBusDumpSubModuleHelp(int fd, char *moduleName, ListNode *varList)
74 {
75     if (fd < 0 || moduleName == NULL || varList == NULL) {
76         COMM_LOGE(COMM_DFX, "param is invalid.");
77         return;
78     }
79     SOFTBUS_DPRINTF(fd, "Usage: hidumper -s 4700 -a \" %s [Option] \n", moduleName);
80     SOFTBUS_DPRINTF(fd, "  Option: [-h]  | [-l <");
81     ListNode *item = NULL;
82     LIST_FOR_EACH(item, varList) {
83         SoftBusDumpVarNode *itemNode = LIST_ENTRY(item, SoftBusDumpVarNode, node);
84         SOFTBUS_DPRINTF(fd, "%s |", itemNode->varName);
85     }
86     SOFTBUS_DPRINTF(fd, ">]\n");
87     SOFTBUS_DPRINTF(fd, "   -h         List all the dump item in %s module\n", moduleName);
88     SOFTBUS_DPRINTF(fd, "   -l <item>  Dump the item in %s module, item is nesessary\n", moduleName);
89 }
90 
SoftBusCreateDumpVarNode(const char * varName,SoftBusVarDumpCb cb)91 static SoftBusDumpVarNode *SoftBusCreateDumpVarNode(const char *varName, SoftBusVarDumpCb cb)
92 {
93     SoftBusDumpVarNode *varNode = (SoftBusDumpVarNode *)SoftBusCalloc(sizeof(SoftBusDumpVarNode));
94     if (varNode == NULL) {
95         COMM_LOGE(COMM_DFX, "SoftBusCreateDumpVarNode malloc fail.");
96         return NULL;
97     }
98     if (strcpy_s(varNode->varName, SOFTBUS_DUMP_VAR_NAME_LEN, varName) != EOK) {
99         COMM_LOGE(COMM_DFX, "SoftBusCreateDumpVarNode set varName fail. varName=%{public}s", varName);
100         SoftBusFree(varNode);
101         return NULL;
102     }
103 
104     varNode->dumpCallback = cb;
105 
106     return varNode;
107 }
108 
SoftBusAddDumpVarToList(const char * dumpVar,SoftBusVarDumpCb cb,ListNode * varList)109 int32_t SoftBusAddDumpVarToList(const char *dumpVar, SoftBusVarDumpCb cb, ListNode *varList)
110 {
111     if (dumpVar == NULL || strlen(dumpVar) >= SOFTBUS_DUMP_VAR_NAME_LEN || cb == NULL || varList == NULL) {
112         COMM_LOGE(COMM_DFX, "SoftBusRegDiscDumpCb invalid param");
113         return SOFTBUS_ERR;
114     }
115 
116     SoftBusDumpVarNode *varNode = SoftBusCreateDumpVarNode(dumpVar, cb);
117     if (varNode == NULL) {
118         COMM_LOGE(COMM_DFX, "SoftBusRegDiscDumpCb node create fail");
119         return SOFTBUS_ERR;
120     }
121     varNode->dumpCallback = cb;
122     ListTailInsert(varList, &varNode->node);
123 
124     return SOFTBUS_OK;
125 }
126 
SoftBusReleaseDumpVar(ListNode * varList)127 void SoftBusReleaseDumpVar(ListNode *varList)
128 {
129     if (varList == NULL) {
130         return;
131     }
132     ListNode *item = NULL;
133     ListNode *nextItem = NULL;
134     LIST_FOR_EACH_SAFE(item, nextItem, varList) {
135         SoftBusDumpVarNode *varNode = LIST_ENTRY(item, SoftBusDumpVarNode, node);
136         ListDelete(&varNode->node);
137         SoftBusFree(varNode);
138     }
139 }
140 
CreateHiDumperHandlerNode(char * moduleName,char * helpInfo,DumpHandlerFunc handler)141 static HandlerNode *CreateHiDumperHandlerNode(char *moduleName, char *helpInfo, DumpHandlerFunc handler)
142 {
143     HandlerNode *handlerNode = (HandlerNode *)SoftBusCalloc(sizeof(HandlerNode));
144     if (handlerNode == NULL) {
145         COMM_LOGE(COMM_DFX, "CreateHiDumperHandlerNode malloc fail.");
146         return NULL;
147     }
148 
149     if (strcpy_s(handlerNode->moduleName, SOFTBUS_MODULE_NAME_LEN, moduleName) != EOK) {
150         COMM_LOGE(COMM_DFX, "CreateHiDumperHandlerNode get moduleName fail.");
151         SoftBusFree(handlerNode);
152         return NULL;
153     }
154     if (strcpy_s(handlerNode->helpInfo, SOFTBUS_MODULE_HELP_LEN, helpInfo) != EOK) {
155         COMM_LOGE(COMM_DFX, "CreateHiDumperHandlerNode get helpInfo fail");
156         SoftBusFree(handlerNode);
157         return NULL;
158     }
159     handlerNode->dumpHandler = handler;
160 
161     return handlerNode;
162 }
163 
SoftBusHiDumperReleaseHandler(void)164 void SoftBusHiDumperReleaseHandler(void)
165 {
166     ListNode *item = NULL;
167     ListNode *nextItem = NULL;
168     LIST_FOR_EACH_SAFE(item, nextItem, &g_hidumperhander_list) {
169         HandlerNode *handlerNode = LIST_ENTRY(item, HandlerNode, node);
170         ListDelete(&handlerNode->node);
171         SoftBusFree(handlerNode);
172     }
173 }
174 
SoftBusRegHiDumperHandler(char * moduleName,char * helpInfo,DumpHandlerFunc handler)175 int32_t SoftBusRegHiDumperHandler(char *moduleName, char *helpInfo, DumpHandlerFunc handler)
176 {
177     if (moduleName == NULL || strlen(moduleName) >= SOFTBUS_MODULE_NAME_LEN || helpInfo == NULL ||
178         strlen(helpInfo) >= SOFTBUS_MODULE_HELP_LEN || handler == NULL) {
179         COMM_LOGE(COMM_DFX, "SoftBusRegHiDumperHandler invalid param");
180         return SOFTBUS_ERR;
181     }
182 
183     HandlerNode *handlerNode = CreateHiDumperHandlerNode(moduleName, helpInfo, handler);
184     if (handlerNode == NULL) {
185         COMM_LOGE(COMM_DFX, "SoftBusRegHiDumperHandler node create fail");
186         return SOFTBUS_ERR;
187     }
188     ListTailInsert(&g_hidumperhander_list, &handlerNode->node);
189     return SOFTBUS_OK;
190 }
191 
SoftBusDumpDispatch(int fd,int32_t argc,const char ** argv)192 int32_t SoftBusDumpDispatch(int fd, int32_t argc, const char **argv)
193 {
194     if (fd < 0 || argc < 0 || argv == NULL) {
195         COMM_LOGE(COMM_DFX, "SoftBusDumpProcess: param invalid ");
196         return SOFTBUS_ERR;
197     }
198 
199     if (argc <= 1 || strcmp(argv[0], "-h") == 0) {
200         SoftBusDumpShowHelp(fd);
201         return SOFTBUS_OK;
202     }
203 
204     ListNode *item = NULL;
205     int32_t isModuleExist = SOFTBUS_DUMP_NOT_EXIST;
206     LIST_FOR_EACH(item, &g_hidumperhander_list) {
207         HandlerNode *itemNode = LIST_ENTRY(item, HandlerNode, node);
208         if (strcmp(itemNode->moduleName, argv[0]) == 0) {
209             if (strcmp(argv[0], "dstream") == 0 || strcmp(argv[0], "dfinder") == 0 ||
210                 strcmp(argv[0], "dfile") == 0 || strcmp(argv[0], "dmsg") == 0) {
211                 itemNode->dumpHandler(fd, argc, argv);
212             } else {
213                 itemNode->dumpHandler(fd, argc - 1, &argv[1]);
214             }
215             isModuleExist = SOFTBUS_DUMP_EXIST;
216             break;
217         }
218     }
219 
220     if (isModuleExist == SOFTBUS_DUMP_NOT_EXIST) {
221         SoftBusDumpErrInfo(fd, argv[1]);
222         SoftBusDumpShowHelp(fd);
223     }
224 
225     return SOFTBUS_OK;
226 }
227 
SoftBusHiDumperModuleInit(void)228 int32_t SoftBusHiDumperModuleInit(void)
229 {
230     if (SoftBusBcMgrHiDumperInit() != SOFTBUS_OK) {
231         COMM_LOGE(COMM_INIT, "init BroadcastManager HiDumper fail!");
232         return SOFTBUS_ERR;
233     }
234 
235     if (SoftBusHiDumperBroadcastInit() != SOFTBUS_OK) {
236         COMM_LOGE(COMM_INIT, "init Broadcast HiDumper fail!");
237         return SOFTBUS_ERR;
238     }
239 
240     if (SoftBusDiscHiDumperInit() != SOFTBUS_OK) {
241         COMM_LOGE(COMM_INIT, "init Disc HiDumper fail!");
242         return SOFTBUS_ERR;
243     }
244 
245     if (SoftBusConnHiDumperInit() != SOFTBUS_OK) {
246         COMM_LOGE(COMM_INIT, "init Conn HiDumper fail!");
247         return SOFTBUS_ERR;
248     }
249 
250     if (SoftBusNStackHiDumperInit() != SOFTBUS_OK) {
251         COMM_LOGE(COMM_INIT, "init NStack HiDumper fail!");
252         return SOFTBUS_ERR;
253     }
254 
255     if (SoftBusHiDumperBusCenterInit() != SOFTBUS_OK) {
256         COMM_LOGE(COMM_INIT, "init BusCenter HiDumper fail!");
257         return SOFTBUS_ERR;
258     }
259 
260     if (SoftBusTransDumpHandlerInit() != SOFTBUS_OK) {
261         COMM_LOGE(COMM_INIT, "init Trans HiDumper fail!");
262         return SOFTBUS_ERR;
263     }
264     return SOFTBUS_OK;
265 }
266 
SoftBusHiDumperModuleDeInit(void)267 void SoftBusHiDumperModuleDeInit(void)
268 {
269     SoftBusHiDumperBcMgrDeInit();
270     SoftBusHiDumperBroadcastDeInit();
271     SoftBusHiDumperDiscDeInit();
272     SoftBusHiDumperConnDeInit();
273     SoftBusHiDumperBusCenterDeInit();
274     SoftBusHiDumperTransDeInit();
275     SoftBusHiDumperReleaseHandler();
276 }
277