• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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 
DevMgrFillDeviceHostInfo(struct HdfSBuf * data,struct HdfSBuf * reply)195 static int32_t DevMgrFillDeviceHostInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
196 {
197     const char *name = HdfSbufReadString(data);
198     if (name == NULL) {
199         return HDF_FAILURE;
200     }
201 
202     char line[LINE_SIZE];
203     // The line is a combination of multiple fields, and the fields are filled with blank characters
204     (void)memset_s(line, sizeof(line), ' ', sizeof(line));
205     if (memcpy_s(line, sizeof(line), name, strlen(name)) != EOK) {
206         HDF_LOGE("%{public}s memcpy_s hostName fail", __func__);
207         return HDF_FAILURE;
208     }
209     HDF_LOGI("%{public}s devName:%{public}s", __func__, name);
210 
211     uint32_t hostId;
212     (void)HdfSbufReadUint32(data, &hostId);
213     const uint32_t hostIdAlign = 32;
214     if (sprintf_s(&line[hostIdAlign], sizeof(line) - hostIdAlign, ":0x%x\n", hostId) == -1) {
215         HDF_LOGE("%{public}s sprintf_s hostId fail", __func__);
216         return HDF_FAILURE;
217     }
218 
219     (void)HdfSbufWriteString(reply, line);
220     return HDF_SUCCESS;
221 }
222 
DevMgrFillDeviceInfo(struct HdfSBuf * data,struct HdfSBuf * reply,uint32_t * hostCnt,uint32_t * nodeCnt)223 static void DevMgrFillDeviceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *hostCnt, uint32_t *nodeCnt)
224 {
225     char line[LINE_SIZE];
226     const uint32_t devNameAlign = 8;
227     const uint32_t devIdAlign = 40;
228     const uint32_t servNameAlign = 56;
229     uint32_t devCnt;
230     uint32_t devId;
231     const uint32_t strEndLen = 2;
232 
233     while (true) {
234         if (DevMgrFillDeviceHostInfo(data, reply) != HDF_SUCCESS) {
235             return;
236         }
237 
238         (void)HdfSbufReadUint32(data, &devCnt);
239         (*hostCnt)++;
240 
241         for (uint32_t i = 0; i < devCnt; i++) {
242             // The line is a combination of multiple fields, and the fields are filled with blank characters
243             (void)memset_s(line, sizeof(line), ' ', sizeof(line));
244 
245             const char *name = HdfSbufReadString(data);
246             const char *devName = (name == NULL) ? "" : name;
247             if (memcpy_s(&line[devNameAlign], sizeof(line) - devNameAlign, devName, strlen(devName)) != EOK) {
248                 HDF_LOGE("%{public}s memcpy_s devName fail", __func__);
249                 return;
250             }
251             HDF_LOGI("%{public}s devName:%{public}s", __func__, devName);
252 
253             (void)HdfSbufReadUint32(data, &devId);
254             int32_t devIdLen = sprintf_s(&line[devIdAlign], sizeof(line) - devIdAlign - 1, ":0x%x", devId);
255             if (devIdLen == -1) {
256                 HDF_LOGE("%{public}s sprintf_s devId fail", __func__);
257                 return;
258             }
259             line[devIdAlign + devIdLen] = ' '; // Clear the string terminator added by sprintf_s
260             line[servNameAlign - 1] = ':';
261 
262             name = HdfSbufReadString(data);
263             const char *servName = (name == NULL) ? "" : name;
264             const uint32_t leftSize = sizeof(line) - servNameAlign - strEndLen;
265             if (memcpy_s(&line[servNameAlign], leftSize, servName, strlen(servName)) != EOK) {
266                 HDF_LOGE("%{public}s memcpy_s servName fail %{public}s", __func__, servName);
267                 return;
268             }
269             line[servNameAlign + strlen(servName)] = '\n';
270             line[servNameAlign + strlen(servName) + 1] = '\0';
271 
272             (void)HdfSbufWriteString(reply, line);
273             (*nodeCnt)++;
274         }
275     }
276     return;
277 }
278 
DevMgrFillServiceInfo(struct HdfSBuf * data,struct HdfSBuf * reply,uint32_t * servCnt)279 static void DevMgrFillServiceInfo(struct HdfSBuf *data, struct HdfSBuf *reply, uint32_t *servCnt)
280 {
281     char line[LINE_SIZE];
282     const uint32_t devClassAlign = 32;
283     const uint32_t devIdAlign = 48;
284     const char *servName = NULL;
285     uint32_t devClass;
286     uint32_t devId;
287 
288     while (true) {
289         servName = HdfSbufReadString(data);
290         if (servName == NULL) {
291             return;
292         }
293 
294         // The line is a combination of multiple fields, and the fields are filled with blank characters
295         (void)memset_s(line, sizeof(line), ' ', sizeof(line));
296         if (memcpy_s(line, sizeof(line), servName, strlen(servName)) != EOK) {
297             HDF_LOGE("%{public}s memcpy_s servName fail", __func__);
298             return;
299         }
300         HDF_LOGI("%{public}s servName:%{public}s", __func__, servName);
301 
302         (void)HdfSbufReadUint32(data, &devClass);
303         int32_t devClassLen = sprintf_s(&line[devClassAlign], sizeof(line) - devClassAlign - 1, ":0x%x", devClass);
304         if (devClassLen == -1) {
305             HDF_LOGE("%{public}s sprintf_s devClass fail", __func__);
306             return;
307         }
308         line[devClassAlign + devClassLen] = ' '; // Clear the string terminator added by sprintf_s
309 
310         (void)HdfSbufReadUint32(data, &devId);
311         if (sprintf_s(&line[devIdAlign], sizeof(line) - devIdAlign, ":0x%x\n", devId) == -1) {
312             HDF_LOGE("%{public}s sprintf_s devId fail", __func__);
313             return;
314         }
315 
316         (void)HdfSbufWriteString(reply, line);
317         (*servCnt)++;
318     }
319 
320     return;
321 }
322 
DevMgrQueryUserDevice(struct HdfSBuf * reply)323 static void DevMgrQueryUserDevice(struct HdfSBuf *reply)
324 {
325     const char *title = "hdf device information in user space, format:\n" \
326                         "hostName                        :hostId\n" \
327                         "        deviceName                      :deviceId      :serviceName\n";
328 
329     struct IDevmgrService *instance = DevmgrServiceGetInstance();
330     if (instance == NULL) {
331         return;
332     }
333 
334     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
335     if (data == NULL) {
336         return;
337     }
338 
339     int32_t ret = instance->ListAllDevice(instance, data);
340     if (ret != HDF_SUCCESS) {
341         HdfSbufRecycle(data);
342         return;
343     }
344 
345     HdfSbufWriteString(reply, title);
346 
347     uint32_t hostCnt = 0;
348     uint32_t devNodeCnt = 0;
349     DevMgrFillDeviceInfo(data, reply, &hostCnt, &devNodeCnt);
350 
351     const uint32_t descLen = 128;
352     char desc[descLen];
353     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
354     if (sprintf_s(desc, sizeof(desc), "total %u hosts, %u devNodes in user space\n\n", hostCnt, devNodeCnt) != -1) {
355         HdfSbufWriteString(reply, desc);
356     }
357 
358     HdfSbufRecycle(data);
359     return;
360 }
361 
DevMgrQueryUserService(struct HdfSBuf * reply)362 static void DevMgrQueryUserService(struct HdfSBuf *reply)
363 {
364     const char *title = "hdf service information in user space, format:\n" \
365                         "serviceName                     :devClass       :devId\n";
366 
367     struct IDevSvcManager *instance = DevSvcManagerGetInstance();
368     if (instance == NULL) {
369         return;
370     }
371 
372     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
373     if (data == NULL) {
374         return;
375     }
376 
377     instance->ListAllService(instance, data);
378 
379     HdfSbufWriteString(reply, title);
380     uint32_t servCnt = 0;
381     DevMgrFillServiceInfo(data, reply, &servCnt);
382 
383     const uint32_t descLen = 128;
384     char desc[descLen];
385     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
386     if (sprintf_s(desc, sizeof(desc), "total %u services in user space\n\n", servCnt) != -1) {
387         HdfSbufWriteString(reply, desc);
388     }
389 
390     HdfSbufRecycle(data);
391     return;
392 }
393 
DevMgrQueryKernelDevice(struct HdfSBuf * reply)394 static void DevMgrQueryKernelDevice(struct HdfSBuf *reply)
395 {
396     const char *title = "hdf device information in kernel space, format:\n" \
397                         "hostName                        :hostId\n" \
398                         "        deviceName                      :deviceId      :serviceName\n";
399 
400     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
401     if (data == NULL) {
402         return;
403     }
404 
405     int32_t ret =  HdfListAllDevice(data);
406     if (ret != HDF_SUCCESS) {
407         HdfSbufRecycle(data);
408         return;
409     }
410 
411     uint32_t hostCnt = 0;
412     uint32_t devNodeCnt = 0;
413     HdfSbufWriteString(reply, title);
414     DevMgrFillDeviceInfo(data, reply, &hostCnt, &devNodeCnt);
415 
416     const uint32_t descLen = 128;
417     char desc[descLen];
418     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
419     if (sprintf_s(desc, sizeof(desc), "total %u hosts, %u devNodes in kernel space\n\n", hostCnt, devNodeCnt) != -1) {
420         HdfSbufWriteString(reply, desc);
421     }
422 
423     HdfSbufRecycle(data);
424     return;
425 }
426 
DevMgrQueryKernelService(struct HdfSBuf * reply)427 static void DevMgrQueryKernelService(struct HdfSBuf *reply)
428 {
429     const char *title = "hdf service information in kernel space, format:\n" \
430                         "serviceName                     :devClass       :devId\n";
431 
432     struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
433     if (data == NULL) {
434         return;
435     }
436 
437     int32_t ret = HdfListAllService(data);
438     if (ret != HDF_SUCCESS) {
439         HdfSbufRecycle(data);
440         return;
441     }
442 
443     HdfSbufWriteString(reply, title);
444     uint32_t servCnt = 0;
445     DevMgrFillServiceInfo(data, reply, &servCnt);
446 
447     const uint32_t descLen = 128;
448     char desc[descLen];
449     (void)memset_s(desc, sizeof(desc), 0, sizeof(desc));
450     if (sprintf_s(desc, sizeof(desc), "total %u services in kernel space\n\n", servCnt) != -1) {
451         HdfSbufWriteString(reply, desc);
452     }
453 
454     HdfSbufRecycle(data);
455     return;
456 }
457 
DevMgrQueryInfo(struct HdfSBuf * reply)458 static void DevMgrQueryInfo(struct HdfSBuf *reply)
459 {
460     DevMgrQueryUserDevice(reply);
461     DevMgrQueryUserService(reply);
462     DevMgrQueryKernelDevice(reply);
463     DevMgrQueryKernelService(reply);
464     return;
465 }
466 
DevMgrDump(struct HdfSBuf * data,struct HdfSBuf * reply)467 static int32_t DevMgrDump(struct HdfSBuf *data, struct HdfSBuf *reply)
468 {
469     if (data == NULL || reply == NULL) {
470         return HDF_FAILURE;
471     }
472 
473     uint32_t argv = 0;
474     HdfSbufReadUint32(data, &argv);
475 
476     if (argv == 0) {
477         (void)HdfSbufWriteString(reply, HELP_COMMENT);
478         return HDF_SUCCESS;
479     }
480 
481     const char *value = HdfSbufReadString(data);
482     if (value == NULL) {
483         HDF_LOGE("%{public}s arg is invalid", __func__);
484         return HDF_FAILURE;
485     }
486 
487     HDF_LOGI("%{public}s argv:%{public}d", value, argv);
488     if (argv == 1) {
489         if (strcmp(value, "-help") == 0) {
490             (void)HdfSbufWriteString(reply, HELP_COMMENT);
491             return HDF_SUCCESS;
492         } else if (strcmp(value, "-query") == 0) {
493             DevMgrQueryInfo(reply);
494             return HDF_SUCCESS;
495         } else {
496             (void)HdfSbufWriteString(reply, HELP_COMMENT);
497             return HDF_SUCCESS;
498         }
499     } else {
500         if (strcmp(value, "-host") == 0) {
501             return DevMgrDumpHost(argv - 1, data, reply);
502         } else if (strcmp(value, "-service") == 0) {
503             return DevMgrDumpService(argv - 1, data, reply);
504         } else {
505             (void)HdfSbufWriteString(reply, HELP_COMMENT);
506             return HDF_SUCCESS;
507         }
508     }
509 
510     return HDF_SUCCESS;
511 }
512 
DevMgrRegisterDumpFunc(void)513 void DevMgrRegisterDumpFunc(void)
514 {
515     HdfRegisterDumpFunc(DevMgrDump);
516 }
517