• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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