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>
28 #include <sensor_types.h>
30 /* TODO: this macro should be adjusted(4224 = 4096(data) + 128(header)) */
31 #define EVENT_BUFFER_SIZE sizeof(sensor_event_t)
37 sensor_event_listener::sensor_event_listener()
39 , m_thread_state(THREAD_STATE_TERMINATE)
40 , m_hup_observer(NULL)
41 , m_client_info(sensor_client_info::get_instance())
45 sensor_event_listener::~sensor_event_listener()
47 stop_event_listener();
50 sensor_event_listener& sensor_event_listener::get_instance(void)
52 static sensor_event_listener inst;
56 bool sensor_event_listener::start_handle(int handle)
58 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
61 bool sensor_event_listener::stop_handle(int handle)
63 return m_client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
66 void sensor_event_listener::operate_sensor(sensor_id_t sensor, int power_save_state)
68 sensor_handle_info_map handles_info;
70 m_client_info.get_sensor_handle_info(sensor, handles_info);
72 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
73 if (it_handle->second.m_sensor_id != sensor)
76 if ((it_handle->second.m_sensor_state == SENSOR_STATE_STARTED) &&
78 !(it_handle->second.m_sensor_option & power_save_state)) {
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);
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))) {
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);
92 client_callback_info* sensor_event_listener::handle_calibration_cb(sensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
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;
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;
107 cal_event_info->m_previous_event_time = time;
109 event_info = handle_info.get_reg_event_info(event_type);
113 sensor_data_t *cal_data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
114 retvm_if(!cal_data, NULL, "Failed to allocate memory");
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;
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;
128 cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data, cal_sensor_data);
130 m_client_info.set_bad_accuracy(handle_info.m_handle, true);
132 print_event_occurrence_log(handle_info, cal_event_info);
135 if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
136 m_client_info.set_bad_accuracy(handle_info.m_handle, false);
138 return cal_callback_info;
142 void sensor_event_listener::handle_events(void* event)
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;
151 sensor_panning_data_t panning_data;
152 int single_state_event_data = 0;
154 int accuracy = SENSOR_ACCURACY_GOOD;
156 unsigned int event_type = *((unsigned int *)(event));
158 client_callback_info* callback_info = NULL;
159 vector<client_callback_info *> client_callback_infos;
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;
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);
177 event_data.event_data = &(sensor_event->data);
178 event_data.event_data_size = sizeof(sensor_event->data);
181 { /* scope for the lock */
182 m_client_info.get_all_handle_info(handles_info);
184 for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
186 sensor_handle_info &sensor_handle_info = it_handle->second;
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) ||
194 if (event_info->m_fired)
197 event_info->m_previous_event_time = cur_time;
199 client_callback_info* cal_callback_info = handle_calibration_cb(sensor_handle_info, event_type, cur_time, accuracy);
201 if (cal_callback_info)
202 client_callback_infos.push_back(cal_callback_info);
204 if (event_info->m_cb_type == SENSOR_LEGACY_CB)
205 callback_info = get_callback_info(sensor_id, event_info, &event_data, event);
207 callback_info = get_callback_info(sensor_id, event_info, sensor_data, event);
209 if (!callback_info) {
210 _E("Failed to get callback_info");
214 if (sensor_handle_info.m_accuracy != accuracy) {
215 m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
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;
223 client_callback_infos.push_back(callback_info);
225 if (is_one_shot_event(event_type))
226 event_info->m_fired = true;
228 print_event_occurrence_log(sensor_handle_info, event_info);
232 auto it_calback_info = client_callback_infos.begin();
234 while (it_calback_info != client_callback_infos.end()) {
235 post_callback_to_main_loop(*it_calback_info);
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)
242 client_callback_info* callback_info;
244 callback_info = new(std::nothrow)client_callback_info;
245 retvm_if (!callback_info, NULL, "Failed to allocate memory");
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;
261 return callback_info;
264 void sensor_event_listener::post_callback_to_main_loop(client_callback_info* cb_info)
266 g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
269 bool sensor_event_listener::is_valid_callback(client_callback_info *cb_info)
271 return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
274 gboolean sensor_event_listener::callback_dispatcher(gpointer data)
276 client_callback_info *cb_info = (client_callback_info*) data;
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);
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);
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);
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;
299 free(cb_info->sensor_data);
303 * To be called only once, it returns false
310 ssize_t sensor_event_listener::sensor_event_poll(void* buffer, int buffer_len, struct epoll_event &event)
314 len = m_event_socket.recv(buffer, buffer_len);
317 if(!m_poller->poll(event))
319 len = m_event_socket.recv(buffer, buffer_len);
322 _I("%s failed to read after poll!", get_client_name());
328 _I("%s failed to recv event from event socket", get_client_name());
335 void sensor_event_listener::listen_events(void)
337 char buffer[EVENT_BUFFER_SIZE];
338 struct epoll_event event;
341 event.events = EPOLLIN | EPOLLPRI;
347 lock l(m_thread_mutex);
348 if (m_thread_state != THREAD_STATE_START)
351 len = sensor_event_poll(buffer, sizeof(sensor_event_t), event);
353 _I("Failed to sensor_event_poll()");
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);
361 len = sensor_event_poll(buffer_data, data_len, event);
363 _I("Failed to sensor_event_poll() for sensor_data");
368 sensor_event->data = reinterpret_cast<sensor_data_t *>(buffer_data);
370 handle_events((void *)buffer);
373 if (m_poller != NULL) {
378 close_event_channel();
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();
386 _I("Event listener thread is terminated.");
388 if (m_client_info.has_client_id() && (event.events & EPOLLHUP)) {
395 bool sensor_event_listener::create_event_channel(void)
398 channel_ready_t event_channel_ready;
400 if (!m_event_socket.create(SOCK_SEQPACKET))
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());
408 if (!m_event_socket.set_connection_mode()) {
409 _E("Failed to set connection mode for client %s", get_client_name());
413 client_id = m_client_info.get_client_id();
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());
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);
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);
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);
439 void sensor_event_listener::close_event_channel(void)
441 m_event_socket.close();
445 void sensor_event_listener::stop_event_listener(void)
447 const int THREAD_TERMINATING_TIMEOUT = 2;
449 ulock u(m_thread_mutex);
451 if (m_thread_state != THREAD_STATE_TERMINATE) {
452 m_thread_state = THREAD_STATE_STOP;
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);
459 _D("Listener thread for %s is terminated", get_client_name());
463 void sensor_event_listener::set_thread_state(thread_state state)
465 lock l(m_thread_mutex);
466 m_thread_state = state;
469 void sensor_event_listener::clear(void)
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);
479 void sensor_event_listener::set_hup_observer(hup_observer_t observer)
481 m_hup_observer = observer;
484 bool sensor_event_listener::start_event_listener(void)
486 if (!create_event_channel()) {
487 _E("Event channel is not established for %s", get_client_name());
491 m_event_socket.set_transfer_mode();
493 m_poller = new(std::nothrow) poller(m_event_socket.get_socket_fd());
494 retvm_if (!m_poller, false, "Failed to allocate memory");
496 set_thread_state(THREAD_STATE_START);
498 thread listener(&sensor_event_listener::listen_events, this);