1 /*
2 * Copyright (c) 2021 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 hdf_sensor_dal
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) / (HDI_SENSOR_FLOAT_TEN_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
37 static struct SensorCovertCoff g_sensorCovertCoff[] = {
38 { SENSOR_TYPE_NONE, 0, DATA_X, { ACCEL_ACCURACY } },
39 { SENSOR_TYPE_ACCELEROMETER, SENSOR_TYPE_MAX, DATA_XYZ, { ACCEL_ACCURACY, ACCEL_ACCURACY, ACCEL_ACCURACY } },
40 { SENSOR_TYPE_GRAVITY, SENSOR_TYPE_MAX, DATA_XYZ, { ACCEL_ACCURACY, ACCEL_ACCURACY, ACCEL_ACCURACY } },
41 { SENSOR_TYPE_GYROSCOPE, SENSOR_TYPE_MAX, DATA_XYZ, { GYRO_ACCURACY, GYRO_ACCURACY, GYRO_ACCURACY } },
42 { SENSOR_TYPE_BAROMETER, SENSOR_TYPE_MAX, DATA_XY,
43 { BAROMETER_BAROMETER_ACCURACY, BAROMETER_TEMPERATURE_ACCURACY } },
44 { SENSOR_TYPE_MAGNETIC_FIELD, SENSOR_TYPE_MAX, DATA_XYZ,
45 { MAGNETIC_ACCURACY, MAGNETIC_ACCURACY, MAGNETIC_ACCURACY } },
46 { SENSOR_TYPE_AMBIENT_LIGHT, SENSOR_TYPE_MAX, DATA_XYZA,
47 { ALS_ACCURACY, ALS_ACCURACY, ALS_ACCURACY, ALS_ACCURACY } },
48 { SENSOR_TYPE_PEDOMETER, SENSOR_TYPE_MAX, DATA_X, { PEDOMETER_ACCURACY } },
49 { SENSOR_TYPE_HALL, SENSOR_TYPE_MAX, DATA_X, { HALL_ACCURACY } },
50 { SENSOR_TYPE_PROXIMITY, SENSOR_TYPE_MAX, DATA_X, { PROXIMITY_ACCURACY } },
51 };
52
SetSensorIdBySensorType(enum SensorTypeTag type,int32_t sensorId)53 void SetSensorIdBySensorType(enum SensorTypeTag type, int32_t sensorId)
54 {
55 uint32_t count = sizeof(g_sensorCovertCoff) / sizeof(g_sensorCovertCoff[0]);
56
57 for (uint32_t i = 0; i < count; ++i) {
58 if (g_sensorCovertCoff[i].sensorTypeId == (int32_t)type) {
59 g_sensorCovertCoff[i].sensorId = sensorId;
60 break;
61 }
62 }
63 }
64
ConvertSensorData(struct SensorEvents * event)65 static void ConvertSensorData(struct SensorEvents *event)
66 {
67 uint32_t dataLen;
68 uint32_t axis;
69 int32_t *data = NULL;
70 float *value = NULL;
71
72 data = (int32_t *)event->data;
73 value = (float *)event->data;
74
75 for (uint32_t i = 0; i < sizeof(g_sensorCovertCoff) / sizeof(g_sensorCovertCoff[0]); ++i) {
76 if ((g_sensorCovertCoff[i].sensorId == event->sensorId) && (g_sensorCovertCoff[i].dim != 0)) {
77 dataLen = event->dataLen / sizeof(int32_t);
78 for (uint32_t j = 0; j < dataLen; ++j) {
79 axis = j % g_sensorCovertCoff[i].dim;
80 value[j] = (float)(data[j] * g_sensorCovertCoff[i].coff[axis]);
81 }
82 }
83 }
84 }
85
OnSensorEventReceived(struct HdfDevEventlistener * listener,struct HdfIoService * service,uint32_t id,struct HdfSBuf * data)86 static int OnSensorEventReceived(struct HdfDevEventlistener *listener,
87 struct HdfIoService *service, uint32_t id, struct HdfSBuf *data)
88 {
89 uint32_t len;
90 struct SensorEvents *event = NULL;
91 struct SensorDevManager *manager = GetSensorDevManager();
92 (void)listener;
93 (void)service;
94 (void)id;
95
96 (void)OsalMutexLock(&manager->eventMutex);
97 if (!HdfSbufReadBuffer(data, (const void **)&event, &len) || event == NULL) {
98 HDF_LOGE("%{public}s: Read sensor event fail!", __func__);
99 (void)OsalMutexUnlock(&manager->eventMutex);
100 return SENSOR_FAILURE;
101 }
102
103 uint8_t *buf = NULL;
104 if (!HdfSbufReadBuffer(data, (const void **)&buf, &len) || buf == NULL) {
105 (void)OsalMutexUnlock(&manager->eventMutex);
106 HDF_LOGE("%{public}s: Read sensor data fail!", __func__);
107 return SENSOR_FAILURE;
108 } else {
109 event->data = buf;
110 event->dataLen = len;
111 }
112
113 enum SensorGroupType groupType;
114 if (event->sensorId >= SENSOR_TYPE_MEDICAL_BEGIN && event->sensorId < SENSOR_TYPE_MEDICAL_END) {
115 groupType = MEDICAL_SENSOR_TYPE;
116 } else {
117 groupType = TRADITIONAL_SENSOR_TYPE;
118 }
119
120 ConvertSensorData(event);
121 if (manager->recordDataCb[groupType] != NULL) {
122 manager->recordDataCb[groupType](event);
123 }
124
125 (void)OsalMutexUnlock(&manager->eventMutex);
126
127 return SENSOR_SUCCESS;
128 }
129
130 static struct HdfDevEventlistener g_listener = {
131 .onReceive = OnSensorEventReceived,
132 .priv = "hdi_sensor"
133 };
134
GetSensorListener()135 struct HdfDevEventlistener *GetSensorListener()
136 {
137 return &g_listener;
138 }
139
AddSensorDevServiceGroup(void)140 static int32_t AddSensorDevServiceGroup(void)
141 {
142 struct SensorManagerNode *pos = NULL;
143 struct SensorDevManager *manager = GetSensorDevManager();
144
145 manager->serviceGroup = HdfIoServiceGroupObtain();
146 if (manager->serviceGroup == NULL) {
147 return SENSOR_FAILURE;
148 }
149
150 DLIST_FOR_EACH_ENTRY(pos, &manager->managerHead, struct SensorManagerNode, node) {
151 if ((pos->ioService != NULL) &&
152 (HdfIoServiceGroupAddService(manager->serviceGroup, pos->ioService) != SENSOR_SUCCESS)) {
153 HdfIoServiceGroupRecycle(manager->serviceGroup);
154 manager->serviceGroup = NULL;
155 HDF_LOGE("%{public}s: Add service to group failed", __func__);
156 return SENSOR_INVALID_SERVICE;
157 }
158 }
159
160 int32_t ret = HdfIoServiceGroupRegisterListener(manager->serviceGroup, &g_listener);
161 if (ret != SENSOR_SUCCESS) {
162 HDF_LOGE("%{public}s: Register listener to group failed", __func__);
163 HdfIoServiceGroupRecycle(manager->serviceGroup);
164 manager->serviceGroup = NULL;
165 return ret;
166 }
167
168 return SENSOR_SUCCESS;
169 }
170
Register(int32_t groupId,RecordDataCallback cb)171 int32_t Register(int32_t groupId, RecordDataCallback cb)
172 {
173 if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
174 HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
175 return SENSOR_INVALID_PARAM;
176 }
177 struct SensorDevManager *manager = NULL;
178 CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
179 manager = GetSensorDevManager();
180 (void)OsalMutexLock(&manager->eventMutex);
181 if (manager->recordDataCb[groupId] != NULL) {
182 HDF_LOGE("%{public}s: groupId [%{public}d] callback already exists", __func__, groupId);
183 (void)OsalMutexUnlock(&manager->eventMutex);
184 return SENSOR_FAILURE;
185 }
186
187 if (manager->serviceGroup != NULL) {
188 manager->recordDataCb[groupId] = cb;
189 (void)OsalMutexUnlock(&manager->eventMutex);
190 return SENSOR_SUCCESS;
191 }
192 int32_t ret = AddSensorDevServiceGroup();
193 if (ret == SENSOR_SUCCESS) {
194 manager->recordDataCb[groupId] = cb;
195 }
196 (void)OsalMutexUnlock(&manager->eventMutex);
197 return ret;
198 }
199
Unregister(int32_t groupId,RecordDataCallback cb)200 int32_t Unregister(int32_t groupId, RecordDataCallback cb)
201 {
202 if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) {
203 HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId);
204 return SENSOR_INVALID_PARAM;
205 }
206 CHECK_NULL_PTR_RETURN_VALUE(cb, SENSOR_NULL_PTR);
207 struct SensorDevManager *manager = GetSensorDevManager();
208
209 (void)OsalMutexLock(&manager->eventMutex);
210 if (manager->recordDataCb[groupId] != cb) {
211 HDF_LOGE("%{public}s: groupId [%{public}d] cb not same with registered", __func__, groupId);
212 (void)OsalMutexUnlock(&manager->eventMutex);
213 return SENSOR_FAILURE;
214 }
215
216 if (manager->recordDataCb[TRADITIONAL_SENSOR_TYPE] != NULL &&
217 manager->recordDataCb[MEDICAL_SENSOR_TYPE] != NULL) {
218 manager->recordDataCb[groupId] = NULL;
219 (void)OsalMutexUnlock(&manager->eventMutex);
220 return SENSOR_SUCCESS;
221 }
222
223 int32_t ret = HdfIoServiceGroupUnregisterListener(manager->serviceGroup, &g_listener);
224 if (ret != SENSOR_SUCCESS) {
225 HDF_LOGE("%{public}s: Sensor unregister listener failed", __func__);
226 (void)OsalMutexUnlock(&manager->eventMutex);
227 return ret;
228 }
229
230 manager->hasSensorListener = false;
231 HdfIoServiceGroupRecycle(manager->serviceGroup);
232 manager->serviceGroup = NULL;
233 manager->recordDataCb[groupId] = NULL;
234 (void)OsalMutexUnlock(&manager->eventMutex);
235
236 return SENSOR_SUCCESS;
237 }
238