sensord: clean up sf_common.h/sensor_common.h/sensor_logs.h
[platform/core/system/sensord.git] / src / client / sensor_event_listener.cpp
1 /*
2  * libsensord
3  *
4  * Copyright (c) 2014 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_event_listener.h>
21 #include <client_common.h>
22 #include <sensor_info_manager.h>
23
24 #include <thread>
25 #include <chrono>
26 #include <vector>
27
28 #define MS_TO_US 1000
29 #define MIN_DELIVERY_DIFF_FACTOR 0.75f
30
31 /* TODO: this macro should be adjusted */
32 #define EVENT_BUFFER_SIZE 4224
33
34 using std::thread;
35 using std::pair;
36 using std::vector;
37
38 sensor_event_listener::sensor_event_listener()
39 : m_poller(NULL)
40 , m_thread_state(THREAD_STATE_TERMINATE)
41 , m_hup_observer(NULL)
42 , m_client_info(sensor_client_info::get_instance())
43 {
44 }
45
46 sensor_event_listener::~sensor_event_listener()
47 {
48         stop_event_listener();
49 }
50
51 sensor_event_listener::sensor_event_listener(const sensor_event_listener& listener)
52 : m_poller(listener.m_poller)
53 , m_thread_state(listener.m_thread_state)
54 , m_hup_observer(listener.m_hup_observer)
55 , m_client_info(listener.m_client_info)
56 {
57 }
58
59 sensor_event_listener& sensor_event_listener::get_instance(void)
60 {
61         static sensor_event_listener inst;
62         return inst;
63 }
64
65 bool sensor_event_listener::start_handle(int handle)
66 {
67         return m_client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
68 }
69
70 bool sensor_event_listener::stop_handle(int handle)
71 {
72         return m_client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
73 }
74
75 void sensor_event_listener::operate_sensor(sensor_id_t sensor, int power_save_state)
76 {
77         sensor_handle_info_map handles_info;
78
79         m_client_info.get_sensor_handle_info(sensor, handles_info);
80
81         auto it_handle = handles_info.begin();
82
83         while (it_handle != handles_info.end()) {
84                 if (it_handle->second.m_sensor_id == sensor) {
85                         if ((it_handle->second.m_sensor_state == SENSOR_STATE_STARTED) &&
86                                 power_save_state &&
87                                 !(it_handle->second.m_sensor_option & power_save_state)) {
88
89                                 m_client_info.set_sensor_state(it_handle->first, SENSOR_STATE_PAUSED);
90                                 INFO("%s's %s[%d] is paused", get_client_name(), get_sensor_name(sensor), it_handle->first);
91
92                         } else if ((it_handle->second.m_sensor_state == SENSOR_STATE_PAUSED) &&
93                                 (!power_save_state || (it_handle->second.m_sensor_option & power_save_state))) {
94
95                                 m_client_info.set_sensor_state(it_handle->first, SENSOR_STATE_STARTED);
96                                 INFO("%s's %s[%d] is resumed", get_client_name(), get_sensor_name(sensor), it_handle->first);
97                         }
98                 }
99
100                 ++it_handle;
101         }
102 }
103
104 client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
105 {
106         unsigned int cal_event_type = get_calibration_event_type(event_type);
107         reg_event_info *event_info = NULL;
108         reg_event_info *cal_event_info = NULL;
109         client_callback_info* cal_callback_info = NULL;
110
111         if (!cal_event_type)
112                 return NULL;
113
114         cal_event_info = handle_info.get_reg_event_info(cal_event_type);
115         if ((accuracy == SENSOR_ACCURACY_BAD) && !handle_info.m_bad_accuracy && cal_event_info) {
116                 sensor_event_data_t cal_event_data;
117                 void *cal_sensor_data;
118
119                 cal_event_info->m_previous_event_time = time;
120
121                 event_info = handle_info.get_reg_event_info(event_type);
122                 if (!event_info)
123                         return NULL;
124
125                 sensor_data_t *cal_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
126                 retvm_if(!cal_data, NULL, "Failed to allocate memory");
127
128                 if (event_info->m_cb_type == SENSOR_LEGACY_CB) {
129                         cal_event_data.event_data = (void *)&(accuracy);
130                         cal_event_data.event_data_size = sizeof(accuracy);
131                         cal_sensor_data = &cal_event_data;
132                 } else {
133                         cal_data->accuracy = accuracy;
134                         cal_data->timestamp = time;
135                         cal_data->values[0] = accuracy;
136                         cal_data->value_count = 1;
137                         cal_sensor_data = cal_data;
138                 }
139
140                 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data, cal_sensor_data);
141
142                 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
143
144                 print_event_occurrence_log(handle_info, cal_event_info);
145         }
146
147         if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
148                 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
149
150         return cal_callback_info;
151 }
152
153
154 void sensor_event_listener::handle_events(void* event)
155 {
156         unsigned long long cur_time;
157         reg_event_info *event_info = NULL;
158         sensor_event_data_t event_data;
159         sensor_id_t sensor_id;
160         sensor_handle_info_map handles_info;
161         void *sensor_data;
162
163         sensor_panning_data_t panning_data;
164         int single_state_event_data = 0;
165
166         int accuracy = SENSOR_ACCURACY_GOOD;
167
168         unsigned int event_type = *((unsigned int *)(event));
169
170         client_callback_info* callback_info = NULL;
171         vector<client_callback_info *> client_callback_infos;
172
173         sensor_event_t *sensor_event = (sensor_event_t *)event;
174         sensor_id = sensor_event->sensor_id;
175         sensor_event->data = (sensor_data_t *)((char *)sensor_event + sizeof(sensor_event_t));
176         sensor_data = sensor_event->data;
177         cur_time = sensor_event->data->timestamp;
178         accuracy = sensor_event->data->accuracy;
179
180         if (is_single_state_event(event_type)) {
181                 single_state_event_data = (int) sensor_event->data->values[0];
182                 event_data.event_data = (void *)&(single_state_event_data);
183                 event_data.event_data_size = sizeof(single_state_event_data);
184         } else if (is_panning_event(event_type)) {
185                 panning_data.x = (int)sensor_event->data->values[0];
186                 panning_data.y = (int)sensor_event->data->values[1];
187                 event_data.event_data = (void *)&panning_data;
188                 event_data.event_data_size = sizeof(panning_data);
189         } else {
190                 event_data.event_data = &(sensor_event->data);
191                 event_data.event_data_size = sizeof(sensor_event->data);
192         }
193
194         {       /* scope for the lock */
195                 m_client_info.get_all_handle_info(handles_info);
196
197                 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
198
199                         sensor_handle_info &sensor_handle_info = it_handle->second;
200
201                         event_info = sensor_handle_info.get_reg_event_info(event_type);
202                         if ((sensor_handle_info.m_sensor_id != sensor_id) ||
203                                 (sensor_handle_info.m_sensor_state != SENSOR_STATE_STARTED) ||
204                                 !event_info)
205                                 continue;
206
207                         if (event_info->m_fired)
208                                 continue;
209
210                         event_info->m_previous_event_time = cur_time;
211
212                         client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
213
214                         if (cal_callback_info)
215                                 client_callback_infos.push_back(cal_callback_info);
216
217                         if (event_info->m_cb_type == SENSOR_LEGACY_CB)
218                                 callback_info = get_callback_info(sensor_id, event_info, &event_data, event);
219                         else
220                                 callback_info = get_callback_info(sensor_id, event_info, sensor_data, event);
221
222                         if (!callback_info) {
223                                 ERR("Failed to get callback_info");
224                                 continue;
225                         }
226
227                         if (sensor_handle_info.m_accuracy != accuracy) {
228                                 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
229
230                                 callback_info->accuracy_cb = sensor_handle_info.m_accuracy_cb;
231                                 callback_info->timestamp = cur_time;
232                                 callback_info->accuracy = accuracy;
233                                 callback_info->accuracy_user_data = sensor_handle_info.m_accuracy_user_data;
234                         }
235
236                         client_callback_infos.push_back(callback_info);
237
238                         if (is_one_shot_event(event_type))
239                                 event_info->m_fired = true;
240
241                         print_event_occurrence_log(sensor_handle_info, event_info);
242                 }
243         }
244
245         auto it_calback_info = client_callback_infos.begin();
246
247         while (it_calback_info != client_callback_infos.end()) {
248                 post_callback_to_main_loop(*it_calback_info);
249                 ++it_calback_info;
250         }
251 }
252
253 client_callback_info* sensor_event_listener::get_callback_info(sensor_id_t sensor_id, const reg_event_info *event_info, void* sensor_data, void *buffer)
254 {
255         client_callback_info* callback_info;
256
257         callback_info = new(std::nothrow)client_callback_info;
258         retvm_if (!callback_info, NULL, "Failed to allocate memory");
259
260         callback_info->sensor = sensor_info_to_sensor(sensor_info_manager::get_instance().get_info(sensor_id));
261         callback_info->event_id = event_info->m_id;
262         callback_info->handle = event_info->m_handle;
263         callback_info->cb_type = event_info->m_cb_type;
264         callback_info->cb = event_info->m_cb;
265         callback_info->event_type = event_info->type;
266         callback_info->user_data = event_info->m_user_data;
267         callback_info->accuracy_cb = NULL;
268         callback_info->timestamp = 0;
269         callback_info->accuracy = -1;
270         callback_info->accuracy_user_data = NULL;
271         callback_info->maincontext = event_info->m_maincontext;
272         callback_info->sensor_data = sensor_data;
273         callback_info->buffer = buffer;
274
275         return callback_info;
276 }
277
278 void sensor_event_listener::post_callback_to_main_loop(client_callback_info* cb_info)
279 {
280         if (cb_info->maincontext) {
281                 GSource *_source = g_idle_source_new();
282
283                 g_source_attach(_source, cb_info->maincontext);
284                 g_source_set_callback(_source, callback_dispatcher, cb_info, NULL);
285         } else {
286                 g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
287         }
288 }
289
290 bool sensor_event_listener::is_valid_callback(client_callback_info *cb_info)
291 {
292         return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
293 }
294
295 gboolean sensor_event_listener::callback_dispatcher(gpointer data)
296 {
297         client_callback_info *cb_info = (client_callback_info*) data;
298
299         if (sensor_event_listener::get_instance().is_valid_callback(cb_info)) {
300                 if (cb_info->accuracy_cb)
301                         cb_info->accuracy_cb(cb_info->sensor, cb_info->timestamp, cb_info->accuracy, cb_info->accuracy_user_data);
302
303                 if (cb_info->cb_type == SENSOR_EVENT_CB)
304                         ((sensor_cb_t) cb_info->cb)(cb_info->sensor, cb_info->event_type, (sensor_data_t *) cb_info->sensor_data, cb_info->user_data);
305                 else if (cb_info->cb_type == SENSORHUB_EVENT_CB)
306                         ((sensorhub_cb_t) cb_info->cb)(cb_info->sensor, cb_info->event_type, (sensorhub_data_t *) cb_info->sensor_data, cb_info->user_data);
307                 else if (cb_info->cb_type == SENSOR_LEGACY_CB)
308                         ((sensor_legacy_cb_t) cb_info->cb)(cb_info->event_type, (sensor_event_data_t *) cb_info->sensor_data, cb_info->user_data);
309         } else {
310                 WARN("Discard invalid callback cb(0x%x)(%s, 0x%x, 0x%x) with id: %llu",
311                 cb_info->cb, get_event_name(cb_info->event_type), cb_info->sensor_data,
312                 cb_info->user_data, cb_info->event_id);
313         }
314
315         if (cb_info->cb_type == SENSOR_LEGACY_CB) {
316                 sensor_event_data_t *data = (sensor_event_data_t *) cb_info->sensor_data;
317                 delete[] (char *)data->event_data;
318         }
319
320         free(cb_info->buffer);
321         delete cb_info;
322
323 /*
324 *       To be called only once, it returns false
325 */
326         return false;
327 }
328
329
330
331 ssize_t sensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, struct epoll_event &event)
332 {
333         ssize_t len;
334
335         len = m_event_socket.recv(buffer, buffer_len);
336
337         if (!len) {
338                 if(!m_poller->poll(event))
339                         return -1;
340                 len = m_event_socket.recv(buffer, buffer_len);
341
342                 if (!len) {
343                         INFO("%s failed to read after poll!", get_client_name());
344                         return -1;
345                 }
346         }
347
348         if (len < 0) {
349                 INFO("%s failed to recv event from event socket", get_client_name());
350                 return -1;
351         }
352
353         return len;
354 }
355
356
357
358 void sensor_event_listener::listen_events(void)
359 {
360         struct epoll_event event;
361         ssize_t len = -1;
362
363         do {
364                 lock l(m_thread_mutex);
365                 if (m_thread_state == THREAD_STATE_START) {
366                         void *buffer = malloc(EVENT_BUFFER_SIZE);
367
368                         if (!buffer) {
369                                 ERR("Failed to allocate memory");
370                                 break;
371                         }
372
373                         len = sensor_event_poll(buffer, EVENT_BUFFER_SIZE, event);
374                         if (len <= 0) {
375                                 INFO("sensor_event_poll failed");
376                                 free(buffer);
377                                 break;
378                         }
379
380                         void *buffer_shrinked = realloc(buffer, len);
381                         if (!buffer_shrinked) {
382                                 ERR("Failed to allocate memory");
383                                 free(buffer);
384                                 break;
385                         }
386
387                         handle_events(buffer_shrinked);
388                 } else {
389                         break;
390                 }
391         } while (true);
392
393         if (m_poller != NULL) {
394                 delete m_poller;
395                 m_poller = NULL;
396         }
397
398         close_event_channel();
399
400         { /* the scope for the lock */
401                 lock l(m_thread_mutex);
402                 m_thread_state = THREAD_STATE_TERMINATE;
403                 m_thread_cond.notify_one();
404         }
405
406         INFO("Event listener thread is terminated.");
407
408         if (m_client_info.has_client_id() && (event.events & EPOLLHUP)) {
409                 if (m_hup_observer)
410                         m_hup_observer();
411         }
412
413 }
414
415 bool sensor_event_listener::create_event_channel(void)
416 {
417         int client_id;
418         event_channel_ready_t event_channel_ready;
419
420         if (!m_event_socket.create(SOCK_SEQPACKET))
421                 return false;
422
423         if (!m_event_socket.connect(EVENT_CHANNEL_PATH)) {
424                 ERR("Failed to connect event channel for client %s, event socket fd[%d]", get_client_name(), m_event_socket.get_socket_fd());
425                 return false;
426         }
427
428         if (!m_event_socket.set_connection_mode()) {
429                 ERR("Failed to set connection mode for client %s", get_client_name());
430                 return false;
431         }
432
433         client_id = m_client_info.get_client_id();
434
435         if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) {
436                 ERR("Failed to send client id for client %s on event socket[%d]", get_client_name(), m_event_socket.get_socket_fd());
437                 return false;
438         }
439
440         if (m_event_socket.recv(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
441                 ERR("%s failed to recv event_channel_ready packet on event socket[%d] with client id [%d]",
442                         get_client_name(), m_event_socket.get_socket_fd(), client_id);
443                 return false;
444         }
445
446         if ((event_channel_ready.magic != EVENT_CHANNEL_MAGIC) || (event_channel_ready.client_id != client_id)) {
447                 ERR("Event_channel_ready packet is wrong, magic = 0x%x, client id = %d",
448                         event_channel_ready.magic, event_channel_ready.client_id);
449                 return false;
450         }
451
452         INFO("Event channel is established for client %s on socket[%d] with client id : %d",
453                 get_client_name(), m_event_socket.get_socket_fd(), client_id);
454
455         return true;
456 }
457
458
459 void sensor_event_listener::close_event_channel(void)
460 {
461         m_event_socket.close();
462 }
463
464
465 void sensor_event_listener::stop_event_listener(void)
466 {
467         const int THREAD_TERMINATING_TIMEOUT = 2;
468
469         ulock u(m_thread_mutex);
470
471         if (m_thread_state != THREAD_STATE_TERMINATE) {
472                 m_thread_state = THREAD_STATE_STOP;
473
474                 DBG("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
475                 if (m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT))
476                         == std::cv_status::timeout)
477                         ERR("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT);
478                 else
479                         DBG("Listener thread for %s is terminated", get_client_name());
480         }
481 }
482
483 void sensor_event_listener::set_thread_state(thread_state state)
484 {
485         lock l(m_thread_mutex);
486         m_thread_state = state;
487 }
488
489 void sensor_event_listener::clear(void)
490 {
491         close_event_channel();
492         stop_event_listener();
493         m_client_info.close_command_channel();
494         m_client_info.clear();
495         m_client_info.set_client_id(CLIENT_ID_INVALID);
496 }
497
498
499 void sensor_event_listener::set_hup_observer(hup_observer_t observer)
500 {
501         m_hup_observer = observer;
502 }
503
504 bool sensor_event_listener::start_event_listener(void)
505 {
506         if (!create_event_channel()) {
507                 ERR("Event channel is not established for %s", get_client_name());
508                 return false;
509         }
510
511         m_event_socket.set_transfer_mode();
512
513         m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
514         retvm_if (!m_poller, false, "Failed to allocate memory");
515
516         set_thread_state(THREAD_STATE_START);
517
518         thread listener(&sensor_event_listener::listen_events, this);
519         listener.detach();
520
521         return true;
522 }