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