diff --git a/adapter/uhdf2/hdi/src/iservmgr_client.cpp b/adapter/uhdf2/hdi/src/iservmgr_client.cpp index 0d80a5fc424ad4206e90c6e450b1b007cd8d3b20..b76fd4ee2b22dd67640fda0521f2fb3083f4c7c5 100644 --- a/adapter/uhdf2/hdi/src/iservmgr_client.cpp +++ b/adapter/uhdf2/hdi/src/iservmgr_client.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "iservmgr_hdi.h" @@ -33,6 +34,7 @@ constexpr int DEVSVC_MANAGER_GET_SERVICE = 3; constexpr int DEVSVC_MANAGER_REGISTER_SVCLISTENER = 4; constexpr int DEVSVC_MANAGER_UNREGISTER_SVCLISTENER = 5; constexpr int DEVSVC_MANAGER_LIST_ALL_SERVICE = 6; +constexpr int DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC = 9; class ServiceManagerProxy : public IProxyBroker { public: @@ -43,6 +45,7 @@ public: int32_t ListAllService(std::vector &serviceInfos) override; int32_t RegisterServiceStatusListener(sptr listener, uint16_t deviceClass) override; int32_t UnregisterServiceStatusListener(sptr listener) override; + int32_t ListServiceByInterfaceDesc(std::vector &serviceNames, const char *interfaceDesc) override; private: static inline BrokerDelegator delegator_; @@ -153,6 +156,38 @@ int32_t ServiceManagerProxy::ListAllService(std::vector &service HDF_LOGD("get all service info success"); return status; } + +int32_t ServiceManagerProxy::ListServiceByInterfaceDesc( + std::vector &serviceNames, const char *interfaceDesc) +{ + MessageParcel data; + MessageParcel reply; + if (interfaceDesc == nullptr || strlen(interfaceDesc) == 0) { + HDF_LOGE("%{public}s: invalid parameter, interfaceDesc is null or empty", __func__); + return HDF_ERR_INVALID_PARAM; + } + if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(interfaceDesc)) { + return HDF_FAILURE; + } + + MessageOption option; + int status = Remote()->SendRequest(DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC, data, reply, option); + if (status != HDF_SUCCESS) { + HDF_LOGE("get hdi service collection by %{public}s failed, %{public}d", interfaceDesc, status); + return status; + } else { + const uint32_t serviceNum = reply.ReadUint32(); + for (uint32_t i = 0; i < serviceNum; i++) { + const char *serviceName = reply.ReadCString(); + if (serviceName == NULL) { + break; + } + serviceNames.push_back(serviceName); + } + } + HDF_LOGD("get hdi service collection by %{public}s successfully", interfaceDesc); + return status; +} } // namespace V1_0 } // namespace ServiceManager } // namespace HDI diff --git a/adapter/uhdf2/hdi/src/servmgr_client.c b/adapter/uhdf2/hdi/src/servmgr_client.c index 3c52d398a48d71479f99eca7992af6e79c92fee2..bda1b0c7162608a94fdce971657e18eecf3c98a8 100644 --- a/adapter/uhdf2/hdi/src/servmgr_client.c +++ b/adapter/uhdf2/hdi/src/servmgr_client.c @@ -18,6 +18,7 @@ #include #include #include +#include "hdf_cstring.h" #include "hdf_service_status.h" #include "servmgr_hdi.h" @@ -38,6 +39,94 @@ static int32_t ServiceManagerHdiCall(struct HDIServiceManagerClient *servMgrClie return servMgrClient->remote->dispatcher->Dispatch(servMgrClient->remote, id, data, reply); } +static void HdiServiceSetGet(const uint32_t serviceNum, struct HdiServiceSet **serviceSet) +{ + *serviceSet = OsalMemAlloc(sizeof(struct HdiServiceSet)); + if (*serviceSet == NULL) { + HDF_LOGE("%{public}s: OOM", __func__); + return; + } + (*serviceSet)->serviceNames = OsalMemCalloc(sizeof(char *) * serviceNum); + if ((*serviceSet)->serviceNames == NULL) { + HDF_LOGE("%{public}s: OOM", __func__); + HdiServiceSetRelease(*serviceSet); + return; + } + (*serviceSet)->count = serviceNum; +} + +static int32_t HdiServiceSetUnMarshalling(struct HdfSBuf *buf, struct HdiServiceSet *serviceSet) +{ + if (serviceSet == NULL || buf == NULL) { + HDF_LOGE("%{public}s: HdiServiceSet unmarshalling failed", __func__); + HdiServiceSetRelease(serviceSet); + return HDF_ERR_INVALID_PARAM; + } + for (uint32_t i = 0; i < serviceSet->count; i++) { + const char *serviceName = HdfSbufReadString(buf); + if (serviceName == NULL) { + break; + } + serviceSet->serviceNames[i] = HdfStringCopy(serviceName); + } + + return HDF_SUCCESS; +} + +int32_t HDIServMgrListServiceByInterfaceDesc( + struct HDIServiceManager *iServMgr, const char *interfaceDesc, struct HdiServiceSet **serviceSet) +{ + if (iServMgr == NULL || interfaceDesc == NULL || serviceSet == NULL || strlen(interfaceDesc) == 0) { + return HDF_ERR_INVALID_PARAM; + } + struct HDIServiceManagerClient *servMgrClient = CONTAINER_OF(iServMgr, struct HDIServiceManagerClient, iservmgr); + struct HdfSBuf *data = NULL; + struct HdfSBuf *reply = NULL; + int status; + uint32_t serviceNum = 0; + + do { + data = HdfSbufTypedObtain(SBUF_IPC); + reply = HdfSbufTypedObtain(SBUF_IPC); + if (data == NULL || reply == NULL) { + status = HDF_ERR_MALLOC_FAIL; + break; + } + if (!HdfRemoteServiceWriteInterfaceToken(servMgrClient->remote, data) || + !HdfSbufWriteString(data, interfaceDesc)) { + return HDF_FAILURE; + } + status = ServiceManagerHdiCall(servMgrClient, DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC, data, reply); + if (status != HDF_SUCCESS) { + HDF_LOGE("%{public}s: failed to get %{public}s service collection, the status is %{public}d", __func__, + interfaceDesc, status); + break; + } + if (!HdfSbufReadUint32(reply, &serviceNum)) { + status = HDF_FAILURE; + break; + } + if (serviceNum == 0) { + break; + } + HdiServiceSetGet(serviceNum, serviceSet); + if (*serviceSet == NULL) { + status = HDF_ERR_MALLOC_FAIL; + break; + } + status = HdiServiceSetUnMarshalling(reply, *serviceSet); + } while (0); + + if (reply != NULL) { + HdfSbufRecycle(reply); + } + if (data != NULL) { + HdfSbufRecycle(data); + } + + return status; +} + struct HdfRemoteService *HDIServMgrGetService(struct HDIServiceManager *iServMgr, const char* serviceName) { if (iServMgr == NULL || serviceName == NULL) { @@ -136,6 +225,7 @@ void HDIServiceManagerConstruct(struct HDIServiceManager *inst) inst->GetService = HDIServMgrGetService; inst->RegisterServiceStatusListener = HDIServMgrRegisterServiceStatusListener; inst->UnregisterServiceStatusListener = HDIServMgrUnregisterServiceStatusListener; + inst->ListServiceByInterfaceDesc = HDIServMgrListServiceByInterfaceDesc; } struct HDIServiceManager *HDIServiceManagerGet(void) @@ -172,4 +262,18 @@ void HDIServiceManagerRelease(struct HDIServiceManager *servmgr) struct HDIServiceManagerClient *iServMgrClient = CONTAINER_OF(servmgr, struct HDIServiceManagerClient, iservmgr); HdfRemoteServiceRecycle(iServMgrClient->remote); OsalMemFree(iServMgrClient); +} + +void HdiServiceSetRelease(struct HdiServiceSet *serviceSet) +{ + if (serviceSet == NULL) { + return; + } + for (uint32_t i = 0; i < serviceSet->count; i++) { + if (serviceSet->serviceNames[i] != NULL) { + OsalMemFree(serviceSet->serviceNames); + serviceSet->serviceNames = NULL; + } + } + OsalMemFree(serviceSet); } \ No newline at end of file diff --git a/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_c_test.cpp b/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_c_test.cpp index 61bdbb24ae3775e1cf9c5cd8f460dd755dc31f3d..758d41c7561fcb40e8e3ee2d7ffa848272dffc0b 100644 --- a/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_c_test.cpp +++ b/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_c_test.cpp @@ -35,6 +35,9 @@ using namespace testing::ext; static constexpr const char *TEST_SERVICE_NAME = "sample_driver_service"; static constexpr const char *TEST_SERVICE_INTERFACE_DESC = "hdf.test.sampele_service"; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_INVALID = "____"; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_VOID = ""; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_NULL = nullptr; static constexpr int PAYLOAD_NUM = 1234; static constexpr int WAIT_LOAD_UNLOAD_TIME = 300; class HdfServiceMangerHdiCTest : public testing::Test { @@ -564,4 +567,71 @@ HWTEST_F(HdfServiceMangerHdiCTest, ServMgrTest011, TestSize.Level1) close(memFd); } + +/* + * Test get service collection by interfacedesc + */ +HWTEST_F(HdfServiceMangerHdiCTest, ServMgrTest012, TestSize.Level1) +{ + struct HDIDeviceManager *devmgr = HDIDeviceManagerGet(); + ASSERT_TRUE(devmgr != nullptr); + devmgr->UnloadDevice(devmgr, TEST_SERVICE_NAME); + OsalMSleep(WAIT_LOAD_UNLOAD_TIME); + struct HDIServiceManager *servmgr = HDIServiceManagerGet(); + ASSERT_TRUE(servmgr != nullptr); + + struct HdfRemoteService *sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + ASSERT_TRUE(sampleService == nullptr); + + int ret = devmgr->LoadDevice(devmgr, TEST_SERVICE_NAME); + ASSERT_EQ(ret, HDF_SUCCESS); + OsalMSleep(WAIT_LOAD_UNLOAD_TIME); + sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + ASSERT_TRUE(sampleService != nullptr); + + struct HdiServiceSet *serviceSet = nullptr; + ret = servmgr->ListServiceByInterfaceDesc(servmgr, TEST_SERVICE_INTERFACE_DESC, &serviceSet); + HDIServiceManagerRelease(servmgr); + ASSERT_TRUE(ret == HDF_SUCCESS); + ASSERT_TRUE(serviceSet != nullptr); + ASSERT_TRUE(serviceSet->count == 1); + ASSERT_TRUE(strcmp(serviceSet->serviceNames[0], TEST_SERVICE_NAME) == 0); + HdiServiceSetRelease(serviceSet); +} + +HWTEST_F(HdfServiceMangerHdiCTest, ServMgrTest013, TestSize.Level1) +{ + struct HDIServiceManager *servmgr = HDIServiceManagerGet(); + ASSERT_TRUE(servmgr != nullptr); + + struct HdiServiceSet *serviceSet = nullptr; + int32_t ret = servmgr->ListServiceByInterfaceDesc(servmgr, TEST_SERVICE_INTERFACE_DESC_INVALID, &serviceSet); + HDIServiceManagerRelease(servmgr); + ASSERT_TRUE(ret == HDF_SUCCESS); + ASSERT_TRUE(serviceSet == nullptr); +} + +HWTEST_F(HdfServiceMangerHdiCTest, ServMgrTest014, TestSize.Level1) +{ + struct HDIServiceManager *servmgr = HDIServiceManagerGet(); + ASSERT_TRUE(servmgr != nullptr); + + struct HdiServiceSet *serviceSet = nullptr; + int32_t ret = servmgr->ListServiceByInterfaceDesc(servmgr, TEST_SERVICE_INTERFACE_DESC_VOID, &serviceSet); + HDIServiceManagerRelease(servmgr); + ASSERT_TRUE(ret == HDF_ERR_INVALID_PARAM); + ASSERT_TRUE(serviceSet == nullptr); +} + +HWTEST_F(HdfServiceMangerHdiCTest, ServMgrTest015, TestSize.Level1) +{ + struct HDIServiceManager *servmgr = HDIServiceManagerGet(); + ASSERT_TRUE(servmgr != nullptr); + + struct HdiServiceSet *serviceSet = nullptr; + int32_t ret = servmgr->ListServiceByInterfaceDesc(servmgr, TEST_SERVICE_INTERFACE_DESC_NULL, &serviceSet); + HDIServiceManagerRelease(servmgr); + ASSERT_TRUE(ret == HDF_ERR_INVALID_PARAM); + ASSERT_TRUE(serviceSet == nullptr); +} } // namespace OHOS \ No newline at end of file diff --git a/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_test.cpp b/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_test.cpp index 6c7824fd32b7bc1a3afc3fe16306537ea8218b9e..295581ce4a7417eff170be02989313a4c36c7955 100644 --- a/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_test.cpp +++ b/adapter/uhdf2/hdi/test/servmgr/service_manager_hdi_test.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "sample_hdi.h" @@ -43,6 +44,10 @@ using OHOS::HDI::ServiceManager::V1_0::ServiceStatus; using OHOS::HDI::ServiceManager::V1_0::ServStatListenerStub; static constexpr const char *TEST_SERVICE_NAME = "sample_driver_service"; static constexpr const char16_t *TEST_SERVICE_INTERFACE_DESC = u"hdf.test.sampele_service"; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_N = "hdf.test.sampele_service"; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_INVALID = "___"; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_VOID = ""; +static constexpr const char *TEST_SERVICE_INTERFACE_DESC_NULL = nullptr; static constexpr int PAYLOAD_NUM = 1234; static constexpr int SMQ_TEST_QUEUE_SIZE = 10; static constexpr int SMQ_TEST_WAIT_TIME = 100; @@ -649,4 +654,48 @@ HWTEST_F(HdfServiceMangerHdiTest, ServMgrTest014, TestSize.Level1) status = servmgr->UnregisterServiceStatusListener(listener); ASSERT_EQ(status, HDF_SUCCESS); } + +/* + * Test get service collection by interfacedesc + */ +HWTEST_F(HdfServiceMangerHdiTest, ServMgrTest015, TestSize.Level1) +{ + auto servmgr = IServiceManager::Get(); + ASSERT_TRUE(servmgr != nullptr); + std::vector serviceNames; + int ret = servmgr->ListServiceByInterfaceDesc(serviceNames, TEST_SERVICE_INTERFACE_DESC_N); + ASSERT_TRUE(ret == HDF_SUCCESS); + ASSERT_FALSE(serviceNames.empty()); + ASSERT_TRUE(serviceNames.front().compare(TEST_SERVICE_NAME) == 0); +} + +HWTEST_F(HdfServiceMangerHdiTest, ServMgrTest016, TestSize.Level1) +{ + auto servmgr = IServiceManager::Get(); + ASSERT_TRUE(servmgr != nullptr); + std::vector serviceNames; + int ret = servmgr->ListServiceByInterfaceDesc(serviceNames, TEST_SERVICE_INTERFACE_DESC_INVALID); + ASSERT_TRUE(ret == HDF_SUCCESS); + ASSERT_TRUE(serviceNames.empty()); +} + +HWTEST_F(HdfServiceMangerHdiTest, ServMgrTest017, TestSize.Level1) +{ + auto servmgr = IServiceManager::Get(); + ASSERT_TRUE(servmgr != nullptr); + std::vector serviceNames; + int ret = servmgr->ListServiceByInterfaceDesc(serviceNames, TEST_SERVICE_INTERFACE_DESC_VOID); + ASSERT_TRUE(ret == HDF_ERR_INVALID_PARAM); + ASSERT_TRUE(serviceNames.empty()); +} + +HWTEST_F(HdfServiceMangerHdiTest, ServMgrTest018, TestSize.Level1) +{ + auto servmgr = IServiceManager::Get(); + ASSERT_TRUE(servmgr != nullptr); + std::vector serviceNames; + int ret = servmgr->ListServiceByInterfaceDesc(serviceNames, TEST_SERVICE_INTERFACE_DESC_NULL); + ASSERT_TRUE(ret == HDF_ERR_INVALID_PARAM); + ASSERT_TRUE(serviceNames.empty()); +} } // namespace OHOS \ No newline at end of file diff --git a/adapter/uhdf2/host/include/devsvc_manager_proxy.h b/adapter/uhdf2/host/include/devsvc_manager_proxy.h index c8035107911f28396c79a2e0f8447921f5729666..54232fb7fbbafb2a8959eec958b7adb1145b6e32 100644 --- a/adapter/uhdf2/host/include/devsvc_manager_proxy.h +++ b/adapter/uhdf2/host/include/devsvc_manager_proxy.h @@ -35,6 +35,7 @@ enum { DEVSVC_MANAGER_LIST_ALL_SERVICE, DEVSVC_MANAGER_LIST_SERVICE, DEVSVC_MANAGER_REMOVE_SERVICE, + DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC, }; struct HdfObject *DevSvcManagerProxyCreate(void); diff --git a/adapter/uhdf2/host/src/devsvc_manager_proxy.c b/adapter/uhdf2/host/src/devsvc_manager_proxy.c index 9125fec5a197e8d0ea67819e6c1f728f1b364f52..73a5f1f6139311bd85557309289a2ffbe1daae01 100644 --- a/adapter/uhdf2/host/src/devsvc_manager_proxy.c +++ b/adapter/uhdf2/host/src/devsvc_manager_proxy.c @@ -59,6 +59,11 @@ static int WriteServiceInfo( HDF_LOGE("Add service failed, failed to write serv info"); return HDF_FAILURE; } + const char *interfaceDesc = servInfo->interfaceDesc != NULL ? servInfo->interfaceDesc : ""; + if (!HdfSbufWriteString(data, interfaceDesc)) { + HDF_LOGE("Add service failed, failed to write interfaceDesc"); + return HDF_FAILURE; + } return HDF_SUCCESS; } diff --git a/adapter/uhdf2/include/hdi/iservmgr_hdi.h b/adapter/uhdf2/include/hdi/iservmgr_hdi.h index 1b45ff27fa040db1531720c2eba3e7165424511a..07b6fb3b0aa74f8a3453e036f19f9e51f35fa02a 100644 --- a/adapter/uhdf2/include/hdi/iservmgr_hdi.h +++ b/adapter/uhdf2/include/hdi/iservmgr_hdi.h @@ -40,6 +40,7 @@ public: virtual int32_t ListAllService(std::vector &serviceInfos) = 0; virtual int32_t RegisterServiceStatusListener(::OHOS::sptr listener, uint16_t deviceClass) = 0; virtual int32_t UnregisterServiceStatusListener(::OHOS::sptr listener) = 0; + virtual int32_t ListServiceByInterfaceDesc(std::vector &serviceNames, const char *interfaceDesc) = 0; }; } // namespace V1_0 } // namespace ServiceManager diff --git a/adapter/uhdf2/include/hdi/servmgr_hdi.h b/adapter/uhdf2/include/hdi/servmgr_hdi.h index 10842ffff66ac9aefaa843a92bc87995228b9fda..795309f1b49a49ac92861bcc8ae30058911a399a 100644 --- a/adapter/uhdf2/include/hdi/servmgr_hdi.h +++ b/adapter/uhdf2/include/hdi/servmgr_hdi.h @@ -21,15 +21,23 @@ extern "C" { #endif /* __cplusplus */ +struct HdiServiceSet { + const char **serviceNames; + uint32_t count; +}; + struct HDIServiceManager { struct HdfRemoteService *(*GetService)(struct HDIServiceManager *self, const char* serviceName); int32_t (*RegisterServiceStatusListener)(struct HDIServiceManager *self, struct ServiceStatusListener *listener, uint16_t deviceClass); int32_t (*UnregisterServiceStatusListener)(struct HDIServiceManager *self, struct ServiceStatusListener *listener); + int32_t (*ListServiceByInterfaceDesc)( + struct HDIServiceManager *self, const char *interfaceName, struct HdiServiceSet **serviceSet); }; struct HDIServiceManager *HDIServiceManagerGet(void); void HDIServiceManagerRelease(struct HDIServiceManager *servmgr); +void HdiServiceSetRelease(struct HdiServiceSet *serviceSet); #ifdef __cplusplus } diff --git a/adapter/uhdf2/manager/src/devsvc_manager_stub.c b/adapter/uhdf2/manager/src/devsvc_manager_stub.c index 91ff50e797588de185106d031d5d765dee249834..f76f2220cce225009ef7440f4f4180e563cbb28c 100644 --- a/adapter/uhdf2/manager/src/devsvc_manager_stub.c +++ b/adapter/uhdf2/manager/src/devsvc_manager_stub.c @@ -137,6 +137,7 @@ static int32_t DevSvcMgrStubGetPara( return HDF_FAILURE; } info->servInfo = HdfSbufReadString(data); + info->interfaceDesc = HdfSbufReadString(data); return HDF_SUCCESS; } @@ -154,7 +155,7 @@ static int32_t DevSvcManagerStubAddService(struct IDevSvcManager *super, struct if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) { return ret; } - + struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service); if (serviceObject == NULL) { return HDF_ERR_MALLOC_FAIL; @@ -254,6 +255,29 @@ static int32_t DevSvcManagerStubListAllService( return HDF_SUCCESS; } +static int32_t DevSvcManagerStubListServiceByInterfaceDesc( + struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply) +{ + int ret; + struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super; + if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) { + HDF_LOGE("%{public}s: invalid interface token", __func__); + return HDF_ERR_INVALID_PARAM; + } + const char *interfaceDesc = HdfSbufReadString(data); + if (interfaceDesc == NULL) { + HDF_LOGE("%{public}s failed, interfaceDesc is null", __func__); + return HDF_FAILURE; + } + ret = ListServicePermCheck(); + if (ret != HDF_SUCCESS) { + return ret; + } + ret = super->ListServiceByInterfaceDesc(super, interfaceDesc, reply); + + return ret; +} + static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data) { struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super; @@ -381,6 +405,9 @@ int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct case DEVSVC_MANAGER_LIST_ALL_SERVICE: ret = DevSvcManagerStubListAllService(super, data, reply); break; + case DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC: + ret = DevSvcManagerStubListServiceByInterfaceDesc(super, data, reply); + break; default: HDF_LOGE("Unknown code : %{public}d", code); ret = HDF_FAILURE; diff --git a/framework/core/manager/src/devsvc_manager.c b/framework/core/manager/src/devsvc_manager.c index 7a4f2de79e9673273e6037000a47d43ae6062a41..316e7b3ec25b4aad5c5fa36d5173de8bd51bd427 100644 --- a/framework/core/manager/src/devsvc_manager.c +++ b/framework/core/manager/src/devsvc_manager.c @@ -17,6 +17,7 @@ #include "osal_mem.h" #define HDF_LOG_TAG devsvc_manager +#define SERVICE_LIST_MAX 16 static struct DevSvcRecord *DevSvcManagerSearchService(struct IDevSvcManager *inst, uint32_t serviceKey) { @@ -110,6 +111,10 @@ int DevSvcManagerAddService(struct IDevSvcManager *inst, record->devId = servInfo->devId; record->servName = HdfStringCopy(servInfo->servName); record->servInfo = HdfStringCopy(servInfo->servInfo); + + if (servInfo->interfaceDesc != NULL && strcmp(servInfo->interfaceDesc, "") != 0) { + record->interfaceDesc = HdfStringCopy(servInfo->interfaceDesc); + } if (record->servName == NULL) { DevSvcRecordFreeInstance(record); return HDF_ERR_MALLOC_FAIL; @@ -257,6 +262,50 @@ void DevSvcManagerListAllService(struct IDevSvcManager *inst, struct HdfSBuf *re HDF_LOGI("%{public}s end ", __func__); } +int DevSvcManagerListServiceByInterfaceDesc( + struct IDevSvcManager *inst, const char *interfaceDesc, struct HdfSBuf *reply) +{ + struct DevSvcRecord *record = NULL; + struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; + int status = HDF_SUCCESS; + if (devSvcManager == NULL || reply == NULL) { + HDF_LOGE("failed to list service collection info, parameter is null"); + return HDF_ERR_INVALID_PARAM; + } + OsalMutexLock(&devSvcManager->mutex); + const char *serviceNames[SERVICE_LIST_MAX]; + uint32_t serviceNum = 0; + DLIST_FOR_EACH_ENTRY(record, &devSvcManager->services, struct DevSvcRecord, entry) { + if (record->interfaceDesc == NULL) { + HDF_LOGD("%{public}s interfacedesc is null", record->servName); + continue; + } + if (serviceNum >= SERVICE_LIST_MAX) { + status = HDF_ERR_OUT_OF_RANGE; + HDF_LOGE( + "%{public}s: More than %{public}d services are found, but up to %{public}d services can be returned", + interfaceDesc, SERVICE_LIST_MAX, SERVICE_LIST_MAX); + break; + } + if (strcmp(record->interfaceDesc, interfaceDesc) == 0) { + serviceNames[serviceNum] = record->servName; + serviceNum = serviceNum + 1; + } + } + HDF_LOGD("find %{public}u services interfacedesc is %{public}s", serviceNum, interfaceDesc); + if (!HdfSbufWriteUint32(reply, serviceNum)) { + HDF_LOGE("failed to write serviceNum to buffer, interfacedesc is %{public}s, serviceNum is %{public}d", + interfaceDesc, serviceNum); + OsalMutexUnlock(&devSvcManager->mutex); + return HDF_FAILURE; + } + for (uint32_t i = 0; i < serviceNum; i++) { + HdfSbufWriteString(reply, serviceNames[i]); + } + OsalMutexUnlock(&devSvcManager->mutex); + return status; +} + int DevSvcManagerRegsterServListener(struct IDevSvcManager *inst, struct ServStatListenerHolder *listenerHolder) { struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst; @@ -302,6 +351,7 @@ bool DevSvcManagerConstruct(struct DevSvcManager *inst) devSvcMgrIf->GetObject = DevSvcManagerGetObject; devSvcMgrIf->RegsterServListener = DevSvcManagerRegsterServListener; devSvcMgrIf->UnregsterServListener = DevSvcManagerUnregsterServListener; + devSvcMgrIf->ListServiceByInterfaceDesc = DevSvcManagerListServiceByInterfaceDesc; if (OsalMutexInit(&inst->mutex) != HDF_SUCCESS) { HDF_LOGE("failed to create device service manager mutex"); return false; diff --git a/framework/core/shared/include/devsvc_manager_if.h b/framework/core/shared/include/devsvc_manager_if.h index 7a021778ca1fac5d2fb8d8d6e782a3dbccbfe722..46f5e2faf5d6868921d202b954caecaa2fbcd0f6 100644 --- a/framework/core/shared/include/devsvc_manager_if.h +++ b/framework/core/shared/include/devsvc_manager_if.h @@ -27,6 +27,7 @@ struct IDevSvcManager { int (*RegsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *); void (*UnregsterServListener)(struct IDevSvcManager *, struct ServStatListenerHolder *); void (*ListAllService)(struct IDevSvcManager *, struct HdfSBuf *); + int (*ListServiceByInterfaceDesc)(struct IDevSvcManager *, const char *, struct HdfSBuf *); }; #endif /* DEVSVC_MANAGER_IF_H */ diff --git a/framework/core/shared/include/hdf_service_info.h b/framework/core/shared/include/hdf_service_info.h index 7ac5dbc06beb31faf8fea9630f661d05cdecb1c2..dbbbbb44e351b8571b2c44b023a77c1ad9cc5800 100644 --- a/framework/core/shared/include/hdf_service_info.h +++ b/framework/core/shared/include/hdf_service_info.h @@ -16,6 +16,7 @@ struct HdfServiceInfo { const char *servInfo; uint16_t devClass; devid_t devId; + const char *interfaceDesc; }; static inline void HdfServiceInfoInit(struct HdfServiceInfo *info, const struct HdfDeviceNode *devNode) @@ -24,6 +25,7 @@ static inline void HdfServiceInfoInit(struct HdfServiceInfo *info, const struct info->servInfo = devNode->servInfo; info->devClass = devNode->deviceObject.deviceClass; info->devId = devNode->devId; + info->interfaceDesc = devNode->interfaceDesc; } #endif // HDF_SERVICE_INFO_H \ No newline at end of file diff --git a/framework/core/shared/include/hdf_service_record.h b/framework/core/shared/include/hdf_service_record.h index 33f49d31e73896f5e767a1cb52332e921fd6e1e1..d2e6111dbd2d6f65ce045b9a7f6d72231a9861f5 100644 --- a/framework/core/shared/include/hdf_service_record.h +++ b/framework/core/shared/include/hdf_service_record.h @@ -20,6 +20,7 @@ struct DevSvcRecord { const char *servInfo; uint16_t devClass; devid_t devId; + const char *interfaceDesc; }; struct DevSvcRecord *DevSvcRecordNewInstance(void); diff --git a/framework/core/shared/src/hdf_service_record.c b/framework/core/shared/src/hdf_service_record.c index 138648b27e9c2d49c999db9b1f4d7c59de863bab..42e4d50eaacf36fface4dcddf568b533fc32dcd5 100644 --- a/framework/core/shared/src/hdf_service_record.c +++ b/framework/core/shared/src/hdf_service_record.c @@ -20,6 +20,7 @@ void DevSvcRecordFreeInstance(struct DevSvcRecord *inst) OsalMemFree((char *)inst->servName); OsalMemFree((char *)inst->servInfo); OsalMemFree(inst); + OsalMemFree((char *)inst->interfaceDesc); } } diff --git a/framework/include/utils/hdf_base.h b/framework/include/utils/hdf_base.h index ba1800a223e61cb777ec985999c60bf340276ce6..543710777985d3eec50b13cb6c96d892c90bcf03 100644 --- a/framework/include/utils/hdf_base.h +++ b/framework/include/utils/hdf_base.h @@ -53,6 +53,7 @@ typedef enum { HDF_ERR_IO = -17, /**< I/O error. */ HDF_ERR_BAD_FD = -18, /**< Incorrect file descriptor. */ HDF_ERR_NOPERM = -19, /**< No permission. */ + HDF_ERR_OUT_OF_RANGE = -20, /**< Failed to get all result */ #define HDF_BSP_ERR_START (-100) /**< Defines the start of the Board Support Package (BSP) module error codes. */ #define HDF_BSP_ERR_NUM(v) (HDF_BSP_ERR_START + (v)) /**< Defines the BSP module error codes. */