#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)
{
}
{
}
-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);
{
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;
}
{
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;
}
#include <channel.h>
#include <sensor_types.h>
#include <unordered_map>
+#include <atomic>
#include "sensor_handler.h"
#include "sensor_observer.h"
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);
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;
};
}
#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)
{
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)
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;
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)
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);
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;
};
}