Add sensor handle attribute
[platform/core/system/sensord.git] / src / client / sensor_internal.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
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>
25
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>
32 #include <regex>
33 #include <thread>
34 #include <cmutex.h>
35 #include <command_types.h>
36
37 #include "sensor_reader.h"
38
39 #define CONVERT_OPTION_TO_PAUSE_POLICY(option) ((option) ^ 0b11)
40 #define MAX_LISTENER 100
41 #define MAX_PROVIDER 20
42
43 using namespace sensor;
44
45 typedef struct {
46         int listener_id;
47         sensor_info *sensor;
48         void* cb;
49         char* data;
50         size_t data_size;
51         void *user_data;
52 } callback_info_s;
53
54 typedef GSourceFunc callback_dispatcher_t;
55
56 static sensor::sensor_manager manager;
57 static std::unordered_map<int, sensor::sensor_listener *> listeners;
58 static cmutex lock;
59 static uint providerCnt = 0;
60
61 static gboolean sensor_events_callback_dispatcher(gpointer data)
62 {
63         int event_type = 0;
64         callback_info_s *info = (callback_info_s *)data;
65
66         AUTOLOCK(lock);
67
68         if (info->sensor)
69                 event_type = CONVERT_TYPE_EVENT(info->sensor->get_type());
70
71         if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
72                 size_t element_size =  sizeof(sensor_data_t);
73                 size_t count = info->data_size / element_size;
74                 ((sensor_events_cb_t)info->cb)(info->sensor, event_type, (sensor_data_t*)info->data, count, info->user_data);
75         }
76
77         delete [] info->data;
78         delete info;
79         return FALSE;
80 }
81
82 static gboolean sensor_event_callback_dispatcher(gpointer data)
83 {
84         int event_type = 0;
85         callback_info_s *info = (callback_info_s *)data;
86
87         AUTOLOCK(lock);
88
89         if (info->sensor)
90                 event_type = CONVERT_TYPE_EVENT(info->sensor->get_type());
91
92         if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
93                 ((sensor_cb_t)info->cb)(info->sensor, event_type, (sensor_data_t*)info->data, info->user_data);
94         }
95
96         delete [] info->data;
97         delete info;
98         return FALSE;
99 }
100
101 static gboolean sensor_accuracy_changed_callback_dispatcher(gpointer data)
102 {
103         callback_info_s *info = (callback_info_s *)data;
104
105         AUTOLOCK(lock);
106
107         if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
108                 sensor_data_t * sensor_data = (sensor_data_t *)info->data;
109                 ((sensor_accuracy_changed_cb_t)info->cb)(info->sensor, sensor_data->timestamp, sensor_data->accuracy, info->user_data);
110         }
111
112         delete [] info->data;
113         delete info;
114         return FALSE;
115 }
116
117 static gboolean sensor_attribute_int_changed_callback_dispatcher(gpointer data)
118 {
119         callback_info_s *info = (callback_info_s *)data;
120
121         AUTOLOCK(lock);
122
123         if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
124                 cmd_listener_attr_int_t *d = (cmd_listener_attr_int_t *)info->data;
125                 ((sensor_attribute_int_changed_cb_t)info->cb)(info->sensor, d->attribute, d->value, info->user_data);
126         }
127
128         delete [] info->data;
129         delete info;
130         return FALSE;
131 }
132
133 static gboolean sensor_attribute_str_changed_callback_dispatcher(gpointer data)
134 {
135         callback_info_s *info = (callback_info_s *)data;
136
137         AUTOLOCK(lock);
138
139         if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) {
140                 cmd_listener_attr_str_t *d = (cmd_listener_attr_str_t *)info->data;
141                 ((sensor_attribute_str_changed_cb_t)info->cb)(info->sensor, d->attribute, d->value, d->len, info->user_data);
142         }
143
144         delete [] info->data;
145         delete info;
146         return FALSE;
147 }
148
149 class sensor_listener_channel_handler : public ipc::channel_handler
150 {
151 public:
152         sensor_listener_channel_handler(int id, sensor_t sensor, void* cb, void *user_data, callback_dispatcher_t dispatcher)
153         : m_listener_id(id)
154         , m_sensor(reinterpret_cast<sensor_info *>(sensor))
155         , m_cb(cb)
156         , m_user_data(user_data)
157         , m_dispatcher(dispatcher)
158         {}
159
160         void connected(ipc::channel *ch) {}
161         void disconnected(ipc::channel *ch) {}
162         void read(ipc::channel *ch, ipc::message &msg)
163         {
164                 callback_info_s *info;
165                 auto size = msg.size();
166                 char *data = new(std::nothrow) char[size];
167                 if (data == NULL)
168                         return;
169                 memcpy(data, msg.body(), size);
170
171                 info = new(std::nothrow) callback_info_s();
172                 info->listener_id = m_listener_id;
173                 info->cb = m_cb;
174                 info->sensor = m_sensor;
175                 info->data = data;
176                 info->data_size = size;
177                 info->user_data = m_user_data;
178
179                 g_idle_add(m_dispatcher, info);
180         }
181
182         void read_complete(ipc::channel *ch) {}
183         void error_caught(ipc::channel *ch, int error) {}
184         void set_handler(int num, ipc::channel_handler* handler) {}
185         void disconnect(void) {}
186
187 private:
188         int m_listener_id;
189         sensor_info *m_sensor;
190         void* m_cb;
191         void *m_user_data;
192         callback_dispatcher_t m_dispatcher;
193 };
194
195 /*
196  * TO-DO-LIST:
197  * 1. power save option / lcd vconf : move to server
198  * 2. thread-safe : ipc_client
199  */
200
201 API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
202 {
203         return sensord_get_sensors_by_uri(utils::get_uri(type), list, count);
204 }
205
206 API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
207 {
208         return sensord_get_default_sensor_by_uri(utils::get_uri(type), sensor);
209 }
210
211 API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
212 {
213         retvm_if(!type, false, "Invalid type");
214         retvm_if(!manager.connect(), false, "Failed to connect");
215         retvm_if(!manager.is_supported(sensor), false,
216                         "Invalid sensor[%p]", sensor);
217
218         *type = static_cast<sensor_info *>(sensor)->get_type();
219
220         return true;
221 }
222
223 API const char* sensord_get_uri(sensor_t sensor)
224 {
225         retvm_if(!manager.connect(), NULL, "Failed to connect");
226         retvm_if(!manager.is_supported(sensor), NULL,
227                         "Invalid sensor[%p]", sensor);
228
229         return static_cast<sensor_info *>(sensor)->get_uri().c_str();
230 }
231
232 API const char* sensord_get_name(sensor_t sensor)
233 {
234         retvm_if(!manager.connect(), NULL, "Failed to connect");
235         retvm_if(!manager.is_supported(sensor), NULL,
236                         "Invalid sensor[%p]", sensor);
237
238         return static_cast<sensor_info *>(sensor)->get_model().c_str();
239 }
240
241 API const char* sensord_get_vendor(sensor_t sensor)
242 {
243         retvm_if(!manager.connect(), NULL, "Failed to connect");
244         retvm_if(!manager.is_supported(sensor), NULL,
245                         "Invalid sensor[%p]", sensor);
246
247         return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
248 }
249
250 API bool sensord_get_min_range(sensor_t sensor, float *min_range)
251 {
252         retvm_if(!min_range, false, "Invalid paramter");
253         retvm_if(!manager.connect(), false, "Failed to connect");
254         retvm_if(!manager.is_supported(sensor), false,
255                         "Invalid sensor[%p]", sensor);
256
257         *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
258
259         return true;
260 }
261
262 API bool sensord_get_max_range(sensor_t sensor, float *max_range)
263 {
264         retvm_if(!max_range, false, "Invalid parameter");
265         retvm_if(!manager.connect(), false, "Failed to connect");
266         retvm_if(!manager.is_supported(sensor), false,
267                         "Invalid sensor[%p]", sensor);
268
269         *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
270
271         return true;
272 }
273
274 API bool sensord_get_resolution(sensor_t sensor, float *resolution)
275 {
276         retvm_if(!resolution, false, "Invalid parameter");
277         retvm_if(!manager.connect(), false, "Failed to connect");
278         retvm_if(!manager.is_supported(sensor), false,
279                         "Invalid sensor[%p]", sensor);
280
281         *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
282
283         return true;
284 }
285
286 API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
287 {
288         retvm_if(!min_interval, false, "Invalid parameter");
289         retvm_if(!manager.connect(), false, "Failed to connect");
290         retvm_if(!manager.is_supported(sensor), false,
291                         "Invalid sensor[%p]", sensor);
292
293         *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
294
295         return true;
296 }
297
298 API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
299 {
300         retvm_if(!fifo_count, false, "Invalid parameter");
301         retvm_if(!manager.connect(), false, "Failed to connect");
302         retvm_if(!manager.is_supported(sensor), false,
303                         "Invalid sensor[%p]", sensor);
304
305         *fifo_count = 0;
306
307         return true;
308 }
309
310 API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
311 {
312         retvm_if(!max_batch_count, false, "Invalid parameter");
313         retvm_if(!manager.connect(), false, "Failed to connect");
314         retvm_if(!manager.is_supported(sensor), false,
315                         "Invalid sensor[%p]", sensor);
316
317         *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
318
319         return true;
320 }
321
322 API bool sensord_is_wakeup_supported(sensor_t sensor)
323 {
324         retvm_if(!manager.connect(), false, "Failed to connect");
325         retvm_if(!manager.is_supported(sensor), false,
326                         "Invalid sensor[%p]", sensor);
327
328         return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
329 }
330
331 API int sensord_connect(sensor_t sensor)
332 {
333         AUTOLOCK(lock);
334
335         retvm_if(!manager.connect(), -EIO, "Failed to connect");
336         retvm_if(!manager.is_supported(sensor), -EINVAL,
337                         "Invalid sensor[%p]", sensor);
338         retvm_if(listeners.size() > MAX_LISTENER, -EPERM, "Exceeded the maximum listener");
339
340         sensor::sensor_listener *listener;
341         static sensor_reader reader;
342
343         listener = new(std::nothrow) sensor::sensor_listener(sensor, reader.get_event_loop());
344         retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
345
346         listeners[listener->get_id()] = listener;
347
348         _D("Connect[%d]", listener->get_id());
349
350         return listener->get_id();
351 }
352
353 API bool sensord_disconnect(int handle)
354 {
355         sensor::sensor_listener *listener;
356
357         AUTOLOCK(lock);
358
359         auto it = listeners.find(handle);
360         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
361
362         listener = it->second;
363         retvm_if(!listener, false, "Invalid handle[%d]", handle);
364
365         _D("Disconnect[%d]", listener->get_id());
366
367         delete listener;
368         listeners.erase(handle);
369
370         if (listeners.empty())
371                 manager.disconnect();
372
373         return true;
374 }
375
376 static inline bool sensord_register_event_impl(int handle, unsigned int event_type,
377                 unsigned int interval, unsigned int max_batch_latency, void* cb, bool is_events_callback, void *user_data)
378 {
379         sensor::sensor_listener *listener;
380         int prev_interval;
381         int prev_max_batch_latency;
382         sensor_listener_channel_handler *handler;
383
384         AUTOLOCK(lock);
385
386         auto it = listeners.find(handle);
387         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
388
389         listener = it->second;
390
391         prev_interval = listener->get_interval();
392         prev_max_batch_latency = listener->get_max_batch_latency();
393
394         if (listener->set_interval(interval) < 0) {
395                 _E("Failed to set interval");
396                 return false;
397         }
398
399         if (listener->set_max_batch_latency(max_batch_latency) < 0) {
400                 listener->set_interval(prev_interval);
401                 _E("Failed to set max_batch_latency");
402                 return false;
403         }
404
405         if (is_events_callback) {
406                 handler = new(std::nothrow)sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_events_callback_dispatcher);
407         } else {
408                 handler = new(std::nothrow)sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_event_callback_dispatcher);
409         }
410
411         if (!handler) {
412                 listener->set_max_batch_latency(prev_max_batch_latency);
413                 listener->set_interval(prev_interval);
414                 _E("Failed to allocate memory");
415                 return false;
416         }
417
418         listener->set_event_handler(handler);
419
420         _D("Register event[%d]", listener->get_id());
421
422         return true;
423 }
424
425 API bool sensord_register_event(int handle, unsigned int event_type,
426                 unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
427 {
428         return sensord_register_event_impl(handle, event_type, interval, max_batch_latency, (void*)cb, false, user_data);
429 }
430
431 static inline bool sensord_unregister_event_imple(int handle)
432 {
433         sensor::sensor_listener *listener;
434
435         AUTOLOCK(lock);
436
437         auto it = listeners.find(handle);
438         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
439
440         listener = it->second;
441
442         listener->unset_event_handler();
443
444         _D("Unregister event[%d]", listener->get_id());
445
446         return true;
447 }
448
449 API bool sensord_unregister_event(int handle, unsigned int event_type)
450 {
451         return sensord_unregister_event_imple(handle);
452 }
453
454 API bool sensord_register_events(int handle, unsigned int event_type, unsigned int max_batch_latency, sensor_events_cb_t cb, void *user_data)
455 {
456         return sensord_register_event_impl(handle, event_type, 0, max_batch_latency, (void*)cb, true, user_data);
457 }
458
459 API bool sensord_unregister_events(int handle, unsigned int event_type)
460 {
461         return sensord_unregister_event_imple(handle);
462 }
463
464 API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
465 {
466         sensor::sensor_listener *listener;
467         sensor_listener_channel_handler *handler;
468
469         AUTOLOCK(lock);
470
471         auto it = listeners.find(handle);
472         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
473
474         listener = it->second;
475
476         handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_accuracy_changed_callback_dispatcher);
477         retvm_if(!handler, false, "Failed to allocate memory");
478
479         listener->set_accuracy_handler(handler);
480
481         return true;
482 }
483
484 API bool sensord_unregister_accuracy_cb(int handle)
485 {
486         sensor::sensor_listener *listener;
487
488         AUTOLOCK(lock);
489
490         auto it = listeners.find(handle);
491         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
492
493         listener = it->second;
494
495         listener->unset_accuracy_handler();
496
497         return true;
498 }
499
500 API bool sensord_register_attribute_int_changed_cb(int handle, sensor_attribute_int_changed_cb_t cb, void *user_data)
501 {
502         sensor::sensor_listener *listener;
503         sensor_listener_channel_handler *handler;
504
505         AUTOLOCK(lock);
506
507         auto it = listeners.find(handle);
508         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
509
510         listener = it->second;
511
512         handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_attribute_int_changed_callback_dispatcher);
513         retvm_if(!handler, false, "Failed to allocate memory");
514
515         listener->set_attribute_int_changed_handler(handler);
516
517         return true;
518 }
519
520 API bool sensord_unregister_attribute_int_changed_cb(int handle)
521 {
522         sensor::sensor_listener *listener;
523
524         AUTOLOCK(lock);
525
526         auto it = listeners.find(handle);
527         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
528
529         listener = it->second;
530
531         listener->unset_attribute_int_changed_handler();
532
533         return true;
534 }
535
536 API bool sensord_register_attribute_str_changed_cb(int handle, sensor_attribute_str_changed_cb_t cb, void *user_data)
537 {
538         sensor::sensor_listener *listener;
539         sensor_listener_channel_handler *handler;
540
541         AUTOLOCK(lock);
542
543         auto it = listeners.find(handle);
544         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
545
546         listener = it->second;
547
548         handler = new(std::nothrow) sensor_listener_channel_handler(handle, listener->get_sensor(), (void *)cb, user_data, sensor_attribute_str_changed_callback_dispatcher);
549         retvm_if(!handler, false, "Failed to allocate memory");
550
551         listener->set_attribute_str_changed_handler(handler);
552
553         return true;
554 }
555
556 API bool sensord_unregister_attribute_str_changed_cb(int handle)
557 {
558         sensor::sensor_listener *listener;
559
560         AUTOLOCK(lock);
561
562         auto it = listeners.find(handle);
563         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
564
565         listener = it->second;
566
567         listener->unset_attribute_str_changed_handler();
568
569         return true;
570 }
571
572 API bool sensord_start(int handle, int option)
573 {
574         sensor::sensor_listener *listener;
575         int prev_pause;
576         int pause;
577         int interval, batch_latency;
578
579         AUTOLOCK(lock);
580
581         auto it = listeners.find(handle);
582         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
583
584         listener = it->second;
585
586         pause = CONVERT_OPTION_TO_PAUSE_POLICY(option);
587         prev_pause = listener->get_pause_policy();
588
589         if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
590                 _E("Failed to set pause policy[%d]", pause);
591                 return false;
592         }
593
594         if (listener->start() < 0) {
595                 listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
596                 _E("Failed to start listener");
597                 return false;
598         }
599
600         interval = listener->get_interval();
601         if (interval > 0)
602                 listener->set_interval(interval);
603
604         batch_latency = listener->get_max_batch_latency();
605         if (batch_latency != SENSOR_BATCH_LATENCY_DEFAULT)
606                 listener->set_max_batch_latency(batch_latency);
607
608         _D("Start[%d] with the interval[%d] batch_latency[%d]",
609                 listener->get_id(), interval, batch_latency);
610
611         return true;
612 }
613
614 API bool sensord_stop(int handle)
615 {
616         int ret;
617         sensor::sensor_listener *listener;
618
619         AUTOLOCK(lock);
620
621         auto it = listeners.find(handle);
622         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
623
624         listener = it->second;
625
626         ret = listener->stop();
627
628         if (ret == -EAGAIN || ret == OP_SUCCESS)
629                 return true;
630
631         _D("Stop[%d]", listener->get_id());
632
633         return false;
634 }
635
636 API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
637 {
638         sensor::sensor_listener *listener;
639
640         AUTOLOCK(lock);
641
642         auto it = listeners.find(handle);
643         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
644
645         listener = it->second;
646
647         if (listener->set_interval(interval) < 0) {
648                 _E("Failed to set interval to listener");
649                 return false;
650         }
651
652         _D("Set interval[%d, %d]", listener->get_id(), interval);
653
654         return true;
655 }
656
657 API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
658 {
659         sensor::sensor_listener *listener;
660
661         AUTOLOCK(lock);
662
663         auto it = listeners.find(handle);
664         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
665
666         listener = it->second;
667
668         if (listener->set_max_batch_latency(max_batch_latency) < 0) {
669                 _E("Failed to set max_batch_latency to listener");
670                 return false;
671         }
672
673         _D("Set max batch latency[%d, %u]", listener->get_id(), max_batch_latency);
674
675         return true;
676 }
677
678 API bool sensord_set_option(int handle, int option)
679 {
680         sensor::sensor_listener *listener;
681         int pause;
682
683         AUTOLOCK(lock);
684
685         auto it = listeners.find(handle);
686         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
687
688         listener = it->second;
689
690         pause = CONVERT_OPTION_TO_PAUSE_POLICY(option);
691
692         if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
693                 _E("Failed to set option[%d(%d)] to listener", option, pause);
694                 return false;
695         }
696
697         _D("Set pause option[%d, %d]", listener->get_id(), pause);
698
699         return true;
700 }
701
702 API int sensord_listener_set_attribute_int(int handle, int attribute, int value)
703 {
704         sensor::sensor_listener *listener;
705
706         auto it = listeners.find(handle);
707         retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
708
709         listener = it->second;
710
711         if (listener->set_attribute(attribute, value) < 0) {
712                 _E("Failed to set attribute[%d, %d]", attribute, value);
713                 return -EIO;
714         }
715
716         _D("Set attribute[%d, %d, %d]", listener->get_id(), attribute, value);
717
718         return OP_SUCCESS;
719 }
720
721 API int sensord_listener_get_attribute_int(int handle, int attribute, int* value)
722 {
723         sensor::sensor_listener *listener;
724
725         auto it = listeners.find(handle);
726         retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
727
728         listener = it->second;
729
730         if (listener->get_attribute(attribute, value) < 0) {
731                 _E("Failed to get attribute[%d]", attribute);
732                 return -EIO;
733         }
734
735         _D("Get attribute[%d, %d, %d]", listener->get_id(), attribute, *value);
736
737         return OP_SUCCESS;
738 }
739
740 API int sensord_listener_set_attribute_str(int handle, int attribute, const char *value, int len)
741 {
742         sensor::sensor_listener *listener;
743
744         auto it = listeners.find(handle);
745         retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
746
747         listener = it->second;
748
749         if (listener->set_attribute(attribute, value, len) < 0) {
750                 _E("Failed to set attribute[%d, %s]", attribute, value);
751                 return -EIO;
752         }
753         _D("Set attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, len);
754
755         return OP_SUCCESS;
756 }
757
758 API int sensord_listener_get_attribute_str(int handle, int attribute, char **value, int* len)
759 {
760         sensor::sensor_listener *listener;
761
762         auto it = listeners.find(handle);
763         retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
764
765         listener = it->second;
766
767         if (listener->get_attribute(attribute, value, len) < 0) {
768                 _E("Failed to get attribute[%d]", attribute);
769                 return -EIO;
770         }
771         _D("Get attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, *len);
772
773         return OP_SUCCESS;
774 }
775
776 API int sensord_set_attribute_int(sensor_t sensor, int attribute, int value)
777 {
778         if (!sensor) {
779                 _E("Failed to validate the parameter");
780                 return -EINVAL;
781         }
782
783         int ret = manager.set_attribute(sensor, attribute, value);
784         if (ret < 0) {
785                 _E("Failed to set attribute[%d, %d]", attribute, value);
786                 return ret;
787         }
788
789         _D("Set attribute[%s, %d, %d]",
790                 ((sensor_info *)(sensor))->get_uri().c_str(), attribute, value);
791
792         return OP_SUCCESS;
793 }
794
795 API int sensord_get_attribute_int(sensor_t sensor, int attribute, int* value)
796 {
797         if (!sensor || !value) {
798                 _E("Failed to validate the parameter");
799                 return -EINVAL;
800         }
801
802         int ret = manager.get_attribute(sensor, attribute, value);
803         if (ret < 0) {
804                 _E("Failed to get attribute[%d]", attribute);
805                 return ret;
806         }
807
808         _D("Get attribute[%s, %d, %d]",
809                 ((sensor_info *)(sensor))->get_uri().c_str(), attribute, *value);
810
811         return OP_SUCCESS;
812 }
813
814 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
815 {
816         sensor::sensor_listener *listener;
817
818         AUTOLOCK(lock);
819
820         auto it = listeners.find(handle);
821         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
822
823         listener = it->second;
824
825         if (listener->get_sensor_data(sensor_data) < 0) {
826                 _E("Failed to get sensor data from listener");
827                 return false;
828         }
829
830         return true;
831 }
832
833 API bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count)
834 {
835         sensor::sensor_listener *listener;
836
837         AUTOLOCK(lock);
838
839         auto it = listeners.find(handle);
840         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
841
842         listener = it->second;
843
844         if (listener->get_sensor_data_list(sensor_data, count) < 0) {
845                 _E("Failed to get sensor data from listener");
846                 return false;
847         }
848
849         return true;
850 }
851
852 API bool sensord_flush(int handle)
853 {
854         sensor::sensor_listener *listener;
855
856         AUTOLOCK(lock);
857
858         auto it = listeners.find(handle);
859         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
860
861         listener = it->second;
862
863         if (listener->flush() < 0) {
864                 _E("Failed to flush sensor");
865                 return false;
866         }
867
868         return true;
869 }
870
871 API bool sensord_set_passive_mode(int handle, bool passive)
872 {
873         sensor::sensor_listener *listener;
874
875         AUTOLOCK(lock);
876
877         auto it = listeners.find(handle);
878         retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
879
880         listener = it->second;
881
882         if (listener->set_passive_mode(passive) < 0) {
883                 _E("Failed to set passive mode");
884                 return false;
885         }
886
887         return true;
888 }
889
890 /* Sensor Internal API using URI */
891 API int sensord_get_default_sensor_by_uri(const char *uri, sensor_t *sensor)
892 {
893         retvm_if(!sensor, -EINVAL, "Invalid parameter");
894         retvm_if(!manager.connect(), -EIO, "Failed to connect");
895
896         return manager.get_sensor(uri, sensor);
897 }
898
899 API int sensord_get_sensors_by_uri(const char *uri, sensor_t **list, int *count)
900 {
901         retvm_if((!list || !count), -EINVAL, "Invalid parameter");
902         retvm_if(!manager.connect(), -EIO, "Failed to connect");
903
904         return manager.get_sensors(uri, list, count);
905 }
906
907 API int sensord_add_sensor_added_cb(sensord_added_cb callback, void *user_data)
908 {
909         retvm_if(!callback, -EINVAL, "Invalid paramter");
910         retvm_if(!manager.connect(), -EIO, "Failed to connect");
911
912         manager.add_sensor_added_cb(callback, user_data);
913         return OP_SUCCESS;
914 }
915
916 API int sensord_remove_sensor_added_cb(sensord_added_cb callback)
917 {
918         retvm_if(!callback, -EINVAL, "Invalid paramter");
919         retvm_if(!manager.connect(), -EIO, "Failed to connect");
920
921         manager.remove_sensor_added_cb(callback);
922         return OP_SUCCESS;
923 }
924
925 API int sensord_add_sensor_removed_cb(sensord_removed_cb callback, void *user_data)
926 {
927         retvm_if(!callback, -EINVAL, "Invalid paramter");
928         retvm_if(!manager.connect(), -EIO, "Failed to connect");
929
930         manager.add_sensor_removed_cb(callback, user_data);
931         return OP_SUCCESS;
932 }
933
934 API int sensord_remove_sensor_removed_cb(sensord_removed_cb callback)
935 {
936         retvm_if(!callback, -EINVAL, "Invalid paramter");
937         retvm_if(!manager.connect(), -EIO, "Failed to connect");
938
939         manager.remove_sensor_removed_cb(callback);
940         return OP_SUCCESS;
941 }
942
943 /* Sensor provider */
944 API int sensord_create_provider(const char *uri, sensord_provider_h *provider)
945 {
946         retvm_if(providerCnt >= MAX_PROVIDER, -EPERM, "Exceeded the maximum provider");
947         retvm_if(!provider, -EINVAL, "Invalid paramter");
948
949         std::string str_uri(uri);
950         retvm_if(str_uri.find(PREDEFINED_TYPE_URI) != std::string::npos,
951                         -EINVAL, "Invalid URI format[%s]", uri);
952
953         static std::regex uri_regex(SENSOR_URI_REGEX, std::regex::optimize);
954         retvm_if(!std::regex_match(uri, uri_regex),
955                         -EINVAL, "Invalid URI format[%s]", uri);
956
957         sensor_provider *p;
958
959         p = new(std::nothrow) sensor_provider(uri);
960         retvm_if(!p, -ENOMEM, "Failed to allocate memory");
961
962         *provider = static_cast<sensord_provider_h>(p);
963         providerCnt++;
964         return OP_SUCCESS;
965 }
966
967 API int sensord_destroy_provider(sensord_provider_h provider)
968 {
969         retvm_if(!provider, -EINVAL, "Invalid paramter");
970
971         delete static_cast<sensor::sensor_provider *>(provider);
972         providerCnt--;
973         return OP_SUCCESS;
974 }
975
976 API int sensord_add_provider(sensord_provider_h provider)
977 {
978         retvm_if(!provider, -EINVAL, "Invalid paramter");
979         retvm_if(!manager.connect(), -EIO, "Failed to connect");
980
981         int ret;
982         sensor_provider *p = static_cast<sensor_provider *>(provider);
983
984         ret = p->connect();
985         retv_if(ret < 0, ret);
986
987         ret = manager.add_sensor(p);
988         if (ret < 0) {
989                 p->disconnect();
990                 return ret;
991         }
992
993         return OP_SUCCESS;
994 }
995
996 API int sensord_remove_provider(sensord_provider_h provider)
997 {
998         retvm_if(!provider, -EINVAL, "Invalid paramter");
999         retvm_if(!manager.connect(), -EIO, "Failed to connect");
1000
1001         int ret;
1002         sensor_provider *p = static_cast<sensor_provider *>(provider);
1003
1004         if (!p->disconnect())
1005                 return OP_ERROR;
1006
1007         ret = manager.remove_sensor(p);
1008         if (ret < 0) {
1009                 p->connect();
1010                 return OP_ERROR;
1011         }
1012
1013         return OP_SUCCESS;
1014 }
1015
1016 API int sensord_provider_set_name(sensord_provider_h provider, const char *name)
1017 {
1018         retvm_if(!provider, -EINVAL, "Invalid paramter");
1019
1020         sensor_provider *p = static_cast<sensor_provider *>(provider);
1021
1022         sensor_info *info = p->get_sensor_info();
1023         info->set_model(name);
1024
1025         return OP_SUCCESS;
1026 }
1027
1028 API int sensord_provider_set_vendor(sensord_provider_h provider, const char *vendor)
1029 {
1030         retvm_if(!provider, -EINVAL, "Invalid paramter");
1031
1032         sensor_provider *p = static_cast<sensor_provider *>(provider);
1033
1034         sensor_info *info = p->get_sensor_info();
1035         info->set_vendor(vendor);
1036
1037         return OP_SUCCESS;
1038 }
1039
1040 API int sensord_provider_set_range(sensord_provider_h provider, float min_range, float max_range)
1041 {
1042         retvm_if(!provider, -EINVAL, "Invalid paramter");
1043
1044         sensor_provider *p = static_cast<sensor_provider *>(provider);
1045
1046         sensor_info *info = p->get_sensor_info();
1047         info->set_min_range(min_range);
1048         info->set_max_range(max_range);
1049
1050         return OP_SUCCESS;
1051 }
1052
1053 API int sensord_provider_set_resolution(sensord_provider_h provider, float resolution)
1054 {
1055         retvm_if(!provider, -EINVAL, "Invalid paramter");
1056
1057         sensor_provider *p = static_cast<sensor_provider *>(provider);
1058
1059         sensor_info *info = p->get_sensor_info();
1060         info->set_resolution(resolution);
1061
1062         return OP_SUCCESS;
1063 }
1064
1065 API int sensord_provider_set_start_cb(sensord_provider_h provider, sensord_provider_start_cb callback, void *user_data)
1066 {
1067         retvm_if(!provider, -EINVAL, "Invalid paramter");
1068         retvm_if(!callback, -EINVAL, "Invalid paramter");
1069
1070         sensor_provider *p = static_cast<sensor_provider *>(provider);
1071
1072         p->set_start_cb(callback, user_data);
1073
1074         return OP_SUCCESS;
1075 }
1076
1077 API int sensord_provider_set_stop_cb(sensord_provider_h provider, sensord_provider_stop_cb callback, void *user_data)
1078 {
1079         retvm_if(!provider, -EINVAL, "Invalid paramter");
1080         retvm_if(!callback, -EINVAL, "Invalid paramter");
1081
1082         sensor_provider *p = static_cast<sensor_provider *>(provider);
1083
1084         p->set_stop_cb(callback, user_data);
1085
1086         return OP_SUCCESS;
1087 }
1088
1089 API int sensord_provider_set_interval_changed_cb(sensord_provider_h provider, sensord_provider_interval_changed_cb callback, void *user_data)
1090 {
1091         retvm_if(!provider, -EINVAL, "Invalid paramter");
1092         retvm_if(!callback, -EINVAL, "Invalid paramter");
1093
1094         sensor_provider *p = static_cast<sensor_provider *>(provider);
1095
1096         p->set_interval_cb(callback, user_data);
1097
1098         return OP_SUCCESS;
1099 }
1100
1101 API int sensord_provider_set_attribute_str_cb(sensord_provider_h provider, sensord_provider_attribute_str_cb callback, void *user_data)
1102 {
1103         retvm_if(!provider, -EINVAL, "Invalid paramter");
1104         retvm_if(!callback, -EINVAL, "Invalid paramter");
1105
1106         sensor_provider *p = static_cast<sensor_provider *>(provider);
1107
1108         p->set_attribute_str_cb(callback, user_data);
1109
1110         return OP_SUCCESS;
1111 }
1112
1113 API int sensord_provider_publish(sensord_provider_h provider, sensor_data_t data)
1114 {
1115         retvm_if(!provider, -EINVAL, "Invalid paramter");
1116
1117         sensor_provider *p = static_cast<sensor_provider *>(provider);
1118
1119         /* TODO: synchronous call is enough? */
1120         return p->publish(data);
1121 }
1122
1123 API int sensord_provider_publish_events(sensord_provider_h provider, sensor_data_t events[], int count)
1124 {
1125         retvm_if(!provider, -EINVAL, "Invalid paramter");
1126
1127         sensor_provider *p = static_cast<sensor_provider *>(provider);
1128
1129         return p->publish(events, count);
1130 };
1131
1132 /* deperecated */
1133 API sensor_t sensord_get_sensor(sensor_type_t type)
1134 {
1135         sensor_t sensor;
1136
1137         if (sensord_get_default_sensor(type, &sensor) < 0)
1138                 return NULL;
1139
1140         return sensor;
1141 }
1142
1143 /* deprecated */
1144 API bool sensord_get_sensor_list(sensor_type_t type, sensor_t **list, int *sensor_count)
1145 {
1146         return (sensord_get_sensors(type, list, sensor_count) == OP_SUCCESS);
1147 }
1148
1149 /* deprecated */
1150 API bool sensord_register_hub_event(int handle, unsigned int event_type,
1151                 unsigned int interval, unsigned int max_batch_latency, sensorhub_cb_t cb, void *user_data)
1152 {
1153         return false;
1154 }
1155
1156 /* deprecated */
1157 API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event_types, int *count)
1158 {
1159         /*
1160          * 1. check parameter
1161          * 2. if there is no sensor, return false
1162          * 3. memory allocation
1163          */
1164         return true;
1165 }
1166
1167 /* deprecated(BUT it is used in C-API....) */
1168 API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
1169 {
1170         if (!manager.is_supported(sensor))
1171                 *supported = false;
1172         else
1173                 *supported = true;
1174
1175         return true;
1176 }
1177
1178 /* deprecated */
1179 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
1180 {
1181         return (sensord_listener_set_attribute_str(handle, 0, data, data_len) == OP_SUCCESS);
1182 }
1183
1184 /* deprecated */
1185 API bool sensord_send_command(int handle, const char *command, int command_len)
1186 {
1187         return (sensord_listener_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
1188 }
1189
1190 /* deprecated */
1191 API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
1192 {
1193         *privilege = SENSOR_PRIVILEGE_PUBLIC;
1194
1195         return true;
1196 }
1197
1198 /* deprecated */
1199 API int sensord_external_connect(const char *key, sensor_external_command_cb_t cb, void *user_data)
1200 {
1201         /*
1202          * 1. check parameter
1203          * 2. create handle in this client
1204          * 3. first connection(client)
1205          * 4. cmd_connect for external sensor with key
1206          */
1207         retvm_if(!key, -EINVAL, "Invalid key");
1208         return 0;
1209 }
1210
1211 /* deprecated */
1212 API bool sensord_external_disconnect(int handle)
1213 {
1214         /*
1215          * 1. check parameter
1216          * 2. create handle in this client
1217          * 3. first connection(client)
1218          * 4. cmd_connect for external sensor with key
1219          * 5. disconnect this handle
1220          * 6. if there is no active sensor, remove client id and stop listener
1221          */
1222         return true;
1223 }
1224
1225 /* deprecated */
1226 API bool sensord_external_post(int handle, unsigned long long timestamp, const float* data, int data_cnt)
1227 {
1228         /*
1229          * 1. check parameter
1230          * 1.1 (data_cnt <= 0) || (data_cnt > POST_DATA_LEN_MAX)), return false
1231          * 2. cmd_post
1232          */
1233
1234         return true;
1235 }
1236