sensord: implement server_channel_handler 57/123657/1
authorkibak.yoon <kibak.yoon@samsung.com>
Thu, 6 Apr 2017 10:14:20 +0000 (19:14 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Thu, 6 Apr 2017 10:14:20 +0000 (19:14 +0900)
- server_channel_handler is a handler that responds to client request.

Change-Id: I788010896384f686fa271d61662cd09ae48ca4c2
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/server/server_channel_handler.cpp
src/server/server_channel_handler.h

index afcfa4e..a34f58f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <sensor_log.h>
 #include <sensor_info.h>
+#include <sensor_handler.h>
 #include <command_types.h>
 
 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;
 }
index 76ea4a3..d48ff7e 100644 (file)
 #include <functional>
 
 #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<ipc::channel *, sensor_listener_proxy *> m_listeners;
+
+       /* {name, application_sensor_handler} */
+       /* TODO: move it to sensor_manager */
+       std::unordered_map<std::string, application_sensor_handler *> m_sensors;
 };
 
 }