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, -EINVAL, "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_min_range(sensor_t sensor, float *min_range)
161 retvm_if(!manager.connect(), false, "Failed to connect");
162 retvm_if(!min_range, false, "Invalid parameter[%#x]", min_range);
163 retvm_if(!manager.is_supported(sensor), false,
164 "Invalid sensor[%#x]", sensor);
166 *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
171 API bool sensord_get_max_range(sensor_t sensor, float *max_range)
173 retvm_if(!max_range, false, "Invalid parameter[%#x]", max_range);
174 retvm_if(!manager.connect(), false, "Failed to connect");
175 retvm_if(!manager.is_supported(sensor), false,
176 "Invalid sensor[%#x]", sensor);
178 *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
183 API bool sensord_get_resolution(sensor_t sensor, float *resolution)
185 retvm_if(!resolution, false, "Invalid parameter[%#x]", resolution);
186 retvm_if(!manager.connect(), false, "Failed to connect");
187 retvm_if(!manager.is_supported(sensor), false,
188 "Invalid sensor[%#x]", sensor);
190 *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
195 API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
197 retvm_if(!min_interval, false, "Invalid parameter[%#x]", min_interval);
198 retvm_if(!manager.connect(), false, "Failed to connect");
199 retvm_if(!manager.is_supported(sensor), false,
200 "Invalid sensor[%#x]", sensor);
202 *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
207 API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
209 retvm_if(!fifo_count, false, "Invalid parameter[%#x]", fifo_count);
210 retvm_if(!manager.connect(), false, "Failed to connect");
211 retvm_if(!manager.is_supported(sensor), false,
212 "Invalid sensor[%#x]", sensor);
219 API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
221 retvm_if(!max_batch_count, false, "Invalid parameter[%#x]", max_batch_count);
222 retvm_if(!manager.connect(), false, "Failed to connect");
223 retvm_if(!manager.is_supported(sensor), false,
224 "Invalid sensor[%#x]", sensor);
226 *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
231 API bool sensord_is_wakeup_supported(sensor_t sensor)
233 retvm_if(!manager.connect(), false, "Failed to connect");
234 retvm_if(!manager.is_supported(sensor), false,
235 "Invalid sensor[%#x]", sensor);
237 return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
240 API int sensord_connect(sensor_t sensor)
242 retvm_if(!manager.connect(), -EIO, "Failed to connect");
243 retvm_if(!manager.is_supported(sensor), -EINVAL,
244 "Invalid sensor[%#x]", sensor);
246 sensor::sensor_listener *listener;
248 listener = new(std::nothrow) sensor::sensor_listener(sensor);
249 retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
251 listeners[listener->get_id()] = listener;
253 return listener->get_id();
256 API bool sensord_disconnect(int handle)
258 sensor::sensor_listener *listener;
260 auto it = listeners.find(handle);
261 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
263 listener = it->second;
264 retvm_if(!listener, false, "Invalid handle[%d]", handle);
267 listeners.erase(handle);
272 API bool sensord_register_event(int handle, unsigned int event_type,
273 unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
275 sensor::sensor_listener *listener;
277 int prev_max_batch_latency;
278 sensor_event_handler *handler;
280 auto it = listeners.find(handle);
281 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
283 listener = it->second;
285 prev_interval = listener->get_interval();
286 prev_max_batch_latency = listener->get_max_batch_latency();
288 if (listener->set_interval(interval) < 0) {
289 _E("Failed to set interval");
293 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
294 listener->set_interval(prev_interval);
295 _E("Failed to set max_batch_latency");
299 handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data);
301 listener->set_max_batch_latency(prev_max_batch_latency);
302 listener->set_interval(prev_interval);
303 _E("Failed to allocate memory");
307 listener->set_event_handler(handler);
312 API bool sensord_unregister_event(int handle, unsigned int event_type)
314 sensor::sensor_listener *listener;
316 auto it = listeners.find(handle);
317 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
319 listener = it->second;
321 listener->unset_event_handler();
326 API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
328 sensor::sensor_listener *listener;
329 sensor_accuracy_handler *handler;
331 auto it = listeners.find(handle);
332 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
334 listener = it->second;
336 handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data);
337 retvm_if(!handler, false, "Failed to allocate memory");
339 listener->set_accuracy_handler(handler);
344 API bool sensord_unregister_accuracy_cb(int handle)
346 sensor::sensor_listener *listener;
348 auto it = listeners.find(handle);
349 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
351 listener = it->second;
353 listener->unset_accuracy_handler();
358 API bool sensord_start(int handle, int option)
360 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 pause = CONVERT_OPTION_PAUSE_POLICY(option);
370 prev_pause = listener->get_pause_policy();
372 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
373 _E("Failed to set pause policy[%d]", pause);
377 if (listener->start() < 0) {
378 listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
379 _E("Failed to start listener");
386 API bool sensord_stop(int handle)
389 sensor::sensor_listener *listener;
391 auto it = listeners.find(handle);
392 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
394 listener = it->second;
396 ret = listener->stop();
398 if (ret == -EAGAIN || ret == OP_SUCCESS)
404 API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
406 sensor::sensor_listener *listener;
408 auto it = listeners.find(handle);
409 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
411 listener = it->second;
413 if (listener->set_interval(interval) < 0) {
414 _E("Failed to set interval to listener");
421 API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
423 sensor::sensor_listener *listener;
425 auto it = listeners.find(handle);
426 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
428 listener = it->second;
430 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
431 _E("Failed to set max_batch_latency to listener");
438 API bool sensord_set_option(int handle, int option)
440 sensor::sensor_listener *listener;
443 auto it = listeners.find(handle);
444 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
446 listener = it->second;
448 pause = CONVERT_OPTION_PAUSE_POLICY(option);
450 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
451 _E("Failed to set option[%d(%d)] to listener", option, pause);
458 API int sensord_set_attribute_int(int handle, int attribute, int value)
460 sensor::sensor_listener *listener;
462 auto it = listeners.find(handle);
463 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
465 listener = it->second;
467 if (listener->set_attribute(attribute, value) < 0) {
468 _E("Failed to set attribute[%d, %d]", attribute, value);
475 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
477 sensor::sensor_listener *listener;
479 auto it = listeners.find(handle);
480 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
482 listener = it->second;
484 if (listener->set_attribute(attribute, value, len) < 0) {
485 _E("Failed to set attribute[%d, %s]", attribute, value);
492 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
494 sensor::sensor_listener *listener;
496 auto it = listeners.find(handle);
497 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
499 listener = it->second;
501 if (listener->get_sensor_data(sensor_data) < 0) {
502 _E("Failed to get sensor data from listener");
509 API bool sensord_flush(int handle)
511 sensor::sensor_listener *listener;
513 auto it = listeners.find(handle);
514 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
516 listener = it->second;
518 if (listener->flush() < 0) {
519 _E("Failed to flush sensor");
526 API bool sensord_set_passive_mode(int handle, bool passive)
528 sensor::sensor_listener *listener;
530 auto it = listeners.find(handle);
531 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
533 listener = it->second;
535 if (listener->set_passive_mode(passive) < 0) {
536 _E("Failed to set passive mode");
543 API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
547 * 2. create handle in this client
548 * 3. first connection(client)
549 * 4. cmd_connect for external sensor with key
551 retvm_if(!key, -EINVAL, "Invalid key");
555 API bool sensord_external_disconnect(int handle)
559 * 2. create handle in this client
560 * 3. first connection(client)
561 * 4. cmd_connect for external sensor with key
562 * 5. disconnect this handle
563 * 6. if there is no active sensor, remove client id and stop listener
568 API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
572 * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false
580 API sensor_t sensord_get_sensor(sensor_type_t type)
584 if (sensord_get_default_sensor(type, &sensor) < 0)
591 API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
593 return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
597 API bool sensord_register_hub_event(int handle, unsigned int event_type,
598 unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
604 API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
608 * 2. if there is no sensor, return false
609 * 3. memory allocation
614 /* deprecated(BUT it is used in C-API....) */
615 API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
617 if (!manager.is_supported(sensor))
626 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
628 return (sensord_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
632 API bool sensord_send_command(int handle, const char *command, int command_len)
634 return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
638 API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
640 *privilege = SENSOR_PRIVILEGE_PUBLIC;