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 39static 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 57static struct SensorDumpDate g_dumpDate = { 0 }; 58static struct SensorDatePack g_listDump = { 0 }; 59 60struct SensorDatePack *GetEventData(void) 61{ 62 return &g_listDump; 63} 64 65void 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 77void 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 110void 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 131static 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 178static struct HdfDevEventlistener g_listener = { 179 .onReceive = OnSensorEventReceived, 180 .priv = "hdi_sensor" 181}; 182 183struct HdfDevEventlistener *GetSensorListener(void) 184{ 185 return &g_listener; 186} 187 188static 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 219int32_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 248int32_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