/* * 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 "devhost_service_proxy.h" #include "dev_attribute_serialize.h" #include "devmgr_service_full.h" #include "hdf_base.h" #include "hdf_log.h" #include "hdf_sbuf.h" #include "osal_mem.h" #include "osal_message.h" #define HDF_LOG_TAG devhost_service_proxy static int32_t DevHostServiceProxyOpsDevice( struct IDevHostService *inst, const struct HdfDeviceInfo *attribute, int opsCode) { int status = HDF_FAILURE; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct DevHostServiceProxy *hostClnt = (struct DevHostServiceProxy *)inst; if (hostClnt->remote == NULL || data == NULL) { HDF_LOGE("Adding device failed, hostClnt->remote or data or reply is null"); goto FINISHED; } DeviceAttributeSerialize(attribute, data); status = hostClnt->remote->dispatcher->Dispatch(hostClnt->remote, DEVHOST_SERVICE_ADD_DEVICE, data, NULL); FINISHED: if (data != NULL) { HdfSbufRecycle(data); } return status; } static int32_t DevHostServiceProxyAddDevice( struct IDevHostService *inst, const struct HdfDeviceInfo *attribute) { return DevHostServiceProxyOpsDevice(inst, attribute, DEVHOST_SERVICE_ADD_DEVICE); } static int32_t DevHostServiceProxyDelDevice( struct IDevHostService *inst, devid_t devid) { int status = HDF_FAILURE; struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC); struct DevHostServiceProxy *hostClnt = (struct DevHostServiceProxy *)inst; if (hostClnt->remote == NULL || data == NULL) { HDF_LOGE("Del device failed, hostClnt->remote or data is null"); goto FINISHED; } HdfSbufWriteUint32(data, devid); status = hostClnt->remote->dispatcher->Dispatch(hostClnt->remote, DEVHOST_SERVICE_DEL_DEVICE, data, NULL); FINISHED: if (data != NULL) { HdfSbufRecycle(data); } return status; } void DevHostServiceProxyOnRemoteDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *service) { if (recipient == NULL || service == NULL) { return; } struct HdfMessageTask *task = DevmgrServiceFullGetMessageTask(); if (task == NULL) { return; } struct HdfMessage *message = HdfMessageObtain(0); if (message == NULL) { return; } struct DevHostServiceProxy *proxy = HDF_SLIST_CONTAINER_OF( struct HdfDeathRecipient, recipient, struct DevHostServiceProxy, recipient); message->messageId = DEVMGR_MESSAGE_DEVHOST_DIED; message->data[0] = (void *)(uintptr_t)proxy->hostId; HDF_LOGD("%{public}s: host %{public}u dead, respawn it", __FUNCTION__, proxy->hostId); task->SendMessage(task, message, false); } void DevHostServiceProxyConstruct( struct DevHostServiceProxy *inst, struct HdfRemoteService *remote) { inst->remote = remote; inst->super.AddDevice = DevHostServiceProxyAddDevice; inst->super.DelDevice = DevHostServiceProxyDelDevice; inst->recipient.OnRemoteDied = DevHostServiceProxyOnRemoteDied; HdfRemoteServiceAddDeathRecipient(remote, &inst->recipient); } struct IDevHostService *DevHostServiceProxyObtain(uint32_t hostId, struct HdfRemoteService *remote) { struct DevHostServiceProxy *instance = (struct DevHostServiceProxy *)OsalMemCalloc(sizeof(struct DevHostServiceProxy)); if (instance != NULL) { instance->hostId = hostId; DevHostServiceProxyConstruct(instance, remote); } return (struct IDevHostService *)instance; } void DevHostServiceProxyRecycle(struct DevHostServiceProxy *inst) { if (inst != NULL) { if (inst->remote != NULL) { HdfRemoteServiceRecycle(inst->remote); inst->remote = NULL; } OsalMemFree(inst); } }