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