From: kibak.yoon Date: Mon, 24 Apr 2017 07:13:00 +0000 (+0900) Subject: sensord: implement application sensor handler X-Git-Tag: accepted/tizen/unified/20170428.032607~2^2~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F61%2F126561%2F6;p=platform%2Fcore%2Fsystem%2Fsensord.git sensord: implement application sensor handler Change-Id: If415a7268adf9d7cd5870ba62a0f4bd7497baccf Signed-off-by: kibak.yoon --- diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp index 1070156..a6bd0bd 100644 --- a/src/server/application_sensor_handler.cpp +++ b/src/server/application_sensor_handler.cpp @@ -19,13 +19,18 @@ #include "application_sensor_handler.h" +#include +#include #include #include 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 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; } diff --git a/src/server/application_sensor_handler.h b/src/server/application_sensor_handler.h index 87d07fd..2d2801e 100644 --- a/src/server/application_sensor_handler.h +++ b/src/server/application_sensor_handler.h @@ -23,6 +23,7 @@ #include #include #include +#include #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 m_started; + int32_t m_prev_interval; + + int get_min_interval(void); + std::vector m_required_sensors; + std::unordered_map m_interval_map; }; } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 3a0fb44..5ad196e 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -26,12 +26,18 @@ #include #include "permission_checker.h" +#include "application_sensor_handler.h" #define PRIV_DELIMINATOR ";" using namespace sensor; using namespace ipc; +/* TODO */ +std::unordered_map server_channel_handler::m_listeners; +std::unordered_map server_channel_handler::m_listener_ids; +std::unordered_map 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) diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index a2d9fce..9c912be 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -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 m_listeners; + static std::unordered_map m_listeners; /* {channel, id} */ - std::unordered_map m_listener_ids; + static std::unordered_map m_listener_ids; - /* {name, application_sensor_handler} */ - /* TODO: move it to sensor_manager */ - std::unordered_map m_sensors; + /* {channel, application_sensor_handler} */ + /* it should move to sensor_manager */ + static std::unordered_map m_app_sensors; }; }