Modified the csensor_event_listener and separated the client information into a separate class. Earlier both the client information and the event listener functionality was present in a single class.
This is more structured code.
Review: Removing the functions from event_listener class as they have been moved to client_info class.
Review2: Removing m_client_info from csensor_event_listener and using it as a static instance.
Change-Id: Ie18e84023a8c448fbd8a06f2d2615b4e8c117c65
add_library(${PROJECT_NAME} SHARED
client.cpp
+ csensor_client_info.cpp
csensor_event_listener.cpp
sensor_info_manager.cpp
csensor_handle_info.cpp
static const int OP_ERROR = -1;
static csensor_event_listener &event_listener = csensor_event_listener::get_instance();
+static csensor_client_info &client_info = csensor_client_info::get_instance();
static cmutex lock;
static int g_power_save_state = 0;
{
handle_vector handles;
- event_listener.get_all_handles(handles);
+ client_info.get_all_handles(handles);
auto it_handle = handles.begin();
g_power_save_state = cur_power_save_state;
_D("power_save_state: %d noti to %s", g_power_save_state, get_client_name());
- event_listener.get_listening_sensors(sensors);
+ client_info.get_listening_sensors(sensors);
auto it_sensor = sensors.begin();
while (it_sensor != sensors.end()) {
- event_listener.get_sensor_rep(*it_sensor, prev_rep);
+ client_info.get_sensor_rep(*it_sensor, prev_rep);
event_listener.operate_sensor(*it_sensor, cur_power_save_state);
- event_listener.get_sensor_rep(*it_sensor, cur_rep);
+ client_info.get_sensor_rep(*it_sensor, cur_rep);
change_sensor_rep(*it_sensor, prev_rep, cur_rep);
++it_sensor;
command_channel *cmd_channel;
int client_id;
- event_listener.close_command_channel();
- event_listener.set_client_id(CLIENT_ID_INVALID);
+ client_info.close_command_channel();
+ client_info.set_client_id(CLIENT_ID_INVALID);
sensor_id_vector sensors;
- event_listener.get_listening_sensors(sensors);
+ client_info.get_listening_sensors(sensors);
bool first_connection = true;
goto FAILED;
}
- event_listener.add_command_channel(*it_sensor, cmd_channel);
+ client_info.add_command_channel(*it_sensor, cmd_channel);
if (first_connection) {
first_connection = false;
goto FAILED;
}
- event_listener.set_client_id(client_id);
+ client_info.set_client_id(client_id);
event_listener.start_event_listener();
}
prev_rep.option = SENSOR_OPTION_DEFAULT;
prev_rep.interval = 0;
- event_listener.get_sensor_rep(*it_sensor, cur_rep);
+ client_info.get_sensor_rep(*it_sensor, cur_rep);
if (!change_sensor_rep(*it_sensor, prev_rep, cur_rep)) {
_E("Failed to change rep(%s) for %s", get_sensor_name(*it_sensor), get_client_name());
goto FAILED;
command_channel *cmd_channel;
event_type_vector add_event_types, del_event_types;
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
return false;
}
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
retvm_if ((client_id < 0), false, "Invalid client id : %d, %s, %s", client_id, get_sensor_name(sensor_id), get_client_name());
get_events_diff(prev_rep.event_types, cur_rep.event_types, add_event_types, del_event_types);
AUTOLOCK(lock);
- sensor_registered = event_listener.is_sensor_registered(sensor_id);
+ sensor_registered = client_info.is_sensor_registered(sensor_id);
- handle = event_listener.create_handle(sensor_id);
+ handle = client_info.create_handle(sensor_id);
if (handle == MAX_HANDLE_REACHED) {
ERR("Maximum number of handles reached, sensor: %s in client %s", get_sensor_name(sensor_id), get_client_name());
return OP_ERROR;
if (!cmd_channel->create_channel()) {
ERR("%s failed to create command channel for %s", get_client_name(), get_sensor_name(sensor_id));
- event_listener.delete_handle(handle);
+ client_info.delete_handle(handle);
delete cmd_channel;
return OP_ERROR;
}
- event_listener.add_command_channel(sensor_id, cmd_channel);
+ client_info.add_command_channel(sensor_id, cmd_channel);
}
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("%s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
- event_listener.delete_handle(handle);
+ client_info.delete_handle(handle);
return OP_ERROR;
}
- if (!event_listener.has_client_id()) {
+ if (!client_info.has_client_id()) {
first_connection = true;
if(!cmd_channel->cmd_get_id(client_id)) {
ERR("Sending cmd_get_id() failed for %s", get_sensor_name(sensor_id));
- event_listener.close_command_channel(sensor_id);
- event_listener.delete_handle(handle);
+ client_info.close_command_channel(sensor_id);
+ client_info.delete_handle(handle);
return OP_ERROR;
}
- event_listener.set_client_id(client_id);
+ client_info.set_client_id(client_id);
INFO("%s gets client_id [%d]", get_client_name(), client_id);
event_listener.start_event_listener();
INFO("%s starts listening events with client_id [%d]", get_client_name(), client_id);
}
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
cmd_channel->set_client_id(client_id);
INFO("%s[%d] connects with %s[%d]", get_client_name(), client_id, get_sensor_name(sensor_id), handle);
- event_listener.set_sensor_params(handle, SENSOR_STATE_STOPPED, SENSOR_OPTION_DEFAULT);
+ client_info.set_sensor_params(handle, SENSOR_STATE_STOPPED, SENSOR_OPTION_DEFAULT);
if (!sensor_registered) {
if(!cmd_channel->cmd_hello(sensor_id)) {
ERR("Sending cmd_hello(%s, %d) failed for %s", get_sensor_name(sensor_id), client_id, get_client_name());
- event_listener.close_command_channel(sensor_id);
- event_listener.delete_handle(handle);
+ client_info.close_command_channel(sensor_id);
+ client_info.delete_handle(handle);
if (first_connection) {
- event_listener.set_client_id(CLIENT_ID_INVALID);
+ client_info.set_client_id(CLIENT_ID_INVALID);
event_listener.stop_event_listener();
}
return OP_ERROR;
AUTOLOCK(lock);
- if (!event_listener.get_sensor_state(handle, sensor_state)||
- !event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_state(handle, sensor_state)||
+ !client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
return false;
}
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
retvm_if ((client_id < 0), false, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor_id), get_client_name());
INFO("%s disconnects with %s[%d]", get_client_name(), get_sensor_name(sensor_id), handle);
sensord_stop(handle);
}
- if (!event_listener.delete_handle(handle))
+ if (!client_info.delete_handle(handle))
return false;
- if (!event_listener.is_active())
- event_listener.set_client_id(CLIENT_ID_INVALID);
+ if (!client_info.is_active())
+ client_info.set_client_id(CLIENT_ID_INVALID);
- if (!event_listener.is_sensor_registered(sensor_id)) {
+ if (!client_info.is_sensor_registered(sensor_id)) {
if(!cmd_channel->cmd_byebye()) {
ERR("Sending cmd_byebye(%d, %s) failed for %s", client_id, get_sensor_name(sensor_id), get_client_name());
return false;
}
- event_listener.close_command_channel(sensor_id);
+ client_info.close_command_channel(sensor_id);
}
- if (!event_listener.is_active()) {
- INFO("Stop listening events for client %s with client id [%d]", get_client_name(), event_listener.get_client_id());
+ if (!client_info.is_active()) {
+ INFO("Stop listening events for client %s with client id [%d]", get_client_name(), client_info.get_client_id());
event_listener.stop_event_listener();
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
get_client_name(), get_event_name(event_type), event_type, get_sensor_name(sensor_id),
handle, interval, max_batch_latency, cb, user_data);
- event_listener.get_sensor_rep(sensor_id, prev_rep);
- event_listener.register_event(handle, event_type, interval, max_batch_latency, cb_type, cb, user_data);
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
+ client_info.register_event(handle, event_type, interval, max_batch_latency, cb_type, cb, user_data);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.unregister_event(handle, event_type);
+ client_info.unregister_event(handle, event_type);
return ret;
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
INFO("%s unregisters event %s[0x%x] for sensor %s[%d]", get_client_name(), get_event_name(event_type),
event_type, get_sensor_name(sensor_id), handle);
- event_listener.get_sensor_rep(sensor_id, prev_rep);
- event_listener.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
+ client_info.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
- if (!event_listener.unregister_event(handle, event_type)) {
+ if (!client_info.unregister_event(handle, event_type)) {
ERR("%s try to unregister non registered event %s[0x%x] for sensor %s[%d]",
get_client_name(),get_event_name(event_type), event_type, get_sensor_name(sensor_id), handle);
return false;
}
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.register_event(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
+ client_info.register_event(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
return ret;
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
INFO("%s registers accuracy_changed_cb for sensor %s[%d] with cb: 0x%x, user_data: 0x%x",
get_client_name(), get_sensor_name(sensor_id), handle, cb, user_data);
- event_listener.register_accuracy_cb(handle, cb , user_data);
+ client_info.register_accuracy_cb(handle, cb , user_data);
return true;
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
INFO("%s unregisters accuracy_changed_cb for sensor %s[%d]",
get_client_name(), get_sensor_name(sensor_id), handle);
- event_listener.unregister_accuracy_cb(handle);
+ client_info.unregister_accuracy_cb(handle);
return true;
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
handle, option, g_power_save_state);
if (g_power_save_state && !(g_power_save_state & option)) {
- event_listener.set_sensor_params(handle, SENSOR_STATE_PAUSED, option);
+ client_info.set_sensor_params(handle, SENSOR_STATE_PAUSED, option);
return true;
}
- event_listener.get_sensor_rep(sensor_id, prev_rep);
- event_listener.get_sensor_params(handle, prev_state, prev_option);
- event_listener.set_sensor_params(handle, SENSOR_STATE_STARTED, option);
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
+ client_info.get_sensor_params(handle, prev_state, prev_option);
+ client_info.set_sensor_params(handle, SENSOR_STATE_STARTED, option);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.set_sensor_params(handle, prev_state, prev_option);
+ client_info.set_sensor_params(handle, prev_state, prev_option);
return ret;
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_state(handle, sensor_state)||
- !event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_state(handle, sensor_state)||
+ !client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
INFO("%s stops sensor %s[%d]", get_client_name(), get_sensor_name(sensor_id), handle);
- event_listener.get_sensor_rep(sensor_id, prev_rep);
- event_listener.get_sensor_params(handle, prev_state, prev_option);
- event_listener.set_sensor_state(handle, SENSOR_STATE_STOPPED);
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
+ client_info.get_sensor_params(handle, prev_state, prev_option);
+ client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.set_sensor_params(handle, prev_state, prev_option);
+ client_info.set_sensor_params(handle, prev_state, prev_option);
return ret;
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
INFO("%s changes batch of event %s[0x%x] for %s[%d] to (%d, %d)", get_client_name(), get_event_name(event_type),
event_type, get_sensor_name(sensor_id), handle, interval, latency);
- event_listener.get_sensor_rep(sensor_id, prev_rep);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
- event_listener.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
+ client_info.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data);
if (interval < MIN_INTERVAL)
interval = MIN_INTERVAL;
- if (!event_listener.set_event_batch(handle, event_type, interval, latency))
+ if (!client_info.set_event_batch(handle, event_type, interval, latency))
return false;
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.set_event_batch(handle, event_type, prev_interval, prev_latency);
+ client_info.set_event_batch(handle, event_type, prev_interval, prev_latency);
return ret;
}
AUTOLOCK(lock);
- if (!event_listener.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data)) {
+ if (!client_info.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data)) {
ERR("Failed to get event info with handle = %d, event_type = 0x%x", handle, event_type);
return false;
}
AUTOLOCK(lock);
- if (!event_listener.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data)) {
+ if (!client_info.get_event_info(handle, event_type, prev_interval, prev_latency, prev_cb_type, prev_cb, prev_user_data)) {
ERR("Failed to get event info with handle = %d, event_type = 0x%x", handle, event_type);
return false;
}
AUTOLOCK(lock);
- if (!event_listener.get_sensor_state(handle, sensor_state)||
- !event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_state(handle, sensor_state)||
+ !client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
option, handle, get_sensor_name(sensor_id), get_client_name());
- event_listener.get_sensor_rep(sensor_id, prev_rep);
- event_listener.get_sensor_params(handle, prev_state, prev_option);
+ client_info.get_sensor_rep(sensor_id, prev_rep);
+ client_info.get_sensor_params(handle, prev_state, prev_option);
if (g_power_save_state) {
if ((option & g_power_save_state) && (sensor_state == SENSOR_STATE_PAUSED))
- event_listener.set_sensor_state(handle, SENSOR_STATE_STARTED);
+ client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
else if (!(option & g_power_save_state) && (sensor_state == SENSOR_STATE_STARTED))
- event_listener.set_sensor_state(handle, SENSOR_STATE_PAUSED);
+ client_info.set_sensor_state(handle, SENSOR_STATE_PAUSED);
}
- event_listener.set_sensor_option(handle, option);
+ client_info.set_sensor_option(handle, option);
- event_listener.get_sensor_rep(sensor_id, cur_rep);
+ client_info.get_sensor_rep(sensor_id, cur_rep);
ret = change_sensor_rep(sensor_id, prev_rep, cur_rep);
if (!ret)
- event_listener.set_sensor_option(handle, prev_option);
+ client_info.set_sensor_option(handle, prev_option);
return ret;
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
retvm_if ((wakeup != SENSOR_WAKEUP_ON) && (wakeup != SENSOR_WAKEUP_OFF), false, "Invalid wakeup value : %d, handle: %d, %s, %s",
wakeup, handle, get_sensor_name(sensor_id), get_client_name());
- event_listener.set_sensor_wakeup(handle, wakeup);
+ client_info.set_sensor_wakeup(handle, wakeup);
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
return false;
}
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
retvm_if ((client_id < 0), false, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor_id), get_client_name());
if (!cmd_channel->cmd_set_wakeup(wakeup)) {
AUTOLOCK(lock);
- if (!event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
retvm_if (sensor_id != CONTEXT_SENSOR, false, "%s use this API wrongly, only for CONTEXT_SENSOR not for %s",
get_client_name(), get_sensor_name(sensor_id));
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
return false;
}
retvm_if((data_len < 0) || (data == NULL), false, "Invalid data_len: %d, data: 0x%x, handle: %d, %s, %s",
data_len, data, handle, get_sensor_name(sensor_id), get_client_name());
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
retvm_if ((client_id < 0), false, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor_id), get_client_name());
- retvm_if (!event_listener.is_sensor_active(sensor_id), false, "%s with client_id:%d is not active state for %s with handle: %d",
+ retvm_if (!client_info.is_sensor_active(sensor_id), false, "%s with client_id:%d is not active state for %s with handle: %d",
get_sensor_name(sensor_id), client_id, get_client_name(), handle);
if (!cmd_channel->cmd_send_sensorhub_data(data, data_len)) {
AUTOLOCK(lock);
- if (!event_listener.get_sensor_state(handle, sensor_state)||
- !event_listener.get_sensor_id(handle, sensor_id)) {
+ if (!client_info.get_sensor_state(handle, sensor_state)||
+ !client_info.get_sensor_id(handle, sensor_id)) {
ERR("client %s failed to get handle information", get_client_name());
return false;
}
- if (!event_listener.get_command_channel(sensor_id, &cmd_channel)) {
+ if (!client_info.get_command_channel(sensor_id, &cmd_channel)) {
ERR("client %s failed to get command channel for %s", get_client_name(), get_sensor_name(sensor_id));
return false;
}
- client_id = event_listener.get_client_id();
+ client_id = client_info.get_client_id();
retvm_if ((client_id < 0), false, "Invalid client id : %d, handle: %d, %s, %s", client_id, handle, get_sensor_name(sensor_id), get_client_name());
if (sensor_state != SENSOR_STATE_STARTED) {
--- /dev/null
+/*
+ * libsensord
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <csensor_event_listener.h>
+#include <client_common.h>
+#include <sf_common.h>
+#include <sensor_info_manager.h>
+
+#include <thread>
+#include <chrono>
+
+#define MS_TO_US 1000
+#define MIN_DELIVERY_DIFF_FACTOR 0.75f
+
+using std::thread;
+using std::pair;
+
+csensor_client_info::csensor_client_info()
+: m_client_id(CLIENT_ID_INVALID)
+{
+}
+
+csensor_client_info::~csensor_client_info()
+{
+}
+
+
+csensor_client_info& csensor_client_info::get_instance(void)
+{
+ static csensor_client_info inst;
+ return inst;
+}
+
+
+int csensor_client_info::create_handle(sensor_id_t sensor)
+{
+ csensor_handle_info handle_info;
+ int handle = 0;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ while (m_sensor_handle_infos.count(handle) > 0)
+ handle++;
+
+ if (handle == MAX_HANDLE) {
+ ERR("Handles of client %s are full", get_client_name());
+ return MAX_HANDLE_REACHED;
+ }
+
+ handle_info.m_sensor_id = sensor;
+ handle_info.m_sensor_state = SENSOR_STATE_STOPPED;
+ handle_info.m_sensor_option = SENSOR_OPTION_DEFAULT;
+ handle_info.m_handle = handle;
+ handle_info.m_accuracy = -1;
+ handle_info.m_accuracy_cb = NULL;
+ handle_info.m_accuracy_user_data = NULL;
+
+ m_sensor_handle_infos.insert(pair<int,csensor_handle_info> (handle, handle_info));
+
+ return handle;
+}
+
+bool csensor_client_info::delete_handle(int handle)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ m_sensor_handle_infos.erase(it_handle);
+ return true;
+}
+
+
+bool csensor_client_info::is_active()
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ return !m_sensor_handle_infos.empty();
+}
+
+bool csensor_client_info::register_event(int handle, unsigned int event_type,
+ unsigned int interval, unsigned int latency, int cb_type, void *cb, void* user_data)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.add_reg_event_info(event_type, interval, latency, cb_type, cb, user_data))
+ return false;
+
+ return true;
+}
+
+bool csensor_client_info::unregister_event(int handle, unsigned int event_type)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.delete_reg_event_info(event_type))
+ return false;
+
+ return true;
+}
+
+bool csensor_client_info::register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void* user_data)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_accuracy = -1;
+ it_handle->second.m_accuracy_cb = cb;
+ it_handle->second.m_accuracy_user_data = user_data;
+
+ return true;
+}
+
+bool csensor_client_info::unregister_accuracy_cb(int handle)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_accuracy = -1;
+ it_handle->second.m_accuracy_cb = NULL;
+ it_handle->second.m_accuracy_user_data = NULL;
+
+ return true;
+}
+
+bool csensor_client_info::set_sensor_params(int handle, int sensor_state, int sensor_option)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_state = sensor_state;
+ it_handle->second.m_sensor_option = sensor_option;
+
+ return true;
+}
+
+bool csensor_client_info::get_sensor_params(int handle, int &sensor_state, int &sensor_option)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor_state = it_handle->second.m_sensor_state;
+ sensor_option = it_handle->second.m_sensor_option;
+
+ return true;
+}
+
+bool csensor_client_info::set_sensor_state(int handle, int sensor_state)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_state = sensor_state;
+
+ return true;
+}
+
+bool csensor_client_info::set_sensor_option(int handle, int sensor_option)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_option = sensor_option;
+
+ return true;
+}
+
+bool csensor_client_info::set_event_batch(int handle, unsigned int event_type, unsigned int interval, unsigned int latency)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ if (!it_handle->second.change_reg_event_batch(event_type, interval, latency))
+ return false;
+
+ return true;
+}
+
+bool csensor_client_info::set_accuracy(int handle, int accuracy)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_accuracy = accuracy;
+
+ return true;
+}
+
+bool csensor_client_info::set_bad_accuracy(int handle, int bad_accuracy)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_bad_accuracy = bad_accuracy;
+
+ return true;
+}
+
+bool csensor_client_info::get_event_info(int handle, unsigned int event_type, unsigned int &interval, unsigned int &latency, int &cb_type, void* &cb, void* &user_data)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ const creg_event_info *event_info;
+
+ event_info = it_handle->second.get_reg_event_info(event_type);
+
+ if (!event_info)
+ return NULL;
+
+
+ interval = event_info->m_interval;
+ cb_type = event_info->m_cb_type;
+ cb = event_info->m_cb;
+ user_data = event_info->m_user_data;
+ latency = event_info->m_latency;
+
+ return true;
+}
+
+
+void csensor_client_info::get_listening_sensors(sensor_id_vector &sensors)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ sensors.push_back(it_handle->second.m_sensor_id);
+ ++it_handle;
+ }
+
+ sort(sensors.begin(), sensors.end());
+ unique(sensors.begin(),sensors.end());
+}
+
+void csensor_client_info::get_sensor_rep(sensor_id_t sensor, sensor_rep& rep) {
+ const unsigned int INVALID_BATCH_VALUE = std::numeric_limits<unsigned int>::max();
+
+ rep.active = is_sensor_active(sensor);
+ rep.option = get_active_option(sensor);
+ if (!get_active_batch(sensor, rep.interval, rep.latency)) {
+ rep.interval = INVALID_BATCH_VALUE;
+ rep.latency = INVALID_BATCH_VALUE;
+ }
+
+ get_active_event_types(sensor, rep.event_types);
+}
+
+bool csensor_client_info::add_command_channel(sensor_id_t sensor, command_channel *cmd_channel)
+{
+ auto it_channel = m_command_channels.find(sensor);
+
+ if (it_channel != m_command_channels.end()) {
+ ERR("%s alreay has command_channel for %s", get_client_name(), get_sensor_name(sensor));
+ return false;
+ }
+
+ m_command_channels.insert(pair<sensor_id_t, command_channel *> (sensor, cmd_channel));
+
+ return true;
+
+}
+bool csensor_client_info::get_command_channel(sensor_id_t sensor, command_channel **cmd_channel)
+{
+ auto it_channel = m_command_channels.find(sensor);
+
+ if (it_channel == m_command_channels.end()) {
+ ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor));
+ return false;
+ }
+
+ *cmd_channel = it_channel->second;
+
+ return true;
+}
+
+
+bool csensor_client_info::close_command_channel(void)
+{
+ auto it_channel = m_command_channels.begin();
+
+ if (it_channel != m_command_channels.end()) {
+ delete it_channel->second;
+ ++it_channel;
+ }
+
+ m_command_channels.clear();
+
+ return true;
+}
+
+bool csensor_client_info::close_command_channel(sensor_id_t sensor_id)
+{
+ auto it_channel = m_command_channels.find(sensor_id);
+
+ if (it_channel == m_command_channels.end()) {
+ ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor_id));
+ return false;
+ }
+
+ delete it_channel->second;
+
+ m_command_channels.erase(it_channel);
+
+ return true;
+}
+
+
+bool csensor_client_info::has_client_id(void)
+{
+ return (m_client_id != CLIENT_ID_INVALID);
+}
+
+int csensor_client_info::get_client_id(void)
+{
+ return m_client_id;
+}
+
+void csensor_client_info::set_client_id(int client_id)
+{
+ m_client_id = client_id;
+}
+
+bool csensor_client_info::get_active_batch(sensor_id_t sensor, unsigned int &interval, unsigned int &latency)
+{
+ unsigned int min_interval = POLL_MAX_HZ_MS;
+ unsigned int min_latency = std::numeric_limits<unsigned int>::max();
+
+ bool active_sensor_found = false;
+ unsigned int _interval;
+ unsigned int _latency;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_id == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
+ active_sensor_found = true;
+ it_handle->second.get_batch(_interval, _latency);
+ min_interval = (_interval < min_interval) ? _interval : min_interval;
+ min_latency = (_latency < min_latency) ? _latency : min_latency;
+ }
+
+ ++it_handle;
+ }
+
+ if (!active_sensor_found) {
+ DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
+ return false;
+ }
+
+ interval = min_interval;
+ latency = min_latency;
+
+ return true;
+}
+
+unsigned int csensor_client_info::get_active_option(sensor_id_t sensor)
+{
+ int active_option = SENSOR_OPTION_DEFAULT;
+ bool active_sensor_found = false;
+ int option;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_id == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
+ active_sensor_found = true;
+ option = it_handle->second.m_sensor_option;
+ active_option = (option > active_option) ? option : active_option;
+ }
+
+ ++it_handle;
+ }
+
+ if (!active_sensor_found)
+ DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
+
+ return active_option;
+}
+
+bool csensor_client_info::get_sensor_id(int handle, sensor_id_t &sensor)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor = it_handle->second.m_sensor_id;
+
+ return true;
+}
+
+bool csensor_client_info::get_sensor_state(int handle, int &sensor_state)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor_state = it_handle->second.m_sensor_state;
+
+ return true;
+}
+
+bool csensor_client_info::get_sensor_wakeup(int handle, int &sensor_wakeup)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ sensor_wakeup = it_handle->second.m_sensor_wakeup;
+
+ return true;
+}
+
+bool csensor_client_info::set_sensor_wakeup(int handle, int sensor_wakeup)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end()) {
+ ERR("Handle[%d] is not found for client %s", handle, get_client_name());
+ return false;
+ }
+
+ it_handle->second.m_sensor_wakeup = sensor_wakeup;
+
+ return true;
+}
+
+void csensor_client_info::get_active_event_types(sensor_id_t sensor, event_type_vector &active_event_types)
+{
+ event_type_vector event_types;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_id == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
+ it_handle->second.get_reg_event_types(event_types);
+
+ ++it_handle;
+ }
+
+ if (event_types.empty())
+ return;
+
+ sort(event_types.begin(), event_types.end());
+
+ unique_copy(event_types.begin(), event_types.end(), back_inserter(active_event_types));
+
+}
+
+
+void csensor_client_info::get_all_handles(handle_vector &handles)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ handles.push_back(it_handle->first);
+ ++it_handle;
+ }
+}
+
+void csensor_client_info::get_sensor_handle_info(sensor_id_t sensor, sensor_handle_info_map &handles_info) {
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if (it_handle->second.m_sensor_id == sensor) {
+ handles_info.insert(pair<int,csensor_handle_info> (it_handle->first, it_handle->second));
+ }
+
+ ++it_handle;
+ }
+}
+
+void csensor_client_info::get_all_handle_info(sensor_handle_info_map &handles_info) {
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ handles_info.insert(pair<int,csensor_handle_info> (it_handle->first, it_handle->second));
+ ++it_handle;
+ }
+}
+
+bool csensor_client_info::is_sensor_registered(sensor_id_t sensor)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if (it_handle->second.m_sensor_id == sensor)
+ return true;
+
+ ++it_handle;
+ }
+
+ return false;
+}
+
+
+bool csensor_client_info::is_sensor_active(sensor_id_t sensor)
+{
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.begin();
+
+ while (it_handle != m_sensor_handle_infos.end()) {
+ if ((it_handle->second.m_sensor_id == sensor) &&
+ (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
+ return true;
+
+ ++it_handle;
+ }
+
+ return false;
+}
+
+bool csensor_client_info::is_event_active(int handle, unsigned int event_type, unsigned long long event_id)
+{
+ creg_event_info *event_info;
+
+ AUTOLOCK(m_handle_info_lock);
+
+ auto it_handle = m_sensor_handle_infos.find(handle);
+
+ if (it_handle == m_sensor_handle_infos.end())
+ return false;
+
+ event_info = it_handle->second.get_reg_event_info(event_type);
+ if (!event_info)
+ return false;
+
+ if (event_info->m_id != event_id)
+ return false;
+
+ return true;
+}
+
+void csensor_client_info::clear(void)
+{
+ close_command_channel();
+ m_sensor_handle_infos.clear();
+ m_command_channels.clear();
+ set_client_id(CLIENT_ID_INVALID);
+}
--- /dev/null
+/*
+ * libsensord
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef CSENSOR_CLIENT_INFO_H_
+#define CSENSOR_CLIENT_INFO_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include <csensor_handle_info.h>
+#include <unistd.h>
+#include <csocket.h>
+#include <string.h>
+#include <sf_common.h>
+#include <algorithm>
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+#include <cmutex.h>
+#include <poller.h>
+
+using std::unordered_map;
+using std::vector;
+using std::string;
+using std::queue;
+using std::mutex;
+using std::lock_guard;
+using std::unique_lock;
+using std::condition_variable;
+
+typedef vector<unsigned int> handle_vector;
+typedef vector<sensor_id_t> sensor_id_vector;
+typedef unordered_map<int,csensor_handle_info> sensor_handle_info_map;
+typedef unordered_map<sensor_id_t, command_channel*> sensor_command_channel_map;
+
+typedef struct sensor_rep
+{
+ bool active;
+ int option;
+ unsigned int interval;
+ unsigned int latency;
+ event_type_vector event_types;
+} sensor_rep;
+
+class csensor_client_info {
+public:
+ static csensor_client_info& get_instance(void);
+ int create_handle(sensor_id_t sensor_id);
+ bool delete_handle(int handle);
+ bool register_event(int handle, unsigned int event_type,
+ unsigned int interval, unsigned int latency, int cb_type, void *cb, void* user_data);
+ bool unregister_event(int handle, unsigned int event_type);
+
+ bool register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void* user_data);
+ bool unregister_accuracy_cb(int handle);
+
+ bool set_sensor_params(int handle, int sensor_state, int sensor_option);
+ bool get_sensor_params(int handle, int &sensor_state, int &sensor_option);
+ bool set_sensor_state(int handle, int sensor_state);
+ bool set_sensor_option(int handle, int sensor_option);
+ bool set_event_batch(int handle, unsigned int event_type, unsigned int interval, unsigned int latency);
+ bool set_accuracy(int handle, int accuracy);
+ bool set_bad_accuracy(int handle, int bad_accuracy);
+ bool get_event_info(int handle, unsigned int event_type, unsigned int &interval, unsigned int &latency, int &cb_type, void* &cb, void* &user_data);
+ void get_listening_sensors(sensor_id_vector &sensors);
+ void get_sensor_rep(sensor_id_t sensor, sensor_rep& rep);
+
+ bool get_active_batch(sensor_id_t sensor, unsigned int &interval, unsigned int &latency);
+ unsigned int get_active_option(sensor_id_t sensor_id);
+ void get_active_event_types(sensor_id_t sensor_id, event_type_vector &active_event_types);
+
+ bool get_sensor_id(int handle, sensor_id_t &sensor_id);
+ bool get_sensor_state(int handle, int &state);
+ bool get_sensor_wakeup(int handle, int &sensor_wakeup);
+ bool set_sensor_wakeup(int handle, int sensor_wakeup);
+
+ bool has_client_id(void);
+ int get_client_id(void);
+ void set_client_id(int client_id);
+
+ bool is_active(void);
+ bool is_sensor_registered(sensor_id_t sensor_id);
+ bool is_sensor_active(sensor_id_t sensor_id);
+ bool is_event_active(int handle, unsigned int event_type, unsigned long long event_id);
+
+ bool add_command_channel(sensor_id_t sensor_id, command_channel *cmd_channel);
+ bool get_command_channel(sensor_id_t sensor_id, command_channel **cmd_channel);
+ bool close_command_channel(void);
+ bool close_command_channel(sensor_id_t sensor_id);
+
+ void get_all_handles(handle_vector &handles);
+ void get_sensor_handle_info(sensor_id_t sensor, sensor_handle_info_map &handles_info);
+ void get_all_handle_info(sensor_handle_info_map &handles_info);
+
+ void clear(void);
+
+ csensor_client_info();
+ ~csensor_client_info();
+
+private:
+ sensor_handle_info_map m_sensor_handle_infos;
+ sensor_command_channel_map m_command_channels;
+
+ int m_client_id;
+
+ cmutex m_handle_info_lock;
+};
+#endif /* CSENSOR_CLIENT_INFO_H_ */
using std::vector;
csensor_event_listener::csensor_event_listener()
-: m_client_id(CLIENT_ID_INVALID)
-, m_poller(NULL)
+: m_poller(NULL)
, m_thread_state(THREAD_STATE_TERMINATE)
, m_hup_observer(NULL)
+, m_client_info(csensor_client_info::get_instance())
{
}
stop_event_listener();
}
-
-csensor_event_listener& csensor_event_listener::get_instance(void)
+csensor_event_listener::csensor_event_listener(const csensor_event_listener& listener)
+: m_poller(listener.m_poller)
+, m_thread_state(listener.m_thread_state)
+, m_hup_observer(listener.m_hup_observer)
+, m_client_info(listener.m_client_info)
{
- static csensor_event_listener inst;
- return inst;
}
-int csensor_event_listener::create_handle(sensor_id_t sensor)
-{
- csensor_handle_info handle_info;
- int handle = 0;
-
- AUTOLOCK(m_handle_info_lock);
-
- while (m_sensor_handle_infos.count(handle) > 0)
- handle++;
-
- if (handle == MAX_HANDLE) {
- ERR("Handles of client %s are full", get_client_name());
- return MAX_HANDLE_REACHED;
- }
-
- handle_info.m_sensor_id = sensor;
- handle_info.m_sensor_state = SENSOR_STATE_STOPPED;
- handle_info.m_sensor_option = SENSOR_OPTION_DEFAULT;
- handle_info.m_handle = handle;
- handle_info.m_accuracy = -1;
- handle_info.m_accuracy_cb = NULL;
- handle_info.m_accuracy_user_data = NULL;
-
- m_sensor_handle_infos.insert(pair<int,csensor_handle_info> (handle, handle_info));
-
- return handle;
-}
-
-bool csensor_event_listener::delete_handle(int handle)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- m_sensor_handle_infos.erase(it_handle);
- return true;
-}
-
-
-bool csensor_event_listener::is_active()
+csensor_event_listener& csensor_event_listener::get_instance(void)
{
- AUTOLOCK(m_handle_info_lock);
-
- return !m_sensor_handle_infos.empty();
+ static csensor_event_listener inst;
+ return inst;
}
bool csensor_event_listener::start_handle(int handle)
{
- return set_sensor_state(handle, SENSOR_STATE_STARTED);
+ return m_client_info.set_sensor_state(handle, SENSOR_STATE_STARTED);
}
bool csensor_event_listener::stop_handle(int handle)
{
- return set_sensor_state(handle, SENSOR_STATE_STOPPED);
-}
-
-bool csensor_event_listener::register_event(int handle, unsigned int event_type,
- unsigned int interval, unsigned int latency, int cb_type, void *cb, void* user_data)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- if (!it_handle->second.add_reg_event_info(event_type, interval, latency, cb_type, cb, user_data))
- return false;
-
- return true;
-}
-
-bool csensor_event_listener::unregister_event(int handle, unsigned int event_type)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- if (!it_handle->second.delete_reg_event_info(event_type))
- return false;
-
- return true;
-}
-
-bool csensor_event_listener::register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void* user_data)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_accuracy = -1;
- it_handle->second.m_accuracy_cb = cb;
- it_handle->second.m_accuracy_user_data = user_data;
-
- return true;
-}
-
-bool csensor_event_listener::unregister_accuracy_cb(int handle)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_accuracy = -1;
- it_handle->second.m_accuracy_cb = NULL;
- it_handle->second.m_accuracy_user_data = NULL;
-
- return true;
-}
-
-bool csensor_event_listener::set_sensor_params(int handle, int sensor_state, int sensor_option)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_sensor_state = sensor_state;
- it_handle->second.m_sensor_option = sensor_option;
-
- return true;
-}
-
-bool csensor_event_listener::get_sensor_params(int handle, int &sensor_state, int &sensor_option)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- sensor_state = it_handle->second.m_sensor_state;
- sensor_option = it_handle->second.m_sensor_option;
-
- return true;
-}
-
-bool csensor_event_listener::set_sensor_state(int handle, int sensor_state)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_sensor_state = sensor_state;
-
- return true;
-}
-
-bool csensor_event_listener::set_sensor_option(int handle, int sensor_option)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_sensor_option = sensor_option;
-
- return true;
-}
-
-bool csensor_event_listener::set_event_batch(int handle, unsigned int event_type, unsigned int interval, unsigned int latency)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- if (!it_handle->second.change_reg_event_batch(event_type, interval, latency))
- return false;
-
- return true;
-}
-
-
-bool csensor_event_listener::get_event_info(int handle, unsigned int event_type, unsigned int &interval, unsigned int &latency, int &cb_type, void* &cb, void* &user_data)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- const creg_event_info *event_info;
-
- event_info = it_handle->second.get_reg_event_info(event_type);
-
- if (!event_info)
- return NULL;
-
- interval = event_info->m_interval;
- latency = event_info->m_latency;
- cb_type = event_info->m_cb_type;
- cb = event_info->m_cb;
- user_data = event_info->m_user_data;
-
- return true;
-}
-
-
-void csensor_event_listener::get_listening_sensors(sensor_id_vector &sensors)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- sensors.push_back(it_handle->second.m_sensor_id);
- ++it_handle;
- }
-
- sort(sensors.begin(), sensors.end());
- unique(sensors.begin(),sensors.end());
-}
-
-
-void csensor_event_listener::get_sensor_rep(sensor_id_t sensor, sensor_rep& rep)
-{
- const unsigned int INVALID_BATCH_VALUE = std::numeric_limits<unsigned int>::max();
-
- AUTOLOCK(m_handle_info_lock);
-
- rep.active = is_sensor_active(sensor);
- rep.option = get_active_option(sensor);
- if (!get_active_batch(sensor, rep.interval, rep.latency)) {
- rep.interval = INVALID_BATCH_VALUE;
- rep.latency = INVALID_BATCH_VALUE;
- }
-
- get_active_event_types(sensor, rep.event_types);
+ return m_client_info.set_sensor_state(handle, SENSOR_STATE_STOPPED);
}
void csensor_event_listener::operate_sensor(sensor_id_t sensor, int power_save_state)
{
- AUTOLOCK(m_handle_info_lock);
+ sensor_handle_info_map handles_info;
+
+ m_client_info.get_sensor_handle_info(sensor, handles_info);
- auto it_handle = m_sensor_handle_infos.begin();
+ auto it_handle = handles_info.begin();
- while (it_handle != m_sensor_handle_infos.end()) {
+ while (it_handle != handles_info.end()) {
if (it_handle->second.m_sensor_id == sensor) {
if ((it_handle->second.m_sensor_state == SENSOR_STATE_STARTED) &&
power_save_state &&
!(it_handle->second.m_sensor_option & power_save_state)) {
- it_handle->second.m_sensor_state = SENSOR_STATE_PAUSED;
+ m_client_info.set_sensor_state(it_handle->first, SENSOR_STATE_PAUSED);
INFO("%s's %s[%d] is paused", get_client_name(), get_sensor_name(sensor), it_handle->first);
} else if ((it_handle->second.m_sensor_state == SENSOR_STATE_PAUSED) &&
(!power_save_state || (it_handle->second.m_sensor_option & power_save_state))) {
- it_handle->second.m_sensor_state = SENSOR_STATE_STARTED;
+ m_client_info.set_sensor_state(it_handle->first, SENSOR_STATE_STARTED);
INFO("%s's %s[%d] is resumed", get_client_name(), get_sensor_name(sensor), it_handle->first);
}
}
}
}
-bool csensor_event_listener::add_command_channel(sensor_id_t sensor, command_channel *cmd_channel)
-{
- auto it_channel = m_command_channels.find(sensor);
-
- if (it_channel != m_command_channels.end()) {
- ERR("%s alreay has command_channel for %s", get_client_name(), get_sensor_name(sensor));
- return false;
- }
-
- m_command_channels.insert(pair<sensor_id_t, command_channel *> (sensor, cmd_channel));
-
- return true;
-
-}
-bool csensor_event_listener::get_command_channel(sensor_id_t sensor, command_channel **cmd_channel)
-{
- auto it_channel = m_command_channels.find(sensor);
-
- if (it_channel == m_command_channels.end()) {
- ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor));
- return false;
- }
-
- *cmd_channel = it_channel->second;
-
- return true;
-}
-
-
-bool csensor_event_listener::close_command_channel(void)
-{
- auto it_channel = m_command_channels.begin();
-
- if (it_channel != m_command_channels.end()) {
- delete it_channel->second;
- ++it_channel;
- }
-
- m_command_channels.clear();
-
- return true;
-}
-
-bool csensor_event_listener::close_command_channel(sensor_id_t sensor_id)
-{
- auto it_channel = m_command_channels.find(sensor_id);
-
- if (it_channel == m_command_channels.end()) {
- ERR("%s doesn't have command_channel for %s", get_client_name(), get_sensor_name(sensor_id));
- return false;
- }
-
- delete it_channel->second;
-
- m_command_channels.erase(it_channel);
-
- return true;
-}
-
-
-bool csensor_event_listener::has_client_id(void)
-{
- return (m_client_id != CLIENT_ID_INVALID);
-}
-
-int csensor_event_listener::get_client_id(void)
-{
- return m_client_id;
-}
-
-void csensor_event_listener::set_client_id(int client_id)
-{
- m_client_id = client_id;
-}
-
-bool csensor_event_listener::get_active_batch(sensor_id_t sensor, unsigned int &interval, unsigned int &latency)
-{
- unsigned int min_interval = POLL_MAX_HZ_MS;
- unsigned int min_latency = std::numeric_limits<unsigned int>::max();
-
- bool active_sensor_found = false;
- unsigned int _interval;
- unsigned int _latency;
-
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- if ((it_handle->second.m_sensor_id == sensor) &&
- (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
- active_sensor_found = true;
- it_handle->second.get_batch(_interval, _latency);
- min_interval = (_interval < min_interval) ? _interval : min_interval;
- min_latency = (_latency < min_latency) ? _latency : min_latency;
- }
-
- ++it_handle;
- }
-
- if (!active_sensor_found) {
- DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
- return false;
- }
-
- interval = min_interval;
- latency = min_latency;
-
- return true;
-}
-
-unsigned int csensor_event_listener::get_active_option(sensor_id_t sensor)
-{
- int active_option = SENSOR_OPTION_DEFAULT;
- bool active_sensor_found = false;
- int option;
-
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- if ((it_handle->second.m_sensor_id == sensor) &&
- (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED)) {
- active_sensor_found = true;
- option = it_handle->second.m_sensor_option;
- active_option = (option > active_option) ? option : active_option;
- }
-
- ++it_handle;
- }
-
- if (!active_sensor_found)
- DBG("Active sensor[0x%x] is not found for client %s", sensor, get_client_name());
-
- return active_option;
-}
-
-bool csensor_event_listener::get_sensor_id(int handle, sensor_id_t &sensor)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- sensor = it_handle->second.m_sensor_id;
-
- return true;
-}
-
-bool csensor_event_listener::get_sensor_state(int handle, int &sensor_state)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- sensor_state = it_handle->second.m_sensor_state;
-
- return true;
-}
-
-bool csensor_event_listener::get_sensor_wakeup(int handle, int &sensor_wakeup)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- sensor_wakeup = it_handle->second.m_sensor_wakeup;
-
- return true;
-}
-
-bool csensor_event_listener::set_sensor_wakeup(int handle, int sensor_wakeup)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end()) {
- ERR("Handle[%d] is not found for client %s", handle, get_client_name());
- return false;
- }
-
- it_handle->second.m_sensor_wakeup = sensor_wakeup;
-
- return true;
-}
-
-void csensor_event_listener::get_active_event_types(sensor_id_t sensor, event_type_vector &active_event_types)
-{
- event_type_vector event_types;
-
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- if ((it_handle->second.m_sensor_id == sensor) &&
- (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
- it_handle->second.get_reg_event_types(event_types);
-
- ++it_handle;
- }
-
- if (event_types.empty())
- return;
-
- sort(event_types.begin(), event_types.end());
-
- unique_copy(event_types.begin(), event_types.end(), back_inserter(active_event_types));
-
-}
-
-
-void csensor_event_listener::get_all_handles(handle_vector &handles)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- handles.push_back(it_handle->first);
- ++it_handle;
- }
-}
-
-bool csensor_event_listener::is_sensor_registered(sensor_id_t sensor)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- if (it_handle->second.m_sensor_id == sensor)
- return true;
-
- ++it_handle;
- }
-
- return false;
-}
-
-
-bool csensor_event_listener::is_sensor_active(sensor_id_t sensor)
-{
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.begin();
-
- while (it_handle != m_sensor_handle_infos.end()) {
- if ((it_handle->second.m_sensor_id == sensor) &&
- (it_handle->second.m_sensor_state == SENSOR_STATE_STARTED))
- return true;
-
- ++it_handle;
- }
-
- return false;
-}
-
client_callback_info* csensor_event_listener::handle_calibration_cb(csensor_handle_info &handle_info, unsigned event_type, unsigned long long time, int accuracy)
{
unsigned int cal_event_type = get_calibration_event_type(event_type);
cal_callback_info = get_callback_info(handle_info.m_sensor_id, cal_event_info, cal_sensor_data);
- handle_info.m_bad_accuracy = true;
+ m_client_info.set_bad_accuracy(handle_info.m_handle, true);
print_event_occurrence_log(handle_info, cal_event_info);
}
if ((accuracy != SENSOR_ACCURACY_BAD) && handle_info.m_bad_accuracy)
- handle_info.m_bad_accuracy = false;
+ m_client_info.set_bad_accuracy(handle_info.m_handle, false);
return cal_callback_info;
}
creg_event_info *event_info = NULL;
sensor_event_data_t event_data;
sensor_id_t sensor_id;
+ sensor_handle_info_map handles_info;
void *sensor_data;
sensor_panning_data_t panning_data;
}
{ /* scope for the lock */
- AUTOLOCK(m_handle_info_lock);
+ m_client_info.get_all_handle_info(handles_info);
- for (auto it_handle = m_sensor_handle_infos.begin(); it_handle != m_sensor_handle_infos.end(); ++it_handle) {
+ for (auto it_handle = handles_info.begin(); it_handle != handles_info.end(); ++it_handle) {
csensor_handle_info &sensor_handle_info = it_handle->second;
}
if (sensor_handle_info.m_accuracy != accuracy) {
- sensor_handle_info.m_accuracy = accuracy;
+ m_client_info.set_accuracy(sensor_handle_info.m_handle, accuracy);
callback_info->accuracy_cb = sensor_handle_info.m_accuracy_cb;
callback_info->timestamp = cur_time;
g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
}
-
-bool csensor_event_listener::is_event_active(int handle, unsigned int event_type, unsigned long long event_id)
-{
- creg_event_info *event_info;
-
- AUTOLOCK(m_handle_info_lock);
-
- auto it_handle = m_sensor_handle_infos.find(handle);
-
- if (it_handle == m_sensor_handle_infos.end())
- return false;
-
- event_info = it_handle->second.get_reg_event_info(event_type);
- if (!event_info)
- return false;
-
- if (event_info->m_id != event_id)
- return false;
-
- return true;
-}
-
-
bool csensor_event_listener::is_valid_callback(client_callback_info *cb_info)
{
- return is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
+ return m_client_info.is_event_active(cb_info->handle, cb_info->event_type, cb_info->event_id);
}
gboolean csensor_event_listener::callback_dispatcher(gpointer data)
INFO("Event listener thread is terminated.");
- if (has_client_id() && (event & EPOLLHUP)) {
+ if (m_client_info.has_client_id() && (event & EPOLLHUP)) {
if (m_hup_observer)
m_hup_observer();
}
m_event_socket.set_connection_mode();
- client_id = get_client_id();
+ client_id = m_client_info.get_client_id();
if (m_event_socket.send(&client_id, sizeof(client_id)) <= 0) {
ERR("Failed to send client id for client %s on event socket[%d]", get_client_name(), m_event_socket.get_socket_fd());
{
close_event_channel();
stop_event_listener();
- close_command_channel();
- m_sensor_handle_infos.clear();
- set_client_id(CLIENT_ID_INVALID);
+ m_client_info.close_command_channel();
+ m_client_info.clear();
+ m_client_info.set_client_id(CLIENT_ID_INVALID);
}
#include <glib.h>
#include <sys/types.h>
#include <csensor_handle_info.h>
+#include <csensor_client_info.h>
#include <unistd.h>
#include <csocket.h>
#include <string.h>
void *accuracy_user_data;
} client_callback_info;
-typedef struct sensor_rep
-{
- bool active;
- int option;
- unsigned int interval;
- unsigned int latency;
- event_type_vector event_types;
-} sensor_rep;
-
typedef void (*hup_observer_t)(void);
class csensor_event_listener {
public:
static csensor_event_listener& get_instance(void);
- int create_handle(sensor_id_t sensor_id);
- bool delete_handle(int handle);
bool start_handle(int handle);
bool stop_handle(int handle);
- bool register_event(int handle, unsigned int event_type, unsigned int interval, unsigned int latency, int cb_type, void *cb, void* user_data);
- bool unregister_event(int handle, unsigned int event_type);
-
- bool register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void* user_data);
- bool unregister_accuracy_cb(int handle);
-
- bool set_sensor_params(int handle, int sensor_state, int sensor_option);
- bool get_sensor_params(int handle, int &sensor_state, int &sensor_option);
- bool set_sensor_state(int handle, int sensor_state);
- bool set_sensor_option(int handle, int sensor_option);
- bool set_event_batch(int handle, unsigned int event_type, unsigned int interval, unsigned int latency);
- bool get_event_info(int handle, unsigned int event_type, unsigned int &interval, unsigned int &latency, int &cb_type, void* &cb, void* &user_data);
+
void operate_sensor(sensor_id_t sensor, int power_save_state);
void get_listening_sensors(sensor_id_vector &sensors);
- bool get_active_batch(sensor_id_t sensor_id, unsigned int &interval, unsigned int &latency);
- unsigned int get_active_option(sensor_id_t sensor_id);
- void get_active_event_types(sensor_id_t sensor_id, event_type_vector &active_event_types);
-
- bool get_sensor_id(int handle, sensor_id_t &sensor_id);
- bool get_sensor_state(int handle, int &state);
-
- bool get_sensor_wakeup(int handle, int &sensor_wakeup);
- bool set_sensor_wakeup(int handle, int sensor_wakeup);
-
- void get_sensor_rep(sensor_id_t sensor_id, sensor_rep& rep);
-
- bool has_client_id(void);
- int get_client_id(void);
- void set_client_id(int client_id);
-
- bool is_active(void);
- bool is_sensor_registered(sensor_id_t sensor_id);
- bool is_sensor_active(sensor_id_t sensor_id);
-
- bool add_command_channel(sensor_id_t sensor_id, command_channel *cmd_channel);
- bool get_command_channel(sensor_id_t sensor_id, command_channel **cmd_channel);
- bool close_command_channel(void);
- bool close_command_channel(sensor_id_t sensor_id);
-
- void get_all_handles(handle_vector &handles);
-
bool start_event_listener(void);
void stop_event_listener(void);
void clear(void);
typedef std::lock_guard<std::mutex> lock;
typedef std::unique_lock<std::mutex> ulock;
- sensor_handle_info_map m_sensor_handle_infos;
- sensor_command_channel_map m_command_channels;
-
- int m_client_id;
-
csocket m_event_socket;
poller *m_poller;
- cmutex m_handle_info_lock;
-
thread_state m_thread_state;
std::mutex m_thread_mutex;
std::condition_variable m_thread_cond;
csensor_event_listener();
~csensor_event_listener();
- csensor_event_listener(const csensor_event_listener&) {};
+ csensor_event_listener(const csensor_event_listener&);
csensor_event_listener& operator=(const csensor_event_listener&);
bool create_event_channel(void);
void post_callback_to_main_loop(client_callback_info *cb_info);
- bool is_event_active(int handle, unsigned int event_type, unsigned long long event_id);
bool is_valid_callback(client_callback_info *cb_info);
static gboolean callback_dispatcher(gpointer data);
void set_thread_state(thread_state state);
+
+ csensor_client_info &m_client_info;
};
#endif /* CSENSOR_EVENT_LISTENER_H_ */