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