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