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_channel.h"
17 #include <securec.h>
18 #include "hdf_io_service_if.h"
19 #include "osal_mutex.h"
20 #include "osal_time.h"
21 #include "sensor_common.h"
22 #include "sensor_manager.h"
23 #include "sensor_type.h"
24 
25 #define HDF_LOG_TAG    uhdf_sensor_service
26 
27 #define ACCEL_ACCURACY    ((HDI_SENSOR_GRAVITY) / (HDI_SENSOR_UNITS) / (HDI_SENSOR_UNITS))
28 #define GYRO_ACCURACY     ((1 / (HDI_SENSOR_FLOAT_UNITS)) * ((HDI_SENSOR_PI) / (HDI_SENSOR_SEMICIRCLE)))
29 #define BAROMETER_BAROMETER_ACCURACY (1 / (HDI_SENSOR_FLOAT_HUN_UNITS))
30 #define BAROMETER_TEMPERATURE_ACCURACY (1 / (HDI_SENSOR_FLOAT_TEN_UNITS))
31 #define MAGNETIC_ACCURACY    (1 / (HDI_SENSOR_FLOAT_UNITS))
32 #define ALS_ACCURACY     (1 / (HDI_SENSOR_FLOAT_UNITS))
33 #define HALL_ACCURACY     ((HDI_SENSOR_FLOAT_TEN_UNITS) / (HDI_SENSOR_FLOAT_TEN_UNITS))
34 #define PROXIMITY_ACCURACY     ((HDI_SENSOR_FLOAT_TEN_UNITS) / (HDI_SENSOR_FLOAT_TEN_UNITS))
35 #define PEDOMETER_ACCURACY     ((HDI_SENSOR_FLOAT_TEN_UNITS) / (HDI_SENSOR_FLOAT_TEN_UNITS))
36 #define TEMPERATURE_ACCURACY     (1 / (HDI_SENSOR_FLOAT_TEN_UNITS))
37 #define HUMIDITY_ACCURACY     (1 / (HDI_SENSOR_FLOAT_HUN_UNITS))
38 
39 static struct SensorCovertCoff g_sensorCovertCoff[] = {
40     { SENSOR_TYPE_NONE, 0, DATA_X, { ACCEL_ACCURACY } },
41     { SENSOR_TYPE_ACCELEROMETER, SENSOR_TYPE_MAX, DATA_XYZ, { ACCEL_ACCURACY, ACCEL_ACCURACY, ACCEL_ACCURACY } },
42     { SENSOR_TYPE_GRAVITY, SENSOR_TYPE_MAX, DATA_XYZ, { ACCEL_ACCURACY, ACCEL_ACCURACY, ACCEL_ACCURACY } },
43     { SENSOR_TYPE_GYROSCOPE, SENSOR_TYPE_MAX, DATA_XYZ, { GYRO_ACCURACY, GYRO_ACCURACY, GYRO_ACCURACY } },
44     { SENSOR_TYPE_BAROMETER, SENSOR_TYPE_MAX, DATA_XY,
45         { BAROMETER_BAROMETER_ACCURACY, BAROMETER_TEMPERATURE_ACCURACY } },
46     { SENSOR_TYPE_MAGNETIC_FIELD, SENSOR_TYPE_MAX, DATA_XYZ,
47         { MAGNETIC_ACCURACY, MAGNETIC_ACCURACY, MAGNETIC_ACCURACY } },
48     { SENSOR_TYPE_AMBIENT_LIGHT, SENSOR_TYPE_MAX, DATA_XYZA,
49         { ALS_ACCURACY, ALS_ACCURACY, ALS_ACCURACY, ALS_ACCURACY } },
50     { SENSOR_TYPE_PEDOMETER, SENSOR_TYPE_MAX, DATA_X, { PEDOMETER_ACCURACY } },
51     { SENSOR_TYPE_HALL, SENSOR_TYPE_MAX, DATA_X, { HALL_ACCURACY } },
52     { SENSOR_TYPE_PROXIMITY, SENSOR_TYPE_MAX, DATA_X, { PROXIMITY_ACCURACY } },
53     { SENSOR_TYPE_TEMPERATURE, SENSOR_TYPE_MAX, DATA_X, { TEMPERATURE_ACCURACY } },
54     { SENSOR_TYPE_HUMIDITY, SENSOR_TYPE_MAX, DATA_X, { HUMIDITY_ACCURACY } },
55 };
56 
57 static struct SensorDumpDate g_dumpDate = { 0 };
58 static struct SensorDatePack g_listDump = { 0 };
59 
GetEventData(void)60 struct SensorDatePack *GetEventData(void)
61 {
62     return &g_listDump;
63 }
64 
SetSensorIdBySensorType(enum SensorTypeTag type,int32_t sensorId)65 void SetSensorIdBySensorType(enum SensorTypeTag type, int32_t sensorId)
66 {
67     uint32_t count = sizeof(g_sensorCovertCoff) / sizeof(g_sensorCovertCoff[0]);
68 
69     for (uint32_t i = 0; i < count; ++i) {
70         if (g_sensorCovertCoff[i].sensorTypeId == (int32_t)type) {
71             g_sensorCovertCoff[i].sensorId = sensorId;
72             break;
73         }
74     }
75 }
76 
CopyEventData(struct SensorEvents * event)77 void CopyEventData(struct SensorEvents *event)
78 {
79     if (event == NULL || event->data == NULL) {
80         HDF_LOGE("%{public}s: event==NULL || event->data==NULL !", __func__);
81         return;
82     }
83 
84     for (uint32_t i = 0; i < event->dataLen; i++) {
85         g_dumpDate.data[i] = event->data[i];
86     }
87     g_dumpDate.dataLen = event->dataLen;
88     g_dumpDate.sensorId = event->sensorId;
89     g_dumpDate.version = event->version;
90     g_dumpDate.timestamp = event->timestamp;
91     g_dumpDate.option = event->option;
92     g_dumpDate.mode = event->mode;
93 
94     if (g_listDump.pos < 0 || g_listDump.pos >= MAX_DUMP_DATA_SIZE) {
95         HDF_LOGE("%{public}s: g_listDump is invalid", __func__);
96         return;
97     }
98     g_listDump.listDumpArr[g_listDump.pos] = g_dumpDate;
99 
100     if (g_listDump.pos + 1 >= MAX_DUMP_DATA_SIZE) {
101         g_listDump.pos = 0;
102     } else {
103         g_listDump.pos++;
104     }
105     if (g_listDump.count < MAX_DUMP_DATA_SIZE) {
106         g_listDump.count++;
107     }
108 }
109 
ConvertSensorData(struct SensorEvents * event)110 void ConvertSensorData(struct SensorEvents *event)
111 {
112     uint32_t dataLen;
113     uint32_t axis;
114     int32_t *data = NULL;
115     float *value = NULL;
116 
117     data = (int32_t *)event->data;
118     value = (float *)event->data;
119 
120     for (uint32_t i = 0; i < sizeof(g_sensorCovertCoff) / sizeof(g_sensorCovertCoff[0]); ++i) {
121         if ((g_sensorCovertCoff[i].sensorId == event->sensorId) && (g_sensorCovertCoff[i].dim != 0)) {
122             dataLen = event->dataLen / sizeof(int32_t);
123             for (uint32_t j = 0; j < dataLen; ++j) {
124                 axis = j % g_sensorCovertCoff[i].dim;
125                 value[j] = (float)(data[j] * g_sensorCovertCoff[i].coff[axis]);
126             }
127         }
128     }
129 }
130 
OnSensorEventReceived(struct HdfDevEventlistener * listener,struct HdfIoService * service,uint32_t id,struct HdfSBuf * data)131 static int OnSensorEventReceived(struct HdfDevEventlistener *listener,
132     struct HdfIoService *service, uint32_t id, struct HdfSBuf *data)
133 {
134     uint32_t len;
135     struct SensorEvents *event = NULL;
136     struct SensorDevManager *manager = GetSensorDevManager();
137     (void)listener;
138     (void)service;
139     (void)id;
140 
141     (void)OsalMutexLock(&manager->eventMutex);
142     if (!HdfSbufReadBuffer(data, (const void **)&event, &len) || event == NULL) {
143         HDF_LOGE("%{public}s: Read sensor event fail!", __func__);
144         (void)OsalMutexUnlock(&manager->eventMutex);
145         return SENSOR_FAILURE;
146     }
147 
148     uint8_t *buf = NULL;
149     if (!HdfSbufReadBuffer(data, (const void **)&buf, &len) || buf == NULL) {
150         (void)OsalMutexUnlock(&manager->eventMutex);
151         HDF_LOGE("%{public}s: Read sensor data fail!", __func__);
152         return SENSOR_FAILURE;
153     } else {
154         event->data = buf;
155         event->dataLen = len;
156     }
157 
158     enum SensorGroupType groupType;
159     if (event->sensorId >= SENSOR_TYPE_MEDICAL_BEGIN && event->sensorId < SENSOR_TYPE_MEDICAL_END) {
160         groupType = MEDICAL_SENSOR_TYPE;
161     } else {
162         groupType = TRADITIONAL_SENSOR_TYPE;
163     }
164     event->option = SENSOR_STATUS_ACCURACY_HIGH;
165 
166     ConvertSensorData(event);
167     CopyEventData(event);
168 
169     if (manager->recordDataCb[groupType] != NULL) {
170         manager->recordDataCb[groupType](event);
171     }
172 
173     (void)OsalMutexUnlock(&manager->eventMutex);
174 
175     return SENSOR_SUCCESS;
176 }
177 
178 static struct HdfDevEventlistener g_listener = {
179     .onReceive = OnSensorEventReceived,
180     .priv = "hdi_sensor"
181 };
182 
GetSensorListener(void)183 struct HdfDevEventlistener *GetSensorListener(void)
184 {
185     return &g_listener;
186 }
187 
AddSensorDevServiceGroup(void)188 static int32_t AddSensorDevServiceGroup(void)
189 {
190     struct SensorManagerNode *pos = NULL;
191     struct SensorDevManager *manager = GetSensorDevManager();
192 
193     manager->serviceGroup = HdfIoServiceGroupObtain();
194     if (manager->serviceGroup == NULL) {
195         return SENSOR_FAILURE;
196     }
197 
198     DLIST_FOR_EACH_ENTRY(pos, &manager->managerHead, struct SensorManagerNode, node) {
199         if ((pos->ioService != NULL) &&
200             (HdfIoServiceGroupAddService(manager->serviceGroup, pos->ioService) != SENSOR_SUCCESS)) {
201             HdfIoServiceGroupRecycle(manager->serviceGroup);
202             manager->serviceGroup = NULL;
203             HDF_LOGE("%{public}s: Add service to group failed", __func__);
204             return SENSOR_INVALID_SERVICE;
205         }
206     }
207 
208     int32_t ret = HdfIoServiceGroupRegisterListener(manager->serviceGroup, &g_listener);
209     if (ret != SENSOR_SUCCESS) {
210         HDF_LOGE("%{public}s: Register listener to group failed", __func__);
211         HdfIoServiceGroupRecycle(manager->serviceGroup);
212         manager->serviceGroup = NULL;
213         return ret;
214     }
215 
216     return SENSOR_SUCCESS;
217 }
218 
Register(int32_t groupId,RecordDataCallback cb)219 int32_t Register(int32_t groupId, RecordDataCallback cb)
220 {
221     if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
222         HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
223         return SENSOR_INVALID_PARAM;
224     }
225     struct SensorDevManager *manager = NULL;
226     CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
227     manager = GetSensorDevManager();
228     (void)OsalMutexLock(&manager->eventMutex);
229     if (manager->recordDataCb[groupId] != NULL) {
230         HDF_LOGE("%{public}s: groupId [%{public}d] callback already exists", __func__, groupId);
231         (void)OsalMutexUnlock(&manager->eventMutex);
232         return SENSOR_FAILURE;
233     }
234 
235     if (manager->serviceGroup != NULL) {
236         manager->recordDataCb[groupId] = cb;
237         (void)OsalMutexUnlock(&manager->eventMutex);
238         return SENSOR_SUCCESS;
239     }
240     int32_t ret = AddSensorDevServiceGroup();
241     if (ret == SENSOR_SUCCESS) {
242         manager->recordDataCb[groupId] = cb;
243     }
244     (void)OsalMutexUnlock(&manager->eventMutex);
245     return ret;
246 }
247 
Unregister(int32_t groupId,RecordDataCallback cb)248 int32_t Unregister(int32_t groupId, RecordDataCallback cb)
249 {
250     if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
251         HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
252         return SENSOR_INVALID_PARAM;
253     }
254     CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
255     struct SensorDevManager *manager = GetSensorDevManager();
256 
257     (void)OsalMutexLock(&manager->eventMutex);
258     if (manager->recordDataCb[groupId] != cb) {
259         HDF_LOGE("%{public}s: groupId [%{public}d] cb not same with registered", __func__, groupId);
260         (void)OsalMutexUnlock(&manager->eventMutex);
261         return SENSOR_FAILURE;
262     }
263 
264     if (manager->recordDataCb[TRADITIONAL_SENSOR_TYPE] != NULL &&
265         manager->recordDataCb[MEDICAL_SENSOR_TYPE] != NULL) {
266         manager->recordDataCb[groupId] = NULL;
267         (void)OsalMutexUnlock(&manager->eventMutex);
268         return SENSOR_SUCCESS;
269     }
270 
271     int32_t ret = HdfIoServiceGroupUnregisterListener(manager->serviceGroup, &g_listener);
272     if (ret != SENSOR_SUCCESS) {
273         HDF_LOGE("%{public}s: Sensor unregister listener failed", __func__);
274         (void)OsalMutexUnlock(&manager->eventMutex);
275         return ret;
276     }
277 
278     manager->hasSensorListener = false;
279     HdfIoServiceGroupRecycle(manager->serviceGroup);
280     manager->serviceGroup = NULL;
281     manager->recordDataCb[groupId] = NULL;
282     (void)OsalMutexUnlock(&manager->eventMutex);
283 
284     return SENSOR_SUCCESS;
285 }
286