1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <iostream>
10 #include <string>
11 #include <string_ex.h>
12 #include <hdf_io_service.h>
13 #include <idevmgr_hdi.h>
14 #include <iservmgr_hdi.h>
15 #include <osal_time.h>
16
17 #define HDF_LOG_TAG hdf_dbg
18
19 static constexpr uint32_t DATA_SIZE = 5000;
20 static constexpr uint32_t FUNC_IDX = 1;
21 static constexpr uint32_t SERVER_NAME_IDX = 3;
22 static constexpr uint32_t INTERFACE_DESC_IDX = 4;
23 static constexpr uint32_t CMD_ID_IDX = 5;
24 static constexpr uint32_t PARA_CNT_IDX = 6;
25 static constexpr uint32_t PARA_MULTIPLE = 2;
26 static constexpr uint32_t WAIT_TIME = 100;
27 static constexpr uint32_t HELP_INFO_PARA_CNT = 2;
28 static constexpr uint32_t GET_INFO_FUNC_NUMS = 5;
29 static constexpr int32_t DBG_HDI_PARA_MIN_LEN = 7;
30 static constexpr int32_t DBG_HDI_SERVICE_LOAD_IDX = 2;
31 static constexpr int32_t QUERY_INFO_PARA_CNT = 3;
32 static constexpr int32_t ALIGN_SIZE = 30;
33 static constexpr const char *HELP_COMMENT =
34 " hdf_dbg menu: \n"
35 " hdf_dbg -h :display help information\n"
36 " hdf_dbg -q :query all service and device information\n"
37 " hdf_dbg -q 0 :query service information of kernel space\n"
38 " hdf_dbg -q 1 :query service information of user space\n"
39 " hdf_dbg -q 2 :query device information of kernel space\n"
40 " hdf_dbg -q 3 :query device information use space\n"
41 " hdf_dbg -d :debug hdi interface\n"
42 " detailed usage:\n"
43 " debug hdi interface, parameterType can be int or string now, for example:\n"
44 " hdf_dbg -d loadFlag serviceName interfaceToken cmd parameterCount parameterType parameterValue\n"
45 " detailed examples:\n"
46 " hdf_dbg -d 1 sample_driver_service hdf.test.sampele_service 1 2 int 100 int 200\n"
47 " hdf_dbg -d 0 sample_driver_service hdf.test.sampele_service 7 1 string foo\n";
48
49 using GetInfoFunc = void (*)();
50 static void GetAllServiceUserSpace();
51 static void GetAllServiceKernelSpace();
52 static void GetAllDeviceUserSpace();
53 static void GetAllDeviceKernelSpace();
54 static void GetAllInformation();
55
56 GetInfoFunc g_getInfoFuncs[GET_INFO_FUNC_NUMS] = {
57 GetAllServiceKernelSpace,
58 GetAllServiceUserSpace,
59 GetAllDeviceKernelSpace,
60 GetAllDeviceUserSpace,
61 GetAllInformation,
62 };
63
64 using OHOS::MessageOption;
65 using OHOS::MessageParcel;
66 using OHOS::HDI::DeviceManager::V1_0::HdiDevHostInfo;
67 using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
68 using OHOS::HDI::ServiceManager::V1_0::HdiServiceInfo;
69 using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
70 using std::cout;
71 using std::endl;
72
PrintHelp()73 static void PrintHelp()
74 {
75 cout << HELP_COMMENT;
76 }
77
SetPadAlign(std::string & name,char padChar,int32_t size)78 static void SetPadAlign(std::string &name, char padChar, int32_t size)
79 {
80 int32_t padCnt = size - static_cast<int32_t>(name.length());
81
82 padCnt = (padCnt <= 0) ? 0 : padCnt;
83 name.append(padCnt, padChar);
84 }
85
PrintAllServiceInfoUser(std::vector<HdiServiceInfo> & serviceInfos)86 static void PrintAllServiceInfoUser(std::vector<HdiServiceInfo> &serviceInfos)
87 {
88 uint32_t cnt = 0;
89 std::string titleName = "serviceName";
90 SetPadAlign(titleName, ' ', ALIGN_SIZE);
91
92 cout << "display service info in user space, format:" << endl;
93 cout << titleName << ":devClass" << "\t:devId" << endl;
94
95 for (auto &info : serviceInfos) {
96 SetPadAlign(info.serviceName, ' ', ALIGN_SIZE);
97 cout << info.serviceName << ":0x" << std::hex << info.devClass << "\t:0x" << info.devId << endl;
98 cnt++;
99 }
100
101 cout << "total " << std::dec << cnt << " services in user space" << endl;
102 }
103
PrintAllServiceInfoKernel(struct HdfSBuf * data,bool flag)104 static void PrintAllServiceInfoKernel(struct HdfSBuf *data, bool flag)
105 {
106 uint32_t cnt = 0;
107 std::string titleName = "serviceName";
108
109 SetPadAlign(titleName, ' ', ALIGN_SIZE);
110 cout << "display service info in kernel space, format:" << endl;
111 cout << titleName << ":devClass" << "\t:devId" << endl;
112
113 while (flag) {
114 const char *servName = HdfSbufReadString(data);
115 if (servName == nullptr) {
116 break;
117 }
118
119 uint16_t devClass;
120 if (!HdfSbufReadUint16(data, &devClass)) {
121 return;
122 }
123
124 uint32_t devId;
125 if (!HdfSbufReadUint32(data, &devId)) {
126 return;
127 }
128
129 std::string serviceName = servName;
130 SetPadAlign(serviceName, ' ', ALIGN_SIZE);
131 cout << serviceName << ":0x" << std::hex << devClass << "\t:0x" << devId << endl;
132 cnt++;
133 }
134
135 cout << "total " << std::dec << cnt << " services in kernel space" << endl;
136 }
137
PrintALLDeviceInfoUser(std::vector<HdiDevHostInfo> & deviceInfos)138 static void PrintALLDeviceInfoUser(std::vector<HdiDevHostInfo> &deviceInfos)
139 {
140 cout << "display device info in user space, format:" << endl;
141 std::string titleHostName = "hostName";
142 SetPadAlign(titleHostName, ' ', ALIGN_SIZE);
143
144 cout << titleHostName << ":hostId" << endl;
145
146 std::string titleDevName = "deviceName";
147 std::string titleSrvName = ":serviceName";
148 SetPadAlign(titleDevName, ' ', ALIGN_SIZE);
149 SetPadAlign(titleSrvName, ' ', ALIGN_SIZE);
150
151 cout << "\t" << titleDevName << ":deviceId \t" << titleSrvName << endl;
152 uint32_t hostCnt = 0;
153 uint32_t devNodeCnt = 0;
154
155 for (auto &info : deviceInfos) {
156 SetPadAlign(info.hostName, ' ', ALIGN_SIZE);
157 cout << info.hostName << ":0x" << std::hex << info.hostId << endl;
158 for (auto &dev : info.devInfo) {
159 SetPadAlign(dev.deviceName, ' ', ALIGN_SIZE);
160 SetPadAlign(dev.servName, ' ', ALIGN_SIZE);
161 cout << "\t" << dev.deviceName << ":0x" << std::hex << dev.devId << "\t:" << dev.servName << endl;
162 devNodeCnt++;
163 }
164 hostCnt++;
165 }
166
167 cout << "total " << std::dec << hostCnt << " hosts, " << devNodeCnt << " devNodes in user space" << endl;
168 }
169
PrintOneHostInfoKernel(struct HdfSBuf * data,uint32_t & devNodeCnt)170 static int32_t PrintOneHostInfoKernel(struct HdfSBuf *data, uint32_t &devNodeCnt)
171 {
172 const char *hostName = HdfSbufReadString(data);
173 if (hostName == nullptr) {
174 return HDF_FAILURE;
175 }
176
177 uint32_t hostId;
178 if (!HdfSbufReadUint32(data, &hostId)) {
179 cout << "PrintOneHostInfoKernel HdfSbufReadUint32 hostId failed" << endl;
180 return HDF_FAILURE;
181 }
182
183 std::string hostNameStr = hostName;
184 SetPadAlign(hostNameStr, ' ', ALIGN_SIZE);
185 cout << hostNameStr << ":0x" << std::hex << hostId << endl;
186
187 uint32_t devCnt;
188 if (!HdfSbufReadUint32(data, &devCnt)) {
189 cout << "PrintOneHostInfoKernel HdfSbufReadUint32 devCnt failed" << endl;
190 return HDF_FAILURE;
191 }
192
193 for (uint32_t i = 0; i < devCnt; i++) {
194 const char *str = HdfSbufReadString(data);
195 std::string deviceName = (str == nullptr) ? "" : str;
196 SetPadAlign(deviceName, ' ', ALIGN_SIZE);
197
198 uint32_t devId;
199 if (!HdfSbufReadUint32(data, &devId)) {
200 cout << "PrintOneHostInfoKernel HdfSbufReadUint32 devId failed" << endl;
201 return HDF_FAILURE;
202 }
203
204 str = HdfSbufReadString(data);
205 std::string servName = (str == nullptr) ? "" : str;
206 SetPadAlign(servName, ' ', ALIGN_SIZE);
207 cout << "\t" << deviceName << ":0x" << std::hex << devId << "\t:" << servName << endl;
208 }
209 devNodeCnt += devCnt;
210
211 return HDF_SUCCESS;
212 }
PrintAllDeviceInfoKernel(struct HdfSBuf * data,bool flag)213 static void PrintAllDeviceInfoKernel(struct HdfSBuf *data, bool flag)
214 {
215 uint32_t hostCnt = 0;
216 uint32_t devNodeCnt = 0;
217
218 std::string titleHostName = "hostName";
219 SetPadAlign(titleHostName, ' ', ALIGN_SIZE);
220 cout << "display device info in kernel space, format:" << endl;
221 cout << titleHostName << ":hostId" << endl;
222
223 std::string titleDevName = "deviceName";
224 std::string titleSrvName = "serviceName";
225 SetPadAlign(titleDevName, ' ', ALIGN_SIZE);
226 SetPadAlign(titleSrvName, ' ', ALIGN_SIZE);
227 cout << "\t" << titleDevName << ":deviceId \t:" << titleSrvName << endl;
228
229 while (flag) {
230 if (PrintOneHostInfoKernel(data, devNodeCnt) == HDF_FAILURE) {
231 break;
232 }
233 hostCnt++;
234 }
235
236 cout << "total " << std::dec << hostCnt << " hosts, " << devNodeCnt << " devNodes in kernel space" << endl;
237 }
238
ParseHdiParameter(int argc,char ** argv,MessageParcel & data)239 static int32_t ParseHdiParameter(int argc, char **argv, MessageParcel &data)
240 {
241 int32_t paraCnt = atoi(argv[PARA_CNT_IDX]);
242 if ((paraCnt * PARA_MULTIPLE) != (argc - PARA_CNT_IDX - 1)) {
243 cout << "parameter count error, input: " << paraCnt << " real: " << (argc - PARA_CNT_IDX - 1) << endl;
244 return HDF_FAILURE;
245 }
246
247 int32_t paraTypeIdx = PARA_CNT_IDX + 1;
248 for (int i = 0; i < paraCnt; i++) {
249 int32_t paraValueIdx = paraTypeIdx + 1;
250 if (strcmp(argv[paraTypeIdx], "string") == 0) {
251 data.WriteCString(argv[paraValueIdx]);
252 } else if (strcmp(argv[paraTypeIdx], "int") == 0) {
253 data.WriteInt32(atoi(argv[paraValueIdx]));
254 } else {
255 cout << "parameterType error:" << argv[paraTypeIdx] << endl;
256 return HDF_FAILURE;
257 }
258 paraTypeIdx += PARA_MULTIPLE;
259 }
260 return HDF_SUCCESS;
261 }
262
InjectDebugHdi(int argc,char ** argv)263 static int32_t InjectDebugHdi(int argc, char **argv)
264 {
265 if (argc < DBG_HDI_PARA_MIN_LEN) {
266 PrintHelp();
267 return HDF_FAILURE;
268 }
269
270 auto servmgr = IServiceManager::Get();
271 auto devmgr = IDeviceManager::Get();
272 int32_t loadFlag = atoi(argv[DBG_HDI_SERVICE_LOAD_IDX]);
273
274 MessageParcel data;
275 data.WriteInterfaceToken(OHOS::Str8ToStr16(argv[INTERFACE_DESC_IDX]));
276
277 int32_t ret = ParseHdiParameter(argc, argv, data);
278 if (ret != HDF_SUCCESS) {
279 PrintHelp();
280 return HDF_FAILURE;
281 }
282
283 if (loadFlag == 1) {
284 devmgr->LoadDevice(argv[SERVER_NAME_IDX]);
285 OsalMSleep(WAIT_TIME);
286 }
287
288 MessageParcel reply;
289 MessageOption option;
290 auto service = servmgr->GetService(argv[SERVER_NAME_IDX]);
291 if (service == nullptr) {
292 cout << "getService " << argv[SERVER_NAME_IDX] << " failed" << endl;
293 goto END;
294 }
295
296 ret = service->SendRequest(atoi(argv[CMD_ID_IDX]), data, reply, option);
297 cout << "call service " << argv[SERVER_NAME_IDX] << " hdi cmd:" << atoi(argv[CMD_ID_IDX]) << " return:" << ret
298 << endl;
299 END:
300 if (loadFlag == 1) {
301 devmgr->UnloadDevice(argv[SERVER_NAME_IDX]);
302 }
303
304 return ret;
305 }
306
GetAllServiceUserSpace()307 static void GetAllServiceUserSpace()
308 {
309 auto servmgr = IServiceManager::Get();
310 if (servmgr == nullptr) {
311 cout << "GetAllServiceUserSpace get ServiceManager failed" << endl;
312 return;
313 }
314
315 std::vector<HdiServiceInfo> serviceInfos;
316 (void)servmgr->ListAllService(serviceInfos);
317
318 PrintAllServiceInfoUser(serviceInfos);
319 }
320
GetAllServiceKernelSpace()321 static void GetAllServiceKernelSpace()
322 {
323 struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
324 if (data == nullptr) {
325 cout << "GetAllServiceKernelSpace HdfSbufObtain failed" << endl;
326 return;
327 }
328
329 int32_t ret = HdfListAllService(data);
330 OsalMSleep(WAIT_TIME);
331 if (ret == HDF_SUCCESS) {
332 PrintAllServiceInfoKernel(data, true);
333 } else {
334 PrintAllServiceInfoKernel(data, false);
335 }
336
337 HdfSbufRecycle(data);
338 }
339
GetAllDeviceUserSpace()340 static void GetAllDeviceUserSpace()
341 {
342 auto devmgr = IDeviceManager::Get();
343 if (devmgr == nullptr) {
344 cout << "GetAllDeviceUserSpace get DeviceManager failed" << endl;
345 return;
346 }
347
348 std::vector<HdiDevHostInfo> deviceInfos;
349 (void)devmgr->ListAllDevice(deviceInfos);
350 PrintALLDeviceInfoUser(deviceInfos);
351 }
352
GetAllDeviceKernelSpace()353 static void GetAllDeviceKernelSpace()
354 {
355 struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
356 if (data == nullptr) {
357 cout << "GetAllDeviceKernelSpace HdfSbufObtain failed" << endl;
358 return;
359 }
360
361 int32_t ret = HdfListAllDevice(data);
362 OsalMSleep(WAIT_TIME);
363 if (ret == HDF_SUCCESS) {
364 PrintAllDeviceInfoKernel(data, true);
365 } else {
366 PrintAllDeviceInfoKernel(data, false);
367 }
368
369 HdfSbufRecycle(data);
370 }
371
GetAllInformation()372 static void GetAllInformation()
373 {
374 GetAllServiceUserSpace();
375 cout << endl;
376 GetAllServiceKernelSpace();
377 cout << endl;
378 GetAllDeviceUserSpace();
379 cout << endl;
380 GetAllDeviceKernelSpace();
381 }
382
main(int argc,char ** argv)383 int main(int argc, char **argv)
384 {
385 if (argc == 1 || (argc == HELP_INFO_PARA_CNT && strcmp(argv[FUNC_IDX], "-h") == 0)) {
386 PrintHelp();
387 } else if (argc == QUERY_INFO_PARA_CNT || argc == QUERY_INFO_PARA_CNT - 1) {
388 if (strcmp(argv[FUNC_IDX], "-q") != 0) {
389 PrintHelp();
390 return HDF_FAILURE;
391 }
392
393 if (argc == QUERY_INFO_PARA_CNT - 1) {
394 g_getInfoFuncs[GET_INFO_FUNC_NUMS - 1]();
395 return HDF_SUCCESS;
396 }
397
398 uint32_t queryIdx = static_cast<uint32_t>(atoi(argv[QUERY_INFO_PARA_CNT - 1]));
399 if (queryIdx < GET_INFO_FUNC_NUMS - 1) {
400 g_getInfoFuncs[queryIdx]();
401 } else {
402 PrintHelp();
403 return HDF_FAILURE;
404 }
405 } else if (argc > QUERY_INFO_PARA_CNT) {
406 if (strcmp(argv[FUNC_IDX], "-d") == 0) {
407 return InjectDebugHdi(argc, argv);
408 } else {
409 PrintHelp();
410 return HDF_FAILURE;
411 }
412 }
413
414 return HDF_SUCCESS;
415 }
416