Add APIs to get an attribute value 17/218717/4
authorBoram Bae <boram21.bae@samsung.com>
Wed, 27 Nov 2019 08:06:10 +0000 (17:06 +0900)
committerBoram Bae <boram21.bae@samsung.com>
Thu, 28 Nov 2019 04:46:57 +0000 (13:46 +0900)
* Implement sensord_get_attribute_int/str
* Update attribute of sensor_listener when another one changes the attribute
* Remove an interface on_attribute_changed of sensor_observer
* Add memebers to store attributes of sensor_listener and sensor_hander
* Add command types

Change-Id: I9e736699e2156a4779ddcb319a3f4a6206c9c4b1
Signed-off-by: Boram Bae <boram21.bae@samsung.com>
19 files changed:
include/sensor_internal.h
src/client-dummy/client_dummy.cpp
src/client/sensor_internal.cpp
src/client/sensor_listener.cpp
src/client/sensor_listener.h
src/sensorctl/testcase/sensor_listener.cpp
src/server/application_sensor_handler.cpp
src/server/external_sensor_handler.cpp
src/server/fusion_sensor_handler.cpp
src/server/fusion_sensor_handler.h
src/server/physical_sensor_handler.cpp
src/server/sensor_handler.cpp
src/server/sensor_handler.h
src/server/sensor_listener_proxy.cpp
src/server/sensor_listener_proxy.h
src/server/sensor_observer.h
src/server/server_channel_handler.cpp
src/server/server_channel_handler.h
src/shared/command_types.h

index fa7e76e..07638fd 100644 (file)
@@ -404,6 +404,19 @@ bool sensord_set_option(int handle, int option);
  */
 int sensord_set_attribute_int(int handle, int attribute, int value);
 
+/*
+ * @brief Get the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to get value
+ * @param[out] value an attribute value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_get_attribute_int(int handle, int attribute, int* value);
+
 /**
  * @brief Set the attribute to a connected sensor
  *
@@ -419,6 +432,20 @@ int sensord_set_attribute_int(int handle, int attribute, int value);
 int sensord_set_attribute_str(int handle, int attribute, const char *value, int len);
 
 /**
+ * @brief Get the attribute to a connected sensor
+ *
+ * @param[in] handle a handle represensting a connected sensor.
+ * @param[in] attribute an attribute to get value
+ * @param[out] value an attribute value, the caller should explicitly free this value
+ * @param[out] len the length of value
+ * @return 0 on success, otherwise a negative error value
+ * @retval 0 Successful
+ * @retval -EINVAL Invalid parameter
+ * @retval -EPERM Operation not permitted
+ */
+int sensord_get_attribute_str(int handle, int attribute, char **value, int *len);
+
+/**
  * @brief Send data to sensorhub
  *
  * @param[in] handle a handle represensting a connected context sensor.
index d84e2ad..accc043 100644 (file)
@@ -203,11 +203,21 @@ API int sensord_set_attribute_int(int handle, int attribute, int value)
        return OP_ERROR;
 }
 
+API int sensord_get_attribute_int(int handle, int attribute, int* value)
+{
+       return OP_ERROR;
+}
+
 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
 {
        return OP_ERROR;
 }
 
+API int sensord_get_attribute_str(int handle, int attribute, char **value, int *len)
+{
+       return OP_ERROR;
+}
+
 API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
 {
        return false;
index 9d13857..376059c 100644 (file)
@@ -714,6 +714,25 @@ API int sensord_set_attribute_int(int handle, int attribute, int value)
        return OP_SUCCESS;
 }
 
+API int sensord_get_attribute_int(int handle, int attribute, int* value)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_attribute(attribute, value) < 0) {
+               _E("Failed to get attribute[%d]", attribute);
+               return -EIO;
+       }
+
+       _D("Get attribute[%d, %d, %d]", listener->get_id(), attribute, *value);
+
+       return OP_SUCCESS;
+}
+
 API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
 {
        sensor::sensor_listener *listener;
@@ -731,6 +750,24 @@ API int sensord_set_attribute_str(int handle, int attribute, const char *value,
        return OP_SUCCESS;
 }
 
+API int sensord_get_attribute_str(int handle, int attribute, char **value, int* len)
+{
+       sensor::sensor_listener *listener;
+
+       auto it = listeners.find(handle);
+       retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+       listener = it->second;
+
+       if (listener->get_attribute(attribute, value, len) < 0) {
+               _E("Failed to get attribute[%d]", attribute);
+               return -EIO;
+       }
+       _D("Get attribute[%d, %d, %s]", listener->get_id(), attribute, *value);
+
+       return OP_SUCCESS;
+}
+
 API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
 {
        sensor::sensor_listener *listener;
index 5e0e69d..6cea7d3 100644 (file)
@@ -49,21 +49,31 @@ public:
        {
                switch (msg.header()->type) {
                case CMD_LISTENER_EVENT:
-                       if (m_listener->get_event_handler())
+                       if (m_listener->get_event_handler()) {
                                m_listener->get_event_handler()->read(ch, msg);
+                       }
                        break;
                case CMD_LISTENER_ACC_EVENT:
-                       if (m_listener->get_accuracy_handler())
+                       if (m_listener->get_accuracy_handler()) {
                                m_listener->get_accuracy_handler()->read(ch, msg);
+                       }
                        break;
-               case CMD_LISTENER_ATTR_INT:
-                       if (m_listener->get_attribute_int_changed_handler())
+               case CMD_LISTENER_SET_ATTR_INT: {
+                       if (m_listener->get_attribute_int_changed_handler()) {
                                m_listener->get_attribute_int_changed_handler()->read(ch, msg);
-                       break;
-               case CMD_LISTENER_ATTR_STR:
-                       if (m_listener->get_attribute_str_changed_handler())
+                       }
+
+                       cmd_listener_attr_int_t* buf = (cmd_listener_attr_int_t*) msg.body();
+                       m_listener->update_attribute(buf->attribute, buf->value);
+               } break;
+               case CMD_LISTENER_SET_ATTR_STR: {
+                       if (m_listener->get_attribute_str_changed_handler()) {
                                m_listener->get_attribute_str_changed_handler()->read(ch, msg);
-                       break;
+                       }
+
+                       cmd_listener_attr_str_t* buf = (cmd_listener_attr_str_t*) msg.body();
+                       m_listener->update_attribute(buf->attribute, buf->value, buf->len);
+               } break;
                default:
                        _W("Invalid command message");
                }
@@ -162,7 +172,8 @@ void sensor_listener::deinit(void)
        delete m_attr_str_changed_handler;
        m_attr_str_changed_handler = NULL;
 
-       m_attributes.clear();
+       m_attributes_int.clear();
+       m_attributes_str.clear();
        _D("Deinitialized..");
 }
 
@@ -187,13 +198,13 @@ void sensor_listener::restore(void)
        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 interval = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
+       if (interval != m_attributes_int.end())
+               set_interval( m_attributes_int[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]);
+       auto latency = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       if (latency != m_attributes_int.end())
+               set_max_batch_latency( m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]);
 
        _D("Restored listener[%d]", get_id());
 }
@@ -398,34 +409,34 @@ int sensor_listener::stop(void)
 
 int sensor_listener::get_interval(void)
 {
-       auto it = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL);
-       retv_if(it == m_attributes.end(), -1);
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL);
+       retv_if(it == m_attributes_int.end(), -1);
 
-       return m_attributes[SENSORD_ATTRIBUTE_INTERVAL];
+       return  m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL];
 }
 
 int sensor_listener::get_max_batch_latency(void)
 {
-       auto it = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
-       retv_if(it == m_attributes.end(), -1);
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY);
+       retv_if(it == m_attributes_int.end(), -1);
 
-       return m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
+       return  m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY];
 }
 
 int sensor_listener::get_pause_policy(void)
 {
-       auto it = m_attributes.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
-       retv_if(it == m_attributes.end(), -1);
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY);
+       retv_if(it == m_attributes_int.end(), -1);
 
-       return m_attributes[SENSORD_ATTRIBUTE_PAUSE_POLICY];
+       return  m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY];
 }
 
 int sensor_listener::get_passive_mode(void)
 {
-       auto it = m_attributes.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
-       retv_if(it == m_attributes.end(), -1);
+       auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PASSIVE_MODE);
+       retv_if(it == m_attributes_int.end(), -1);
 
-       return m_attributes[SENSORD_ATTRIBUTE_PASSIVE_MODE];
+       return  m_attributes_int[SENSORD_ATTRIBUTE_PASSIVE_MODE];
 }
 
 int sensor_listener::set_interval(unsigned int interval)
@@ -444,7 +455,7 @@ int sensor_listener::set_interval(unsigned int interval)
 
        /* If it is not started, store the value only */
        if (!m_started.load()) {
-               m_attributes[SENSORD_ATTRIBUTE_INTERVAL] = _interval;
+                m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL] = _interval;
                return OP_SUCCESS;
        }
 
@@ -457,7 +468,7 @@ int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency)
 
        /* If it is not started, store the value only */
        if (!m_started.load()) {
-               m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency;
+                m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency;
                return OP_SUCCESS;
        }
 
@@ -489,7 +500,7 @@ int sensor_listener::set_attribute(int attribute, int value)
        buf.listener_id = m_id;
        buf.attribute = attribute;
        buf.value = value;
-       msg.set_type(CMD_LISTENER_ATTR_INT);
+       msg.set_type(CMD_LISTENER_SET_ATTR_INT);
        msg.enclose((char *)&buf, sizeof(buf));
 
        m_cmd_channel->send_sync(&msg);
@@ -498,11 +509,47 @@ int sensor_listener::set_attribute(int attribute, int value)
        if (reply.header()->err < 0)
                return reply.header()->err;
 
-       m_attributes[attribute] = value;
+       update_attribute(attribute, value);
 
        return OP_SUCCESS;
 }
 
+int sensor_listener::get_attribute(int attribute, int* value)
+{
+       auto it = m_attributes_int.find(attribute);
+       if (it == m_attributes_int.end()) {
+               ipc::message msg;
+               ipc::message reply;
+               cmd_listener_attr_int_t buf;
+
+               buf.listener_id = m_id;
+               buf.attribute = attribute;
+
+               msg.set_type(CMD_LISTENER_GET_ATTR_INT);
+               msg.enclose((char *)&buf, sizeof(buf));
+               m_cmd_channel->send_sync(&msg);
+
+               m_cmd_channel->read_sync(reply);
+
+               if (reply.header()->err < 0) {
+                       _D("reply.header()->err < 0");
+                       return reply.header()->err;
+               }
+               if (reply.header()->length && reply.body()) {
+                       update_attribute(attribute, ((cmd_listener_attr_int_t *)reply.body())->value);
+               }
+       }
+
+       *value = m_attributes_int[attribute];
+       return OP_SUCCESS;
+}
+
+void sensor_listener::update_attribute(int attribute, int value)
+{
+       m_attributes_int[attribute] = value;
+       _I("listener[%d]'s attribues(int) size : %d", get_id(), m_attributes_int.size());
+}
+
 int sensor_listener::set_attribute(int attribute, const char *value, int len)
 {
        ipc::message msg;
@@ -517,7 +564,7 @@ int sensor_listener::set_attribute(int attribute, const char *value, int len)
        buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
        retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
 
-       msg.set_type(CMD_LISTENER_ATTR_STR);
+       msg.set_type(CMD_LISTENER_SET_ATTR_STR);
        buf->listener_id = m_id;
        buf->attribute = attribute;
 
@@ -537,9 +584,52 @@ int sensor_listener::set_attribute(int attribute, const char *value, int len)
        if (reply.header()->err < 0)
                return reply.header()->err;
 
+       update_attribute(attribute, value, len);
+
        return OP_SUCCESS;
 }
 
+int sensor_listener::get_attribute(int attribute, char **value, int* len)
+{
+       auto it = m_attributes_str.find(attribute);
+       if (it == m_attributes_str.end()) {
+               ipc::message msg;
+               ipc::message reply;
+               cmd_listener_attr_str_t buf;
+
+               buf.listener_id = m_id;
+               buf.attribute = attribute;
+
+               msg.set_type(CMD_LISTENER_GET_ATTR_STR);
+               msg.enclose((char *)&buf, sizeof(buf));
+               m_cmd_channel->send_sync(&msg);
+
+               m_cmd_channel->read_sync(reply);
+               if (reply.header()->err < 0) {
+                       _D("reply.header()->err < 0");
+                       return reply.header()->err;
+               }
+
+               if (reply.header()->length && reply.body()) {
+                       cmd_listener_attr_str_t * recv_buf = (cmd_listener_attr_str_t *)reply.body();
+                       update_attribute(attribute, (char *)recv_buf->value, recv_buf->len);
+               }
+       }
+
+       *len = m_attributes_str[attribute].size();
+       *value = (char *) malloc(*len);
+       std::copy(m_attributes_str[attribute].begin(), m_attributes_str[attribute].end(), *value);
+
+       return OP_SUCCESS;
+}
+
+void sensor_listener::update_attribute(int attribute, const char *value, int len)
+{
+       m_attributes_str[attribute].clear();
+       m_attributes_str[attribute].insert(m_attributes_str[attribute].begin(), value, value + len);
+       _I("listener[%d]'s attribues(str) size : %d", get_id(), m_attributes_str.size());
+}
+
 int sensor_listener::get_sensor_data(sensor_data_t *data)
 {
        ipc::message msg;
@@ -570,5 +660,4 @@ int sensor_listener::get_sensor_data(sensor_data_t *data)
        _D("Listener[%d] read sensor data", get_id());
 
        return OP_SUCCESS;
-}
-
+}
\ No newline at end of file
index fd4d059..47cab20 100644 (file)
@@ -28,6 +28,7 @@
 #include <sensor_types.h>
 #include <map>
 #include <atomic>
+#include <vector>
 
 namespace sensor {
 
@@ -68,8 +69,11 @@ public:
        int set_max_batch_latency(unsigned int max_batch_latency);
        int set_passive_mode(bool passive);
        int set_attribute(int attribute, int value);
+       int get_attribute(int attribute, int* value);
+       void update_attribute(int attribute, int value);
        int set_attribute(int attribute, const char *value, int len);
-
+       int get_attribute(int attribute, char **value, int *len);
+       void update_attribute(int attribute, const char *value, int len);
        int get_sensor_data(sensor_data_t *data);
        int flush(void);
 
@@ -98,7 +102,8 @@ private:
        ipc::event_loop *m_loop;
        std::atomic<bool> m_connected;
        std::atomic<bool> m_started;
-       std::map<int, int> m_attributes;
+       std::map<int, int> m_attributes_int;
+       std::map<int, std::vector<char>> m_attributes_str;
 };
 
 }
index 7a38371..c5adee2 100644 (file)
@@ -224,22 +224,202 @@ TESTCASE(sensor_listener, bad_disconnect_p_2)
        return true;
 }
 
+TESTCASE(sensor_listener, set_get_attribute_int_1)
+{
+       int err = 0;
+       bool ret = true;
+       int handle = 0;
+       sensor_t sensor = NULL;
+       int attr = 1;
+       int value = -1;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+       err = sensord_set_attribute_int(handle, attr, 1);
+       ASSERT_EQ(err, 0);
+
+       err = sensord_get_attribute_int(handle, attr, &value);
+       ASSERT_EQ(err, 0);
+
+       ASSERT_EQ(value, 1);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       return true;
+}
+
+TESTCASE(sensor_listener, set_get_attribute_int_2)
+{
+       int err = 0;
+       bool ret = true;
+       int handle = 0;
+       sensor_t sensor = NULL;
+       int attr = 20;
+       int value = -1;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+       err = sensord_set_attribute_int(handle, attr, 1);
+       ASSERT_EQ(err, 0);
+
+       err = sensord_get_attribute_int(handle, attr, &value);
+       ASSERT_EQ(err, 0);
+
+       ASSERT_EQ(value, 1);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       return true;
+}
+
+TESTCASE(sensor_listener, get_attribute_int_1)
+{
+       int err = 0;
+       bool ret = true;
+       int handle = 0;
+       sensor_t sensor = NULL;
+       int attr = 100;
+       int value = -1;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+
+       // attr 100 value is never set in these tests.
+       err = sensord_get_attribute_int(handle, attr, &value);
+       ASSERT_EQ(err, -5);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       return true;
+}
+
 #define TEST_STRING "TESTTESTTEST"
-#define TEST_STRING_LEN 12
+#define TEST_STRING_LEN 13
+
+TESTCASE(sensor_listener, set_attribute_string_1)
+{
+       int err = 0;
+       bool ret = true;
+       int handle = 0;
+       sensor_t sensor = NULL;
+       int attr = 1;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+       err = sensord_set_attribute_str(handle, attr, TEST_STRING, TEST_STRING_LEN);
+       ASSERT_EQ(err, 0);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       return true;
+}
+
+TESTCASE(sensor_listener, set_get_attribute_string_1)
+{
+       int err = 0;
+       bool ret = true;
+       int handle = 0;
+       char *value = NULL;
+       int len = 0;
+       sensor_t sensor = NULL;
+       int attr = 1;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+       err = sensord_set_attribute_str(handle, attr, TEST_STRING, TEST_STRING_LEN);
+       ASSERT_EQ(err, 0);
+
+       err = sensord_get_attribute_str(handle, attr, &value, &len);
+       ASSERT_EQ(err, 0);
+       ASSERT_EQ(len, TEST_STRING_LEN);
+       ASSERT_EQ(strncmp(value, TEST_STRING, len), 0);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       free(value);
+       return true;
+}
 
-TESTCASE(sensor_listener, attribute_string_1)
+TESTCASE(sensor_listener, set_get_get_attribute_string_1)
 {
        int err;
        bool ret;
        int handle;
+       char *value = NULL;
+       int len = 0;
        sensor_t sensor;
+       int attr = 1;
 
        err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
        ASSERT_EQ(err, 0);
 
        handle = sensord_connect(sensor);
-       err = sensord_set_attribute_str(handle, 1, TEST_STRING, TEST_STRING_LEN);
+       err = sensord_set_attribute_str(handle, attr, TEST_STRING, TEST_STRING_LEN);
+       ASSERT_EQ(err, 0);
+
+       err = sensord_get_attribute_str(handle, attr, &value, &len);
        ASSERT_EQ(err, 0);
+       ASSERT_EQ(len, TEST_STRING_LEN);
+       ASSERT_EQ(strncmp(value, TEST_STRING, len), 0);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       free(value);
+
+       value = NULL;
+       len = 0;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+
+       err = sensord_get_attribute_str(handle, attr, &value, &len);
+       ASSERT_EQ(err, 0);
+       ASSERT_EQ(len, TEST_STRING_LEN);
+       ASSERT_EQ(strncmp(value, TEST_STRING, len), 0);
+
+       ret = sensord_disconnect(handle);
+       ASSERT_TRUE(ret);
+
+       free(value);
+       return true;
+}
+
+TESTCASE(sensor_listener, get_attribute_string_2)
+{
+       int err;
+       bool ret;
+       int handle;
+       char *value;
+       int len;
+       sensor_t sensor;
+       int attr = 100;
+
+       err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor);
+       ASSERT_EQ(err, 0);
+
+       handle = sensord_connect(sensor);
+
+       // attr 100 value is never set in these tests.
+       err = sensord_get_attribute_str(handle, attr, &value, &len);
+       ASSERT_EQ(err, -EIO);
 
        ret = sensord_disconnect(handle);
        ASSERT_TRUE(ret);
index f2abadc..df5db08 100644 (file)
@@ -135,6 +135,7 @@ int application_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t l
 
 int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value)
 {
+       update_attribute(attr, value);
        return OP_SUCCESS;
 }
 
@@ -159,7 +160,7 @@ int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr,
        m_ch->send_sync(&msg);
 
        _I("Set attribute[%d] to sensor[%s]", attr, m_info.get_uri().c_str());
-
+       update_attribute(attr, value, len);
        return OP_SUCCESS;
 }
 
index 474f764..e0f74bf 100644 (file)
@@ -211,6 +211,9 @@ int external_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, in
        if (m_policy == OP_DEFAULT) {
                /* default logic */
        }
+
+       update_attribute(attr, value);
+
        return OP_SUCCESS;
 }
 
@@ -226,6 +229,9 @@ int external_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, co
        if (m_policy == OP_DEFAULT) {
                /* default logic */
        }
+
+       update_attribute(attr, value, len);
+
        return OP_SUCCESS;
 }
 
index 6cbc692..5d5a8d1 100644 (file)
@@ -199,6 +199,8 @@ int fusion_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int3
                /* default logic */
        }
 
+       update_attribute(attr, value);
+
        return set_attribute_internal(attr, value);
 }
 
@@ -215,6 +217,8 @@ int fusion_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, cons
                /* default logic */
        }
 
+       update_attribute(attr, value, len);
+
        return set_attribute_internal(attr, value, len);
 }
 
index 5e12f10..9feb67f 100644 (file)
@@ -51,11 +51,6 @@ public:
 
        /* subscriber */
        int update(const char *uri, ipc::message *msg);
-       int on_attribute_changed(ipc::message *msg)
-       {
-               // Do nothing
-               return OP_SUCCESS;
-       }
 
        /* sensor interface */
        const sensor_info &get_sensor_info(void);
index 1b44a87..da82314 100644 (file)
@@ -271,6 +271,9 @@ int physical_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, in
 
        ret = m_device->set_attribute_int(m_hal_id, attr, value);
 
+       if (ret) {
+               update_attribute(attr, value);
+       }
        return (ret ? OP_SUCCESS : OP_ERROR);
 }
 
@@ -296,6 +299,10 @@ int physical_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, co
 
        ret = m_device->set_attribute_str(m_hal_id, attr, const_cast<char *>(value), len);
 
+       if (ret) {
+               update_attribute(attr, value, len);
+       }
+
        return (ret ? OP_SUCCESS : OP_ERROR);
 }
 
index 0de7fd0..843c794 100644 (file)
@@ -24,6 +24,7 @@
 #include <sensor_utils.h>
 #include <sensor_types_private.h>
 #include <command_types.h>
+#include <sensor_listener_proxy.h>
 
 using namespace sensor;
 
@@ -90,8 +91,9 @@ int sensor_handler::notify(const char *uri, sensor_data_t *data, int len)
 
        set_cache(data, len);
 
-       if (msg->ref_count() == 0)
+       if (msg->ref_count() == 0) {
                msg->unref();
+       }
 
        return OP_SUCCESS;
 }
@@ -129,12 +131,13 @@ int sensor_handler::get_cache(sensor_data_t **data, int *len)
        return 0;
 }
 
-bool sensor_handler::notify_attribute_changed(int attribute, int value)
+bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int value)
 {
        if (observer_count() == 0)
                return OP_ERROR;
 
        cmd_listener_attr_int_t buf;
+       buf.listener_id = id;
        buf.attribute = attribute;
        buf.value = value;
 
@@ -142,11 +145,16 @@ bool sensor_handler::notify_attribute_changed(int attribute, int value)
        msg = new(std::nothrow) ipc::message();
        retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
 
-       msg->set_type(CMD_LISTENER_ATTR_INT);
+       msg->set_type(CMD_LISTENER_SET_ATTR_INT);
        msg->enclose((char *)&buf, sizeof(buf));
 
-       for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
-               (*it)->on_attribute_changed(msg);
+       sensor_listener_proxy *proxy = NULL;
+       for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
+               proxy = dynamic_cast<sensor_listener_proxy *>(*it);
+               if (proxy && proxy->get_id() != id) {
+                       proxy->on_attribute_changed(msg);
+               }
+       }
 
        if (msg->ref_count() == 0)
                msg->unref();
@@ -154,7 +162,7 @@ bool sensor_handler::notify_attribute_changed(int attribute, int value)
        return OP_SUCCESS;
 }
 
-bool sensor_handler::notify_attribute_changed(int attribute, const char *value, int len)
+bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const char *value, int len)
 {
        if (observer_count() == 0)
                return OP_ERROR;
@@ -169,18 +177,26 @@ bool sensor_handler::notify_attribute_changed(int attribute, const char *value,
        msg = new(std::nothrow) ipc::message();
        retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
 
+       buf->listener_id = id;
        buf->attribute = attribute;
        memcpy(buf->value, value, len);
        buf->len = len;
 
-       msg->set_type(CMD_LISTENER_ATTR_STR);
+       msg->set_type(CMD_LISTENER_SET_ATTR_STR);
        msg->enclose((char *)buf, size);
 
-       for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
-               (*it)->on_attribute_changed(msg);
+       _I("notify attribute changed by listener[%zu]\n", id);
+       sensor_listener_proxy *proxy = NULL;
+       for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
+               proxy = dynamic_cast<sensor_listener_proxy *>(*it);
+               if (proxy && proxy->get_id() != id) {
+                       proxy->on_attribute_changed(msg);
+               }
+       }
 
-       if (msg->ref_count() == 0)
+       if (msg->ref_count() == 0) {
                msg->unref();
+       }
 
        delete[] buf;
 
@@ -191,3 +207,38 @@ int sensor_handler::delete_batch_latency(sensor_observer *ob)
 {
        return 0;
 }
+
+int sensor_handler::get_attribute(int32_t attr, int32_t* value)
+{
+       auto it = m_attributes_int.find(attr);
+       retv_if(it == m_attributes_int.end(), OP_ERROR);
+
+       *value = it->second;
+       return OP_SUCCESS;
+}
+
+void sensor_handler::update_attribute(int32_t attr, int32_t value)
+{
+       m_attributes_int[attr] = value;
+       _I("[%s] attributes(int) size : %d", m_info.get_uri().c_str(), m_attributes_int.size());
+}
+
+int sensor_handler::get_attribute(int32_t attr, char **value, int *len)
+{
+       auto it = m_attributes_str.find(attr);
+       retv_if(it == m_attributes_str.end(), OP_ERROR);
+
+       *len = it->second.size();
+       *value = new(std::nothrow) char[*len];
+       std::copy(it->second.begin(), it->second.end(), *value);
+
+       return OP_SUCCESS;
+}
+
+void sensor_handler::update_attribute(int32_t attr, const char *value, int len)
+{
+       m_attributes_str[attr].clear();
+       m_attributes_str[attr].insert(m_attributes_str[attr].begin(), value, value + len);
+       _I("[%s] attributes(int) size : %d", m_info.get_uri().c_str(), m_attributes_int.size());
+
+}
\ No newline at end of file
index cb7bde8..e42a8e3 100644 (file)
@@ -25,6 +25,8 @@
 #include <sensor_types.h>
 #include <sensor_info.h>
 #include <list>
+#include <map>
+#include <vector>
 
 namespace sensor {
 
@@ -49,17 +51,23 @@ public:
        virtual int set_batch_latency(sensor_observer *ob, int32_t latency) = 0;
        virtual int delete_batch_latency(sensor_observer *ob);
        virtual int set_attribute(sensor_observer *ob, int32_t attr, int32_t value) = 0;
+       virtual int get_attribute(int32_t attr, int32_t* value);
+       void update_attribute(int32_t attr, int32_t value);
        virtual int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) = 0;
+       virtual int get_attribute(int32_t attr, char **value, int *len);
+       void update_attribute(int32_t attr, const char *value, int len);
        virtual int flush(sensor_observer *ob) = 0;
        virtual int get_data(sensor_data_t **data, int *len) = 0;
 
        void set_cache(sensor_data_t *data, int size);
        int get_cache(sensor_data_t **data, int *len);
-       bool notify_attribute_changed(int attribute, int value);
-       bool notify_attribute_changed(int attribute, const char *value, int len);
+       bool notify_attribute_changed(uint32_t id, int attribute, int value);
+       bool notify_attribute_changed(uint32_t id, int attribute, const char *value, int len);
 
 protected:
        sensor_info m_info;
+       std::map<int32_t, int32_t> m_attributes_int;
+       std::map<int32_t, std::vector<char>> m_attributes_str;
 
 private:
        std::list<sensor_observer *> m_observers;
index a52927d..f184e45 100644 (file)
@@ -69,7 +69,7 @@ int sensor_listener_proxy::update(const char *uri, ipc::message *msg)
 int sensor_listener_proxy::on_attribute_changed(ipc::message *msg)
 {
        retv_if(!m_ch || !m_ch->is_connected(), OP_CONTINUE);
-
+       _I("Proxy[%zu] call on_attribute_changed\n", get_id());
        m_ch->send(msg);
        return OP_CONTINUE;
 }
@@ -207,6 +207,26 @@ int sensor_listener_proxy::set_attribute(int attribute, int value)
        return sensor->set_attribute(this, attribute, value);
 }
 
+int sensor_listener_proxy::get_attribute(int attribute, int *value)
+{
+       sensor_handler *sensor = m_manager->get_sensor(m_uri);
+       retv_if(!sensor, -EINVAL);
+
+       _D("Listener[%d] try to get attribute[%d] int", get_id(), attribute);
+
+       if (attribute == SENSORD_ATTRIBUTE_PAUSE_POLICY) {
+               *value = m_pause_policy;
+               return OP_SUCCESS;
+       } else if (attribute == SENSORD_ATTRIBUTE_AXIS_ORIENTATION) {
+               *value = m_axis_orientation;
+               return OP_SUCCESS;
+       } else if (attribute == SENSORD_ATTRIBUTE_FLUSH) {
+               return -EINVAL;
+       }
+
+       return sensor->get_attribute(attribute, value);
+}
+
 int sensor_listener_proxy::set_attribute(int attribute, const char *value, int len)
 {
        sensor_handler *sensor = m_manager->get_sensor(m_uri);
@@ -217,6 +237,16 @@ int sensor_listener_proxy::set_attribute(int attribute, const char *value, int l
        return sensor->set_attribute(this, attribute, value, len);
 }
 
+int sensor_listener_proxy::get_attribute(int attribute, char **value, int *len)
+{
+       sensor_handler *sensor = m_manager->get_sensor(m_uri);
+       retv_if(!sensor, -EINVAL);
+
+       _D("Listener[%d] try to get attribute str[%d]", get_id(), attribute);
+
+       return sensor->get_attribute(attribute, value, len);
+}
+
 int sensor_listener_proxy::flush(void)
 {
        sensor_handler *sensor = m_manager->get_sensor(m_uri);
@@ -262,7 +292,7 @@ bool sensor_listener_proxy::notify_attribute_changed(int attribute, int value)
        sensor_handler *sensor = m_manager->get_sensor(m_uri);
        retv_if(!sensor, -EINVAL);
 
-       return sensor->notify_attribute_changed(attribute, value);
+       return sensor->notify_attribute_changed(m_id, attribute, value);
 }
 
 bool sensor_listener_proxy::notify_attribute_changed(int attribute, const char *value, int len)
@@ -270,5 +300,5 @@ bool sensor_listener_proxy::notify_attribute_changed(int attribute, const char *
        sensor_handler *sensor = m_manager->get_sensor(m_uri);
        retv_if(!sensor, -EINVAL);
 
-       return sensor->notify_attribute_changed(attribute, value, len);
+       return sensor->notify_attribute_changed(m_id, attribute, value, len);
 }
\ No newline at end of file
index f0d1dae..f87447b 100644 (file)
@@ -49,7 +49,9 @@ public:
        int delete_batch_latency(void);
        int set_passive_mode(bool passive);
        int set_attribute(int attribute, int value);
+       int get_attribute(int attribute, int *value);
        int set_attribute(int attribute, const char *value, int len);
+       int get_attribute(int attribute, char **value, int *len);
        int flush(void);
        int get_data(sensor_data_t **data, int *len);
        std::string get_required_privileges(void);
index 02603b0..ee04c20 100644 (file)
@@ -30,7 +30,6 @@ public:
 
        /* for performance, use message */
        virtual int update(const char *uri, ipc::message *msg) = 0;
-       virtual int on_attribute_changed(ipc::message *msg) = 0;
 };
 
 }
index 86606df..c8c8d0b 100644 (file)
@@ -89,12 +89,16 @@ void server_channel_handler::read(channel *ch, message &msg)
                err = listener_start(ch, msg); break;
        case CMD_LISTENER_STOP:
                err = listener_stop(ch, msg); break;
-       case CMD_LISTENER_ATTR_INT:
-               err = listener_attr_int(ch, msg); break;
-       case CMD_LISTENER_ATTR_STR:
-               err = listener_attr_str(ch, msg); break;
+       case CMD_LISTENER_SET_ATTR_INT:
+               err = listener_set_attr_int(ch, msg); break;
+       case CMD_LISTENER_SET_ATTR_STR:
+               err = listener_set_attr_str(ch, msg); break;
        case CMD_LISTENER_GET_DATA:
                err = listener_get_data(ch, msg); break;
+       case CMD_LISTENER_GET_ATTR_INT:
+               err = listener_get_attr_int(ch, msg); break;
+       case CMD_LISTENER_GET_ATTR_STR:
+               err = listener_get_attr_str(ch, msg); break;
        case CMD_PROVIDER_CONNECT:
                err = provider_connect(ch, msg); break;
        case CMD_PROVIDER_PUBLISH:
@@ -202,7 +206,7 @@ int server_channel_handler::listener_stop(channel *ch, message &msg)
        return send_reply(ch, OP_SUCCESS);
 }
 
-int server_channel_handler::listener_attr_int(channel *ch, message &msg)
+int server_channel_handler::listener_set_attr_int(channel *ch, message &msg)
 {
        cmd_listener_attr_int_t buf;
        msg.disclose((char *)&buf);
@@ -246,7 +250,7 @@ int server_channel_handler::listener_attr_int(channel *ch, message &msg)
        return ret;
 }
 
-int server_channel_handler::listener_attr_str(channel *ch, message &msg)
+int server_channel_handler::listener_set_attr_str(channel *ch, message &msg)
 {
        uint32_t id;
        cmd_listener_attr_str_t *buf;
@@ -282,6 +286,96 @@ int server_channel_handler::listener_attr_str(channel *ch, message &msg)
        return ret;
 }
 
+int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message &msg)
+{
+       cmd_listener_attr_int_t buf;
+       msg.disclose((char *)&buf);
+       uint32_t id = buf.listener_id;
+
+       int ret = OP_SUCCESS;
+
+       auto it = m_listeners.find(id);
+       retv_if(it == m_listeners.end(), -EINVAL);
+       retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
+                       -EACCES, "Permission denied[%d, %s]",
+                       id, m_listeners[id]->get_required_privileges().c_str());
+
+       switch (buf.attribute) {
+       case SENSORD_ATTRIBUTE_INTERVAL:
+       case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY:
+       case SENSORD_ATTRIBUTE_PASSIVE_MODE:
+               // TODO : Are these features required?
+               ret = OP_ERROR;
+               break;
+       case SENSORD_ATTRIBUTE_PAUSE_POLICY:
+       case SENSORD_ATTRIBUTE_AXIS_ORIENTATION:
+       default:
+               ret = m_listeners[id]->get_attribute(buf.attribute, &buf.value);
+       }
+
+       if (ret == OP_SUCCESS) {
+               message reply((char *)&buf, sizeof(buf));
+               reply.set_type(CMD_LISTENER_GET_ATTR_INT);
+               ret = ch->send_sync(&reply);
+       } else {
+               ret = send_reply(ch, OP_ERROR);
+       }
+
+       return ret;
+}
+
+int server_channel_handler::listener_get_attr_str(ipc::channel *ch, ipc::message &msg)
+{
+       uint32_t id;
+       cmd_listener_attr_str_t *buf;
+
+       buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[msg.size()];
+       retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
+
+       msg.disclose((char *)buf);
+
+       id = buf->listener_id;
+       auto it = m_listeners.find(id);
+       auto attr = buf->attribute;
+       delete [] buf;
+
+       if (it == m_listeners.end()) {
+               return -EINVAL;
+       }
+
+       if (!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges())) {
+               _E("Permission denied[%d, %s]", id, m_listeners[id]->get_required_privileges().c_str());
+               return -EACCES;
+       }
+
+       char *value = NULL;
+       int len = 0;
+       int ret = m_listeners[id]->get_attribute(attr, &value, &len);
+
+       if (ret == OP_SUCCESS) {
+               cmd_listener_attr_str_t *reply_buf;
+               size_t size = sizeof(cmd_listener_attr_str_t) + len;
+               reply_buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
+               retvm_if(!reply_buf, -ENOMEM, "Failed to allocate memory");
+
+               reply_buf->attribute = attr;
+               memcpy(reply_buf->value, value, len);
+               reply_buf->len = len;
+               delete [] value;
+
+               ipc::message reply;
+               reply.enclose((char *)reply_buf, size);
+               reply.set_type(CMD_LISTENER_GET_ATTR_STR);
+
+               ret = ch->send_sync(&reply);
+               delete [] reply_buf;
+       } else {
+               ret = send_reply(ch, OP_ERROR);
+       }
+
+       return ret;
+}
+
 int server_channel_handler::listener_get_data(channel *ch, message &msg)
 {
        ipc::message reply;
index befa663..6befe1c 100644 (file)
@@ -53,9 +53,11 @@ private:
        int listener_disconnect(ipc::channel *ch, ipc::message &msg);
        int listener_start(ipc::channel *ch, ipc::message &msg);
        int listener_stop(ipc::channel *ch, ipc::message &msg);
-       int listener_attr_int(ipc::channel *ch, ipc::message &msg);
-       int listener_attr_str(ipc::channel *ch, ipc::message &msg);
+       int listener_set_attr_int(ipc::channel *ch, ipc::message &msg);
+       int listener_set_attr_str(ipc::channel *ch, ipc::message &msg);
        int listener_get_data(ipc::channel *ch, ipc::message &msg);
+       int listener_get_attr_int(ipc::channel *ch, ipc::message &msg);
+       int listener_get_attr_str(ipc::channel *ch, ipc::message &msg);
 
        int provider_connect(ipc::channel *ch, ipc::message &msg);
        int provider_disconnect(ipc::channel *ch, ipc::message &msg);
index 0bc2de5..5d98e46 100644 (file)
@@ -43,9 +43,11 @@ enum cmd_type_e {
        CMD_LISTENER_CONNECT,
        CMD_LISTENER_START,
        CMD_LISTENER_STOP,
-       CMD_LISTENER_ATTR_INT,
-       CMD_LISTENER_ATTR_STR,
+       CMD_LISTENER_SET_ATTR_INT,
+       CMD_LISTENER_SET_ATTR_STR,
        CMD_LISTENER_GET_DATA,
+       CMD_LISTENER_GET_ATTR_INT,
+       CMD_LISTENER_GET_ATTR_STR,
 
        /* Provider */
        CMD_PROVIDER_CONNECT = 0x300,
@@ -79,13 +81,13 @@ typedef struct {
        int listener_id;
 } cmd_listener_stop_t;
 
-typedef struct  {
+typedef struct {
        int listener_id;
        int attribute;
        int value;
 } cmd_listener_attr_int_t;
 
-typedef struct  {
+typedef struct {
        int listener_id;
        int attribute;
        int len;