fix:add command line to query device information and debug hdi

Signed-off-by: zhang <zhangfengxi@huawei.com>
This commit is contained in:
zhang 2022-04-27 17:30:14 +08:00
parent ee21646b53
commit 4134f37755
10 changed files with 553 additions and 24 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -78,3 +78,60 @@ OUT:
return ret; return ret;
} }
int32_t HdfListAllService(struct HdfSBuf *reply)
{
int32_t ret = HDF_FAILURE;
struct HdfSBuf *data = NULL;
if (reply == NULL) {
HDF_LOGE("%s input reply is null", __func__);
return ret;
}
struct HdfIoService *ioService = HdfIoServiceBind(DEV_MGR_NODE);
if (ioService == NULL) {
HDF_LOGE("failed to get %s service", DEV_MGR_NODE);
return ret;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("%s failed to obtain sbuf data", __func__);
ret = HDF_DEV_ERR_NO_MEMORY;
goto OUT;
}
ret = ioService->dispatcher->Dispatch(&ioService->object, DEVMGR_LIST_ALL_SERVICE, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("failed to list all service info");
}
OUT:
HdfIoServiceRecycle(ioService);
HdfSbufRecycle(data);
return ret;
}
int32_t HdfListAllDevice(struct HdfSBuf *reply)
{
int32_t ret = HDF_FAILURE;
struct HdfSBuf *data = NULL;
if (reply == NULL) {
HDF_LOGE("%s input reply is null", __func__);
return ret;
}
struct HdfIoService *ioService = HdfIoServiceBind(DEV_MGR_NODE);
if (ioService == NULL) {
HDF_LOGE("failed to get %s service", DEV_MGR_NODE);
return ret;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("%s failed to obtain sbuf data", __func__);
ret = HDF_DEV_ERR_NO_MEMORY;
goto OUT;
}
ret = ioService->dispatcher->Dispatch(&ioService->object, DEVMGR_LIST_ALL_DEVICE, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("failed to list all device info");
}
OUT:
HdfIoServiceRecycle(ioService);
HdfSbufRecycle(data);
return ret;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -33,6 +33,29 @@ static void GetDeviceServiceNameByClass(struct HdfSBuf *reply, DeviceClass devic
HdfSbufWriteString(reply, NULL); HdfSbufWriteString(reply, NULL);
} }
static int32_t ListAllService(struct HdfSBuf *reply)
{
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)DevSvcManagerGetInstance();
if (reply == NULL || devSvcManager == NULL || devSvcManager->super.ListAllService == NULL) {
return HDF_FAILURE;
}
HdfSbufFlush(reply);
devSvcManager->super.ListAllService(&devSvcManager->super, reply);
HdfSbufWriteString(reply, NULL);
return HDF_SUCCESS;
}
static int32_t ListAllDevice(struct DevmgrService *devMgrSvc, struct HdfSBuf *reply)
{
if (reply == NULL || devMgrSvc->super.ListAllDevice == NULL) {
return HDF_FAILURE;
}
HdfSbufFlush(reply);
devMgrSvc->super.ListAllDevice(&devMgrSvc->super, reply);
HdfSbufWriteString(reply, NULL);
return HDF_SUCCESS;
}
int DeviceManagerDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply) int DeviceManagerDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
{ {
int ret = HDF_FAILURE; int ret = HDF_FAILURE;
@ -73,6 +96,12 @@ int DeviceManagerDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data
GetDeviceServiceNameByClass(reply, deviceClass); GetDeviceServiceNameByClass(reply, deviceClass);
ret = HDF_SUCCESS; ret = HDF_SUCCESS;
break; break;
case DEVMGR_LIST_ALL_SERVICE:
ret = ListAllService(reply);
break;
case DEVMGR_LIST_ALL_DEVICE:
ret = ListAllDevice(devMgrSvc, reply);
break;
default: default:
HDF_LOGE("%s: unsupported configuration type: %d", __func__, code); HDF_LOGE("%s: unsupported configuration type: %d", __func__, code);
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -51,8 +51,10 @@ int DevHostServiceClntInstallDriver(struct DevHostServiceClnt *hostClnt)
HDF_LOGE("failed to install driver %s, ret = %d", deviceInfo->svcName, ret); HDF_LOGE("failed to install driver %s, ret = %d", deviceInfo->svcName, ret);
continue; continue;
} }
deviceInfo->status = HDF_SERVICE_USABLE;
#ifndef __USER__ #ifndef __USER__
HdfSListIteratorRemove(&it); HdfSListIteratorRemove(&it);
HdfDeviceInfoFreeInstance(deviceInfo);
#endif #endif
} }
return HDF_SUCCESS; return HDF_SUCCESS;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -86,6 +86,7 @@ static int DevmgrServiceLoadDevice(struct IDevmgrService *devMgrSvc, const char
struct HdfDeviceInfo *deviceInfo = NULL; struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL; struct DevHostServiceClnt *hostClnt = NULL;
bool dynamic = true; bool dynamic = true;
int ret;
(void)devMgrSvc; (void)devMgrSvc;
if (serviceName == NULL) { if (serviceName == NULL) {
@ -107,8 +108,11 @@ static int DevmgrServiceLoadDevice(struct IDevmgrService *devMgrSvc, const char
HDF_LOGW("failed to start device host(%s, %u)", hostClnt->hostName, hostClnt->hostId); HDF_LOGW("failed to start device host(%s, %u)", hostClnt->hostName, hostClnt->hostId);
return HDF_FAILURE; return HDF_FAILURE;
} }
ret = hostClnt->hostService->AddDevice(hostClnt->hostService, deviceInfo);
return hostClnt->hostService->AddDevice(hostClnt->hostService, deviceInfo); if (ret == HDF_SUCCESS) {
deviceInfo->status = HDF_SERVICE_USABLE;
}
return ret;
} }
static int DevmgrServiceStopHost(struct DevHostServiceClnt *hostClnt) static int DevmgrServiceStopHost(struct DevHostServiceClnt *hostClnt)
@ -148,7 +152,7 @@ static int DevmgrServiceUnloadDevice(struct IDevmgrService *devMgrSvc, const cha
HDF_LOGI("%{public}s:unload service %{public}s delDevice failed", __func__, serviceName); HDF_LOGI("%{public}s:unload service %{public}s delDevice failed", __func__, serviceName);
return ret; return ret;
} }
deviceInfo->status = HDF_SERVICE_UNUSABLE;
if (!HdfSListIsEmpty(&hostClnt->devices)) { if (!HdfSListIsEmpty(&hostClnt->devices)) {
HDF_LOGD("%{public}s host %{public}s devices is not empty", __func__, hostClnt->hostName); HDF_LOGD("%{public}s host %{public}s devices is not empty", __func__, hostClnt->hostName);
return HDF_SUCCESS; return HDF_SUCCESS;
@ -176,6 +180,7 @@ int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
HDF_LOGE("%s:failed to load driver %s", __func__, deviceInfo->moduleName); HDF_LOGE("%s:failed to load driver %s", __func__, deviceInfo->moduleName);
continue; continue;
} }
deviceInfo->status = HDF_SERVICE_USABLE;
HdfSListIteratorRemove(&itDeviceInfo); HdfSListIteratorRemove(&itDeviceInfo);
} }
} }
@ -319,6 +324,35 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
return HDF_SUCCESS; return HDF_SUCCESS;
} }
static int32_t DevmgrServiceListAllDevice(struct IDevmgrService *inst, struct HdfSBuf *reply)
{
struct DevmgrService *devMgrSvc = (struct DevmgrService *)inst;
struct DevHostServiceClnt *hostClnt = NULL;
struct HdfSListIterator iterator;
struct HdfSListNode *node = NULL;
if (devMgrSvc == NULL || reply == NULL) {
HDF_LOGE("%{public}s failed, parameter is null", __func__);
return HDF_FAILURE;
}
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSbufWriteString(reply, hostClnt->hostName);
HdfSbufWriteUint32(reply, hostClnt->hostId);
HdfSbufWriteUint32(reply, HdfSListCount(&hostClnt->devices));
HdfSListIteratorInit(&iterator, &hostClnt->devices);
while (HdfSListIteratorHasNext(&iterator)) {
node = HdfSListIteratorNext(&iterator);
struct DeviceTokenClnt *tokenClnt = (struct DeviceTokenClnt *)node;
if (tokenClnt != NULL && tokenClnt->tokenIf != NULL) {
HdfSbufWriteUint32(reply, tokenClnt->tokenIf->devid);
} else {
HDF_LOGI("%{public}s host:%{public}s token null", __func__, hostClnt->hostName);
}
}
}
return HDF_SUCCESS;
}
int DevmgrServiceStartService(struct IDevmgrService *inst) int DevmgrServiceStartService(struct IDevmgrService *inst)
{ {
int ret; int ret;
@ -389,6 +423,7 @@ bool DevmgrServiceConstruct(struct DevmgrService *inst)
devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost; devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
devMgrSvcIf->StartService = DevmgrServiceStartService; devMgrSvcIf->StartService = DevmgrServiceStartService;
devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange; devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
devMgrSvcIf->ListAllDevice = DevmgrServiceListAllDevice;
DListHeadInit(&inst->hosts); DListHeadInit(&inst->hosts);
return true; return true;
} else { } else {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -10,10 +10,10 @@
#include "devmgr_service.h" #include "devmgr_service.h"
#include "hdf_base.h" #include "hdf_base.h"
#include "hdf_cstring.h" #include "hdf_cstring.h"
#include "hdf_device_node.h"
#include "hdf_log.h" #include "hdf_log.h"
#include "hdf_object_manager.h" #include "hdf_object_manager.h"
#include "hdf_service_record.h" #include "hdf_service_record.h"
#include "hdf_device_node.h"
#include "osal_mem.h" #include "osal_mem.h"
#define HDF_LOG_TAG devsvc_manager #define HDF_LOG_TAG devsvc_manager
@ -39,8 +39,8 @@ static struct DevSvcRecord *DevSvcManagerSearchService(struct IDevSvcManager *in
return searchResult; return searchResult;
} }
static void NotifyServiceStatusLocked(struct DevSvcManager *devSvcManager, static void NotifyServiceStatusLocked(
struct DevSvcRecord *record, uint32_t status) struct DevSvcManager *devSvcManager, struct DevSvcRecord *record, uint32_t status)
{ {
struct ServStatListenerHolder *holder = NULL; struct ServStatListenerHolder *holder = NULL;
struct ServStatListenerHolder *tmp = NULL; struct ServStatListenerHolder *tmp = NULL;
@ -62,8 +62,8 @@ static void NotifyServiceStatusLocked(struct DevSvcManager *devSvcManager,
} }
} }
static void NotifyServiceStatusOnRegisterLocked(struct DevSvcManager *devSvcManager, static void NotifyServiceStatusOnRegisterLocked(
struct ServStatListenerHolder *listenerHolder) struct DevSvcManager *devSvcManager, struct ServStatListenerHolder *listenerHolder)
{ {
struct DevSvcRecord *record = NULL; struct DevSvcRecord *record = NULL;
DLIST_FOR_EACH_ENTRY(record, &devSvcManager->services, struct DevSvcRecord, entry) { DLIST_FOR_EACH_ENTRY(record, &devSvcManager->services, struct DevSvcRecord, entry) {
@ -82,8 +82,8 @@ static void NotifyServiceStatusOnRegisterLocked(struct DevSvcManager *devSvcMana
} }
} }
int DevSvcManagerAddService(struct IDevSvcManager *inst, const char *servName, int DevSvcManagerAddService(struct IDevSvcManager *inst, const char *servName, uint16_t devClass,
uint16_t devClass, struct HdfDeviceObject *service, const char *servInfo) struct HdfDeviceObject *service, const char *servInfo)
{ {
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
struct DevSvcRecord *record = NULL; struct DevSvcRecord *record = NULL;
@ -120,8 +120,8 @@ int DevSvcManagerAddService(struct IDevSvcManager *inst, const char *servName,
return HDF_SUCCESS; return HDF_SUCCESS;
} }
int DevSvcManagerUpdateService(struct IDevSvcManager *inst, const char *servName, int DevSvcManagerUpdateService(struct IDevSvcManager *inst, const char *servName, uint16_t devClass,
uint16_t devClass, struct HdfDeviceObject *service, const char *servInfo) struct HdfDeviceObject *service, const char *servInfo)
{ {
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
struct DevSvcRecord *record = NULL; struct DevSvcRecord *record = NULL;
@ -236,8 +236,25 @@ struct HdfObject *DevSvcManagerGetService(struct IDevSvcManager *inst, const cha
return (struct HdfObject *)deviceObject->service; return (struct HdfObject *)deviceObject->service;
} }
int DevSvcManagerRegsterServListener(struct IDevSvcManager *inst, void DevSvcManagerListAllService(struct IDevSvcManager *inst, struct HdfSBuf *reply)
struct ServStatListenerHolder *listenerHolder) {
struct DevSvcRecord *record = NULL;
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
if (devSvcManager == NULL || reply == NULL) {
HDF_LOGE("failed to list all service info, parameter is null");
return;
}
OsalMutexLock(&devSvcManager->mutex);
DLIST_FOR_EACH_ENTRY(record, &devSvcManager->services, struct DevSvcRecord, entry) {
HdfSbufWriteString(reply, record->servName);
HdfSbufWriteUint16(reply, record->devClass);
HDF_LOGD("%{public}s %{public}d", record->servName, record->devClass);
}
OsalMutexUnlock(&devSvcManager->mutex);
HDF_LOGI("%{public}s end ", __func__);
}
int DevSvcManagerRegsterServListener(struct IDevSvcManager *inst, struct ServStatListenerHolder *listenerHolder)
{ {
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
if (devSvcManager == NULL || listenerHolder == NULL) { if (devSvcManager == NULL || listenerHolder == NULL) {
@ -252,8 +269,7 @@ int DevSvcManagerRegsterServListener(struct IDevSvcManager *inst,
return HDF_SUCCESS; return HDF_SUCCESS;
} }
void DevSvcManagerUnregsterServListener(struct IDevSvcManager *inst, void DevSvcManagerUnregsterServListener(struct IDevSvcManager *inst, struct ServStatListenerHolder *listenerHolder)
struct ServStatListenerHolder *listenerHolder)
{ {
struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
if (devSvcManager == NULL || listenerHolder == NULL) { if (devSvcManager == NULL || listenerHolder == NULL) {
@ -279,6 +295,7 @@ bool DevSvcManagerConstruct(struct DevSvcManager *inst)
devSvcMgrIf->UnsubscribeService = NULL; devSvcMgrIf->UnsubscribeService = NULL;
devSvcMgrIf->RemoveService = DevSvcManagerRemoveService; devSvcMgrIf->RemoveService = DevSvcManagerRemoveService;
devSvcMgrIf->GetService = DevSvcManagerGetService; devSvcMgrIf->GetService = DevSvcManagerGetService;
devSvcMgrIf->ListAllService = DevSvcManagerListAllService;
devSvcMgrIf->GetObject = DevSvcManagerGetObject; devSvcMgrIf->GetObject = DevSvcManagerGetObject;
devSvcMgrIf->RegsterServListener = DevSvcManagerRegsterServListener; devSvcMgrIf->RegsterServListener = DevSvcManagerRegsterServListener;
devSvcMgrIf->UnregsterServListener = DevSvcManagerUnregsterServListener; devSvcMgrIf->UnregsterServListener = DevSvcManagerUnregsterServListener;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -25,6 +25,7 @@ struct IDevmgrService {
int (*UnloadDevice)(struct IDevmgrService *, const char *); int (*UnloadDevice)(struct IDevmgrService *, const char *);
int (*StartService)(struct IDevmgrService *); int (*StartService)(struct IDevmgrService *);
int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent); int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent);
int (*ListAllDevice)(struct IDevmgrService *, struct HdfSBuf *);
}; };
#endif /* DEVMGR_SERVICE_IF_H */ #endif /* DEVMGR_SERVICE_IF_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -25,6 +25,7 @@ struct IDevSvcManager {
void (*RemoveService)(struct IDevSvcManager *, const char *); void (*RemoveService)(struct IDevSvcManager *, const char *);
int (*RegsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *); int (*RegsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *);
void (*UnregsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *); void (*UnregsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *);
void (*ListAllService)(struct IDevSvcManager *, struct HdfSBuf *);
}; };
#endif /* DEVSVC_MANAGER_IF_H */ #endif /* DEVSVC_MANAGER_IF_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* *
* HDF is dual licensed: you can use it either under the terms of * HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option. * the GPL, or the BSD license, at your option.
@ -31,6 +31,8 @@ typedef enum {
DEVMGR_LOAD_SERVICE = 0, DEVMGR_LOAD_SERVICE = 0,
DEVMGR_UNLOAD_SERVICE, DEVMGR_UNLOAD_SERVICE,
DEVMGR_GET_SERVICE, DEVMGR_GET_SERVICE,
DEVMGR_LIST_ALL_SERVICE,
DEVMGR_LIST_ALL_DEVICE,
} DevMgrCmd; } DevMgrCmd;
struct HdfWriteReadBuf { struct HdfWriteReadBuf {
@ -51,6 +53,8 @@ void HdfIoServiceAdapterRecycle(struct HdfIoService *service);
struct HdfIoService *HdfIoServiceAdapterPublish(const char *serviceName, uint32_t mode) __attribute__((weak)); struct HdfIoService *HdfIoServiceAdapterPublish(const char *serviceName, uint32_t mode) __attribute__((weak));
void HdfIoServiceAdapterRemove(struct HdfIoService *service) __attribute__((weak)); void HdfIoServiceAdapterRemove(struct HdfIoService *service) __attribute__((weak));
int32_t HdfLoadDriverByServiceName(const char *serviceName); int32_t HdfLoadDriverByServiceName(const char *serviceName);
int32_t HdfListAllService(struct HdfSBuf *reply);
int32_t HdfListAllDevice(struct HdfSBuf *reply);
#ifdef __cplusplus #ifdef __cplusplus
} }

36
tools/hdf_dbg/BUILD.gn Normal file
View File

@ -0,0 +1,36 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("//drivers/adapter/uhdf2/uhdf.gni")
ohos_executable("hdf_dbg") {
sources = [ "hdf_dbg.cpp" ]
if (is_standard_system) {
external_deps = [
"device_driver_framework:libhdf_utils",
"device_driver_framework:libhdi",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_single",
"utils_base:utils",
]
} else {
external_deps = [ "hilog:libhilog" ]
}
install_enable = true
install_images = [ chipset_base_dir ]
subsystem_name = "hdf"
part_name = "device_driver_framework"
}

347
tools/hdf_dbg/hdf_dbg.cpp Normal file
View File

@ -0,0 +1,347 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <string>
#include <string_ex.h>
#include <hdf_io_service.h>
#include <idevmgr_hdi.h>
#include <iservmgr_hdi.h>
#include <osal_time.h>
#define HDF_LOG_TAG hdf_dbg
static constexpr uint32_t DATA_SIZE = 5000;
static constexpr uint32_t FUNC_IDX = 1;
static constexpr uint32_t SERVER_NAME_IDX = 3;
static constexpr uint32_t INTERFACE_DESC_IDX = 4;
static constexpr uint32_t CMD_ID_IDX = 5;
static constexpr uint32_t PARA_CNT_IDX = 6;
static constexpr uint32_t PARA_MULTIPLE = 2;
static constexpr uint32_t WAIT_TIME = 100;
static constexpr uint32_t HELP_INFO_PARA_CNT = 2;
static constexpr int32_t DBG_HDI_PARA_MIN_LEN = 7;
static constexpr int32_t DBG_HDI_SERVICE_LOAD_IDX = 2;
static constexpr int32_t QUERY_INFO_PARA_CNT = 3;
static constexpr const char *HELP_COMMENT =
" ============== hdf_dbg menu ================================================================================\n"
" hdf_dbg -h :display help information\n"
" hdf_dbg -q :query all service and device information\n"
" hdf_dbg -q 0 :query service information of kernel space\n"
" hdf_dbg -q 1 :query service information of user space\n"
" hdf_dbg -q 2 :query device information of kernel space\n"
" hdf_dbg -q 3 :query device information use space\n"
" hdf_dbg -d :debug hdi interface\n"
" detail usage:\n"
" debug hdi interface, parameterType can be int or string now, for example:\n"
" hdf_dbg -d loadFlag serviceName interfaceToken cmd parameterCount parameterType parameterValue\n"
" detail example:\n"
" hdf_dbg -d 1 sample_driver_service hdf.test.sampele_service 1 2 int 100 int 200\n"
" hdf_dbg -d 0 sample_driver_service hdf.test.sampele_service 7 1 string foo\n"
" =============================================================================================================\n";
using GetInfoFunc = void (*)();
static void GetAllServiceUserSpace();
static void GetAllServiceKernelSpace();
static void GetAllDeviceUserSpace();
static void GetAllDeviceKernelSpace();
static void GetAllInformation();
GetInfoFunc g_getInfoFuncs[] = {
GetAllServiceKernelSpace,
GetAllServiceUserSpace,
GetAllDeviceKernelSpace,
GetAllDeviceUserSpace,
GetAllInformation,
};
using OHOS::MessageOption;
using OHOS::MessageParcel;
using OHOS::HDI::DeviceManager::V1_0::HdiDevHostInfo;
using OHOS::HDI::DeviceManager::V1_0::IDeviceManager;
using OHOS::HDI::ServiceManager::V1_0::HdiServiceInfo;
using OHOS::HDI::ServiceManager::V1_0::IServiceManager;
using std::cout;
using std::endl;
static void PrintHelp()
{
cout << HELP_COMMENT;
}
static void PrintAllServiceInfoUser(const std::vector<HdiServiceInfo> &serviceInfos)
{
uint32_t cnt = 0;
cout << "display service info in user space, format:" << endl;
cout << "servName:\t" << "devClass" << endl;
for (auto &info : serviceInfos) {
cout << info.serviceName << ":\t0x" << std::hex << info.devClass << endl;
cnt++;
}
cout << "total " << std::dec << cnt << " services in user space" << endl;
}
static void PrintAllServiceInfoKernel(struct HdfSBuf *data, bool flag)
{
uint32_t cnt = 0;
cout << "display service info in kernel space, format:" << endl;
cout << "servName:\t" << "devClass" << endl;
while (flag) {
const char *servName = HdfSbufReadString(data);
if (servName == nullptr) {
break;
}
uint16_t devClass;
bool ret = HdfSbufReadUint16(data, &devClass);
if (!ret) {
return;
}
cout << servName << ":\t0x" << std::hex << devClass << endl;
cnt++;
}
cout << "total " << std::dec << cnt << " services in kernel space" << endl;
}
static void PrintALLDeviceInfoUser(const std::vector<HdiDevHostInfo> &deviceInfos)
{
cout << "display device info in user space, format:" << endl;
cout << "hostName:\t" << "hostId" << endl;
cout << "deviceId" << endl;
uint32_t hostCnt = 0;
uint32_t devNodeCnt = 0;
for (auto &info : deviceInfos) {
cout << info.hostName << ":\t0x" << std::hex << info.hostId << endl;
for (auto &id : info.devId) {
cout << "0x" << std::hex << id << endl;
devNodeCnt++;
}
hostCnt++;
}
cout << "total " << std::dec << hostCnt << " hosts, " << devNodeCnt << " devNodes in user space" << endl;
}
static int32_t PrintOneHostInfoKernel(struct HdfSBuf *data, uint32_t &devNodeCnt)
{
const char *hostName = HdfSbufReadString(data);
if (hostName == nullptr) {
return HDF_FAILURE;
}
uint32_t hostId;
bool flag = HdfSbufReadUint32(data, &hostId);
if (!flag) {
return HDF_FAILURE;
}
cout << hostName << ":\t0x" << std::hex << hostId << endl;
uint32_t devCnt;
flag = HdfSbufReadUint32(data, &devCnt);
if (!flag) {
return HDF_FAILURE;
}
for (uint32_t i = 0; i < devCnt; i++) {
uint32_t devId;
flag = HdfSbufReadUint32(data, &devId);
if (!flag) {
return HDF_FAILURE;
}
cout << "0x" << std::hex << devId << endl;
}
devNodeCnt += devCnt;
return HDF_SUCCESS;
}
static void PrintAllDeviceInfoKernel(struct HdfSBuf *data, bool flag)
{
uint32_t hostCnt = 0;
uint32_t devNodeCnt = 0;
cout << "display device info in kernel space, format:" << endl;
cout << "hostName:" << '\t' << "hostId" << endl;
cout << "deviceId" << endl;
while (flag) {
int32_t ret = PrintOneHostInfoKernel(data, devNodeCnt);
if (ret == HDF_FAILURE) {
break;
}
hostCnt++;
}
cout << "total " << std::dec << hostCnt << " hosts, " << devNodeCnt << " devNodes in kernel space" << endl;
}
static int32_t ParseHdiParameter(int argc, char **argv, MessageParcel &data)
{
int32_t paraCnt = atoi(argv[PARA_CNT_IDX]);
if ((paraCnt * PARA_MULTIPLE) != (argc - PARA_CNT_IDX - 1)) {
cout << "parameter count error, input: " << paraCnt << " real: " << (argc - PARA_CNT_IDX - 1) << endl;
return HDF_FAILURE;
}
int32_t paraTypeIdx = PARA_CNT_IDX + 1;
for (int i = 0; i < paraCnt; i++) {
int32_t paraValueIdx = paraTypeIdx + 1;
if (strcmp(argv[paraTypeIdx], "string") == 0) {
data.WriteCString(argv[paraValueIdx]);
} else if (strcmp(argv[paraTypeIdx], "int") == 0) {
data.WriteInt32(atoi(argv[paraValueIdx]));
} else {
cout << "parameterType error:" << argv[paraTypeIdx] << endl;
return HDF_FAILURE;
}
paraTypeIdx += PARA_MULTIPLE;
}
return HDF_SUCCESS;
}
static int32_t InjectDebugHdi(int argc, char **argv)
{
if (argc < DBG_HDI_PARA_MIN_LEN) {
PrintHelp();
return HDF_FAILURE;
}
auto servmgr = IServiceManager::Get();
auto devmgr = IDeviceManager::Get();
int32_t loadFlag = atoi(argv[DBG_HDI_SERVICE_LOAD_IDX]);
MessageParcel data;
data.WriteInterfaceToken(OHOS::Str8ToStr16(argv[INTERFACE_DESC_IDX]));
int32_t ret = ParseHdiParameter(argc, argv, data);
if (ret != HDF_SUCCESS) {
PrintHelp();
return ret;
}
if (loadFlag == 1) {
devmgr->LoadDevice(argv[SERVER_NAME_IDX]);
OsalMSleep(WAIT_TIME);
}
MessageParcel reply;
MessageOption option;
auto service = servmgr->GetService(argv[SERVER_NAME_IDX]);
if (service == nullptr) {
cout << "getService " << argv[SERVER_NAME_IDX] << " failed" << endl;
goto END;
}
ret = service->SendRequest(atoi(argv[CMD_ID_IDX]), data, reply, option);
cout << "call service " << argv[SERVER_NAME_IDX] << " hdi cmd:" << atoi(argv[CMD_ID_IDX]) << " return:" << ret
<< endl;
END:
if (loadFlag == 1) {
devmgr->UnloadDevice(argv[SERVER_NAME_IDX]);
}
return ret;
}
static void GetAllServiceUserSpace()
{
auto servmgr = IServiceManager::Get();
if (servmgr == nullptr) {
cout << "GetAllServiceUserSpace get ServiceManager failed" << endl;
return;
}
std::vector<HdiServiceInfo> serviceInfos;
(void)servmgr->ListAllService(serviceInfos);
PrintAllServiceInfoUser(serviceInfos);
}
static void GetAllServiceKernelSpace()
{
struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
if (data == nullptr) {
cout << "GetAllServiceKernelSpace HdfSbufObtain failed" << endl;
return;
}
int32_t ret = HdfListAllService(data);
OsalMSleep(WAIT_TIME);
if (ret == HDF_SUCCESS) {
PrintAllServiceInfoKernel(data, true);
} else {
PrintAllServiceInfoKernel(data, false);
}
HdfSbufRecycle(data);
}
static void GetAllDeviceUserSpace()
{
auto devmgr = IDeviceManager::Get();
if (devmgr == nullptr) {
cout << "GetAllDeviceUserSpace get DeviceManager failed" << endl;
return;
}
std::vector<HdiDevHostInfo> deviceInfos;
(void)devmgr->ListAllDevice(deviceInfos);
PrintALLDeviceInfoUser(deviceInfos);
}
static void GetAllDeviceKernelSpace()
{
struct HdfSBuf *data = HdfSbufObtain(DATA_SIZE);
if (data == nullptr) {
cout << "GetAllDeviceKernelSpace HdfSbufObtain failed" << endl;
return;
}
int32_t ret = HdfListAllDevice(data);
OsalMSleep(WAIT_TIME);
if (ret == HDF_SUCCESS) {
PrintAllDeviceInfoKernel(data, true);
} else {
PrintAllDeviceInfoKernel(data, false);
}
HdfSbufRecycle(data);
}
static void GetAllInformation()
{
GetAllServiceUserSpace();
GetAllServiceKernelSpace();
GetAllDeviceUserSpace();
GetAllDeviceKernelSpace();
}
int main(int argc, char **argv)
{
if (argc == 1 || (argc == HELP_INFO_PARA_CNT && strcmp(argv[FUNC_IDX], "-h") == 0)) {
PrintHelp();
} else if (argc == QUERY_INFO_PARA_CNT || argc == QUERY_INFO_PARA_CNT - 1) {
if (strcmp(argv[FUNC_IDX], "-q") != 0) {
PrintHelp();
return HDF_SUCCESS;
}
uint32_t funcCnt = sizeof(g_getInfoFuncs) / sizeof(g_getInfoFuncs[0]);
if (argc == QUERY_INFO_PARA_CNT - 1) {
g_getInfoFuncs[funcCnt - 1]();
return HDF_SUCCESS;
}
uint32_t queryIdx = atoi(argv[QUERY_INFO_PARA_CNT - 1]);
if (queryIdx < funcCnt - 1) {
g_getInfoFuncs[queryIdx]();
} else {
PrintHelp();
}
} else if (argc > QUERY_INFO_PARA_CNT) {
if (strcmp(argv[FUNC_IDX], "-d") == 0) {
return InjectDebugHdi(argc, argv);
} else {
PrintHelp();
}
}
return HDF_SUCCESS;
}