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>
23 #include <sensor_types_private.h>
24 #include <sensor_utils.h>
26 #include <channel_handler.h>
27 #include <sensor_manager.h>
28 #include <sensor_listener.h>
29 #include <sensor_provider.h>
30 #include <sensor_log.h>
31 #include <unordered_map>
34 #define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11)
36 using namespace sensor;
38 class sensor_event_handler : public ipc::channel_handler
41 sensor_event_handler(sensor_t sensor, sensor_cb_t cb, void *user_data)
42 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
44 , m_user_data(user_data)
47 void connected(ipc::channel *ch) {}
48 void disconnected(ipc::channel *ch) {}
49 void read(ipc::channel *ch, ipc::message &msg)
54 data = reinterpret_cast<sensor_data_t *>(msg.body());
55 event_type = CONVERT_TYPE_EVENT(m_sensor->get_type());
57 m_cb(m_sensor, event_type, data, m_user_data);
60 void read_complete(ipc::channel *ch) {}
61 void error_caught(ipc::channel *ch, int error) {}
64 sensor_info *m_sensor;
69 class sensor_accuracy_handler : public ipc::channel_handler
72 sensor_accuracy_handler(sensor_t sensor, sensor_accuracy_changed_cb_t cb, void *user_data)
73 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
75 , m_user_data(user_data)
78 void connected(ipc::channel *ch) {}
79 void disconnected(ipc::channel *ch) {}
80 void read(ipc::channel *ch, ipc::message &msg)
83 data = reinterpret_cast<sensor_data_t *>(msg.body());
85 m_cb(m_sensor, data->timestamp, data->accuracy, m_user_data);
88 void read_complete(ipc::channel *ch) {}
89 void error_caught(ipc::channel *ch, int error) {}
92 sensor_info *m_sensor;
93 sensor_accuracy_changed_cb_t m_cb;
97 static sensor::sensor_manager manager;
98 static std::unordered_map<int, sensor::sensor_listener *> listeners;
102 * 1. power save option / lcd vconf : move to server
103 * 2. thread-safe : ipc_client
106 API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
108 return sensord_get_sensors_by_uri(utils::get_uri(type), list, count);
111 API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
113 return sensord_get_default_sensor_by_uri(utils::get_uri(type), sensor);
116 API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
118 retvm_if(!type, false, "Invalid parameter[%#x]", type);
119 retvm_if(!manager.connect(), false, "Failed to connect");
120 retvm_if(!manager.is_supported(sensor), false,
121 "Invalid sensor[%#x]", sensor);
123 *type = static_cast<sensor_info *>(sensor)->get_type();
128 API const char* sensord_get_uri(sensor_t sensor)
130 retvm_if(!manager.connect(), NULL, "Failed to connect");
131 retvm_if(!manager.is_supported(sensor), NULL,
132 "Invalid sensor[%#x]", sensor);
134 return static_cast<sensor_info *>(sensor)->get_uri().c_str();
137 API const char* sensord_get_name(sensor_t sensor)
139 retvm_if(!manager.connect(), NULL, "Failed to connect");
140 retvm_if(!manager.is_supported(sensor), NULL,
141 "Invalid sensor[%#x]", sensor);
143 return static_cast<sensor_info *>(sensor)->get_model().c_str();
146 API const char* sensord_get_vendor(sensor_t sensor)
148 retvm_if(!manager.connect(), NULL, "Failed to connect");
149 retvm_if(!manager.is_supported(sensor), NULL,
150 "Invalid sensor[%#x]", sensor);
152 return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
155 API bool sensord_get_min_range(sensor_t sensor, float *min_range)
157 retvm_if(!min_range, false, "Invalid parameter[%#x]", min_range);
158 retvm_if(!manager.connect(), false, "Failed to connect");
159 retvm_if(!manager.is_supported(sensor), false,
160 "Invalid sensor[%#x]", sensor);
162 *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
167 API bool sensord_get_max_range(sensor_t sensor, float *max_range)
169 retvm_if(!max_range, false, "Invalid parameter[%#x]", max_range);
170 retvm_if(!manager.connect(), false, "Failed to connect");
171 retvm_if(!manager.is_supported(sensor), false,
172 "Invalid sensor[%#x]", sensor);
174 *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
179 API bool sensord_get_resolution(sensor_t sensor, float *resolution)
181 retvm_if(!resolution, false, "Invalid parameter[%#x]", resolution);
182 retvm_if(!manager.connect(), false, "Failed to connect");
183 retvm_if(!manager.is_supported(sensor), false,
184 "Invalid sensor[%#x]", sensor);
186 *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
191 API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
193 retvm_if(!min_interval, false, "Invalid parameter[%#x]", min_interval);
194 retvm_if(!manager.connect(), false, "Failed to connect");
195 retvm_if(!manager.is_supported(sensor), false,
196 "Invalid sensor[%#x]", sensor);
198 *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
203 API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
205 retvm_if(!fifo_count, false, "Invalid parameter[%#x]", fifo_count);
206 retvm_if(!manager.connect(), false, "Failed to connect");
207 retvm_if(!manager.is_supported(sensor), false,
208 "Invalid sensor[%#x]", sensor);
215 API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
217 retvm_if(!max_batch_count, false, "Invalid parameter[%#x]", max_batch_count);
218 retvm_if(!manager.connect(), false, "Failed to connect");
219 retvm_if(!manager.is_supported(sensor), false,
220 "Invalid sensor[%#x]", sensor);
222 *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
227 API bool sensord_is_wakeup_supported(sensor_t sensor)
229 retvm_if(!manager.connect(), false, "Failed to connect");
230 retvm_if(!manager.is_supported(sensor), false,
231 "Invalid sensor[%#x]", sensor);
233 return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
236 API int sensord_connect(sensor_t sensor)
238 retvm_if(!manager.connect(), -EIO, "Failed to connect");
239 retvm_if(!manager.is_supported(sensor), -EINVAL,
240 "Invalid sensor[%#x]", sensor);
242 sensor::sensor_listener *listener;
244 listener = new(std::nothrow) sensor::sensor_listener(sensor);
245 retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
247 listeners[listener->get_id()] = listener;
249 return listener->get_id();
252 API bool sensord_disconnect(int handle)
254 sensor::sensor_listener *listener;
256 auto it = listeners.find(handle);
257 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
259 listener = it->second;
260 retvm_if(!listener, false, "Invalid handle[%d]", handle);
263 listeners.erase(handle);
268 API bool sensord_register_event(int handle, unsigned int event_type,
269 unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
271 sensor::sensor_listener *listener;
273 int prev_max_batch_latency;
274 sensor_event_handler *handler;
276 auto it = listeners.find(handle);
277 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
279 listener = it->second;
281 prev_interval = listener->get_interval();
282 prev_max_batch_latency = listener->get_max_batch_latency();
284 if (listener->set_interval(interval) < 0) {
285 _E("Failed to set interval");
289 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
290 listener->set_interval(prev_interval);
291 _E("Failed to set max_batch_latency");
295 handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data);
297 listener->set_max_batch_latency(prev_max_batch_latency);
298 listener->set_interval(prev_interval);
299 _E("Failed to allocate memory");
303 listener->set_event_handler(handler);
308 API bool sensord_unregister_event(int handle, unsigned int event_type)
310 sensor::sensor_listener *listener;
312 auto it = listeners.find(handle);
313 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
315 listener = it->second;
317 listener->unset_event_handler();
322 API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
324 sensor::sensor_listener *listener;
325 sensor_accuracy_handler *handler;
327 auto it = listeners.find(handle);
328 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
330 listener = it->second;
332 handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data);
333 retvm_if(!handler, false, "Failed to allocate memory");
335 listener->set_accuracy_handler(handler);
340 API bool sensord_unregister_accuracy_cb(int handle)
342 sensor::sensor_listener *listener;
344 auto it = listeners.find(handle);
345 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
347 listener = it->second;
349 listener->unset_accuracy_handler();
354 API bool sensord_start(int handle, int option)
356 sensor::sensor_listener *listener;
360 auto it = listeners.find(handle);
361 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
363 listener = it->second;
365 pause = CONVERT_OPTION_PAUSE_POLICY(option);
366 prev_pause = listener->get_pause_policy();
368 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
369 _E("Failed to set pause policy[%d]", pause);
373 if (listener->start() < 0) {
374 listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
375 _E("Failed to start listener");
382 API bool sensord_stop(int handle)
385 sensor::sensor_listener *listener;
387 auto it = listeners.find(handle);
388 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
390 listener = it->second;
392 ret = listener->stop();
394 if (ret == -EAGAIN || ret == OP_SUCCESS)
400 API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
402 sensor::sensor_listener *listener;
404 auto it = listeners.find(handle);
405 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
407 listener = it->second;
409 if (listener->set_interval(interval) < 0) {
410 _E("Failed to set interval to listener");
417 API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
419 sensor::sensor_listener *listener;
421 auto it = listeners.find(handle);
422 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
424 listener = it->second;
426 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
427 _E("Failed to set max_batch_latency to listener");
434 API bool sensord_set_option(int handle, int option)
436 sensor::sensor_listener *listener;
439 auto it = listeners.find(handle);
440 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
442 listener = it->second;
444 pause = CONVERT_OPTION_PAUSE_POLICY(option);
446 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
447 _E("Failed to set option[%d(%d)] to listener", option, pause);
454 API int sensord_set_attribute_int(int handle, int attribute, int value)
456 sensor::sensor_listener *listener;
458 auto it = listeners.find(handle);
459 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
461 listener = it->second;
463 if (listener->set_attribute(attribute, value) < 0) {
464 _E("Failed to set attribute[%d, %d]", attribute, value);
471 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
473 sensor::sensor_listener *listener;
475 auto it = listeners.find(handle);
476 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
478 listener = it->second;
480 if (listener->set_attribute(attribute, value, len) < 0) {
481 _E("Failed to set attribute[%d, %s]", attribute, value);
488 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
490 sensor::sensor_listener *listener;
492 auto it = listeners.find(handle);
493 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
495 listener = it->second;
497 if (listener->get_sensor_data(sensor_data) < 0) {
498 _E("Failed to get sensor data from listener");
505 API bool sensord_flush(int handle)
507 sensor::sensor_listener *listener;
509 auto it = listeners.find(handle);
510 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
512 listener = it->second;
514 if (listener->flush() < 0) {
515 _E("Failed to flush sensor");
522 API bool sensord_set_passive_mode(int handle, bool passive)
524 sensor::sensor_listener *listener;
526 auto it = listeners.find(handle);
527 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
529 listener = it->second;
531 if (listener->set_passive_mode(passive) < 0) {
532 _E("Failed to set passive mode");
539 /* Sensor Internal API using URI */
540 API int sensord_get_default_sensor_by_uri(const char *uri, sensor_t *sensor)
542 retvm_if(!sensor, -EINVAL, "Invalid parameter");
543 retvm_if(!manager.connect(), -EIO, "Failed to connect");
545 return manager.get_sensor(uri, sensor);
548 API int sensord_get_sensors_by_uri(const char *uri, sensor_t **list, int *count)
550 retvm_if((!list || !count), -EINVAL, "Invalid parameter");
551 retvm_if(!manager.connect(), -EIO, "Failed to connect");
553 return manager.get_sensors(uri, list, count);
556 API int sensord_add_sensor_added_cb(sensord_added_cb callback, void *user_data)
558 retvm_if(!callback, -EINVAL, "Invalid paramter");
559 retvm_if(!manager.connect(), -EIO, "Failed to connect");
561 manager.add_sensor_added_cb(callback, user_data);
565 API int sensord_remove_sensor_added_cb(sensord_added_cb callback)
567 retvm_if(!callback, -EINVAL, "Invalid paramter");
568 retvm_if(!manager.connect(), -EIO, "Failed to connect");
570 manager.remove_sensor_added_cb(callback);
574 API int sensord_add_sensor_removed_cb(sensord_removed_cb callback, void *user_data)
576 retvm_if(!callback, -EINVAL, "Invalid paramter");
577 retvm_if(!manager.connect(), -EIO, "Failed to connect");
579 manager.add_sensor_removed_cb(callback, user_data);
583 API int sensord_remove_sensor_removed_cb(sensord_removed_cb callback)
585 retvm_if(!callback, -EINVAL, "Invalid paramter");
586 retvm_if(!manager.connect(), -EIO, "Failed to connect");
588 manager.remove_sensor_removed_cb(callback);
592 /* Sensor provider */
593 API int sensord_create_provider(const char *uri, sensord_provider_h *provider)
595 retvm_if(!provider, -EINVAL, "Invalid paramter");
597 std::string str_uri(uri);
598 retvm_if(str_uri.find(PREDEFINED_TYPE_URI) != std::string::npos,
599 -EINVAL, "Invalid URI format[%s]", uri);
601 static std::regex uri_regex(SENSOR_URI_REGEX, std::regex::optimize);
602 retvm_if(!std::regex_match(uri, uri_regex),
603 -EINVAL, "Invalid URI format[%s]", uri);
607 p = new(std::nothrow) sensor_provider(uri);
608 retvm_if(!p, -ENOMEM, "Failed to allocate memory");
610 *provider = static_cast<sensord_provider_h>(p);
614 API int sensord_destroy_provider(sensord_provider_h provider)
616 retvm_if(!provider, -EINVAL, "Invalid paramter");
618 delete static_cast<sensor::sensor_provider *>(provider);
622 API int sensord_add_provider(sensord_provider_h provider)
624 retvm_if(!provider, -EINVAL, "Invalid paramter");
625 retvm_if(!manager.connect(), -EIO, "Failed to connect");
628 sensor_provider *p = static_cast<sensor_provider *>(provider);
631 retv_if(ret < 0, ret);
633 ret = manager.add_sensor(p);
642 API int sensord_remove_provider(sensord_provider_h provider)
644 retvm_if(!provider, -EINVAL, "Invalid paramter");
645 retvm_if(!manager.connect(), -EIO, "Failed to connect");
648 sensor_provider *p = static_cast<sensor_provider *>(provider);
650 if (!p->disconnect())
653 ret = manager.remove_sensor(p);
662 API int sensord_provider_set_name(sensord_provider_h provider, const char *name)
664 retvm_if(!provider, -EINVAL, "Invalid paramter");
666 sensor_provider *p = static_cast<sensor_provider *>(provider);
668 sensor_info *info = p->get_sensor_info();
669 info->set_model(name);
674 API int sensord_provider_set_vendor(sensord_provider_h provider, const char *vendor)
676 retvm_if(!provider, -EINVAL, "Invalid paramter");
678 sensor_provider *p = static_cast<sensor_provider *>(provider);
680 sensor_info *info = p->get_sensor_info();
681 info->set_vendor(vendor);
686 API int sensord_provider_set_range(sensord_provider_h provider, float min_range, float max_range)
688 retvm_if(!provider, -EINVAL, "Invalid paramter");
690 sensor_provider *p = static_cast<sensor_provider *>(provider);
692 sensor_info *info = p->get_sensor_info();
693 info->set_min_range(min_range);
694 info->set_max_range(max_range);
699 API int sensord_provider_set_resolution(sensord_provider_h provider, float resolution)
701 retvm_if(!provider, -EINVAL, "Invalid paramter");
703 sensor_provider *p = static_cast<sensor_provider *>(provider);
705 sensor_info *info = p->get_sensor_info();
706 info->set_resolution(resolution);
711 API int sensord_provider_set_start_cb(sensord_provider_h provider, sensord_provider_start_cb callback, void *user_data)
713 retvm_if(!provider, -EINVAL, "Invalid paramter");
714 retvm_if(!callback, -EINVAL, "Invalid paramter");
716 sensor_provider *p = static_cast<sensor_provider *>(provider);
718 p->set_start_cb(callback, user_data);
723 API int sensord_provider_set_stop_cb(sensord_provider_h provider, sensord_provider_stop_cb callback, void *user_data)
725 retvm_if(!provider, -EINVAL, "Invalid paramter");
726 retvm_if(!callback, -EINVAL, "Invalid paramter");
728 sensor_provider *p = static_cast<sensor_provider *>(provider);
730 p->set_stop_cb(callback, user_data);
735 API int sensord_provider_set_interval_changed_cb(sensord_provider_h provider, sensord_provider_interval_changed_cb callback, void *user_data)
737 retvm_if(!provider, -EINVAL, "Invalid paramter");
738 retvm_if(!callback, -EINVAL, "Invalid paramter");
740 sensor_provider *p = static_cast<sensor_provider *>(provider);
742 p->set_interval_cb(callback, user_data);
747 API int sensord_provider_publish(sensord_provider_h provider, sensor_data_t data)
749 retvm_if(!provider, -EINVAL, "Invalid paramter");
751 sensor_provider *p = static_cast<sensor_provider *>(provider);
753 /* TODO: synchronous call is enough? */
754 return p->publish(&data, sizeof(data));
758 API sensor_t sensord_get_sensor(sensor_type_t type)
762 if (sensord_get_default_sensor(type, &sensor) < 0)
769 API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
771 return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
775 API bool sensord_register_hub_event(int handle, unsigned int event_type,
776 unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
782 API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
786 * 2. if there is no sensor, return false
787 * 3. memory allocation
792 /* deprecated(BUT it is used in C-API....) */
793 API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
795 if (!manager.is_supported(sensor))
804 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
806 return (sensord_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
810 API bool sensord_send_command(int handle, const char *command, int command_len)
812 return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
816 API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
818 *privilege = SENSOR_PRIVILEGE_PUBLIC;
824 API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
828 * 2. create handle in this client
829 * 3. first connection(client)
830 * 4. cmd_connect for external sensor with key
832 retvm_if(!key, -EINVAL, "Invalid key");
837 API bool sensord_external_disconnect(int handle)
841 * 2. create handle in this client
842 * 3. first connection(client)
843 * 4. cmd_connect for external sensor with key
844 * 5. disconnect this handle
845 * 6. if there is no active sensor, remove client id and stop listener
851 API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
855 * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false