From d1e1914574deef5df62b3a3c38f11c1658e79ae9 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 15:33:47 +0900 Subject: [PATCH] sensord: implement sensor_listener class for clients - sensor_listener provides: - controls for sensor actions such as start and stop. - controls for changing sensor settings - listening for sensor events from server Change-Id: I7216b282cc3429d0864b4343d65ff192951b1038 Signed-off-by: kibak.yoon --- src/client/sensor_listener.cpp | 238 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 222 insertions(+), 16 deletions(-) diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index 83145ef..da9dbe8 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -34,8 +34,25 @@ public: : m_listener(listener) {} void connected(ipc::channel *ch) {} - void disconnected(ipc::channel *ch) {} - void read(ipc::channel *ch, ipc::message &msg) {} + void disconnected(ipc::channel *ch) + { + /* If channel->disconnect() is not explicitly called, + * listener will be restored */ + m_listener->restore(); + } + + void read(ipc::channel *ch, ipc::message &msg) + { + switch (msg.header()->type) { + case CMD_LISTENER_EVENT: + if (m_listener->get_event_handler()) + m_listener->get_event_handler()->read(ch, msg); + case CMD_LISTENER_ACC_EVENT: + if (m_listener->get_accuracy_handler()) + m_listener->get_accuracy_handler()->read(ch, msg); + } + } + void read_complete(ipc::channel *ch) {} void error_caught(ipc::channel *ch, int error) {} @@ -64,11 +81,37 @@ sensor_listener::~sensor_listener() bool sensor_listener::init(void) { + m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH); + retvm_if(!m_client, false, "Failed to allocate memory"); + + m_handler = new(std::nothrow) listener_handler(this); + if (!m_handler) { + delete m_client; + return false; + } + + if (!connect()) { + delete m_handler; + delete m_client; + m_handler = NULL; + m_client = NULL; + return false; + } + return true; } void sensor_listener::deinit(void) { + disconnect(); + + delete m_handler; + m_handler = NULL; + + delete m_client; + m_client = NULL; + + m_attributes.clear(); } int sensor_listener::get_id(void) @@ -83,18 +126,66 @@ sensor_t sensor_listener::get_sensor(void) void sensor_listener::restore(void) { + ret_if(!is_connected()); + retm_if(!connect(), "Failed to restore listener"); + + /* Restore attributes/status */ + if (m_started.load()) + start(); + + auto interval = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL); + if (interval != m_attributes.end()) + set_interval(m_attributes[SENSORD_ATTRIBUTE_INTERVAL]); + + auto latency = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY); + if (latency != m_attributes.end()) + set_max_batch_latency(m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]); + _D("Restored listener[%d]", get_id()); } bool sensor_listener::connect(void) { - _I("Listener ID[%d]", get_id()); + m_channel = m_client->connect(m_handler, &m_loop); + retvm_if(!m_channel, false, "Failed to connect to server"); + + ipc::message msg; + ipc::message reply; + cmd_listener_connect_t buf = {0, }; + + memcpy(buf.sensor, m_sensor->get_uri().c_str(), m_sensor->get_uri().size()); + msg.set_type(CMD_LISTENER_CONNECT); + msg.enclose((const char *)&buf, sizeof(buf)); + m_channel->send_sync(&msg); + + m_channel->read_sync(reply); + reply.disclose((char *)&buf); + + m_id = buf.listener_id; + m_connected.store(true); + + _D("Listener ID[%d]", get_id()); return true; } void sensor_listener::disconnect(void) { + ret_if(!is_connected()); + m_connected.store(false); + + ipc::message msg; + ipc::message reply; + + msg.set_type(CMD_LISTENER_DISCONNECT); + m_channel->send_sync(&msg); + + m_channel->read_sync(reply); + m_channel->disconnect(); + + delete m_channel; + m_channel = NULL; + _I("Disconnected[%d]", get_id()); } @@ -131,71 +222,186 @@ void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler) void sensor_listener::unset_accuracy_handler(void) { + delete m_acc_handler; m_acc_handler = NULL; } int sensor_listener::start(void) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_start_t buf; + + retvm_if(!m_channel, -EINVAL, "Failed to connect to server"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_START); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_started.store(true); + + return OP_SUCCESS; } int sensor_listener::stop(void) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_stop_t buf; + + retvm_if(!m_channel, -EINVAL, "Failed to connect to server"); + retvm_if(!m_started.load(), -EAGAIN, "Already stopped"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_STOP); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_started.store(false); + + return OP_SUCCESS; } int sensor_listener::get_interval(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_INTERVAL]; } int sensor_listener::get_max_batch_latency(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]; } int sensor_listener::get_pause_policy(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_PAUSE_POLICY); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_PAUSE_POLICY]; } int sensor_listener::get_passive_mode(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_PASSIVE_MODE); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_PASSIVE_MODE]; } int sensor_listener::set_interval(unsigned int interval) { - return OP_ERROR; + int _interval; + + /* TODO: move this logic to server */ + if (interval == 0) + _interval = DEFAULT_INTERVAL; + else if (interval < (unsigned int)m_sensor->get_min_interval()) + _interval = m_sensor->get_min_interval(); + else + _interval = interval; + + return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval); } int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency); } int sensor_listener::set_passive_mode(bool passive) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive); } int sensor_listener::flush(void) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1); } int sensor_listener::set_attribute(int attribute, int value) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_int_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + buf.listener_id = m_id; + buf.attribute = attribute; + buf.value = value; + msg.set_type(CMD_LISTENER_ATTR_INT); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_attributes[attribute] = value; + + return OP_SUCCESS; } int sensor_listener::set_attribute(int attribute, const char *value, int len) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_str_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + msg.set_type(CMD_LISTENER_ATTR_STR); + buf.listener_id = m_id; + buf.attribute = attribute; + memcpy(buf.value, value, len); + buf.len = len; + + msg.enclose((char *)&buf, sizeof(buf) + len); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + return reply.header()->err; } int sensor_listener::get_sensor_data(sensor_data_t *data) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_get_data_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_GET_DATA); + msg.enclose((char *)&buf, sizeof(buf)); + m_channel->send_sync(&msg); + + m_channel->read_sync(reply); + /* TODO */ + /* + reply.disclose((char *)&buf); + memcpy(data, buf.data, sizeof(buf.len)); + */ + + return OP_SUCCESS; } -- 2.7.4