1/*
2 * Copyright (c) 2022-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 <hdf_base.h>
17#include <hdf_device_desc.h>
18#include "light_uhdf_log.h"
19#include <hdf_sbuf_ipc.h>
20#include <osal_mem.h>
21#include "v1_0/light_interface_stub.h"
22
23#define HDF_LOG_TAG           uhdf_light_service
24
25using namespace OHOS::HDI::Light::V1_0;
26
27struct HdfLightInterfaceHost {
28    struct IDeviceIoService ioService;
29    OHOS::sptr<OHOS::IRemoteObject> stub;
30};
31
32static int32_t LightInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
33    struct HdfSBuf *reply)
34{
35    auto *hdfLightInterfaceHost = CONTAINER_OF(client->device->service, struct HdfLightInterfaceHost, ioService);
36
37    OHOS::MessageParcel *dataParcel = nullptr;
38    OHOS::MessageParcel *replyParcel = nullptr;
39    OHOS::MessageOption option;
40
41    if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
42        HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
43        return HDF_ERR_INVALID_PARAM;
44    }
45    if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
46        HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
47        return HDF_ERR_INVALID_PARAM;
48    }
49
50    return hdfLightInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
51}
52
53static int HdfLightInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
54{
55    (void)deviceObject;
56
57    HDF_LOGI("HdfLightInterfaceDriverInit enter");
58    return HDF_SUCCESS;
59}
60
61static int HdfLightInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
62{
63    auto *hdfLightInterfaceHost = new (std::nothrow) HdfLightInterfaceHost;
64    if (hdfLightInterfaceHost == nullptr) {
65        HDF_LOGE("%{public}s: failed to create HdfLightInterfaceHost object", __func__);
66        return HDF_FAILURE;
67    }
68
69    hdfLightInterfaceHost->ioService.Dispatch = LightInterfaceDriverDispatch;
70    hdfLightInterfaceHost->ioService.Open = nullptr;
71    hdfLightInterfaceHost->ioService.Release = nullptr;
72
73    auto serviceImpl = ILightInterface::Get(true);
74    if (serviceImpl == nullptr) {
75        HDF_LOGE("%{public}s: failed to get of implement service", __func__);
76        delete hdfLightInterfaceHost;
77        return HDF_FAILURE;
78    }
79
80    hdfLightInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
81        ILightInterface::GetDescriptor());
82    if (hdfLightInterfaceHost->stub == nullptr) {
83        HDF_LOGE("%{public}s: failed to get stub object", __func__);
84        delete hdfLightInterfaceHost;
85        return HDF_FAILURE;
86    }
87
88    deviceObject->service = &hdfLightInterfaceHost->ioService;
89    HDF_LOGI("HdfLightInterfaceDriverBind success");
90    return HDF_SUCCESS;
91}
92
93static void HdfLightInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
94{
95    HDF_LOGI("HdfLightInterfaceDriverRelease enter");
96    if (deviceObject->service == nullptr) {
97        HDF_LOGE("HdfLightInterfaceDriverRelease not initted");
98        return;
99    }
100
101    auto *hdfLightInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfLightInterfaceHost, ioService);
102    delete hdfLightInterfaceHost;
103}
104
105static struct HdfDriverEntry g_lightinterfaceDriverEntry = {
106    .moduleVersion = 1,
107    .moduleName = "light_service",
108    .Bind = HdfLightInterfaceDriverBind,
109    .Init = HdfLightInterfaceDriverInit,
110    .Release = HdfLightInterfaceDriverRelease,
111};
112
113#ifdef __cplusplus
114extern "C" {
115#endif /* __cplusplus */
116HDF_INIT(g_lightinterfaceDriverEntry);
117#ifdef __cplusplus
118}
119#endif /* __cplusplus */
120