From 26eff59fb807a5f0a943f3cb96392ae8f7d0485f Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 19:14:20 +0900 Subject: [PATCH] sensord: implement server_channel_handler - server_channel_handler is a handler that responds to client request. Change-Id: I788010896384f686fa271d61662cd09ae48ca4c2 Signed-off-by: kibak.yoon --- src/server/server_channel_handler.cpp | 128 +++++++++++++++++++++++++++++++--- src/server/server_channel_handler.h | 12 +++- 2 files changed, 128 insertions(+), 12 deletions(-) diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index afcfa4e..a34f58f 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -21,6 +21,7 @@ #include #include +#include #include using namespace sensor; @@ -41,6 +42,13 @@ void server_channel_handler::connected(channel *ch) void server_channel_handler::disconnected(channel *ch) { + auto it = m_listeners.find(ch); + ret_if(it == m_listeners.end()); + + _I("Disconnected listener[%u]", it->second->get_id()); + + delete it->second; + m_listeners.erase(ch); } void server_channel_handler::read(channel *ch, message &msg) @@ -81,55 +89,153 @@ void server_channel_handler::read(channel *ch, message &msg) int server_channel_handler::manager_get_sensor_list(channel *ch, message &msg) { - return OP_ERROR; + ipc::message reply; + char *bytes; + int size; + + size = m_manager->serialize(ch->get_fd(), &bytes); + retv_if(size < 0, size); + + reply.enclose((const char *)bytes, size); + ch->send_sync(&reply); + + delete [] bytes; + + return OP_SUCCESS; } int server_channel_handler::listener_connect(channel *ch, message &msg) { - return OP_ERROR; + static uint32_t listener_id = 1; + sensor_handler *sensor; + cmd_listener_connect_t buf; + + msg.disclose((char *)&buf); + + sensor = m_manager->get_sensor(buf.sensor); + retv_if(!sensor, OP_ERROR); + + sensor_listener_proxy *listener = + new(std::nothrow) sensor_listener_proxy(listener_id, sensor, ch); + retvm_if(!listener, OP_ERROR, "Failed to allocate memory"); + + buf.listener_id = listener_id; + + message reply; + reply.enclose((const char *)&buf, sizeof(buf)); + reply.header()->err = OP_SUCCESS; + + if (!ch->send_sync(&reply)) + return OP_ERROR; + + _I("Connected sensor_listener[fd(%d) -> id(%u)]", ch->get_fd(), listener_id); + listener_id++; + m_listeners[ch] = listener; + + return OP_SUCCESS; } int server_channel_handler::listener_disconnect(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + uint32_t id = m_listeners[ch]->get_id(); + + delete m_listeners[ch]; + m_listeners.erase(ch); + + _D("Disconnected sensor_listener[%u]", id); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_start(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + int ret = m_listeners[ch]->start(); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_stop(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + int ret = m_listeners[ch]->stop(); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_attr_int(channel *ch, message &msg) { - return OP_ERROR; + int ret = OP_SUCCESS; + + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + cmd_listener_attr_int_t buf; + msg.disclose((char *)&buf); + + switch (buf.attribute) { + case SENSORD_ATTRIBUTE_INTERVAL: + ret = m_listeners[ch]->set_interval(buf.value); break; + case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY: + ret = m_listeners[ch]->set_max_batch_latency(buf.value); break; + case SENSORD_ATTRIBUTE_PASSIVE_MODE: + ret = m_listeners[ch]->set_passive_mode(buf.value); break; + case SENSORD_ATTRIBUTE_PAUSE_POLICY: + case SENSORD_ATTRIBUTE_AXIS_ORIENTATION: + default: + ret = m_listeners[ch]->set_attribute(buf.attribute, buf.value); + } + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_attr_str(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + cmd_listener_attr_str_t buf; + msg.disclose((char *)&buf); + + int ret = m_listeners[ch]->set_attribute(buf.attribute, buf.value, buf.len); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_get_data(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_connect(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_disconnect(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_post(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); +} + +int server_channel_handler::send_reply(channel *ch, int error) +{ + message reply(error); + retvm_if(!ch->send_sync(&reply), OP_ERROR, "Failed to send reply"); + return OP_SUCCESS; } diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index 76ea4a3..d48ff7e 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -26,10 +26,11 @@ #include #include "sensor_manager.h" +#include "sensor_listener_proxy.h" +#include "application_sensor_handler.h" namespace sensor { -/* TODO: this class seems to be able to split */ class server_channel_handler : public ipc::channel_handler { public: @@ -57,7 +58,16 @@ private: int provider_disconnect(ipc::channel *ch, ipc::message &msg); int provider_post(ipc::channel *ch, ipc::message &msg); + int send_reply(ipc::channel *ch, int error); + sensor_manager *m_manager; + + /* {fd, listener} */ + std::unordered_map m_listeners; + + /* {name, application_sensor_handler} */ + /* TODO: move it to sensor_manager */ + std::unordered_map m_sensors; }; } -- 2.7.4