1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "sensor_device_manager.h"
10 #include <securec.h>
11 #include "asm/io.h"
12 #include "osal_mem.h"
13 #include "sensor_platform_if.h"
14
15 #define HDF_LOG_TAG hdf_sensor_commom
16
17 #define HDF_SENSOR_INFO_MAX_BUF (4 * 1024) // 4kB for all sensor info
18 #define HDF_SENSOR_EVENT_MAX_BUF (4 * 1024) // 4kB
19
20 struct SensorDevMgrData *g_sensorDeviceManager = NULL;
21
GetSensorDeviceManager(void)22 static struct SensorDevMgrData *GetSensorDeviceManager(void)
23 {
24 return g_sensorDeviceManager;
25 }
26
AddSensorDevice(const struct SensorDeviceInfo * deviceInfo)27 int32_t AddSensorDevice(const struct SensorDeviceInfo *deviceInfo)
28 {
29 struct SensorDevInfoNode *pos = NULL;
30 struct SensorDevInfoNode *devInfoNode = NULL;
31 struct SensorDevMgrData *manager = GetSensorDeviceManager();
32
33 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
34 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
35
36 DLIST_FOR_EACH_ENTRY(pos, &manager->sensorDevInfoHead, struct SensorDevInfoNode, node) {
37 if ((deviceInfo->sensorInfo.sensorId == pos->devInfo.sensorInfo.sensorId) &&
38 (strcmp(deviceInfo->sensorInfo.sensorName, pos->devInfo.sensorInfo.sensorName) == 0)) {
39 HDF_LOGE("%s: sensor id[%d] had existed", __func__, deviceInfo->sensorInfo.sensorId);
40 return HDF_FAILURE;
41 }
42 }
43
44 (void)OsalMutexLock(&manager->mutex);
45 devInfoNode = (struct SensorDevInfoNode*)OsalMemCalloc(sizeof(*devInfoNode));
46 if (devInfoNode == NULL) {
47 (void)OsalMutexUnlock(&manager->mutex);
48 return HDF_FAILURE;
49 }
50 if (memcpy_s(&devInfoNode->devInfo, sizeof(devInfoNode->devInfo),
51 (void *)deviceInfo, sizeof(*deviceInfo)) != EOK) {
52 HDF_LOGE("%s: copy sensor info failed", __func__);
53 OsalMemFree(devInfoNode);
54 (void)OsalMutexUnlock(&manager->mutex);
55 return HDF_FAILURE;
56 }
57 DListInsertTail(&devInfoNode->node, &manager->sensorDevInfoHead);
58 (void)OsalMutexUnlock(&manager->mutex);
59 HDF_LOGI("%s: register sensor name[%s] success", __func__, deviceInfo->sensorInfo.sensorName);
60
61 return HDF_SUCCESS;
62 }
63
DeleteSensorDevice(const struct SensorBasicInfo * sensorBaseInfo)64 int32_t DeleteSensorDevice(const struct SensorBasicInfo *sensorBaseInfo)
65 {
66 struct SensorDevInfoNode *pos = NULL;
67 struct SensorDevInfoNode *tmp = NULL;
68 struct SensorDevMgrData *manager = GetSensorDeviceManager();
69
70 CHECK_NULL_PTR_RETURN_VALUE(sensorBaseInfo, HDF_ERR_INVALID_PARAM);
71 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
72
73 (void)OsalMutexLock(&manager->mutex);
74 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->sensorDevInfoHead, struct SensorDevInfoNode, node) {
75 if ((sensorBaseInfo->sensorId == pos->devInfo.sensorInfo.sensorId) &&
76 (strcmp(sensorBaseInfo->sensorName, pos->devInfo.sensorInfo.sensorName) == 0)) {
77 DListRemove(&pos->node);
78 OsalMemFree(pos);
79 (void)OsalMutexUnlock(&manager->mutex);
80 return HDF_SUCCESS;
81 }
82 }
83 (void)OsalMutexUnlock(&manager->mutex);
84 HDF_LOGE("%s: delete sensor id invalid para", __func__);
85 return HDF_FAILURE;
86 }
87
ReportSensorEvent(const struct SensorReportEvent * events)88 int32_t ReportSensorEvent(const struct SensorReportEvent *events)
89 {
90 int32_t ret;
91 struct SensorDevMgrData *manager = NULL;
92 struct HdfSBuf *msg = NULL;
93
94 CHECK_NULL_PTR_RETURN_VALUE(events, HDF_ERR_INVALID_PARAM);
95
96 manager = GetSensorDeviceManager();
97 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
98
99 (void)OsalMutexLock(&manager->eventMutex);
100 msg = HdfSbufObtain(HDF_SENSOR_EVENT_MAX_BUF);
101 if (msg == NULL) {
102 (void)OsalMutexUnlock(&manager->eventMutex);
103 return HDF_ERR_INVALID_PARAM;
104 }
105
106 if (!HdfSbufWriteBuffer(msg, events, sizeof(*events))) {
107 HDF_LOGE("%s: sbuf write event failed", __func__);
108 ret = HDF_FAILURE;
109 goto EXIT;
110 }
111
112 if (!HdfSbufWriteBuffer(msg, events->data, events->dataLen)) {
113 HDF_LOGE("%s: sbuf write event data failed", __func__);
114 ret = HDF_FAILURE;
115 goto EXIT;
116 }
117
118 if (HdfDeviceSendEvent(manager->device, 0, msg) != HDF_SUCCESS) {
119 HDF_LOGE("%s: send sensor data event failed", __func__);
120 ret = HDF_FAILURE;
121 goto EXIT;
122 }
123 ret = HDF_SUCCESS;
124
125 EXIT:
126 HdfSbufRecycle(msg);
127 (void)OsalMutexUnlock(&manager->eventMutex);
128 return ret;
129 }
130
GetAllSensorInfo(struct HdfSBuf * data,struct HdfSBuf * reply)131 static int32_t GetAllSensorInfo(struct HdfSBuf *data, struct HdfSBuf *reply)
132 {
133 int32_t count = 0;
134 struct SensorDevInfoNode *pos = NULL;
135 struct SensorBasicInfo *sensorInfo = NULL;
136 struct SensorDevMgrData *manager = NULL;
137
138 (void)data;
139
140 manager = GetSensorDeviceManager();
141
142 CHECK_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM);
143 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
144
145 DLIST_FOR_EACH_ENTRY(pos, &manager->sensorDevInfoHead, struct SensorDevInfoNode, node) {
146 sensorInfo = &(pos->devInfo.sensorInfo);
147 if (!HdfSbufWriteBuffer(reply, sensorInfo, sizeof(*sensorInfo))) {
148 HDF_LOGE("%s: write sbuf failed", __func__);
149 return HDF_FAILURE;
150 }
151
152 count++;
153 if ((count + 1) * sizeof(*sensorInfo) > HDF_SENSOR_INFO_MAX_BUF) {
154 HDF_LOGE("%s: write sbuf exceed max buf, sensor count[%d]", __func__, count);
155 break;
156 }
157 }
158
159 return HDF_SUCCESS;
160 }
161
Enable(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)162 static int32_t Enable(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
163 {
164 (void)data;
165 (void)reply;
166 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
167 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo->ops.Enable, HDF_ERR_INVALID_PARAM);
168 return deviceInfo->ops.Enable();
169 }
170
Disable(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)171 static int32_t Disable(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
172 {
173 (void)data;
174 (void)reply;
175 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
176 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo->ops.Disable, HDF_ERR_INVALID_PARAM);
177
178 return deviceInfo->ops.Disable();
179 }
180
SetBatch(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)181 static int32_t SetBatch(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
182 {
183 int64_t samplingInterval;
184 int64_t reportInterval;
185 (void)reply;
186
187 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
188 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
189 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo->ops.SetBatch, HDF_ERR_INVALID_PARAM);
190
191 if (!HdfSbufReadInt64(data, &samplingInterval) || !HdfSbufReadInt64(data, &reportInterval)) {
192 HDF_LOGE("%s: sbuf read interval failed", __func__);
193 return HDF_FAILURE;
194 }
195
196 return deviceInfo->ops.SetBatch(samplingInterval, reportInterval);
197 }
198
SetMode(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)199 static int32_t SetMode(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
200 {
201 int32_t mode;
202 (void)reply;
203
204 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
205 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
206 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo->ops.SetMode, HDF_ERR_INVALID_PARAM);
207
208 if (!HdfSbufReadInt32(data, &mode)) {
209 HDF_LOGE("%s: sbuf read mode failed", __func__);
210 return HDF_FAILURE;
211 }
212
213 return deviceInfo->ops.SetMode(mode);
214 }
215
SetOption(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)216 static int32_t SetOption(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
217 {
218 uint32_t option;
219 (void)reply;
220
221 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo, HDF_ERR_INVALID_PARAM);
222 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
223 CHECK_NULL_PTR_RETURN_VALUE(deviceInfo->ops.SetOption, HDF_ERR_INVALID_PARAM);
224
225 if (!HdfSbufReadUint32(data, &option)) {
226 HDF_LOGE("%s: sbuf read option failed", __func__);
227 return HDF_FAILURE;
228 }
229
230 return deviceInfo->ops.SetOption(option);
231 }
232
233 static struct SensorCmdHandleList g_sensorCmdHandle[] = {
234 {SENSOR_OPS_CMD_ENABLE, Enable}, // SENSOR_CMD_ENABLE
235 {SENSOR_OPS_CMD_DISABLE, Disable}, // SENSOR_CMD_DISABLE
236 {SENSOR_OPS_CMD_SET_BATCH, SetBatch}, // SENSOR_CMD_SET_BATCH
237 {SENSOR_OPS_CMD_SET_MODE, SetMode}, // SENSOR_CMD_SET_MODE
238 {SENSOR_OPS_CMD_SET_OPTION, SetOption}, // SENSOR_CMD_SET_OPTION
239 };
240
DispatchCmdHandle(struct SensorDeviceInfo * deviceInfo,struct HdfSBuf * data,struct HdfSBuf * reply)241 static int32_t DispatchCmdHandle(struct SensorDeviceInfo *deviceInfo, struct HdfSBuf *data, struct HdfSBuf *reply)
242 {
243 int32_t opsCmd;
244 int32_t loop;
245 int32_t count;
246
247 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
248
249 if (!HdfSbufReadInt32(data, &opsCmd)) {
250 HDF_LOGE("%s: sbuf read opsCmd failed", __func__);
251 return HDF_FAILURE;
252 }
253
254 if ((opsCmd >= SENSOR_OPS_CMD_BUTT) || (opsCmd < SENSOR_OPS_CMD_ENABLE)) {
255 HDF_LOGE("%s: invalid cmd = %d", __func__, opsCmd);
256 return HDF_FAILURE;
257 }
258
259 count = sizeof(g_sensorCmdHandle) / sizeof(g_sensorCmdHandle[0]);
260 for (loop = 0; loop < count; ++loop) {
261 if ((opsCmd == g_sensorCmdHandle[loop].cmd) && (g_sensorCmdHandle[loop].func != NULL)) {
262 return g_sensorCmdHandle[loop].func(deviceInfo, data, reply);
263 }
264 }
265
266 return HDF_FAILURE;
267 }
268
DispatchSensor(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)269 static int32_t DispatchSensor(struct HdfDeviceIoClient *client,
270 int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
271 {
272 struct SensorDevMgrData *manager = GetSensorDeviceManager();
273 struct SensorDevInfoNode *pos = NULL;
274 int32_t sensorId;
275 int32_t ret;
276
277 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
278 CHECK_NULL_PTR_RETURN_VALUE(client, HDF_ERR_INVALID_PARAM);
279
280 if (cmd >= SENSOR_CMD_END) {
281 HDF_LOGE("%s: sensor cmd invalid para", __func__);
282 return HDF_ERR_INVALID_PARAM;
283 }
284
285 if (cmd == SENSOR_CMD_GET_INFO_LIST) {
286 return GetAllSensorInfo(data, reply);
287 }
288
289 (void)OsalMutexLock(&manager->mutex);
290 if (!HdfSbufReadInt32(data, &sensorId)) {
291 HDF_LOGE("%s: sbuf read sensorId failed", __func__);
292 (void)OsalMutexUnlock(&manager->mutex);
293 return HDF_ERR_INVALID_PARAM;
294 }
295
296 DLIST_FOR_EACH_ENTRY(pos, &manager->sensorDevInfoHead, struct SensorDevInfoNode, node) {
297 if (sensorId == pos->devInfo.sensorInfo.sensorId) {
298 ret = DispatchCmdHandle(&pos->devInfo, data, reply);
299 (void)OsalMutexUnlock(&manager->mutex);
300 return ret;
301 }
302 }
303 (void)OsalMutexUnlock(&manager->mutex);
304
305 HDF_LOGE("%s: not find sensor[%d] handle function", __func__, sensorId);
306 return HDF_FAILURE;
307 }
308
BindSensorDevManager(struct HdfDeviceObject * device)309 int32_t BindSensorDevManager(struct HdfDeviceObject *device)
310 {
311 struct SensorDevMgrData *manager = NULL;
312
313 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
314
315 manager = (struct SensorDevMgrData *)OsalMemCalloc(sizeof(*manager));
316 if (manager == NULL) {
317 HDF_LOGE("%s: malloc manager fail!", __func__);
318 return HDF_ERR_MALLOC_FAIL;
319 }
320
321 manager->ioService.Dispatch = DispatchSensor;
322 manager->device = device;
323 device->service = &manager->ioService;
324 g_sensorDeviceManager = manager;
325
326 return HDF_SUCCESS;
327 }
328
InitSensorDevManager(struct HdfDeviceObject * device)329 int32_t InitSensorDevManager(struct HdfDeviceObject *device)
330 {
331 struct SensorDevMgrData *manager = NULL;
332
333 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
334 manager = (struct SensorDevMgrData *)device->service;
335 CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_ERR_INVALID_PARAM);
336
337 DListHeadInit(&manager->sensorDevInfoHead);
338 if (OsalMutexInit(&manager->mutex) != HDF_SUCCESS) {
339 HDF_LOGE("%s: init mutex failed", __func__);
340 return HDF_FAILURE;
341 }
342
343 if (OsalMutexInit(&manager->eventMutex) != HDF_SUCCESS) {
344 HDF_LOGE("%s: init eventMutex failed", __func__);
345 return HDF_FAILURE;
346 }
347
348 if (!HdfDeviceSetClass(device, DEVICE_CLASS_SENSOR)) {
349 HDF_LOGE("%s: init sensor set class failed", __func__);
350 return HDF_FAILURE;
351 }
352
353 HDF_LOGI("%s: init sensor manager successfully", __func__);
354 return HDF_SUCCESS;
355 }
356
ReleaseSensorDevManager(struct HdfDeviceObject * device)357 void ReleaseSensorDevManager(struct HdfDeviceObject *device)
358 {
359 struct SensorDevInfoNode *pos = NULL;
360 struct SensorDevInfoNode *tmp = NULL;
361 struct SensorDevMgrData *manager = NULL;
362
363 CHECK_NULL_PTR_RETURN(device);
364
365 manager = (struct SensorDevMgrData *)device->service;
366 CHECK_NULL_PTR_RETURN(manager);
367
368 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->sensorDevInfoHead, struct SensorDevInfoNode, node) {
369 DListRemove(&pos->node);
370 OsalMemFree(pos);
371 }
372
373 OsalMutexDestroy(&manager->mutex);
374 OsalMutexDestroy(&manager->eventMutex);
375 OsalMemFree(manager);
376 g_sensorDeviceManager = NULL;
377 }
378
379 struct HdfDriverEntry g_sensorDevManagerEntry = {
380 .moduleVersion = 1,
381 .moduleName = "HDF_SENSOR_MGR_AP",
382 .Bind = BindSensorDevManager,
383 .Init = InitSensorDevManager,
384 .Release = ReleaseSensorDevManager,
385 };
386
387 HDF_INIT(g_sensorDevManagerEntry);
388