/* * Copyright (c) 2021 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 "devmgr_service_proxy.h" #include "devhost_service_stub.h" #include "device_token_stub.h" #include "devmgr_service.h" #include "devmgr_service_stub.h" #include "devsvc_manager_clnt.h" #include "hdf_base.h" #include "hdf_log.h" #include "hdf_sbuf.h" #include "osal_mem.h" #define HDF_LOG_TAG devmgr_service_proxy int DevmgrServiceProxyAttachDeviceHost(struct IDevmgrService *inst, uint16_t hostId, struct IDevHostService *service) { int status = HDF_FAILURE; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); struct HdfRemoteDispatcher *dipatcher = NULL; struct HdfRemoteService *remoteService = NULL; struct DevmgrServiceProxy *serviceProxy = (struct DevmgrServiceProxy *)inst; struct DevHostServiceStub *hostStub = (struct DevHostServiceStub *)service; if ((serviceProxy->remote == NULL) || (data == NULL) || (reply == NULL)) { HDF_LOGE("DevmgrServiceProxyAttachDeviceHost failed, host id is %{public}u", hostId); goto FINISHED; } remoteService = serviceProxy->remote; dipatcher = remoteService->dispatcher; if (!HdfRemoteServiceWriteInterfaceToken(remoteService, data) || !HdfSbufWriteInt32(data, hostId) || HdfSbufWriteRemoteService(data, hostStub->remote) != HDF_SUCCESS) { HDF_LOGE("failed to attach host, write sbuf error"); goto FINISHED; } status = dipatcher->Dispatch(remoteService, DEVMGR_SERVICE_ATTACH_DEVICE_HOST, data, reply); HDF_LOGI("Attach device host dispatch finish, status is %{public}d", status); FINISHED: if (reply != NULL) { HdfSbufRecycle(reply); } if (data != NULL) { HdfSbufRecycle(data); } return status; } int DevmgrServiceProxyAttachDevice(struct IDevmgrService *inst, struct IHdfDeviceToken *token) { int status = HDF_FAILURE; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); struct DevmgrServiceProxy *serviceProxy = (struct DevmgrServiceProxy *)inst; if (serviceProxy == NULL || serviceProxy->remote == NULL || data == NULL || reply == NULL || token == NULL) { HDF_LOGE("DevmgrServiceProxyAttachDevice failed"); goto FINISHED; } struct HdfRemoteService *remoteService = serviceProxy->remote; if (!HdfRemoteServiceWriteInterfaceToken(remoteService, data) || !HdfSbufWriteInt32(data, token->devid)) { goto FINISHED; } status = remoteService->dispatcher->Dispatch(remoteService, DEVMGR_SERVICE_ATTACH_DEVICE, data, reply); FINISHED: if (reply != NULL) { HdfSbufRecycle(reply); } if (data != NULL) { HdfSbufRecycle(data); } return status; } int DevmgrServiceProxyDetachDevice(struct IDevmgrService *inst, devid_t devid) { int status = HDF_FAILURE; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfSBuf *reply = HdfSbufTypedObtain(SBUF_IPC); struct DevmgrServiceProxy *serviceProxy = (struct DevmgrServiceProxy *)inst; if (serviceProxy == NULL || serviceProxy->remote == NULL || data == NULL || reply == NULL) { HDF_LOGE("DevmgrServiceProxyDetachDevice failed"); goto FINISHED; } struct HdfRemoteService *remoteService = serviceProxy->remote; if (!HdfRemoteServiceWriteInterfaceToken(remoteService, data) || !HdfSbufWriteInt32(data, devid)) { goto FINISHED; } status = remoteService->dispatcher->Dispatch(remoteService, DEVMGR_SERVICE_DETACH_DEVICE, data, reply); FINISHED: if (reply != NULL) { HdfSbufRecycle(reply); } if (data != NULL) { HdfSbufRecycle(data); } return status; } int DevmgrServiceProxyLoadDevice(struct IDevmgrService *inst, const char *svcName) { struct DevmgrServiceProxy *serviceProxy = (struct DevmgrServiceProxy *)inst; if (serviceProxy == NULL || serviceProxy->remote == NULL || svcName == NULL) { HDF_LOGE("DevmgrServiceProxyLoadDevice failed"); return HDF_ERR_INVALID_PARAM; } struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfRemoteService *remoteService = serviceProxy->remote; if (!HdfRemoteServiceWriteInterfaceToken(remoteService, data) || !HdfSbufWriteString(data, svcName)) { HdfSbufRecycle(data); return HDF_FAILURE; } int status = remoteService->dispatcher->Dispatch(remoteService, DEVMGR_SERVICE_LOAD_DEVICE, data, NULL); HdfSbufRecycle(data); return status; } int DevmgrServiceProxyUnLoadDevice(struct IDevmgrService *inst, const char *svcName) { struct DevmgrServiceProxy *serviceProxy = (struct DevmgrServiceProxy *)inst; if (serviceProxy == NULL || serviceProxy->remote == NULL || svcName == NULL) { HDF_LOGE("DevmgrServiceProxyLoadDevice failed"); return HDF_ERR_INVALID_PARAM; } struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct HdfRemoteService *remoteService = serviceProxy->remote; if (!HdfRemoteServiceWriteInterfaceToken(remoteService, data) || !HdfSbufWriteString(data, svcName)) { HdfSbufRecycle(data); return HDF_FAILURE; } int status = remoteService->dispatcher->Dispatch(remoteService, DEVMGR_SERVICE_UNLOAD_DEVICE, data, NULL); HdfSbufRecycle(data); return status; } static void DevmgrServiceProxyConstruct(struct DevmgrServiceProxy *inst) { struct IDevmgrService *pvtbl = (struct IDevmgrService *)inst; pvtbl->AttachDeviceHost = DevmgrServiceProxyAttachDeviceHost; pvtbl->AttachDevice = DevmgrServiceProxyAttachDevice; pvtbl->DetachDevice = DevmgrServiceProxyDetachDevice; pvtbl->LoadDevice = DevmgrServiceProxyLoadDevice; pvtbl->UnloadDevice = DevmgrServiceProxyUnLoadDevice; pvtbl->StartService = NULL; } static struct IDevmgrService *DevmgrServiceProxyObtain(struct HdfRemoteService *service) { if (service != NULL) { struct DevmgrServiceProxy *demgrServicProxy = (struct DevmgrServiceProxy *)OsalMemCalloc(sizeof(struct DevmgrServiceProxy)); if (demgrServicProxy != NULL) { demgrServicProxy->remote = service; DevmgrServiceProxyConstruct(demgrServicProxy); return &demgrServicProxy->super; } } HDF_LOGE("DevmgrServiceProxyObtain failed"); return NULL; } struct HdfObject *DevmgrServiceProxyCreate(void) { static struct IDevmgrService *instance = NULL; if (instance != NULL) { return (struct HdfObject *)instance; } struct IDevSvcManager *serviceManagerIf = NULL; struct DevSvcManagerClnt *serviceManager = (struct DevSvcManagerClnt *)DevSvcManagerClntGetInstance(); if ((serviceManager == NULL) || (serviceManager->devSvcMgrIf == NULL)) { HDF_LOGE("Fail to Create Service Manager Client"); return NULL; } serviceManagerIf = serviceManager->devSvcMgrIf; if (serviceManagerIf->GetService == NULL) { HDF_LOGE("Get Service is not implement!!!"); return NULL; } struct HdfRemoteService *remote = (struct HdfRemoteService *)serviceManagerIf->GetService(serviceManagerIf, DEVICE_MANAGER_SERVICE); if (remote != NULL) { if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IDeviceManager.V1_0")) { HDF_LOGE("%{public}s: failed to init interface desc", __func__); HdfRemoteServiceRecycle(remote); return NULL; } instance = DevmgrServiceProxyObtain(remote); } return (struct HdfObject *)instance; } void DevmgrServiceProxyRelease(struct HdfObject *object) { struct DevmgrServiceProxy *instance = (struct DevmgrServiceProxy *)object; if (instance != NULL) { if (instance->remote != NULL) { HdfRemoteServiceRecycle(instance->remote); instance->remote = NULL; } OsalMemFree(instance); } }