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)
35 #define MAX_LISTENER 100
37 using namespace sensor;
39 class sensor_event_handler : public ipc::channel_handler
42 sensor_event_handler(sensor_t sensor, sensor_cb_t cb, void *user_data)
43 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
45 , m_user_data(user_data)
48 void connected(ipc::channel *ch) {}
49 void disconnected(ipc::channel *ch) {}
50 void read(ipc::channel *ch, ipc::message &msg)
55 data = reinterpret_cast<sensor_data_t *>(msg.body());
56 event_type = CONVERT_TYPE_EVENT(m_sensor->get_type());
58 m_cb(m_sensor, event_type, data, m_user_data);
61 void read_complete(ipc::channel *ch) {}
62 void error_caught(ipc::channel *ch, int error) {}
65 sensor_info *m_sensor;
70 class sensor_accuracy_handler : public ipc::channel_handler
73 sensor_accuracy_handler(sensor_t sensor, sensor_accuracy_changed_cb_t cb, void *user_data)
74 : m_sensor(reinterpret_cast<sensor_info *>(sensor))
76 , m_user_data(user_data)
79 void connected(ipc::channel *ch) {}
80 void disconnected(ipc::channel *ch) {}
81 void read(ipc::channel *ch, ipc::message &msg)
84 data = reinterpret_cast<sensor_data_t *>(msg.body());
86 m_cb(m_sensor, data->timestamp, data->accuracy, m_user_data);
89 void read_complete(ipc::channel *ch) {}
90 void error_caught(ipc::channel *ch, int error) {}
93 sensor_info *m_sensor;
94 sensor_accuracy_changed_cb_t m_cb;
98 static sensor::sensor_manager manager;
99 static std::unordered_map<int, sensor::sensor_listener *> listeners;
103 * 1. power save option / lcd vconf : move to server
104 * 2. thread-safe : ipc_client
107 API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
109 return sensord_get_sensors_by_uri(utils::get_uri(type), list, count);
112 API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
114 return sensord_get_default_sensor_by_uri(utils::get_uri(type), sensor);
117 API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
119 retvm_if(!type, false, "Invalid type");
120 retvm_if(!manager.connect(), false, "Failed to connect");
121 retvm_if(!manager.is_supported(sensor), false,
122 "Invalid sensor[%p]", sensor);
124 *type = static_cast<sensor_info *>(sensor)->get_type();
129 API const char* sensord_get_uri(sensor_t sensor)
131 retvm_if(!manager.connect(), NULL, "Failed to connect");
132 retvm_if(!manager.is_supported(sensor), NULL,
133 "Invalid sensor[%p]", sensor);
135 return static_cast<sensor_info *>(sensor)->get_uri().c_str();
138 API const char* sensord_get_name(sensor_t sensor)
140 retvm_if(!manager.connect(), NULL, "Failed to connect");
141 retvm_if(!manager.is_supported(sensor), NULL,
142 "Invalid sensor[%p]", sensor);
144 return static_cast<sensor_info *>(sensor)->get_model().c_str();
147 API const char* sensord_get_vendor(sensor_t sensor)
149 retvm_if(!manager.connect(), NULL, "Failed to connect");
150 retvm_if(!manager.is_supported(sensor), NULL,
151 "Invalid sensor[%p]", sensor);
153 return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
156 API bool sensord_get_min_range(sensor_t sensor, float *min_range)
158 retvm_if(!min_range, false, "Invalid paramter");
159 retvm_if(!manager.connect(), false, "Failed to connect");
160 retvm_if(!manager.is_supported(sensor), false,
161 "Invalid sensor[%p]", sensor);
163 *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
168 API bool sensord_get_max_range(sensor_t sensor, float *max_range)
170 retvm_if(!max_range, false, "Invalid parameter");
171 retvm_if(!manager.connect(), false, "Failed to connect");
172 retvm_if(!manager.is_supported(sensor), false,
173 "Invalid sensor[%p]", sensor);
175 *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
180 API bool sensord_get_resolution(sensor_t sensor, float *resolution)
182 retvm_if(!resolution, false, "Invalid parameter");
183 retvm_if(!manager.connect(), false, "Failed to connect");
184 retvm_if(!manager.is_supported(sensor), false,
185 "Invalid sensor[%p]", sensor);
187 *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
192 API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
194 retvm_if(!min_interval, false, "Invalid parameter");
195 retvm_if(!manager.connect(), false, "Failed to connect");
196 retvm_if(!manager.is_supported(sensor), false,
197 "Invalid sensor[%p]", sensor);
199 *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
204 API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
206 retvm_if(!fifo_count, false, "Invalid parameter");
207 retvm_if(!manager.connect(), false, "Failed to connect");
208 retvm_if(!manager.is_supported(sensor), false,
209 "Invalid sensor[%p]", sensor);
216 API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
218 retvm_if(!max_batch_count, false, "Invalid parameter");
219 retvm_if(!manager.connect(), false, "Failed to connect");
220 retvm_if(!manager.is_supported(sensor), false,
221 "Invalid sensor[%p]", sensor);
223 *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
228 API bool sensord_is_wakeup_supported(sensor_t sensor)
230 retvm_if(!manager.connect(), false, "Failed to connect");
231 retvm_if(!manager.is_supported(sensor), false,
232 "Invalid sensor[%p]", sensor);
234 return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
237 API int sensord_connect(sensor_t sensor)
239 retvm_if(!manager.connect(), -EIO, "Failed to connect");
240 retvm_if(!manager.is_supported(sensor), -EINVAL,
241 "Invalid sensor[%p]", sensor);
242 retvm_if(listeners.size() > MAX_LISTENER, -EPERM, "Exceeded the maximum listener");
244 sensor::sensor_listener *listener;
246 listener = new(std::nothrow) sensor::sensor_listener(sensor);
247 retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
249 listeners[listener->get_id()] = listener;
251 return listener->get_id();
254 API bool sensord_disconnect(int handle)
256 sensor::sensor_listener *listener;
258 auto it = listeners.find(handle);
259 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
261 listener = it->second;
262 retvm_if(!listener, false, "Invalid handle[%d]", handle);
265 listeners.erase(handle);
270 API bool sensord_register_event(int handle, unsigned int event_type,
271 unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
273 sensor::sensor_listener *listener;
275 int prev_max_batch_latency;
276 sensor_event_handler *handler;
278 auto it = listeners.find(handle);
279 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
281 listener = it->second;
283 prev_interval = listener->get_interval();
284 prev_max_batch_latency = listener->get_max_batch_latency();
286 if (listener->set_interval(interval) < 0) {
287 _E("Failed to set interval");
291 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
292 listener->set_interval(prev_interval);
293 _E("Failed to set max_batch_latency");
297 handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data);
299 listener->set_max_batch_latency(prev_max_batch_latency);
300 listener->set_interval(prev_interval);
301 _E("Failed to allocate memory");
305 listener->set_event_handler(handler);
310 API bool sensord_unregister_event(int handle, unsigned int event_type)
312 sensor::sensor_listener *listener;
314 auto it = listeners.find(handle);
315 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
317 listener = it->second;
319 listener->unset_event_handler();
324 API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
326 sensor::sensor_listener *listener;
327 sensor_accuracy_handler *handler;
329 auto it = listeners.find(handle);
330 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
332 listener = it->second;
334 handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data);
335 retvm_if(!handler, false, "Failed to allocate memory");
337 listener->set_accuracy_handler(handler);
342 API bool sensord_unregister_accuracy_cb(int handle)
344 sensor::sensor_listener *listener;
346 auto it = listeners.find(handle);
347 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
349 listener = it->second;
351 listener->unset_accuracy_handler();
356 API bool sensord_start(int handle, int option)
358 sensor::sensor_listener *listener;
362 auto it = listeners.find(handle);
363 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
365 listener = it->second;
367 pause = CONVERT_OPTION_PAUSE_POLICY(option);
368 prev_pause = listener->get_pause_policy();
370 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
371 _E("Failed to set pause policy[%d]", pause);
375 if (listener->start() < 0) {
376 listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
377 _E("Failed to start listener");
384 API bool sensord_stop(int handle)
387 sensor::sensor_listener *listener;
389 auto it = listeners.find(handle);
390 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
392 listener = it->second;
394 ret = listener->stop();
396 if (ret == -EAGAIN || ret == OP_SUCCESS)
402 API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
404 sensor::sensor_listener *listener;
406 auto it = listeners.find(handle);
407 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
409 listener = it->second;
411 if (listener->set_interval(interval) < 0) {
412 _E("Failed to set interval to listener");
419 API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
421 sensor::sensor_listener *listener;
423 auto it = listeners.find(handle);
424 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
426 listener = it->second;
428 if (listener->set_max_batch_latency(max_batch_latency) < 0) {
429 _E("Failed to set max_batch_latency to listener");
436 API bool sensord_set_option(int handle, int option)
438 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 pause = CONVERT_OPTION_PAUSE_POLICY(option);
448 if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
449 _E("Failed to set option[%d(%d)] to listener", option, pause);
456 API int sensord_set_attribute_int(int handle, int attribute, int value)
458 sensor::sensor_listener *listener;
460 auto it = listeners.find(handle);
461 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
463 listener = it->second;
465 if (listener->set_attribute(attribute, value) < 0) {
466 _E("Failed to set attribute[%d, %d]", attribute, value);
473 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
475 sensor::sensor_listener *listener;
477 auto it = listeners.find(handle);
478 retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
480 listener = it->second;
482 if (listener->set_attribute(attribute, value, len) < 0) {
483 _E("Failed to set attribute[%d, %s]", attribute, value);
490 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
492 sensor::sensor_listener *listener;
494 auto it = listeners.find(handle);
495 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
497 listener = it->second;
499 if (listener->get_sensor_data(sensor_data) < 0) {
500 _E("Failed to get sensor data from listener");
507 API bool sensord_flush(int handle)
509 sensor::sensor_listener *listener;
511 auto it = listeners.find(handle);
512 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
514 listener = it->second;
516 if (listener->flush() < 0) {
517 _E("Failed to flush sensor");
524 API bool sensord_set_passive_mode(int handle, bool passive)
526 sensor::sensor_listener *listener;
528 auto it = listeners.find(handle);
529 retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
531 listener = it->second;
533 if (listener->set_passive_mode(passive) < 0) {
534 _E("Failed to set passive mode");
541 /* Sensor Internal API using URI */
542 API int sensord_get_default_sensor_by_uri(const char *uri, sensor_t *sensor)
544 retvm_if(!sensor, -EINVAL, "Invalid parameter");
545 retvm_if(!manager.connect(), -EIO, "Failed to connect");
547 return manager.get_sensor(uri, sensor);
550 API int sensord_get_sensors_by_uri(const char *uri, sensor_t **list, int *count)
552 retvm_if((!list || !count), -EINVAL, "Invalid parameter");
553 retvm_if(!manager.connect(), -EIO, "Failed to connect");
555 return manager.get_sensors(uri, list, count);
558 API int sensord_add_sensor_added_cb(sensord_added_cb callback, void *user_data)
560 retvm_if(!callback, -EINVAL, "Invalid paramter");
561 retvm_if(!manager.connect(), -EIO, "Failed to connect");
563 manager.add_sensor_added_cb(callback, user_data);
567 API int sensord_remove_sensor_added_cb(sensord_added_cb callback)
569 retvm_if(!callback, -EINVAL, "Invalid paramter");
570 retvm_if(!manager.connect(), -EIO, "Failed to connect");
572 manager.remove_sensor_added_cb(callback);
576 API int sensord_add_sensor_removed_cb(sensord_removed_cb callback, void *user_data)
578 retvm_if(!callback, -EINVAL, "Invalid paramter");
579 retvm_if(!manager.connect(), -EIO, "Failed to connect");
581 manager.add_sensor_removed_cb(callback, user_data);
585 API int sensord_remove_sensor_removed_cb(sensord_removed_cb callback)
587 retvm_if(!callback, -EINVAL, "Invalid paramter");
588 retvm_if(!manager.connect(), -EIO, "Failed to connect");
590 manager.remove_sensor_removed_cb(callback);
594 /* Sensor provider */
595 API int sensord_create_provider(const char *uri, sensord_provider_h *provider)
597 retvm_if(!provider, -EINVAL, "Invalid paramter");
599 std::string str_uri(uri);
600 retvm_if(str_uri.find(PREDEFINED_TYPE_URI) != std::string::npos,
601 -EINVAL, "Invalid URI format[%s]", uri);
603 static std::regex uri_regex(SENSOR_URI_REGEX, std::regex::optimize);
604 retvm_if(!std::regex_match(uri, uri_regex),
605 -EINVAL, "Invalid URI format[%s]", uri);
609 p = new(std::nothrow) sensor_provider(uri);
610 retvm_if(!p, -ENOMEM, "Failed to allocate memory");
612 *provider = static_cast<sensord_provider_h>(p);
616 API int sensord_destroy_provider(sensord_provider_h provider)
618 retvm_if(!provider, -EINVAL, "Invalid paramter");
620 delete static_cast<sensor::sensor_provider *>(provider);
624 API int sensord_add_provider(sensord_provider_h provider)
626 retvm_if(!provider, -EINVAL, "Invalid paramter");
627 retvm_if(!manager.connect(), -EIO, "Failed to connect");
630 sensor_provider *p = static_cast<sensor_provider *>(provider);
633 retv_if(ret < 0, ret);
635 ret = manager.add_sensor(p);
644 API int sensord_remove_provider(sensord_provider_h provider)
646 retvm_if(!provider, -EINVAL, "Invalid paramter");
647 retvm_if(!manager.connect(), -EIO, "Failed to connect");
650 sensor_provider *p = static_cast<sensor_provider *>(provider);
652 if (!p->disconnect())
655 ret = manager.remove_sensor(p);
664 API int sensord_provider_set_name(sensord_provider_h provider, const char *name)
666 retvm_if(!provider, -EINVAL, "Invalid paramter");
668 sensor_provider *p = static_cast<sensor_provider *>(provider);
670 sensor_info *info = p->get_sensor_info();
671 info->set_model(name);
676 API int sensord_provider_set_vendor(sensord_provider_h provider, const char *vendor)
678 retvm_if(!provider, -EINVAL, "Invalid paramter");
680 sensor_provider *p = static_cast<sensor_provider *>(provider);
682 sensor_info *info = p->get_sensor_info();
683 info->set_vendor(vendor);
688 API int sensord_provider_set_range(sensord_provider_h provider, float min_range, float max_range)
690 retvm_if(!provider, -EINVAL, "Invalid paramter");
692 sensor_provider *p = static_cast<sensor_provider *>(provider);
694 sensor_info *info = p->get_sensor_info();
695 info->set_min_range(min_range);
696 info->set_max_range(max_range);
701 API int sensord_provider_set_resolution(sensord_provider_h provider, float resolution)
703 retvm_if(!provider, -EINVAL, "Invalid paramter");
705 sensor_provider *p = static_cast<sensor_provider *>(provider);
707 sensor_info *info = p->get_sensor_info();
708 info->set_resolution(resolution);
713 API int sensord_provider_set_start_cb(sensord_provider_h provider, sensord_provider_start_cb callback, void *user_data)
715 retvm_if(!provider, -EINVAL, "Invalid paramter");
716 retvm_if(!callback, -EINVAL, "Invalid paramter");
718 sensor_provider *p = static_cast<sensor_provider *>(provider);
720 p->set_start_cb(callback, user_data);
725 API int sensord_provider_set_stop_cb(sensord_provider_h provider, sensord_provider_stop_cb callback, void *user_data)
727 retvm_if(!provider, -EINVAL, "Invalid paramter");
728 retvm_if(!callback, -EINVAL, "Invalid paramter");
730 sensor_provider *p = static_cast<sensor_provider *>(provider);
732 p->set_stop_cb(callback, user_data);
737 API int sensord_provider_set_interval_changed_cb(sensord_provider_h provider, sensord_provider_interval_changed_cb callback, void *user_data)
739 retvm_if(!provider, -EINVAL, "Invalid paramter");
740 retvm_if(!callback, -EINVAL, "Invalid paramter");
742 sensor_provider *p = static_cast<sensor_provider *>(provider);
744 p->set_interval_cb(callback, user_data);
749 API int sensord_provider_publish(sensord_provider_h provider, sensor_data_t data)
751 retvm_if(!provider, -EINVAL, "Invalid paramter");
753 sensor_provider *p = static_cast<sensor_provider *>(provider);
755 /* TODO: synchronous call is enough? */
756 return p->publish(&data, sizeof(data));
760 API sensor_t sensord_get_sensor(sensor_type_t type)
764 if (sensord_get_default_sensor(type, &sensor) < 0)
771 API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
773 return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
777 API bool sensord_register_hub_event(int handle, unsigned int event_type,
778 unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
784 API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
788 * 2. if there is no sensor, return false
789 * 3. memory allocation
794 /* deprecated(BUT it is used in C-API....) */
795 API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
797 if (!manager.is_supported(sensor))
806 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
808 return (sensord_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
812 API bool sensord_send_command(int handle, const char *command, int command_len)
814 return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
818 API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
820 *privilege = SENSOR_PRIVILEGE_PUBLIC;
826 API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
830 * 2. create handle in this client
831 * 3. first connection(client)
832 * 4. cmd_connect for external sensor with key
834 retvm_if(!key, -EINVAL, "Invalid key");
839 API bool sensord_external_disconnect(int handle)
843 * 2. create handle in this client
844 * 3. first connection(client)
845 * 4. cmd_connect for external sensor with key
846 * 5. disconnect this handle
847 * 6. if there is no active sensor, remove client id and stop listener
853 API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
857 * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false