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 <sensor_event_listener.h>
21 #include <client_common.h>
22 #include <sensor_info_manager.h>
29 #define MIN_DELIVERY_DIFF_FACTOR 0.75f
31 /* TODO: this macro should be adjusted */
32 #define EVENT_BUFFER_SIZE 4224
38 sensor_event_listener::sensor_event_listener()
40 , m_thread_state(THREAD_STATE_TERMINATE)
41 , m_hup_observer(NULL)
42 , m_client_info(sensor_client_info::get_instance())
46 sensor_event_listener::~sensor_event_listener()
48 stop_event_listener();
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)
59 sensor_event_listener& sensor_event_listener::get_instance(void)
61 static sensor_event_listener inst;
65 bool sensor_event_listener::start_handle(int handle)
67 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
70 bool sensor_event_listener::stop_handle(int handle)
72 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
75 void sensor_event_listener::operate_sensor(sensor_id_t sensor, int power_save_state)
77 sensor_handle_info_map handles_info;
79 m_client_info.get_sensor_handle_info(sensor, handles_info);
81 auto it_handle = handles_info.begin();
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) &&
87 !(it_handle->second.m_sensor_option & power_save_state)) {
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);
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))) {
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);
104 client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
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;
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;
119 cal_event_info->m_previous_event_time = time;
121 event_info = handle_info.get_reg_event_info(event_type);
125 sensor_data_t *cal_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
126 retvm_if(!cal_data, NULL, "Failed to allocate memory");
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;
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;
140 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data, cal_sensor_data);
142 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
144 print_event_occurrence_log(handle_info, cal_event_info);
147 if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
148 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
150 return cal_callback_info;
154 void sensor_event_listener::handle_events(void* event)
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;
163 sensor_panning_data_t panning_data;
164 int single_state_event_data = 0;
166 int accuracy = SENSOR_ACCURACY_GOOD;
168 unsigned int event_type = *((unsigned int *)(event));
170 client_callback_info* callback_info = NULL;
171 vector<client_callback_info *> client_callback_infos;
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;
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);
190 event_data.event_data = &(sensor_event->data);
191 event_data.event_data_size = sizeof(sensor_event->data);
194 { /* scope for the lock */
195 m_client_info.get_all_handle_info(handles_info);
197 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
199 sensor_handle_info &sensor_handle_info = it_handle->second;
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) ||
207 if (event_info->m_fired)
210 event_info->m_previous_event_time = cur_time;
212 client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
214 if (cal_callback_info)
215 client_callback_infos.push_back(cal_callback_info);
217 if (event_info->m_cb_type == SENSOR_LEGACY_CB)
218 callback_info = get_callback_info(sensor_id, event_info, &event_data, event);
220 callback_info = get_callback_info(sensor_id, event_info, sensor_data, event);
222 if (!callback_info) {
223 ERR("Failed to get callback_info");
227 if (sensor_handle_info.m_accuracy != accuracy) {
228 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
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;
236 client_callback_infos.push_back(callback_info);
238 if (is_one_shot_event(event_type))
239 event_info->m_fired = true;
241 print_event_occurrence_log(sensor_handle_info, event_info);
245 auto it_calback_info = client_callback_infos.begin();
247 while (it_calback_info != client_callback_infos.end()) {
248 post_callback_to_main_loop(*it_calback_info);
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)
255 client_callback_info* callback_info;
257 callback_info = new(std::nothrow)client_callback_info;
258 retvm_if (!callback_info, NULL, "Failed to allocate memory");
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;
275 return callback_info;
278 void sensor_event_listener::post_callback_to_main_loop(client_callback_info* cb_info)
280 if (cb_info->maincontext) {
281 GSource *_source = g_idle_source_new();
283 g_source_attach(_source, cb_info->maincontext);
284 g_source_set_callback(_source, callback_dispatcher, cb_info, NULL);
286 g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
290 bool sensor_event_listener::is_valid_callback(client_callback_info *cb_info)
292 return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
295 gboolean sensor_event_listener::callback_dispatcher(gpointer data)
297 client_callback_info *cb_info = (client_callback_info*) data;
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);
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);
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);
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;
320 free(cb_info->buffer);
324 * To be called only once, it returns false
331 ssize_t sensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, struct epoll_event &event)
335 len = m_event_socket.recv(buffer, buffer_len);
338 if(!m_poller->poll(event))
340 len = m_event_socket.recv(buffer, buffer_len);
343 INFO("%s failed to read after poll!", get_client_name());
349 INFO("%s failed to recv event from event socket", get_client_name());
358 void sensor_event_listener::listen_events(void)
360 struct epoll_event event;
364 lock l(m_thread_mutex);
365 if (m_thread_state == THREAD_STATE_START) {
366 void *buffer = malloc(EVENT_BUFFER_SIZE);
369 ERR("Failed to allocate memory");
373 len = sensor_event_poll(buffer, EVENT_BUFFER_SIZE, event);
375 INFO("sensor_event_poll failed");
380 void *buffer_shrinked = realloc(buffer, len);
381 if (!buffer_shrinked) {
382 ERR("Failed to allocate memory");
387 handle_events(buffer_shrinked);
393 if (m_poller != NULL) {
398 close_event_channel();
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();
406 INFO("Event listener thread is terminated.");
408 if (m_client_info.has_client_id() && (event.events & EPOLLHUP)) {
415 bool sensor_event_listener::create_event_channel(void)
418 event_channel_ready_t event_channel_ready;
420 if (!m_event_socket.create(SOCK_SEQPACKET))
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());
428 if (!m_event_socket.set_connection_mode()) {
429 ERR("Failed to set connection mode for client %s", get_client_name());
433 client_id = m_client_info.get_client_id();
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());
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);
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);
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);
459 void sensor_event_listener::close_event_channel(void)
461 m_event_socket.close();
465 void sensor_event_listener::stop_event_listener(void)
467 const int THREAD_TERMINATING_TIMEOUT = 2;
469 ulock u(m_thread_mutex);
471 if (m_thread_state != THREAD_STATE_TERMINATE) {
472 m_thread_state = THREAD_STATE_STOP;
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);
479 DBG("Listener thread for %s is terminated", get_client_name());
483 void sensor_event_listener::set_thread_state(thread_state state)
485 lock l(m_thread_mutex);
486 m_thread_state = state;
489 void sensor_event_listener::clear(void)
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);
499 void sensor_event_listener::set_hup_observer(hup_observer_t observer)
501 m_hup_observer = observer;
504 bool sensor_event_listener::start_event_listener(void)
506 if (!create_event_channel()) {
507 ERR("Event channel is not established for %s", get_client_name());
511 m_event_socket.set_transfer_mode();
513 m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
514 retvm_if (!m_poller, false, "Failed to allocate memory");
516 set_thread_state(THREAD_STATE_START);
518 thread listener(&sensor_event_listener::listen_events, this);