4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <csensor_event_listener.h>
21 #include <client_common.h>
22 #include <sf_common.h>
23 #include <sensor_info_manager.h>
30 #define MIN_DELIVERY_DIFF_FACTOR 0.75f
36 csensor_event_listener::csensor_event_listener()
38 , m_thread_state(THREAD_STATE_TERMINATE)
39 , m_hup_observer(NULL)
40 , m_client_info(csensor_client_info::get_instance())
44 csensor_event_listener::~csensor_event_listener()
46 stop_event_listener();
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)
58 csensor_event_listener& csensor_event_listener::get_instance(void)
60 static csensor_event_listener inst;
64 bool csensor_event_listener::start_handle(int handle)
66 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
69 bool csensor_event_listener::stop_handle(int handle)
71 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
74 void csensor_event_listener::operate_sensor(sensor_id_t sensor, int power_save_state)
76 sensor_handle_info_map handles_info;
78 m_client_info.get_sensor_handle_info(sensor, handles_info);
80 auto it_handle = handles_info.begin();
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) &&
86 !(it_handle->second.m_sensor_option & power_save_state)) {
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);
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))) {
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);
103 client_callback_info* csensor_event_listener::handle_calibration_cb(csensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
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;
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;
119 cal_event_info->m_previous_event_time = time;
121 event_info = handle_info.get_reg_event_info(event_type);
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;
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;
137 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data);
139 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
141 print_event_occurrence_log(handle_info, cal_event_info);
144 if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
145 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
147 return cal_callback_info;
151 void csensor_event_listener::handle_events(void* event)
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;
160 sensor_panning_data_t panning_data;
161 int single_state_event_data = 0;
163 int accuracy = SENSOR_ACCURACY_GOOD;
165 unsigned int event_type = *((unsigned int *)(event));
166 bool is_hub_event = is_sensorhub_event(event_type);
168 client_callback_info* callback_info = NULL;
169 vector<client_callback_info *> client_callback_infos;
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;
177 event_data.event_data = &(sensor_hub_event->data);
178 event_data.event_data_size = sizeof(sensor_hub_event->data);
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;
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);
196 event_data.event_data = &(sensor_event->data);
197 event_data.event_data_size = sizeof(sensor_event->data);
201 { /* scope for the lock */
202 m_client_info.get_all_handle_info(handles_info);
204 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
206 csensor_handle_info &sensor_handle_info = it_handle->second;
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) ||
214 if (event_info->m_fired)
217 event_info->m_previous_event_time = cur_time;
219 client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
221 if (cal_callback_info)
222 client_callback_infos.push_back(cal_callback_info);
224 if (event_info->m_cb_type == SENSOR_LEGACY_CB)
225 callback_info = get_callback_info(sensor_id, event_info, &event_data);
227 callback_info = get_callback_info(sensor_id, event_info, sensor_data);
229 if (!callback_info) {
230 ERR("Failed to get callback_info");
234 if (sensor_handle_info.m_accuracy != accuracy) {
235 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
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;
243 client_callback_infos.push_back(callback_info);
245 if (is_one_shot_event(event_type))
246 event_info->m_fired = true;
248 print_event_occurrence_log(sensor_handle_info, event_info);
252 auto it_calback_info = client_callback_infos.begin();
254 while (it_calback_info != client_callback_infos.end()) {
255 post_callback_to_main_loop(*it_calback_info);
262 client_callback_info* csensor_event_listener::get_callback_info(sensor_id_t sensor_id, const creg_event_info *event_info, void* sensor_data)
264 client_callback_info* callback_info;
266 callback_info = new(std::nothrow)client_callback_info;
267 retvm_if (!callback_info, NULL, "Failed to allocate memory");
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;
282 if (event_info->m_cb_type == SENSOR_EVENT_CB) {
283 callback_info->sensor_data = new(std::nothrow) char[sizeof(sensor_data_t)];
285 if (!callback_info->sensor_data) {
286 ERR("Failed to allocate memory");
287 delete callback_info;
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)];
295 if (!callback_info->sensor_data) {
296 ERR("Failed to allocate memory");
297 delete callback_info;
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)];
307 if (!callback_info->sensor_data) {
308 ERR("Failed to allocate memory");
309 delete callback_info;
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];
317 if (!dest_sensor_data->event_data) {
318 ERR("Failed to allocate memory");
319 delete[] (char *)(callback_info->sensor_data);
320 delete callback_info;
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);
327 memcpy(dest_sensor_data->event_data, src_sensor_data->event_data, src_sensor_data->event_data_size);
330 return callback_info;
333 void csensor_event_listener::post_callback_to_main_loop(client_callback_info* cb_info)
335 if (cb_info->maincontext) {
336 GSource *_source = g_idle_source_new();
338 g_source_attach(_source, cb_info->maincontext);
339 g_source_set_callback(_source, callback_dispatcher, cb_info, NULL);
341 g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
345 bool csensor_event_listener::is_valid_callback(client_callback_info *cb_info)
347 return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
350 gboolean csensor_event_listener::callback_dispatcher(gpointer data)
352 client_callback_info *cb_info = (client_callback_info*) data;
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);
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);
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);
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;
375 delete[] (char*)(cb_info->sensor_data);
379 * To be called only once, it returns false
386 bool csensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, int &event)
390 len = m_event_socket.recv(buffer, buffer_len);
393 if(!m_poller->poll(event))
395 len = m_event_socket.recv(buffer, buffer_len);
398 INFO("%s failed to read after poll!", get_client_name());
404 INFO("%s failed to recv event from event socket", get_client_name());
413 void csensor_event_listener::listen_events(void)
415 sensorhub_event_t buffer;
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");
426 handle_events(&buffer);
432 if (m_poller != NULL) {
437 close_event_channel();
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();
445 INFO("Event listener thread is terminated.");
447 if (m_client_info.has_client_id() && (event & EPOLLHUP)) {
454 bool csensor_event_listener::create_event_channel(void)
457 event_channel_ready_t event_channel_ready;
459 if (!m_event_socket.create(SOCK_SEQPACKET))
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());
467 m_event_socket.set_connection_mode();
469 client_id = m_client_info.get_client_id();
471 if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) {
472 ERR("Failed to send client id for client %s on event socket[%d]", get_client_name(), m_event_socket.get_socket_fd());
476 if (m_event_socket.recv(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
477 ERR("%s failed to recv event_channel_ready packet on event socket[%d] with client id [%d]",
478 get_client_name(), m_event_socket.get_socket_fd(), client_id);
482 if ((event_channel_ready.magic != EVENT_CHANNEL_MAGIC) || (event_channel_ready.client_id != client_id)) {
483 ERR("Event_channel_ready packet is wrong, magic = 0x%x, client id = %d",
484 event_channel_ready.magic, event_channel_ready.client_id);
488 INFO("Event channel is established for client %s on socket[%d] with client id : %d",
489 get_client_name(), m_event_socket.get_socket_fd(), client_id);
495 void csensor_event_listener::close_event_channel(void)
497 m_event_socket.close();
501 void csensor_event_listener::stop_event_listener(void)
503 const int THREAD_TERMINATING_TIMEOUT = 2;
505 ulock u(m_thread_mutex);
507 if (m_thread_state != THREAD_STATE_TERMINATE) {
508 m_thread_state = THREAD_STATE_STOP;
510 _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
511 if (m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT))
512 == std::cv_status::timeout)
513 _E("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT);
515 _D("Listener thread for %s is terminated", get_client_name());
519 void csensor_event_listener::set_thread_state(thread_state state)
521 lock l(m_thread_mutex);
522 m_thread_state = state;
525 void csensor_event_listener::clear(void)
527 close_event_channel();
528 stop_event_listener();
529 m_client_info.close_command_channel();
530 m_client_info.clear();
531 m_client_info.set_client_id(CLIENT_ID_INVALID);
535 void csensor_event_listener::set_hup_observer(hup_observer_t observer)
537 m_hup_observer = observer;
540 bool csensor_event_listener::start_event_listener(void)
542 if (!create_event_channel()) {
543 ERR("Event channel is not established for %s", get_client_name());
547 m_event_socket.set_transfer_mode();
549 m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
550 retvm_if (!m_poller, false, "Failed to allocate memory");
552 set_thread_state(THREAD_STATE_START);
554 thread listener(&csensor_event_listener::listen_events, this);