1 /*
2  * Copyright (c) 2023 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 "securec.h"
17 
18 #include "devmgr_service.h"
19 #include "devhost_service_clnt.h"
20 #include "devhost_service_proxy.h"
21 #include "device_token_clnt.h"
22 #include "devmgr_service.h"
23 #include "devsvc_manager.h"
24 #include "hdf_dlist.h"
25 #include "hdf_dump_reg.h"
26 #include "hdf_io_service.h"
27 #include "hdf_core_log.h"
28 #include "hdf_sbuf.h"
29 #include "devmgr_dump.h"
30 
31 #define HDF_LOG_TAG devmgr_dump
32 
33 static const char *HELP_COMMENT =
34     " usage:\n"
35     " -help  :display help information\n"
36     " -query :query all services and devices information\n"
37     " -host hostName parameter1 parameter2 ... :dump for host, maximum number of parameters is 20\n"
38     " -service serviceName parameter1 parameter2 ... :dump for device service, maximum number of parameters is 20\n";
39 
40 static const uint32_t DATA_SIZE = 5000;
41 static const uint32_t LINE_SIZE = 128;
42 
DevMgrDumpHostFindHost(const char *hostName, struct HdfSBuf *data, struct HdfSBuf *reply)43 static int32_t DevMgrDumpHostFindHost(const char *hostName, struct HdfSBuf *data, struct HdfSBuf *reply)
44 {
45     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
46     if (devMgrSvc == NULL) {
47         return HDF_FAILURE;
48     }
49 
50     struct DevHostServiceClnt *hostClnt = NULL;
51     int32_t ret = HDF_FAILURE;
52     bool findFlag = false;
53 
54     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
55         HDF_LOGI("%{public}s hostName:%{public}s %{public}s", __func__, hostClnt->hostName, hostName);
56         if (strcmp(hostClnt->hostName, hostName) != 0) {
57             continue;
58         }
59         findFlag = true;
60         if (hostClnt->hostService == NULL || hostClnt->hostService->Dump == NULL) {
61             (void)HdfSbufWriteString(reply, "The host does not start\n");
62             break;
63         }
64         ret = hostClnt->hostService->Dump(hostClnt->hostService, data, reply);
65         break;
66     }
67 
68     if (!findFlag) {
69         (void)HdfSbufWriteString(reply, "The host does not exist\n");
70     }
71 
72     return ret;
73 }
74 
DevMgrDumpHost(uint32_t argv, struct HdfSBuf *data, struct HdfSBuf *reply)75 static int32_t DevMgrDumpHost(uint32_t argv, struct HdfSBuf *data, struct HdfSBuf *reply)
76 {
77     const char *hostName = HdfSbufReadString(data);
78     if (hostName == NULL) {
79         HDF_LOGE("%{public}s hostName is null", __func__);
80         return HDF_FAILURE;
81     }
82 
83     struct HdfSBuf *hostData = HdfSbufTypedObtain(SBUF_IPC);
84     if (hostData == NULL) {
85         return HDF_FAILURE;
86     }
87 
88     // this parameters are processed in the framework part and will not be sent to the business module
89     if (!HdfSbufWriteString(hostData, "dumpHost")) {
90         HdfSbufRecycle(hostData);
91         return HDF_FAILURE;
92     }
93 
94     // the hostName will not be send to host
95     if (!HdfSbufWriteUint32(hostData, argv - 1)) {
96         HdfSbufRecycle(hostData);
97         return HDF_FAILURE;
98     }
99 
100     for (uint32_t i = 0; i < argv - 1; i++) {
101         const char *value = HdfSbufReadString(data);
102         if (value == NULL || !HdfSbufWriteString(hostData, value)) {
103             HdfSbufRecycle(hostData);
104             return HDF_FAILURE;
105         }
106     }
107 
108     int32_t ret = DevMgrDumpHostFindHost(hostName, hostData, reply);
109 
110     HdfSbufRecycle(hostData);
111     return ret;
112 }
113 
DevMgrDumpServiceFindHost(const char *servName, struct HdfSBuf *data, struct HdfSBuf *reply)114 static int32_t DevMgrDumpServiceFindHost(const char *servName, struct HdfSBuf *data, struct HdfSBuf *reply)
115 {
116     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
117     if (devMgrSvc == NULL) {
118         return HDF_FAILURE;
119     }
120 
121     struct HdfSListIterator iterator;
122     struct DevHostServiceClnt *hostClnt = NULL;
123     int32_t ret = HDF_FAILURE;
124     const char *name = NULL;
125     struct HdfSListNode *node = NULL;
126     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
127         HdfSListIteratorInit(&iterator, &hostClnt->devices);
128         while (HdfSListIteratorHasNext(&iterator)) {
129             node = HdfSListIteratorNext(&iterator);
130             struct DeviceTokenClnt *tokenClnt = (struct DeviceTokenClnt *)node;
131             if (tokenClnt == NULL || tokenClnt->tokenIf == NULL) {
132                 continue;
133             }
134             name = (tokenClnt->tokenIf->servName == NULL) ? "" : tokenClnt->tokenIf->servName;
135             HDF_LOGI("%{public}s servName:%{public}s %{public}s", __func__, name, servName);
136             if (strcmp(name, servName) != 0) {
137                 continue;
138             }
139             if (hostClnt->hostService == NULL || hostClnt->hostService->Dump == NULL) {
140                 return ret;
141             }
142             ret = hostClnt->hostService->Dump(hostClnt->hostService, data, reply);
143             return ret;
144         }
145     }
146 
147     (void)HdfSbufWriteString(reply, "The service does not exist\n");
148     return ret;
149 }
150 
DevMgrDumpService(uint32_t argv, struct HdfSBuf *data, struct HdfSBuf *reply)151 static int32_t DevMgrDumpService(uint32_t argv, struct HdfSBuf *data, struct HdfSBuf *reply)
152 {
153     const char *servName = HdfSbufReadString(data);
154     if (servName == NULL) {
155         HDF_LOGE("%{public}s serviceName is null", __func__);
156         return HDF_FAILURE;
157     }
158 
159     struct HdfSBuf *servData = HdfSbufTypedObtain(SBUF_IPC);
160     if (servData == NULL) {
161         return HDF_FAILURE;
162     }
163 
164     // this parameters are processed in the framework part and will not be sent to the business module
165     if (!HdfSbufWriteString(servData, "dumpService")) {
166         HdfSbufRecycle(servData);
167         return HDF_FAILURE;
168     }
169 
170     // this parameters are processed in the framework part and will not be sent to the business module
171     if (!HdfSbufWriteString(servData, servName)) {
172         HdfSbufRecycle(servData);
173         return HDF_FAILURE;
174     }
175 
176     if (!HdfSbufWriteUint32(servData, argv - 1)) {
177         HdfSbufRecycle(servData);
178         return HDF_FAILURE;
179     }
180 
181     // the servName will not be send to business module
182     for (uint32_t i = 0; i < argv - 1; i++) {
183         const char *value = HdfSbufReadString(data);
184         if (value == NULL || !HdfSbufWriteString(servData, value)) {
185             HdfSbufRecycle(servData);
186             return HDF_FAILURE;
187         }
188     }
189 
190     int32_t ret = DevMgrDumpServiceFindHost(servName, servData, reply);
191     HdfSbufRecycle(servData);
192     return ret;
193 }
194 
DevMgrDumpIpcFillHostCmd(struct HdfSBuf *ipcData, int32_t fd, const char *cmd)195 static int32_t DevMgrDumpIpcFillHostCmd(struct HdfSBuf *ipcData, int32_t fd, const char *cmd)
196 {
197     if (!HdfSbufWriteString(ipcData, "--ipc")) {
198         return HDF_FAILURE;
199     }
200 
201     if (!HdfSbufWriteFileDescriptor(ipcData, fd)) {
202         return HDF_FAILURE;
203     }
204 
205     if (!HdfSbufWriteString(ipcData, cmd)) {
206         return HDF_FAILURE;
207     }
208 
209     return HDF_SUCCESS;
210 }
211 
DevMgrDumpAllHostsIpcStats(struct HdfSBuf *data, struct HdfSBuf *reply)212 static int32_t DevMgrDumpAllHostsIpcStats(struct HdfSBuf *data, struct HdfSBuf *reply)
213 {
214     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
215     if (devMgrSvc == NULL) {
216         return HDF_FAILURE;
217     }
218 
219     struct DevHostServiceClnt *hostClnt = NULL;
220     int32_t ret = HDF_FAILURE;
221     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
222         HDF_LOGI("%{public}s hostName:%{public}s", __func__, hostClnt->hostName);
223         if (hostClnt->hostService == NULL || hostClnt->hostService->Dump == NULL) {
224             HDF_LOGI("The host does not start");
225             continue;
226         }
227         ret = hostClnt->hostService->Dump(hostClnt->hostService, data, reply);
228         if (ret != HDF_SUCCESS) {
229             HDF_LOGE("Dump Host failed");
230         }
231     }
232 
233     return ret;
234 }
235 
DevMgrDumpIpcAllHosts(int32_t fd, const char *cmd, struct HdfSBuf *reply)236 static int32_t DevMgrDumpIpcAllHosts(int32_t fd, const char *cmd, struct HdfSBuf *reply)
237 {
238     struct HdfSBuf *ipcData = HdfSbufTypedObtain(SBUF_IPC);
239     if (ipcData == NULL) {
240         return HDF_FAILURE;
241     }
242 
243     int32_t ret = DevMgrDumpIpcFillHostCmd(ipcData, fd, cmd);
244     if (ret != HDF_SUCCESS) {
245         HdfSbufRecycle(ipcData);
246         return HDF_FAILURE;
247     }
248 
249     ret = DevMgrDumpAllHostsIpcStats(ipcData, reply);
250     HdfSbufRecycle(ipcData);
251     return ret;
252 }
253 
DevMgrDumpSingleHostIpcStats(int32_t pid, struct HdfSBuf *data, struct HdfSBuf *reply)254 static int32_t DevMgrDumpSingleHostIpcStats(int32_t pid, struct HdfSBuf *data, struct HdfSBuf *reply)
255 {
256     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
257     if (devMgrSvc == NULL) {
258         return HDF_FAILURE;
259     }
260 
261     struct DevHostServiceClnt *hostClnt = NULL;
262     int32_t ret = HDF_FAILURE;
263     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
264         if (hostClnt->hostService == NULL || hostClnt->hostService->Dump == NULL) {
265             HDF_LOGI("The host does not start");
266             continue;
267         }
268         if (hostClnt->hostProcessId == pid) {
269             HDF_LOGI("%{public}s hostName:%{public}s %{public}d %{public}d", __func__,
270                 hostClnt->hostName, hostClnt->hostProcessId, pid);
271             ret = hostClnt->hostService->Dump(hostClnt->hostService, data, reply);
272             break;
273         }
274     }
275 
276     return ret;
277 }
278 
DevMgrDumpIpcSingleHost(int32_t pid, int32_t fd, const char *cmd, struct HdfSBuf *reply)279 static int32_t DevMgrDumpIpcSingleHost(int32_t pid, int32_t fd, const char *cmd, struct HdfSBuf *reply)
280 {
281     struct HdfSBuf *ipcData = HdfSbufTypedObtain(SBUF_IPC);
282     if (ipcData == NULL) {
283         return HDF_FAILURE;
284     }
285 
286     int32_t ret = DevMgrDumpIpcFillHostCmd(ipcData, fd, cmd);
287     if (ret != HDF_SUCCESS) {
288         HdfSbufRecycle(ipcData);
289         return HDF_FAILURE;
290     }
291 
292     ret = DevMgrDumpSingleHostIpcStats(pid, ipcData, reply);
293     HdfSbufRecycle(ipcData);
294     return ret;
295 }
296 
DevMgrDumpIpc(int32_t fd, struct HdfSBuf *data, struct HdfSBuf *reply)297 static int32_t DevMgrDumpIpc(int32_t fd, struct HdfSBuf *data, struct HdfSBuf *reply)
298 {
299     const char *value = HdfSbufReadString(data);
300     if (value == NULL) {
301         HDF_LOGE("%{public}s value is null", __func__);
302         return HDF_FAILURE;
303     }
304 
305     const char *dumpCmd = HdfSbufReadString(data);
306     if (dumpCmd == NULL) {
307         HDF_LOGE("%{public}s dumpCmd is null", __func__);
308         return HDF_FAILURE;
309     }
310 
311     HDF_LOGI("%{public}s %{public}s fd:%{public}d", value, dumpCmd, fd);
312     if (strcmp(value, "all") == 0) {
313         HdfDumpIpcStat(fd, dumpCmd);
314         return DevMgrDumpIpcAllHosts(fd, dumpCmd, reply);
315     } else {
316         int32_t pid = atoi(value);
317         if (pid == getpid()) {
318             HdfDumpIpcStat(fd, dumpCmd);
319         } else {
320             return DevMgrDumpIpcSingleHost(pid, fd, dumpCmd, reply);
321         }
322     }
323 
324     return HDF_SUCCESS;
325 }
326 
DevMgrFillDeviceHostInfo(struct HdfSBuf *data, struct HdfSBuf *reply)327 static int32_t DevMgrFillDeviceHostInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
328 {
329     const char *name = HdfSbufReadString(data);
330     if (name == NULL) {
331         return HDF_FAILURE;
332     }
333 
334     char line[LINE_SIZE];
335     // The line is a combination of multiple fields, and the fields are filled with blank characters
336     (void)memset_s(line, sizeof(line), ' ', sizeof(line));
337     if (memcpy_s(line, sizeof(line), name, strlen(name)) != EOK) {
338         HDF_LOGE("%{public}s memcpy_s hostName fail", __func__);
339         return HDF_FAILURE;
340     }
341     HDF_LOGI("%{public}s devName:%{public}s", __func__, name);
342 
343     uint32_t hostId;
344     (void)HdfSbufReadUint32(data, &hostId);
345     const uint32_t hostIdAlign = 32;
346     if (sprintf_s(&line[hostIdAlign], sizeof(line) - hostIdAlign, ":0x%x\n", hostId) == -1) {
347         HDF_LOGE("%{public}s sprintf_s hostId fail", __func__);
348         return HDF_FAILURE;
349     }
350 
351     (void)HdfSbufWriteString(reply, line);
352     return HDF_SUCCESS;
353 }
354 
DevMgrFillDeviceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *hostCnt, uint32_t *nodeCnt)355 static void DevMgrFillDeviceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *hostCnt, uint32_t *nodeCnt)
356 {
357     char line[LINE_SIZE];
358     const uint32_t devNameAlign = 8;
359     const uint32_t devIdAlign = 40;
360     const uint32_t servNameAlign = 56;
361     uint32_t devCnt;
362     uint32_t devId;
363     const uint32_t strEndLen = 2;
364 
365     while (true) {
366         if (DevMgrFillDeviceHostInfo(data, reply) != HDF_SUCCESS) {
367             return;
368         }
369 
370         (void)HdfSbufReadUint32(data, &devCnt);
371         (*hostCnt)++;
372 
373         for (uint32_t i = 0; i < devCnt; i++) {
374             // The line is a combination of multiple fields, and the fields are filled with blank characters
375             (void)memset_s(line, sizeof(line), ' ', sizeof(line));
376 
377             const char *name = HdfSbufReadString(data);
378             const char *devName = (name == NULL) ? "" : name;
379             if (memcpy_s(&line[devNameAlign], sizeof(line) - devNameAlign, devName, strlen(devName)) != EOK) {
380                 HDF_LOGE("%{public}s memcpy_s devName fail", __func__);
381                 return;
382             }
383             HDF_LOGI("%{public}s devName:%{public}s", __func__, devName);
384 
385             (void)HdfSbufReadUint32(data, &devId);
386             int32_t devIdLen = sprintf_s(&line[devIdAlign], sizeof(line) - devIdAlign - 1, ":0x%x", devId);
387             if (devIdLen == -1) {
388                 HDF_LOGE("%{public}s sprintf_s devId fail", __func__);
389                 return;
390             }
391             line[devIdAlign + devIdLen] = ' '; // Clear the string terminator added by sprintf_s
392             line[servNameAlign - 1] = ':';
393 
394             name = HdfSbufReadString(data);
395             const char *servName = (name == NULL) ? "" : name;
396             const uint32_t leftSize = sizeof(line) - servNameAlign - strEndLen;
397             if (memcpy_s(&line[servNameAlign], leftSize, servName, strlen(servName)) != EOK) {
398                 HDF_LOGE("%{public}s memcpy_s servName fail %{public}s", __func__, servName);
399                 return;
400             }
401             line[servNameAlign + strlen(servName)] = '\n';
402             line[servNameAlign + strlen(servName) + 1] = '\0';
403 
404             (void)HdfSbufWriteString(reply, line);
405             (*nodeCnt)++;
406         }
407     }
408     return;
409 }
410 
DevMgrFillServiceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *servCnt)411 static void DevMgrFillServiceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *servCnt)
412 {
413     char line[LINE_SIZE];
414     const uint32_t devClassAlign = 32;
415     const uint32_t devIdAlign = 48;
416     const char *servName = NULL;
417     uint32_t devClass;
418     uint32_t devId;
419 
420     while (true) {
421         servName = HdfSbufReadString(data);
422         if (servName == NULL) {
423             return;
424         }
425 
426         // The line is a combination of multiple fields, and the fields are filled with blank characters
427         (void)memset_s(line, sizeof(line), ' ', sizeof(line));
428         if (memcpy_s(line, sizeof(line), servName, strlen(servName)) != EOK) {
429             HDF_LOGE("%{public}s memcpy_s servName fail", __func__);
430             return;
431         }
432         HDF_LOGI("%{public}s servName:%{public}s", __func__, servName);
433 
434         (void)HdfSbufReadUint32(data, &devClass);
435         int32_t devClassLen = sprintf_s(&line[devClassAlign], sizeof(line) - devClassAlign - 1, ":0x%x", devClass);
436         if (devClassLen == -1) {
437             HDF_LOGE("%{public}s sprintf_s devClass fail", __func__);
438             return;
439         }
440         line[devClassAlign + devClassLen] = ' '; // Clear the string terminator added by sprintf_s
441 
442         (void)HdfSbufReadUint32(data, &devId);
443         if (sprintf_s(&line[devIdAlign], sizeof(line) - devIdAlign, ":0x%x\n", devId) == -1) {
444             HDF_LOGE("%{public}s sprintf_s devId fail", __func__);
445             return;
446         }
447 
448         (void)HdfSbufWriteString(reply, line);
449         (*servCnt)++;
450     }
451 
452     return;
453 }
454 
DevMgrQueryUserDevice(struct HdfSBuf *reply)455 static void DevMgrQueryUserDevice(struct HdfSBuf *reply)
456 {
457     const char *title = "hdf device information in user space, format:\n" \
458                         "hostName                        :hostId\n" \
459                         "        deviceName                      :deviceId      :serviceName\n";
460 
461     struct IDevmgrService *instance = DevmgrServiceGetInstance();
462     if (instance == NULL) {
463         return;
464     }
465 
466     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
467     if (data == NULL) {
468         return;
469     }
470 
471     int32_t ret = instance->ListAllDevice(instance, data);
472     if (ret != HDF_SUCCESS) {
473         HdfSbufRecycle(data);
474         return;
475     }
476 
477     HdfSbufWriteString(reply, title);
478 
479     uint32_t hostCnt = 0;
480     uint32_t devNodeCnt = 0;
481     DevMgrFillDeviceInfo(data, reply, &hostCnt, &devNodeCnt);
482 
483     const uint32_t descLen = 128;
484     char desc[descLen];
485     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
486     if (sprintf_s(desc, sizeof(desc), "total %u hosts, %u devNodes in user space\n\n", hostCnt, devNodeCnt) != -1) {
487         HdfSbufWriteString(reply, desc);
488     }
489 
490     HdfSbufRecycle(data);
491     return;
492 }
493 
DevMgrQueryUserService(struct HdfSBuf *reply)494 static void DevMgrQueryUserService(struct HdfSBuf *reply)
495 {
496     const char *title = "hdf service information in user space, format:\n" \
497                         "serviceName                     :devClass       :devId\n";
498 
499     struct IDevSvcManager *instance = DevSvcManagerGetInstance();
500     if (instance == NULL) {
501         return;
502     }
503 
504     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
505     if (data == NULL) {
506         return;
507     }
508 
509     instance->ListAllService(instance, data);
510 
511     HdfSbufWriteString(reply, title);
512     uint32_t servCnt = 0;
513     DevMgrFillServiceInfo(data, reply, &servCnt);
514 
515     const uint32_t descLen = 128;
516     char desc[descLen];
517     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
518     if (sprintf_s(desc, sizeof(desc), "total %u services in user space\n\n", servCnt) != -1) {
519         HdfSbufWriteString(reply, desc);
520     }
521 
522     HdfSbufRecycle(data);
523     return;
524 }
525 
DevMgrQueryKernelDevice(struct HdfSBuf *reply)526 static void DevMgrQueryKernelDevice(struct HdfSBuf *reply)
527 {
528     const char *title = "hdf device information in kernel space, format:\n" \
529                         "hostName                        :hostId\n" \
530                         "        deviceName                      :deviceId      :serviceName\n";
531 
532     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
533     if (data == NULL) {
534         return;
535     }
536 
537     int32_t ret =  HdfListAllDevice(data);
538     if (ret != HDF_SUCCESS) {
539         HdfSbufRecycle(data);
540         return;
541     }
542 
543     uint32_t hostCnt = 0;
544     uint32_t devNodeCnt = 0;
545     HdfSbufWriteString(reply, title);
546     DevMgrFillDeviceInfo(data, reply, &hostCnt, &devNodeCnt);
547 
548     const uint32_t descLen = 128;
549     char desc[descLen];
550     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
551     if (sprintf_s(desc, sizeof(desc), "total %u hosts, %u devNodes in kernel space\n\n", hostCnt, devNodeCnt) != -1) {
552         HdfSbufWriteString(reply, desc);
553     }
554 
555     HdfSbufRecycle(data);
556     return;
557 }
558 
DevMgrQueryKernelService(struct HdfSBuf *reply)559 static void DevMgrQueryKernelService(struct HdfSBuf *reply)
560 {
561     const char *title = "hdf service information in kernel space, format:\n" \
562                         "serviceName                     :devClass       :devId\n";
563 
564     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
565     if (data == NULL) {
566         return;
567     }
568 
569     int32_t ret = HdfListAllService(data);
570     if (ret != HDF_SUCCESS) {
571         HdfSbufRecycle(data);
572         return;
573     }
574 
575     HdfSbufWriteString(reply, title);
576     uint32_t servCnt = 0;
577     DevMgrFillServiceInfo(data, reply, &servCnt);
578 
579     const uint32_t descLen = 128;
580     char desc[descLen];
581     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
582     if (sprintf_s(desc, sizeof(desc), "total %u services in kernel space\n\n", servCnt) != -1) {
583         HdfSbufWriteString(reply, desc);
584     }
585 
586     HdfSbufRecycle(data);
587     return;
588 }
589 
DevMgrQueryInfo(struct HdfSBuf *reply)590 static void DevMgrQueryInfo(struct HdfSBuf *reply)
591 {
592     DevMgrQueryUserDevice(reply);
593     DevMgrQueryUserService(reply);
594     DevMgrQueryKernelDevice(reply);
595     DevMgrQueryKernelService(reply);
596     return;
597 }
598 
DevMgrDump(struct HdfSBuf *data, struct HdfSBuf *reply)599 static int32_t DevMgrDump(struct HdfSBuf *data, struct HdfSBuf *reply)
600 {
601     if (data == NULL || reply == NULL) {
602         return HDF_FAILURE;
603     }
604 
605     int32_t fd = HdfSbufReadFileDescriptor(data);
606     if (fd < 0) {
607         HDF_LOGE("invalid fd %{public}d", fd);
608         return HDF_FAILURE;
609     }
610 
611     uint32_t argv = 0;
612     HdfSbufReadUint32(data, &argv);
613 
614     if (argv == 0) {
615         (void)HdfSbufWriteString(reply, HELP_COMMENT);
616         return HDF_SUCCESS;
617     }
618 
619     const char *value = HdfSbufReadString(data);
620     if (value == NULL) {
621         HDF_LOGE("%{public}s arg is invalid", __func__);
622         return HDF_FAILURE;
623     }
624 
625     HDF_LOGI("%{public}s argv:%{public}d", value, argv);
626     if (argv == 1) {
627         if (strcmp(value, "-help") == 0) {
628             (void)HdfSbufWriteString(reply, HELP_COMMENT);
629             return HDF_SUCCESS;
630         } else if (strcmp(value, "-query") == 0) {
631             DevMgrQueryInfo(reply);
632             return HDF_SUCCESS;
633         } else {
634             (void)HdfSbufWriteString(reply, HELP_COMMENT);
635             return HDF_SUCCESS;
636         }
637     } else {
638         if (strcmp(value, "-host") == 0) {
639             return DevMgrDumpHost(argv - 1, data, reply);
640         } else if (strcmp(value, "-service") == 0) {
641             return DevMgrDumpService(argv - 1, data, reply);
642         } else if (strcmp(value, "--ipc") == 0) {
643             return DevMgrDumpIpc(fd, data, reply);
644         } else {
645             (void)HdfSbufWriteString(reply, HELP_COMMENT);
646             return HDF_SUCCESS;
647         }
648     }
649 
650     return HDF_SUCCESS;
651 }
652 
DevMgrRegisterDumpFunc(void)653 void DevMgrRegisterDumpFunc(void)
654 {
655     HdfRegisterDumpFunc(DevMgrDump);
656 }
657