sensord: implement application sensor handler 61/126561/6
authorkibak.yoon <kibak.yoon@samsung.com>
Mon, 24 Apr 2017 07:13:00 +0000 (16:13 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Mon, 24 Apr 2017 10:23:32 +0000 (19:23 +0900)
Change-Id: If415a7268adf9d7cd5870ba62a0f4bd7497baccf
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/server/application_sensor_handler.cpp
src/server/application_sensor_handler.h
src/server/server_channel_handler.cpp
src/server/server_channel_handler.h

index 1070156..a6bd0bd 100644 (file)
 
 #include "application_sensor_handler.h"
 
+#include <message.h>
+#include <command_types.h>
 #include <sensor_log.h>
 #include <algorithm>
 
 using namespace sensor;
 
-application_sensor_handler::application_sensor_handler(const sensor_info &info)
+application_sensor_handler::application_sensor_handler(const sensor_info &info, ipc::channel *ch)
 : m_info(info)
+, m_ch(ch)
+, m_started(false)
+, m_prev_interval(0)
 {
 }
 
@@ -33,7 +38,7 @@ application_sensor_handler::~application_sensor_handler()
 {
 }
 
-int application_sensor_handler::post(sensor_data_t *data, int len)
+int application_sensor_handler::publish(sensor_data_t *data, int len)
 {
        std::string uri = m_info.get_uri();
        return notify(uri.c_str(), data, len);
@@ -48,6 +53,14 @@ int application_sensor_handler::start(sensor_observer *ob)
 {
        add_observer(ob);
 
+       if (observer_count() > 1 || m_started.load())
+               return OP_SUCCESS; /* already started */
+
+       ipc::message msg;
+       msg.set_type(CMD_PROVIDER_START);
+       m_ch->send_sync(&msg);
+       m_started.store(true);
+
        return OP_SUCCESS;
 }
 
@@ -55,11 +68,57 @@ int application_sensor_handler::stop(sensor_observer *ob)
 {
        remove_observer(ob);
 
+       if (observer_count() > 0 || !m_started.load())
+               return OP_SUCCESS; /* already started */
+
+       ipc::message msg;
+       msg.set_type(CMD_PROVIDER_STOP);
+       m_ch->send_sync(&msg);
+       m_started.store(false);
+
        return OP_SUCCESS;
 }
 
+int application_sensor_handler::get_min_interval(void)
+{
+       int interval;
+       std::vector<int> temp;
+
+       for (auto it = m_interval_map.begin(); it != m_interval_map.end(); ++it)
+               if (it->second > 0)
+                   temp.push_back(it->second);
+
+       if (temp.empty())
+               return m_info.get_min_interval();
+
+       interval = *std::min_element(temp.begin(), temp.end());
+
+       if (interval < m_info.get_min_interval())
+               return m_info.get_min_interval();
+
+       return interval;
+}
+
 int application_sensor_handler::set_interval(sensor_observer *ob, int32_t interval)
 {
+       retv_if(interval == m_prev_interval, OP_SUCCESS);
+
+       int32_t cur_interval = interval;
+
+       m_interval_map[ob] = cur_interval;
+       cur_interval = get_min_interval();
+
+       ipc::message msg;
+       cmd_provider_attr_int_t buf;
+       buf.attribute = SENSORD_ATTRIBUTE_INTERVAL;
+       buf.value = cur_interval;
+
+       msg.set_type(CMD_PROVIDER_ATTR_INT);
+       msg.enclose((const char *)&buf, sizeof(cmd_provider_attr_int_t));
+       m_ch->send_sync(&msg);
+
+       m_prev_interval = cur_interval;
+
        return OP_SUCCESS;
 }
 
index 87d07fd..2d2801e 100644 (file)
@@ -23,6 +23,7 @@
 #include <channel.h>
 #include <sensor_types.h>
 #include <unordered_map>
+#include <atomic>
 
 #include "sensor_handler.h"
 #include "sensor_observer.h"
@@ -31,11 +32,11 @@ namespace sensor {
 
 class application_sensor_handler : public sensor_handler {
 public:
-       application_sensor_handler(const sensor_info &info);
+       application_sensor_handler(const sensor_info &info, ipc::channel *ch);
        ~application_sensor_handler();
 
        /* TODO: const */
-       int post(sensor_data_t *data, int len);
+       int publish(sensor_data_t *data, int len);
 
        /* sensor interface */
        const sensor_info &get_sensor_info(void);
@@ -52,7 +53,14 @@ public:
 
 private:
        sensor_info m_info;
+       ipc::channel *m_ch;
+       std::atomic<bool> m_started;
+       int32_t m_prev_interval;
+
+       int get_min_interval(void);
+
        std::vector<sensor_handler *> m_required_sensors;
+       std::unordered_map<sensor_observer *, int> m_interval_map;
 };
 
 }
index 3a0fb44..5ad196e 100644 (file)
 #include <command_types.h>
 
 #include "permission_checker.h"
+#include "application_sensor_handler.h"
 
 #define PRIV_DELIMINATOR ";"
 
 using namespace sensor;
 using namespace ipc;
 
+/* TODO */
+std::unordered_map<uint32_t, sensor_listener_proxy *> server_channel_handler::m_listeners;
+std::unordered_map<ipc::channel *, uint32_t> server_channel_handler::m_listener_ids;
+std::unordered_map<ipc::channel *, application_sensor_handler *> server_channel_handler::m_app_sensors;
+
 server_channel_handler::server_channel_handler(sensor_manager *manager)
 : m_manager(manager)
 {
@@ -47,14 +53,25 @@ void server_channel_handler::connected(channel *ch)
 
 void server_channel_handler::disconnected(channel *ch)
 {
-       auto it = m_listener_ids.find(ch);
-       ret_if(it == m_listener_ids.end());
+       auto it_asensor = m_app_sensors.find(ch);
+       if (it_asensor != m_app_sensors.end()) {
+               sensor_info info = it_asensor->second->get_sensor_info();
 
-       _I("Disconnected listener[%u]", it->second);
+               _I("Disconnected provider[%s]", info.get_uri().c_str());
 
-       delete m_listeners[it->second];
-       m_listeners.erase(it->second);
-       m_listener_ids.erase(ch);
+               /* TODO: if sensor is unregistered, related listeners has to be handled */
+               m_manager->deregister_sensor(info.get_uri());
+               m_app_sensors.erase(ch);
+       }
+
+       auto it_listener = m_listener_ids.find(ch);
+       if (it_listener != m_listener_ids.end()) {
+               _I("Disconnected listener[%u]", it_listener->second);
+
+               delete m_listeners[it_listener->second];
+               m_listeners.erase(it_listener->second);
+               m_listener_ids.erase(ch);
+       }
 }
 
 void server_channel_handler::read(channel *ch, message &msg)
@@ -83,7 +100,7 @@ void server_channel_handler::read(channel *ch, message &msg)
        case CMD_PROVIDER_DISCONNECT:
                err = provider_disconnect(ch, msg); break;
        case CMD_PROVIDER_PUBLISH:
-               err = provider_post(ch, msg); break;
+               err = provider_publish(ch, msg); break;
        case CMD_HAS_PRIVILEGE:
                err = has_privileges(ch, msg); break;
        default: break;
@@ -281,17 +298,56 @@ int server_channel_handler::listener_get_data(channel *ch, message &msg)
 
 int server_channel_handler::provider_connect(channel *ch, message &msg)
 {
-       return send_reply(ch, OP_ERROR);
+       retvm_if(!has_privileges(ch->get_fd(), PRIV_APPLICATION_SENSOR_WRITE),
+                       -EACCES, "Permission denied");
+
+       sensor_info info;
+       info.clear();
+       info.deserialize(msg.body(), msg.size());
+
+       info.show();
+
+       application_sensor_handler *sensor;
+       sensor = new(std::nothrow) application_sensor_handler(info, ch);
+       retvm_if(!sensor, -ENOMEM, "Failed to allocate memory");
+
+       if (!m_manager->register_sensor(sensor)) {
+               delete sensor;
+               return -EINVAL;
+       }
+
+       /* temporarily */
+       m_app_sensors[ch] = sensor;
+
+       return send_reply(ch, OP_SUCCESS);
 }
 
 int server_channel_handler::provider_disconnect(channel *ch, message &msg)
 {
-       return send_reply(ch, OP_ERROR);
+       auto it = m_app_sensors.find(ch);
+       retv_if(it == m_app_sensors.end(), -EINVAL);
+
+       sensor_info info = it->second->get_sensor_info();
+
+       m_manager->deregister_sensor(info.get_uri());
+       m_app_sensors.erase(ch);
+
+       return send_reply(ch, OP_SUCCESS);
 }
 
-int server_channel_handler::provider_post(channel *ch, message &msg)
+int server_channel_handler::provider_publish(channel *ch, message &msg)
 {
-       return send_reply(ch, OP_ERROR);
+       auto it = m_app_sensors.find(ch);
+       retv_if(it == m_app_sensors.end(), -EINVAL);
+
+       sensor_data_t *data = (sensor_data_t *)malloc(sizeof(sensor_data_t));
+       retvm_if(!data, -ENOMEM, "Failed to allocate memory");
+
+       msg.disclose((char *)data);
+
+       it->second->publish(data, sizeof(sensor_data_t));
+
+       return OP_SUCCESS;
 }
 
 int server_channel_handler::has_privileges(channel *ch, message &msg)
index a2d9fce..9c912be 100644 (file)
@@ -56,7 +56,7 @@ private:
 
        int provider_connect(ipc::channel *ch, ipc::message &msg);
        int provider_disconnect(ipc::channel *ch, ipc::message &msg);
-       int provider_post(ipc::channel *ch, ipc::message &msg);
+       int provider_publish(ipc::channel *ch, ipc::message &msg);
 
        int has_privileges(ipc::channel *ch, ipc::message &msg);
 
@@ -68,14 +68,14 @@ private:
        sensor_manager *m_manager;
 
        /* {id, listener} */
-       std::unordered_map<uint32_t, sensor_listener_proxy *> m_listeners;
+       static std::unordered_map<uint32_t, sensor_listener_proxy *> m_listeners;
 
        /* {channel, id} */
-       std::unordered_map<ipc::channel *, uint32_t> m_listener_ids;
+       static std::unordered_map<ipc::channel *, uint32_t> m_listener_ids;
 
-       /* {name, application_sensor_handler} */
-       /* TODO: move it to sensor_manager */
-       std::unordered_map<std::string, application_sensor_handler *> m_sensors;
+       /* {channel, application_sensor_handler} */
+       /* it should move to sensor_manager */
+       static std::unordered_map<ipc::channel *, application_sensor_handler *> m_app_sensors;
 };
 
 }