From: Boram Bae Date: Wed, 27 Nov 2019 08:06:10 +0000 (+0900) Subject: Add APIs to get an attribute value X-Git-Tag: submit/tizen_5.5/20191219.060634~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3fce175a19d9258c545b66223885e75d0d95252a;p=platform%2Fcore%2Fsystem%2Fsensord.git Add APIs to get an attribute value * 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 --- diff --git a/include/sensor_internal.h b/include/sensor_internal.h index fa7e76ee..07638fd5 100644 --- a/include/sensor_internal.h +++ b/include/sensor_internal.h @@ -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 * @@ -418,6 +431,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 * diff --git a/src/client-dummy/client_dummy.cpp b/src/client-dummy/client_dummy.cpp index d84e2ad9..accc0430 100644 --- a/src/client-dummy/client_dummy.cpp +++ b/src/client-dummy/client_dummy.cpp @@ -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; diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 9d13857b..376059c6 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -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; diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index 5e0e69d7..6cea7d32 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -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 diff --git a/src/client/sensor_listener.h b/src/client/sensor_listener.h index fd4d059d..47cab206 100644 --- a/src/client/sensor_listener.h +++ b/src/client/sensor_listener.h @@ -28,6 +28,7 @@ #include #include #include +#include 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 m_connected; std::atomic m_started; - std::map m_attributes; + std::map m_attributes_int; + std::map> m_attributes_str; }; } diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index 7a383711..c5adee27 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -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); diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp index f2abadc3..df5db088 100644 --- a/src/server/application_sensor_handler.cpp +++ b/src/server/application_sensor_handler.cpp @@ -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; } diff --git a/src/server/external_sensor_handler.cpp b/src/server/external_sensor_handler.cpp index 474f764b..e0f74bfd 100644 --- a/src/server/external_sensor_handler.cpp +++ b/src/server/external_sensor_handler.cpp @@ -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; } diff --git a/src/server/fusion_sensor_handler.cpp b/src/server/fusion_sensor_handler.cpp index 6cbc6922..5d5a8d12 100644 --- a/src/server/fusion_sensor_handler.cpp +++ b/src/server/fusion_sensor_handler.cpp @@ -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); } diff --git a/src/server/fusion_sensor_handler.h b/src/server/fusion_sensor_handler.h index 5e12f109..9feb67f9 100644 --- a/src/server/fusion_sensor_handler.h +++ b/src/server/fusion_sensor_handler.h @@ -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); diff --git a/src/server/physical_sensor_handler.cpp b/src/server/physical_sensor_handler.cpp index 1b44a874..da82314d 100644 --- a/src/server/physical_sensor_handler.cpp +++ b/src/server/physical_sensor_handler.cpp @@ -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(value), len); + if (ret) { + update_attribute(attr, value, len); + } + return (ret ? OP_SUCCESS : OP_ERROR); } diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp index 0de7fd00..843c794a 100644 --- a/src/server/sensor_handler.cpp +++ b/src/server/sensor_handler.cpp @@ -24,6 +24,7 @@ #include #include #include +#include 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(*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(*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 diff --git a/src/server/sensor_handler.h b/src/server/sensor_handler.h index cb7bde88..e42a8e36 100644 --- a/src/server/sensor_handler.h +++ b/src/server/sensor_handler.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include 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 m_attributes_int; + std::map> m_attributes_str; private: std::list m_observers; diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index a52927d6..f184e458 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -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 diff --git a/src/server/sensor_listener_proxy.h b/src/server/sensor_listener_proxy.h index f0d1dae6..f87447b2 100644 --- a/src/server/sensor_listener_proxy.h +++ b/src/server/sensor_listener_proxy.h @@ -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); diff --git a/src/server/sensor_observer.h b/src/server/sensor_observer.h index 02603b00..ee04c208 100644 --- a/src/server/sensor_observer.h +++ b/src/server/sensor_observer.h @@ -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; }; } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 86606dff..c8c8d0be 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -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; diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index befa6633..6befe1c5 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -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); diff --git a/src/shared/command_types.h b/src/shared/command_types.h index 0bc2de5c..5d98e46d 100644 --- a/src/shared/command_types.h +++ b/src/shared/command_types.h @@ -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;