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