sensord: implement sensor_listener class for clients 87/123287/2
authorkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 06:33:47 +0000 (15:33 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 09:48:08 +0000 (18:48 +0900)
- sensor_listener provides:
  - controls for sensor actions such as start and stop.
  - controls for changing sensor settings
  - listening for sensor events from server

Change-Id: I7216b282cc3429d0864b4343d65ff192951b1038
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/client/sensor_listener.cpp

index 83145ef..da9dbe8 100644 (file)
@@ -34,8 +34,25 @@ public:
        : m_listener(listener)
        {}
        void connected(ipc::channel *ch) {}
-       void disconnected(ipc::channel *ch) {}
-       void read(ipc::channel *ch, ipc::message &msg) {}
+       void disconnected(ipc::channel *ch)
+       {
+               /* If channel->disconnect() is not explicitly called,
+                * listener will be restored */
+               m_listener->restore();
+       }
+
+       void read(ipc::channel *ch, ipc::message &msg)
+       {
+               switch (msg.header()->type) {
+               case CMD_LISTENER_EVENT:
+                       if (m_listener->get_event_handler())
+                               m_listener->get_event_handler()->read(ch, msg);
+               case CMD_LISTENER_ACC_EVENT:
+                       if (m_listener->get_accuracy_handler())
+                               m_listener->get_accuracy_handler()->read(ch, msg);
+               }
+       }
+
        void read_complete(ipc::channel *ch) {}
        void error_caught(ipc::channel *ch, int error) {}
 
@@ -64,11 +81,37 @@ sensor_listener::~sensor_listener()
 
 bool sensor_listener::init(void)
 {
+       m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
+       retvm_if(!m_client, false, "Failed to allocate memory");
+
+       m_handler = new(std::nothrow) listener_handler(this);
+       if (!m_handler) {
+               delete m_client;
+               return false;
+       }
+
+       if (!connect()) {
+               delete m_handler;
+               delete m_client;
+               m_handler = NULL;
+               m_client = NULL;
+               return false;
+       }
+
        return true;
 }
 
 void sensor_listener::deinit(void)
 {
+       disconnect();
+
+       delete m_handler;
+       m_handler = NULL;
+
+       delete m_client;
+       m_client = NULL;
+
+       m_attributes.clear();
 }
 
 int sensor_listener::get_id(void)
@@ -83,18 +126,66 @@ sensor_t sensor_listener::get_sensor(void)
 
 void sensor_listener::restore(void)
 {
+       ret_if(!is_connected());
+       retm_if(!connect(), "Failed to restore listener");
+
+       /* Restore attributes/status */
+       if (m_started.load())
+               start();
+
+       auto interval = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL);
+       if (interval != m_attributes.end())
+               set_interval(m_attributes[SENSORD_ATTRIBUTE_INTERVAL]);
+
+       auto latency = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       if (latency != m_attributes.end())
+               set_max_batch_latency(m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]);
+
        _D("Restored listener[%d]", get_id());
 }
 
 bool sensor_listener::connect(void)
 {
-       _I("Listener ID[%d]", get_id());
+       m_channel = m_client->connect(m_handler, &m_loop);
+       retvm_if(!m_channel, false, "Failed to connect to server");
+
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_connect_t buf = {0, };
+
+       memcpy(buf.sensor, m_sensor->get_uri().c_str(), m_sensor->get_uri().size());
+       msg.set_type(CMD_LISTENER_CONNECT);
+       msg.enclose((const char *)&buf, sizeof(buf));
+       m_channel->send_sync(&msg);
+
+       m_channel->read_sync(reply);
+       reply.disclose((char *)&buf);
+
+       m_id = buf.listener_id;
+       m_connected.store(true);
+
+       _D("Listener ID[%d]", get_id());
 
        return true;
 }
 
 void sensor_listener::disconnect(void)
 {
+       ret_if(!is_connected());
+       m_connected.store(false);
+
+       ipc::message msg;
+       ipc::message reply;
+
+       msg.set_type(CMD_LISTENER_DISCONNECT);
+       m_channel->send_sync(&msg);
+
+       m_channel->read_sync(reply);
+       m_channel->disconnect();
+
+       delete m_channel;
+       m_channel = NULL;
+
        _I("Disconnected[%d]", get_id());
 }
 
@@ -131,71 +222,186 @@ void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler)
 
 void sensor_listener::unset_accuracy_handler(void)
 {
+       delete m_acc_handler;
        m_acc_handler = NULL;
 }
 
 int sensor_listener::start(void)
 {
-       return OP_ERROR;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_start_t buf;
+
+       retvm_if(!m_channel, -EINVAL, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_START);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(reply);
+
+       if (reply.header()->err < 0)
+               return reply.header()->err;
+
+       m_started.store(true);
+
+       return OP_SUCCESS;
 }
 
 int sensor_listener::stop(void)
 {
-       return OP_ERROR;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_stop_t buf;
+
+       retvm_if(!m_channel, -EINVAL, "Failed to connect to server");
+       retvm_if(!m_started.load(), -EAGAIN, "Already stopped");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_STOP);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(reply);
+
+       if (reply.header()->err < 0)
+               return reply.header()->err;
+
+       m_started.store(false);
+
+       return OP_SUCCESS;
 }
 
 int sensor_listener::get_interval(void)
 {
-       return OP_ERROR;
+       auto it = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL);
+       retv_if(it == m_attributes.end(), -1);
+
+       return m_attributes[SENSORD_ATTRIBUTE_INTERVAL];
 }
 
 int sensor_listener::get_max_batch_latency(void)
 {
-       return OP_ERROR;
+       auto it = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       retv_if(it == m_attributes.end(), -1);
+
+       return m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
 }
 
 int sensor_listener::get_pause_policy(void)
 {
-       return OP_ERROR;
+       auto it = m_attributes.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
+       retv_if(it == m_attributes.end(), -1);
+
+       return m_attributes[SENSORD_ATTRIBUTE_PAUSE_POLICY];
 }
 
 int sensor_listener::get_passive_mode(void)
 {
-       return OP_ERROR;
+       auto it = m_attributes.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
+       retv_if(it == m_attributes.end(), -1);
+
+       return m_attributes[SENSORD_ATTRIBUTE_PASSIVE_MODE];
 }
 
 int sensor_listener::set_interval(unsigned int interval)
 {
-       return OP_ERROR;
+       int _interval;
+
+       /* TODO: move this logic to server */
+       if (interval == 0)
+               _interval = DEFAULT_INTERVAL;
+       else if (interval < (unsigned int)m_sensor->get_min_interval())
+               _interval = m_sensor->get_min_interval();
+       else
+               _interval = interval;
+
+       return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval);
 }
 
 int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency)
 {
-       return OP_ERROR;
+       return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency);
 }
 
 int sensor_listener::set_passive_mode(bool passive)
 {
-       return OP_ERROR;
+       return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive);
 }
 
 int sensor_listener::flush(void)
 {
-       return OP_ERROR;
+       return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1);
 }
 
 int sensor_listener::set_attribute(int attribute, int value)
 {
-       return OP_ERROR;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_int_t buf;
+
+       retvm_if(!m_channel, false, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       buf.attribute = attribute;
+       buf.value = value;
+       msg.set_type(CMD_LISTENER_ATTR_INT);
+       msg.enclose((char *)&buf, sizeof(buf));
+
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(reply);
+
+       if (reply.header()->err < 0)
+               return reply.header()->err;
+
+       m_attributes[attribute] = value;
+
+       return OP_SUCCESS;
 }
 
 int sensor_listener::set_attribute(int attribute, const char *value, int len)
 {
-       return OP_ERROR;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_attr_str_t buf;
+
+       retvm_if(!m_channel, false, "Failed to connect to server");
+
+       msg.set_type(CMD_LISTENER_ATTR_STR);
+       buf.listener_id = m_id;
+       buf.attribute = attribute;
+       memcpy(buf.value, value, len);
+       buf.len = len;
+
+       msg.enclose((char *)&buf, sizeof(buf) + len);
+
+       m_channel->send_sync(&msg);
+       m_channel->read_sync(reply);
+
+       return reply.header()->err;
 }
 
 int sensor_listener::get_sensor_data(sensor_data_t *data)
 {
-       return OP_ERROR;
+       ipc::message msg;
+       ipc::message reply;
+       cmd_listener_get_data_t buf;
+
+       retvm_if(!m_channel, false, "Failed to connect to server");
+
+       buf.listener_id = m_id;
+       msg.set_type(CMD_LISTENER_GET_DATA);
+       msg.enclose((char *)&buf, sizeof(buf));
+       m_channel->send_sync(&msg);
+
+       m_channel->read_sync(reply);
+       /* TODO */
+       /*
+       reply.disclose((char *)&buf);
+       memcpy(data, buf.data, sizeof(buf.len));
+       */
+
+       return OP_SUCCESS;
 }