4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <sensor_internal.h>
21 #include <sensor_internal_deprecated.h>
22 #include <sensor_types.h>
24 #include <channel_handler.h>
25 #include <sensor_manager.h>
26 #include <sensor_listener.h>
27 #include <sensor_log.h>
28 #include <unordered_map>
30 #define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11)
32 using namespace sensor;
34 class sensor_event_handler : public ipc::channel_handler
37 sensor_event_handler(sensor_t sensor, sensor_cb_t cb, void *user_data)
38 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
40 , m_user_data(user_data)
43 void connected(ipc::channel *ch) {}
44 void disconnected(ipc::channel *ch) {}
45 void read(ipc::channel *ch, ipc::message &msg)
50 data = reinterpret_cast<sensor_data_t *>(msg.body());
51 event_type = CONVERT_TYPE_EVENT(m_sensor->get_type());
53 m_cb(m_sensor, event_type, data, m_user_data);
56 void read_complete(ipc::channel *ch) {}
57 void error_caught(ipc::channel *ch, int error) {}
60 sensor_info *m_sensor;
65 class sensor_accuracy_handler : public ipc::channel_handler
68 sensor_accuracy_handler(sensor_t sensor, sensor_accuracy_changed_cb_t cb, void *user_data)
69 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
71 , m_user_data(user_data)
74 void connected(ipc::channel *ch) {}
75 void disconnected(ipc::channel *ch) {}
76 void read(ipc::channel *ch, ipc::message &msg)
79 data = reinterpret_cast<sensor_data_t *>(msg.body());
81 m_cb(m_sensor, data->timestamp, data->accuracy, m_user_data);
84 void read_complete(ipc::channel *ch) {}
85 void error_caught(ipc::channel *ch, int error) {}
88 sensor_info *m_sensor;
89 sensor_accuracy_changed_cb_t m_cb;
93 static sensor::sensor_manager manager;
94 static std::unordered_map<int, sensor::sensor_listener *> listeners;
98 * 1. power save option / lcd vconf : move to server
99 * 2. thread-safe : ipc_client
102 API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
106 retvm_if((!list || !count), -EINVAL,
107 "Invalid parameter[%#x, %#x]", list, count);
108 retvm_if(!manager.connect(), -EIO, "Failed to connect");
110 ret = manager.get_sensors(type, list, count);
111 retv_if(ret < 0, ret);
116 API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
120 retvm_if(!sensor, -EPERM, "Invalid parameter[%#x]", sensor);
121 retvm_if(!manager.connect(), -EIO, "Failed to connect");
123 ret = manager.get_sensor(type, sensor);
124 retv_if(ret < 0, ret);
129 API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
131 retvm_if(!type, false, "Invalid parameter[%#x]", type);
132 retvm_if(!manager.connect(), false, "Failed to connect");
133 retvm_if(!manager.is_supported(sensor), false,
134 "Invalid sensor[%#x]", sensor);
136 *type = static_cast<sensor_info *>(sensor)->get_type();
141 API const char* sensord_get_name(sensor_t sensor)
143 retvm_if(!manager.connect(), NULL, "Failed to connect");
144 retvm_if(!manager.is_supported(sensor), NULL,
145 "Invalid sensor[%#x]", sensor);
147 return static_cast<sensor_info *>(sensor)->get_uri().c_str();
150 API const char* sensord_get_vendor(sensor_t sensor)
152 retvm_if(!manager.connect(), NULL, "Failed to connect");
153 retvm_if(!manager.is_supported(sensor), NULL,
154 "Invalid sensor[%#x]", sensor);
156 return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
159 API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
161 retvm_if(!manager.connect(), false, "Failed to connect");
162 retvm_if(!privilege, false, "Invalid parameter[%#x]", privilege);
163 retvm_if(!manager.is_supported(sensor), false,
164 "Invalid sensor[%#x]", sensor);
167 * sensor_permission_t perm = static_cast<sensor_info *>(sensor)->get_permission();
168 * *privilege = static_cast<sensor_privilege_t>(perm);
170 *privilege = SENSOR_PRIVILEGE_PUBLIC;
175 API bool sensord_get_min_range(sensor_t sensor, float *min_range)
177 retvm_if(!manager.connect(), false, "Failed to connect");
178 retvm_if(!min_range, false, "Invalid parameter[%#x]", min_range);
179 retvm_if(!manager.is_supported(sensor), false,
180 "Invalid sensor[%#x]", sensor);
182 *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
187 API bool sensord_get_max_range(sensor_t sensor, float *max_range)
189 retvm_if(!max_range, false, "Invalid parameter[%#x]", max_range);
190 retvm_if(!manager.connect(), false, "Failed to connect");
191 retvm_if(!manager.is_supported(sensor), false,
192 "Invalid sensor[%#x]", sensor);
194 *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
199 API bool sensord_get_resolution(sensor_t sensor, float *resolution)
201 retvm_if(!resolution, false, "Invalid parameter[%#x]", resolution);
202 retvm_if(!manager.connect(), false, "Failed to connect");
203 retvm_if(!manager.is_supported(sensor), false,
204 "Invalid sensor[%#x]", sensor);
206 *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
211 API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
213 retvm_if(!min_interval, false, "Invalid parameter[%#x]", min_interval);
214 retvm_if(!manager.connect(), false, "Failed to connect");
215 retvm_if(!manager.is_supported(sensor), false,
216 "Invalid sensor[%#x]", sensor);
218 *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
223 API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
225 retvm_if(!fifo_count, false, "Invalid parameter[%#x]", fifo_count);
226 retvm_if(!manager.connect(), false, "Failed to connect");
227 retvm_if(!manager.is_supported(sensor), false,
228 "Invalid sensor[%#x]", sensor);
235 API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
237 retvm_if(!max_batch_count, false, "Invalid parameter[%#x]", max_batch_count);
238 retvm_if(!manager.connect(), false, "Failed to connect");
239 retvm_if(!manager.is_supported(sensor), false,
240 "Invalid sensor[%#x]", sensor);
242 *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
247 API bool sensord_is_wakeup_supported(sensor_t sensor)
249 retvm_if(!manager.connect(), false, "Failed to connect");
250 retvm_if(!manager.is_supported(sensor), false,
251 "Invalid sensor[%#x]", sensor);
253 return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
256 API int sensord_connect(sensor_t sensor)
258 retvm_if(!manager.connect(), -EIO, "Failed to connect");
259 retvm_if(!manager.is_supported(sensor), -EINVAL,
260 "Invalid sensor[%#x]", sensor);
262 sensor::sensor_listener *listener;
264 listener = new(std::nothrow) sensor::sensor_listener(sensor);
265 retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
267 listeners[listener->get_id()] = listener;
269 return listener->get_id();
272 API bool sensord_disconnect(int handle)
274 sensor::sensor_listener *listener;
276 auto it = listeners.find(handle);
277 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
279 listener = it->second;
280 retvm_if(!listener, false, "Invalid handle[%d]", handle);
283 listeners.erase(handle);
288 API bool sensord_register_event(int handle, unsigned int event_type,
289 unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
291 sensor::sensor_listener *listener;
293 int prev_max_batch_latency;
294 sensor_event_handler *handler;
296 auto it = listeners.find(handle);
297 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
299 listener = it->second;
301 prev_interval = listener->get_interval();
302 prev_max_batch_latency = listener->get_max_batch_latency();
304 if (listener->set_interval(interval) < 0) {
305 _E("Failed to set interval");
309 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
310 listener->set_interval(prev_interval);
311 _E("Failed to set max_batch_latency");
315 handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data);
317 listener->set_max_batch_latency(prev_max_batch_latency);
318 listener->set_interval(prev_interval);
319 _E("Failed to allocate memory");
323 listener->set_event_handler(handler);
328 API bool sensord_unregister_event(int handle, unsigned int event_type)
330 sensor::sensor_listener *listener;
332 auto it = listeners.find(handle);
333 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
335 listener = it->second;
337 listener->unset_event_handler();
342 API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
344 sensor::sensor_listener *listener;
345 sensor_accuracy_handler *handler;
347 auto it = listeners.find(handle);
348 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
350 listener = it->second;
352 handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data);
353 retvm_if(!handler, false, "Failed to allocate memory");
355 listener->set_accuracy_handler(handler);
360 API bool sensord_unregister_accuracy_cb(int handle)
362 sensor::sensor_listener *listener;
364 auto it = listeners.find(handle);
365 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
367 listener = it->second;
369 listener->unset_accuracy_handler();
374 API bool sensord_start(int handle, int option)
376 sensor::sensor_listener *listener;
380 auto it = listeners.find(handle);
381 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
383 listener = it->second;
385 pause = CONVERT_OPTION_PAUSE_POLICY(option);
386 prev_pause = listener->get_pause_policy();
388 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
389 _E("Failed to set pause policy[%d]", pause);
393 if (listener->start() < 0) {
394 listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
395 _E("Failed to start listener");
402 API bool sensord_stop(int handle)
405 sensor::sensor_listener *listener;
407 auto it = listeners.find(handle);
408 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
410 listener = it->second;
412 ret = listener->stop();
414 if (ret == -EAGAIN || ret == OP_SUCCESS)
420 API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
422 sensor::sensor_listener *listener;
424 auto it = listeners.find(handle);
425 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
427 listener = it->second;
429 if (listener->set_interval(interval) < 0) {
430 _E("Failed to set interval to listener");
437 API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
439 sensor::sensor_listener *listener;
441 auto it = listeners.find(handle);
442 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
444 listener = it->second;
446 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
447 _E("Failed to set max_batch_latency to listener");
454 API bool sensord_set_option(int handle, int option)
456 sensor::sensor_listener *listener;
459 auto it = listeners.find(handle);
460 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
462 listener = it->second;
464 pause = CONVERT_OPTION_PAUSE_POLICY(option);
466 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
467 _E("Failed to set option[%d(%d)] to listener", option, pause);
474 API int sensord_set_attribute_int(int handle, int attribute, int value)
476 sensor::sensor_listener *listener;
478 auto it = listeners.find(handle);
479 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
481 listener = it->second;
483 if (listener->set_attribute(attribute, value) < 0) {
484 _E("Failed to set attribute[%d, %d]", attribute, value);
491 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
493 sensor::sensor_listener *listener;
495 auto it = listeners.find(handle);
496 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
498 listener = it->second;
500 if (listener->set_attribute(attribute, value, len) < 0) {
501 _E("Failed to set attribute[%d, %s]", attribute, value);
508 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
510 sensor::sensor_listener *listener;
512 auto it = listeners.find(handle);
513 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
515 listener = it->second;
517 if (listener->get_sensor_data(sensor_data) < 0) {
518 _E("Failed to get sensor data from listener");
525 API bool sensord_flush(int handle)
527 sensor::sensor_listener *listener;
529 auto it = listeners.find(handle);
530 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
532 listener = it->second;
534 if (listener->flush() < 0) {
535 _E("Failed to flush sensor");
542 API bool sensord_set_passive_mode(int handle, bool passive)
544 sensor::sensor_listener *listener;
546 auto it = listeners.find(handle);
547 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
549 listener = it->second;
551 if (listener->set_passive_mode(passive) < 0) {
552 _E("Failed to set passive mode");
559 API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
563 * 2. create handle in this client
564 * 3. first connection(client)
565 * 4. cmd_connect for external sensor with key
567 retvm_if(!key, -EPERM, "Invalid key");
571 API bool sensord_external_disconnect(int handle)
575 * 2. create handle in this client
576 * 3. first connection(client)
577 * 4. cmd_connect for external sensor with key
578 * 5. disconnect this handle
579 * 6. if there is no active sensor, remove client id and stop listener
584 API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
588 * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false
596 API sensor_t sensord_get_sensor(sensor_type_t type)
600 if (sensord_get_default_sensor(type, &sensor) < 0)
607 API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
609 return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
613 API bool sensord_register_hub_event(int handle, unsigned int event_type,
614 unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
620 API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
624 * 2. if there is no sensor, return false
625 * 3. memory allocation
630 /* deprecated(BUT it is used in C-API....) */
631 API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
633 if (!manager.is_supported(sensor))
642 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
644 return (sensord_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
648 API bool sensord_send_command(int handle, const char *command, int command_len)
650 return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);