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 "sensor_manager.h"
17#include "sensor_dump.h"
18#include <fcntl.h>
19#include "hdf_dlist.h"
20#include "hdf_io_service_if.h"
21#include "osal_mem.h"
22#include "sensor_channel.h"
23#include "sensor_common.h"
24#include "sensor_controller.h"
25#include "sensor_if.h"
26
27#define HDF_LOG_TAG    uhdf_sensor_service
28
29struct SensorDevManager *GetSensorDevManager(void)
30{
31    static struct SensorDevManager devManager = {
32        .initState = false,
33        .hasSensorListener = false,
34        .sensorSum = 0,
35        .sensorInfoEntry = NULL,
36        .serviceGroup = NULL,
37    };
38
39    return &devManager;
40}
41
42static int32_t GetSensorServiceList(void)
43{
44    struct SensorManagerNode *managerNode = NULL;
45    struct SensorDevManager *manager = GetSensorDevManager();
46    struct HdfSBuf *data = HdfSbufObtainDefaultSize();
47    const char *svcName = NULL;
48
49    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_NULL_PTR);
50    int32_t ret = HdfGetServiceNameByDeviceClass(DEVICE_CLASS_SENSOR, data);
51    if (ret != SENSOR_SUCCESS) {
52        HDF_LOGE("%{public}s :sensor manager get service class failed", __func__);
53        HdfSbufRecycle(data);
54        return SENSOR_INVALID_SERVICE;
55    }
56
57    (void)OsalMutexLock(&manager->mutex);
58    while (true) {
59        svcName = HdfSbufReadString(data);
60        if (svcName == NULL) {
61            break;
62        }
63
64        managerNode = (struct SensorManagerNode*)OsalMemCalloc(sizeof(*managerNode));
65        if (managerNode == NULL) {
66            break;
67        }
68
69        managerNode->sensorCount = 0;
70        managerNode->ioService = HdfIoServiceBind(svcName);
71        if (managerNode->ioService == NULL) {
72            HDF_LOGE("%{public}s: Sensor manager get manager service name[%{public}s] failed", __func__, svcName);
73            OsalMemFree(managerNode);
74            managerNode = NULL;
75            continue;
76        }
77
78        DListInsertTail(&managerNode->node, &manager->managerHead);
79    }
80    (void)OsalMutexUnlock(&manager->mutex);
81
82    HdfSbufRecycle(data);
83    data = NULL;
84
85    if (DListIsEmpty(&manager->managerHead)) {
86        HDF_LOGE("%{public}s: Sensor get service failed", __func__);
87        return SENSOR_INVALID_SERVICE;
88    }
89
90    return SENSOR_SUCCESS;
91}
92
93static void ReleaseSensorServiceList()
94{
95    struct SensorManagerNode *pos = NULL;
96    struct SensorManagerNode *tmp = NULL;
97    struct SensorDevManager *manager = GetSensorDevManager();
98
99    HDF_LOGI("%{public}s: Sensor host release service group", __func__);
100    (void)OsalMutexLock(&manager->mutex);
101    DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->managerHead, struct SensorManagerNode, node) {
102        if (pos->ioService != NULL) {
103            HdfIoServiceRecycle(pos->ioService);
104            pos->ioService = NULL;
105        };
106
107        DListRemove(&(pos->node));
108        OsalMemFree(pos);
109        pos = NULL;
110    }
111
112    (void)OsalMutexLock(&manager->eventMutex);
113    if (manager->serviceGroup != NULL) {
114        if (manager->hasSensorListener) {
115            struct HdfDevEventlistener *listener = GetSensorListener();
116            if (listener != NULL) {
117                HdfIoServiceGroupUnregisterListener(manager->serviceGroup, listener);
118                manager->hasSensorListener = false;
119            }
120        }
121        HdfIoServiceGroupRecycle(manager->serviceGroup);
122        manager->serviceGroup = NULL;
123    }
124    (void)OsalMutexUnlock(&manager->eventMutex);
125    (void)OsalMutexUnlock(&manager->mutex);
126}
127
128static int32_t InitSensorManager(void)
129{
130    struct SensorDevManager *manager = GetSensorDevManager();
131    manager->recordDataCb[TRADITIONAL_SENSOR_TYPE] = NULL;
132    manager->recordDataCb[MEDICAL_SENSOR_TYPE] = NULL;
133    DListHeadInit(&manager->managerHead);
134    DListHeadInit(&manager->sensorIdListHead);
135    OsalMutexInit(&manager->mutex);
136    OsalMutexInit(&manager->eventMutex);
137
138    int32_t ret = GetSensorServiceList();
139    if (ret != SENSOR_SUCCESS) {
140        HDF_LOGE("%{public}s: Sensor get service failed", __func__);
141        ReleaseSensorServiceList();
142        OsalMutexDestroy(&manager->mutex);
143        OsalMutexDestroy(&manager->eventMutex);
144        return SENSOR_INVALID_SERVICE;
145    }
146
147    return SENSOR_SUCCESS;
148}
149
150const struct SensorInterface *NewSensorInterfaceInstance(void)
151{
152    static struct SensorInterface sensorDevInstance;
153    struct SensorDevManager *manager = GetSensorDevManager();
154
155    if (manager->initState) {
156        return &sensorDevInstance;
157    }
158
159    // Construct device interface instance
160    GetSensorDeviceMethods(&sensorDevInstance);
161
162    if (InitSensorManager() != SENSOR_SUCCESS) {
163        HDF_LOGE("%{public}s: Sensor init manager failed", __func__);
164        return NULL;
165    }
166    manager->initState = true;
167    HDF_LOGD("%{public}s: Get sensor device instance success", __func__);
168
169    return &sensorDevInstance;
170}
171
172int32_t FreeSensorInterfaceInstance(void)
173{
174    struct SensorDevManager *manager = GetSensorDevManager();
175
176    if (!manager->initState) {
177        return SENSOR_SUCCESS;
178    }
179
180    ReleaseAllSensorInfo();
181    ReleaseSensorServiceList();
182    manager->recordDataCb[TRADITIONAL_SENSOR_TYPE] = NULL;
183    manager->recordDataCb[MEDICAL_SENSOR_TYPE] = NULL;
184
185    OsalMutexDestroy(&manager->mutex);
186    OsalMutexDestroy(&manager->eventMutex);
187
188    manager->initState = false;
189
190    return SENSOR_SUCCESS;
191}
192