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