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
165 ConvertSensorData(event);
166 CopyEventData(event);
167
168 if (manager->recordDataCb[groupType] != NULL) {
169 manager->recordDataCb[groupType](event);
170 }
171
172 (void)OsalMutexUnlock(&manager->eventMutex);
173
174 return SENSOR_SUCCESS;
175 }
176
177 static struct HdfDevEventlistener g_listener = {
178 .onReceive = OnSensorEventReceived,
179 .priv = "hdi_sensor"
180 };
181
GetSensorListener(void)182 struct HdfDevEventlistener *GetSensorListener(void)
183 {
184 return &g_listener;
185 }
186
AddSensorDevServiceGroup(void)187 static int32_t AddSensorDevServiceGroup(void)
188 {
189 struct SensorManagerNode *pos = NULL;
190 struct SensorDevManager *manager = GetSensorDevManager();
191
192 manager->serviceGroup = HdfIoServiceGroupObtain();
193 if (manager->serviceGroup == NULL) {
194 return SENSOR_FAILURE;
195 }
196
197 DLIST_FOR_EACH_ENTRY(pos, &manager->managerHead, struct SensorManagerNode, node) {
198 if ((pos->ioService != NULL) &&
199 (HdfIoServiceGroupAddService(manager->serviceGroup, pos->ioService) != SENSOR_SUCCESS)) {
200 HdfIoServiceGroupRecycle(manager->serviceGroup);
201 manager->serviceGroup = NULL;
202 HDF_LOGE("%{public}s: Add service to group failed", __func__);
203 return SENSOR_INVALID_SERVICE;
204 }
205 }
206
207 int32_t ret = HdfIoServiceGroupRegisterListener(manager->serviceGroup, &g_listener);
208 if (ret != SENSOR_SUCCESS) {
209 HDF_LOGE("%{public}s: Register listener to group failed", __func__);
210 HdfIoServiceGroupRecycle(manager->serviceGroup);
211 manager->serviceGroup = NULL;
212 return ret;
213 }
214
215 return SENSOR_SUCCESS;
216 }
217
Register(int32_t groupId,RecordDataCallback cb)218 int32_t Register(int32_t groupId, RecordDataCallback cb)
219 {
220 if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
221 HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
222 return SENSOR_INVALID_PARAM;
223 }
224 struct SensorDevManager *manager = NULL;
225 CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
226 manager = GetSensorDevManager();
227 (void)OsalMutexLock(&manager->eventMutex);
228 if (manager->recordDataCb[groupId] != NULL) {
229 HDF_LOGE("%{public}s: groupId [%{public}d] callback already exists", __func__, groupId);
230 (void)OsalMutexUnlock(&manager->eventMutex);
231 return SENSOR_FAILURE;
232 }
233
234 if (manager->serviceGroup != NULL) {
235 manager->recordDataCb[groupId] = cb;
236 (void)OsalMutexUnlock(&manager->eventMutex);
237 return SENSOR_SUCCESS;
238 }
239 int32_t ret = AddSensorDevServiceGroup();
240 if (ret == SENSOR_SUCCESS) {
241 manager->recordDataCb[groupId] = cb;
242 }
243 (void)OsalMutexUnlock(&manager->eventMutex);
244 return ret;
245 }
246
Unregister(int32_t groupId,RecordDataCallback cb)247 int32_t Unregister(int32_t groupId, RecordDataCallback cb)
248 {
249 if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
250 HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
251 return SENSOR_INVALID_PARAM;
252 }
253 CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
254 struct SensorDevManager *manager = GetSensorDevManager();
255
256 (void)OsalMutexLock(&manager->eventMutex);
257 if (manager->recordDataCb[groupId] != cb) {
258 HDF_LOGE("%{public}s: groupId [%{public}d] cb not same with registered", __func__, groupId);
259 (void)OsalMutexUnlock(&manager->eventMutex);
260 return SENSOR_FAILURE;
261 }
262
263 if (manager->recordDataCb[TRADITIONAL_SENSOR_TYPE] != NULL &&
264 manager->recordDataCb[MEDICAL_SENSOR_TYPE] != NULL) {
265 manager->recordDataCb[groupId] = NULL;
266 (void)OsalMutexUnlock(&manager->eventMutex);
267 return SENSOR_SUCCESS;
268 }
269
270 int32_t ret = HdfIoServiceGroupUnregisterListener(manager->serviceGroup, &g_listener);
271 if (ret != SENSOR_SUCCESS) {
272 HDF_LOGE("%{public}s: Sensor unregister listener failed", __func__);
273 (void)OsalMutexUnlock(&manager->eventMutex);
274 return ret;
275 }
276
277 manager->hasSensorListener = false;
278 HdfIoServiceGroupRecycle(manager->serviceGroup);
279 manager->serviceGroup = NULL;
280 manager->recordDataCb[groupId] = NULL;
281 (void)OsalMutexUnlock(&manager->eventMutex);
282
283 return SENSOR_SUCCESS;
284 }
285