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