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