From 3fce175a19d9258c545b66223885e75d0d95252a Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Wed, 27 Nov 2019 17:06:10 +0900 Subject: [PATCH 01/16] 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 --- include/sensor_internal.h | 27 +++++ src/client-dummy/client_dummy.cpp | 10 ++ src/client/sensor_internal.cpp | 37 ++++++ src/client/sensor_listener.cpp | 157 ++++++++++++++++++------ src/client/sensor_listener.h | 9 +- src/sensorctl/testcase/sensor_listener.cpp | 186 ++++++++++++++++++++++++++++- src/server/application_sensor_handler.cpp | 3 +- src/server/external_sensor_handler.cpp | 6 + src/server/fusion_sensor_handler.cpp | 4 + src/server/fusion_sensor_handler.h | 5 - src/server/physical_sensor_handler.cpp | 7 ++ src/server/sensor_handler.cpp | 71 +++++++++-- src/server/sensor_handler.h | 12 +- src/server/sensor_listener_proxy.cpp | 36 +++++- src/server/sensor_listener_proxy.h | 2 + src/server/sensor_observer.h | 1 - src/server/server_channel_handler.cpp | 106 +++++++++++++++- src/server/server_channel_handler.h | 6 +- src/shared/command_types.h | 10 +- 19 files changed, 622 insertions(+), 73 deletions(-) diff --git a/include/sensor_internal.h b/include/sensor_internal.h index fa7e76e..07638fd 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 * @@ -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. diff --git a/src/client-dummy/client_dummy.cpp b/src/client-dummy/client_dummy.cpp index d84e2ad..accc043 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 9d13857..376059c 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 5e0e69d..6cea7d3 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 fd4d059..47cab20 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 7a38371..c5adee2 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 f2abadc..df5db08 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 474f764..e0f74bf 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 6cbc692..5d5a8d1 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 5e12f10..9feb67f 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 1b44a87..da82314 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 0de7fd0..843c794 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 cb7bde8..e42a8e3 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 a52927d..f184e45 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 f0d1dae..f87447b 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 02603b0..ee04c20 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 86606df..c8c8d0b 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 befa663..6befe1c 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 0bc2de5..5d98e46 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; -- 2.7.4 From ccf9ba4209e4fd281cadf7a764c724e508a04113 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Fri, 29 Nov 2019 13:35:56 +0900 Subject: [PATCH 02/16] Implement sensord_get_data_list * Add a command type CMD_LISTENER_GET_DATA_LIST * Add sensorctl tests * Now, you can use sensor_get_data_list instead of sensor_get_data Change-Id: I2c90e680a6b3f86076df5702f3b29d5ff7eec1bf Signed-off-by: Boram Bae --- include/sensor_internal.h | 11 ++ src/client-dummy/client_dummy.cpp | 5 + src/client/sensor_internal.cpp | 19 ++++ src/client/sensor_listener.cpp | 51 ++++++++- src/client/sensor_listener.h | 1 + src/sensorctl/testcase/sensor_listener.cpp | 50 +++++++++ src/sensorctl/testcase/sensor_provider.cpp | 160 +++++++++++++++++++++++++++++ src/server/server_channel_handler.cpp | 46 +++++++++ src/server/server_channel_handler.h | 1 + src/shared/command_types.h | 8 ++ 10 files changed, 349 insertions(+), 3 deletions(-) diff --git a/include/sensor_internal.h b/include/sensor_internal.h index 07638fd..1fbfabe 100644 --- a/include/sensor_internal.h +++ b/include/sensor_internal.h @@ -467,6 +467,17 @@ bool sensord_send_command(int handle, const char *command, int command_len); bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data); /** + * @brief get sensor data from a connected sensor + * + * @param[in] handle a handle represensting a connected context sensor. + * @param[in] data_id it specifies data to get + * @param[out] sensor_data the data list from connected sensor, the caller should explicitly free this list. + * @param[out] count the count of data contained in the list. + * @return true on success, otherwise false. + */ +bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count); + +/** * @brief flush sensor data from a connected sensor * * @param[in] handle a handle represensting a connected context sensor. diff --git a/src/client-dummy/client_dummy.cpp b/src/client-dummy/client_dummy.cpp index accc043..8432ba2 100644 --- a/src/client-dummy/client_dummy.cpp +++ b/src/client-dummy/client_dummy.cpp @@ -233,6 +233,11 @@ API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* senso return false; } +API bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count) +{ + return false; +} + API bool sensord_flush(int handle) { return false; diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 376059c..950c28d 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -787,6 +787,25 @@ API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* senso return true; } +API bool sensord_get_data_list(int handle, unsigned int data_id, sensor_data_t** sensor_data, int* count) +{ + sensor::sensor_listener *listener; + + AUTOLOCK(lock); + + auto it = listeners.find(handle); + retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle); + + listener = it->second; + + if (listener->get_sensor_data_list(sensor_data, count) < 0) { + _E("Failed to get sensor data from listener"); + return false; + } + + return true; +} + API bool sensord_flush(int handle) { sensor::sensor_listener *listener; diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index 6cea7d3..c979244 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -532,7 +532,6 @@ int sensor_listener::get_attribute(int attribute, int* value) 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()) { @@ -606,7 +605,6 @@ int sensor_listener::get_attribute(int attribute, char **value, int* len) m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) { - _D("reply.header()->err < 0"); return reply.header()->err; } @@ -660,4 +658,51 @@ 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 +} + +int sensor_listener::get_sensor_data_list(sensor_data_t **data, int *count) +{ + ipc::message msg; + ipc::message reply; + cmd_listener_get_data_list_t buf; + + retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_GET_DATA_LIST); + msg.enclose((char *)&buf, sizeof(buf)); + + m_cmd_channel->send_sync(&msg); + m_cmd_channel->read_sync(reply); + + if (reply.header()->err < 0) { + return reply.header()->err; + } + + size_t size = reply.size(); + cmd_listener_get_data_list_t* reply_buf = (cmd_listener_get_data_list_t *) new(std::nothrow) char[size]; + + retvm_if(!reply_buf, -ENOMEM, "Failed to allocate memory"); + + reply.disclose((char *)reply_buf); + + if (reply_buf->len <= 0) { + delete [] reply_buf; + return OP_ERROR; + } + + *count = reply_buf->data_count; + *data = (sensor_data_t*) malloc(reply_buf->len); + + if (!(*data)) { + _E("Memory allocation failed"); + delete [] reply_buf; + return -ENOMEM; + } + + memcpy(*data, reply_buf->data, reply_buf->len); + + _D("Listener[%d] read sensor data list", get_id()); + delete [] reply_buf; + return OP_SUCCESS; +} diff --git a/src/client/sensor_listener.h b/src/client/sensor_listener.h index 47cab20..581b2a1 100644 --- a/src/client/sensor_listener.h +++ b/src/client/sensor_listener.h @@ -75,6 +75,7 @@ public: 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 get_sensor_data_list(sensor_data_t **data, int *count); int flush(void); void restore(void); diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index c5adee2..6fc6bf4 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -427,6 +427,56 @@ TESTCASE(sensor_listener, get_attribute_string_2) return true; } +#define SENSOR_SHIFT_TYPE 16 +TESTCASE(sensor_listener, get_data_list) +{ + int err; + bool ret; + int handle; + sensor_t sensor; + sensor_type_t type; + + called = false; + + err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + + sensord_get_type(sensor, &type); + ASSERT_EQ(err, 0); + + ret = sensord_start(handle, 0); + ASSERT_TRUE(ret); + + sensor_data_t* data_list = NULL; + int count = 0; + unsigned int data_id = type << SENSOR_SHIFT_TYPE | 0x1; + + ret = sensord_get_data_list(handle, data_id, &data_list, &count); + ASSERT_TRUE(ret); + ASSERT_EQ(count, 1); + + for (int i = 0 ; i < count; i++) { + _I("[%llu]", data_list[i].timestamp); + for (int j = 0; j < data_list[i].value_count; j++) + _I(" %f", data_list[i].values[j]); + _I("\n"); + } + free(data_list); + + ret = sensord_stop(handle); + ASSERT_TRUE(ret); + + ret = sensord_unregister_events(handle, 1); + ASSERT_TRUE(ret); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + return true; +} + void sensor_attribute_int_changed_callback(sensor_t sensor, int attribute, int value, void *data) { _I("[ATTRIBUTE INT CHANGED] attribute : %d, value : %d\n", attribute, value); diff --git a/src/sensorctl/testcase/sensor_provider.cpp b/src/sensorctl/testcase/sensor_provider.cpp index bcd5101..d7ed1bb 100644 --- a/src/sensorctl/testcase/sensor_provider.cpp +++ b/src/sensorctl/testcase/sensor_provider.cpp @@ -356,3 +356,163 @@ TESTCASE(skip_sensor_provider, mysensor_batch_with_listener_p_1) return true; } + +TESTCASE(skip_sensor_provider, mysensor_batch_events_once) +{ + int err = 0; + bool ret = false; + sensor_t sensor; + sensord_provider_h provider; + + err = sensord_create_provider(MYSENSOR_BATCH_URI, &provider); + ASSERT_EQ(err, 0); + + err = sensord_provider_set_name(provider, MYSENSOR_BATCH_NAME); + ASSERT_EQ(err, 0); + err = sensord_provider_set_vendor(provider, MYSENSOR_VENDOR); + ASSERT_EQ(err, 0); + err = sensord_provider_set_range(provider, 0.0f, 1.0f); + ASSERT_EQ(err, 0); + err = sensord_provider_set_resolution(provider, 0.01f); + ASSERT_EQ(err, 0); + + err = sensord_add_provider(provider); + ASSERT_EQ(err, 0); + + err = sensord_provider_set_start_cb(provider, start_cb, NULL); + ASSERT_EQ(err, 0); + err = sensord_provider_set_stop_cb(provider, stop_cb, NULL); + ASSERT_EQ(err, 0); + err = sensord_provider_set_interval_changed_cb(provider, interval_cb, NULL); + ASSERT_EQ(err, 0); + + err = sensord_get_default_sensor_by_uri(MYSENSOR_BATCH_URI, &sensor); + ASSERT_EQ(err, 0); + + int client_handle; + sensor_t client_sensor; + err = sensord_get_default_sensor_by_uri(MYSENSOR_BATCH_URI, &client_sensor); + ASSERT_EQ(err, 0); + client_handle = sensord_connect(client_sensor); + ASSERT_EQ(err, 0); + + ret = sensord_start(client_handle, 0); + ASSERT_TRUE(ret); + + sensor_data_t data[NUMBER_OF_EVENT]; + for (int i = 0 ; i < NUMBER_OF_EVENT; i++) { + data[i].accuracy = 3; + data[i].timestamp = sensor::utils::get_timestamp(); + data[i].value_count = 3; + data[i].values[0] = i; + data[i].values[1] = i; + data[i].values[2] = i; + } + err = sensord_provider_publish_events(provider, data, NUMBER_OF_EVENT); + ASSERT_EQ(err, 0); + + ret = sensord_stop(client_handle); + ASSERT_TRUE(ret); + ret = sensord_disconnect(client_handle); + ASSERT_TRUE(ret); + + mainloop::run(); + + err = sensord_remove_provider(provider); + ASSERT_EQ(err, 0); + err = sensord_destroy_provider(provider); + ASSERT_EQ(err, 0); + + return true; +} + +TESTCASE(skip_sensor_provider, mysensor_batch_p_without_publish) +{ + int err = 0; + sensor_t sensor; + sensord_provider_h provider; + + err = sensord_create_provider(MYSENSOR_BATCH_URI, &provider); + ASSERT_EQ(err, 0); + + err = sensord_provider_set_name(provider, MYSENSOR_BATCH_NAME); + ASSERT_EQ(err, 0); + err = sensord_provider_set_vendor(provider, MYSENSOR_VENDOR); + ASSERT_EQ(err, 0); + err = sensord_provider_set_range(provider, 0.0f, 1.0f); + ASSERT_EQ(err, 0); + err = sensord_provider_set_resolution(provider, 0.01f); + ASSERT_EQ(err, 0); + + err = sensord_add_provider(provider); + ASSERT_EQ(err, 0); + + err = sensord_provider_set_start_cb(provider, start_cb, NULL); + ASSERT_EQ(err, 0); + err = sensord_provider_set_stop_cb(provider, stop_cb, NULL); + ASSERT_EQ(err, 0); + err = sensord_provider_set_interval_changed_cb(provider, interval_cb, NULL); + ASSERT_EQ(err, 0); + + err = sensord_get_default_sensor_by_uri(MYSENSOR_BATCH_URI, &sensor); + ASSERT_EQ(err, 0); + + mainloop::run(); + + err = sensord_remove_provider(provider); + ASSERT_EQ(err, 0); + err = sensord_destroy_provider(provider); + ASSERT_EQ(err, 0); + + return true; +} + +#define SENSOR_SHIFT_TYPE 16 +TESTCASE(skip_sensor_provider, mysensor_get_data_list) +{ + int err; + bool ret; + int handle; + sensor_t sensor; + sensor_type_t type; + + called = false; + + err = sensord_get_default_sensor_by_uri(MYSENSOR_BATCH_URI, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + + sensord_get_type(sensor, &type); + ASSERT_EQ(err, 0); + + ret = sensord_start(handle, 0); + ASSERT_TRUE(ret); + + sensor_data_t* data_list = NULL; + int count = 0; + unsigned int data_id = type << SENSOR_SHIFT_TYPE | 0x1; + + ret = sensord_get_data_list(handle, data_id, &data_list, &count); + ASSERT_TRUE(ret); + ASSERT_EQ(count, NUMBER_OF_EVENT); + + for (int i = 0 ; i < count; i++) { + _I("[%llu]", data_list[i].timestamp); + for (int j = 0; j < data_list[i].value_count; j++) + _I(" %f", data_list[i].values[j]); + _I("\n"); + } + free(data_list); + + ret = sensord_stop(handle); + ASSERT_TRUE(ret); + + ret = sensord_unregister_events(handle, 1); + ASSERT_TRUE(ret); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + return true; +} \ No newline at end of file diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index c8c8d0b..69f15f4 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -99,6 +99,8 @@ void server_channel_handler::read(channel *ch, message &msg) err = listener_get_attr_int(ch, msg); break; case CMD_LISTENER_GET_ATTR_STR: err = listener_get_attr_str(ch, msg); break; + case CMD_LISTENER_GET_DATA_LIST: + err = listener_get_data_list(ch, msg); break; case CMD_PROVIDER_CONNECT: err = provider_connect(ch, msg); break; case CMD_PROVIDER_PUBLISH: @@ -410,6 +412,50 @@ int server_channel_handler::listener_get_data(channel *ch, message &msg) return OP_SUCCESS; } +int server_channel_handler::listener_get_data_list(ipc::channel *ch, ipc::message &msg) +{ + ipc::message reply; + cmd_listener_get_data_list_t buf; + sensor_data_t *data; + int len; + uint32_t id; + + msg.disclose((char *)&buf); + id = buf.listener_id; + + 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()); + + int ret = m_listeners[id]->get_data(&data, &len); + retv_if(ret < 0, ret); + + size_t reply_size = sizeof(cmd_listener_get_data_list_t) + len; + cmd_listener_get_data_list_t* reply_buf = (cmd_listener_get_data_list_t *) malloc(reply_size); + if (!reply_buf) { + _E("Failed to allocate memory"); + free(data); + return -ENOMEM; + } + + memcpy(reply_buf->data, data, len); + reply_buf->len = len; + reply_buf->data_count = len / sizeof(sensor_data_t); + reply.enclose((const char *)reply_buf, reply_size); + reply.header()->err = OP_SUCCESS; + reply.header()->type = CMD_LISTENER_GET_DATA_LIST; + + ch->send_sync(&reply); + + free(data); + free(reply_buf); + + return OP_SUCCESS; + +} + int server_channel_handler::provider_connect(channel *ch, message &msg) { sensor_info info; diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index 6befe1c..456c4d1 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -58,6 +58,7 @@ private: 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 listener_get_data_list(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 5d98e46..7acf878 100644 --- a/src/shared/command_types.h +++ b/src/shared/command_types.h @@ -48,6 +48,7 @@ enum cmd_type_e { CMD_LISTENER_GET_DATA, CMD_LISTENER_GET_ATTR_INT, CMD_LISTENER_GET_ATTR_STR, + CMD_LISTENER_GET_DATA_LIST, /* Provider */ CMD_PROVIDER_CONNECT = 0x300, @@ -101,6 +102,13 @@ typedef struct { } cmd_listener_get_data_t; typedef struct { + int listener_id; + int len; + int data_count; + sensor_data_t data[0]; +} cmd_listener_get_data_list_t; + +typedef struct { char info[0]; } cmd_provider_connect_t; -- 2.7.4 From 638806e5844cc9401d0792e66caad4e07fb20040 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Tue, 3 Dec 2019 10:31:09 +0900 Subject: [PATCH 03/16] Use share_ptr to send message, Use reference to send_sync message * fix some memory leak Change-Id: I20bbc5e29fa1ed9f801b3f6bb904b49fea857506 Signed-off-by: Boram Bae --- src/client/sensor_internal.cpp | 3 +- src/client/sensor_listener.cpp | 18 +++++----- src/client/sensor_manager.cpp | 6 ++-- src/client/sensor_provider.cpp | 8 ++--- src/sensorctl/testcase/sensor_listener.cpp | 31 +++++++++++++++++ src/sensorctl/testcase/unit_ipc.cpp | 16 ++++----- src/server/application_sensor_handler.cpp | 8 ++--- src/server/fusion_sensor_handler.cpp | 2 +- src/server/fusion_sensor_handler.h | 2 +- src/server/sensor_handler.cpp | 21 +++--------- src/server/sensor_listener_proxy.cpp | 11 ++++--- src/server/sensor_listener_proxy.h | 8 ++--- src/server/sensor_manager.cpp | 16 ++++++--- src/server/sensor_observer.h | 3 +- src/server/server_channel_handler.cpp | 19 ++++++----- src/shared/channel.cpp | 39 +++++++++++----------- src/shared/channel.h | 4 +-- src/shared/ipc_server.cpp | 1 + src/shared/message.cpp | 53 ++++++++---------------------- src/shared/message.h | 9 ++++- 20 files changed, 144 insertions(+), 134 deletions(-) diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 950c28d..0695e63 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -746,6 +746,7 @@ API int sensord_set_attribute_str(int handle, int attribute, const char *value, _E("Failed to set attribute[%d, %s]", attribute, value); return -EIO; } + _D("Set attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, len); return OP_SUCCESS; } @@ -763,7 +764,7 @@ API int sensord_get_attribute_str(int handle, int attribute, char **value, int* _E("Failed to get attribute[%d]", attribute); return -EIO; } - _D("Get attribute[%d, %d, %s]", listener->get_id(), attribute, *value); + _D("Get attribute ID[%d], attr[%d], len[%d]", listener->get_id(), attribute, *len); return OP_SUCCESS; } diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index c979244..612c1ad 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -224,7 +224,7 @@ bool sensor_listener::connect(void) 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_evt_channel->send_sync(&msg); + m_evt_channel->send_sync(msg); m_evt_channel->read_sync(reply); reply.disclose((char *)&buf); @@ -364,7 +364,7 @@ int sensor_listener::start(void) msg.set_type(CMD_LISTENER_START); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) { @@ -392,7 +392,7 @@ int sensor_listener::stop(void) msg.set_type(CMD_LISTENER_STOP); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) { @@ -503,7 +503,7 @@ int sensor_listener::set_attribute(int attribute, int value) msg.set_type(CMD_LISTENER_SET_ATTR_INT); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) @@ -527,7 +527,7 @@ int sensor_listener::get_attribute(int attribute, int* value) msg.set_type(CMD_LISTENER_GET_ATTR_INT); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); @@ -572,7 +572,7 @@ int sensor_listener::set_attribute(int attribute, const char *value, int len) msg.enclose((char *)buf, size); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); /* Message memory is released automatically after sending message, @@ -601,7 +601,7 @@ int sensor_listener::get_attribute(int attribute, char **value, int* len) msg.set_type(CMD_LISTENER_GET_ATTR_STR); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) { @@ -640,7 +640,7 @@ int sensor_listener::get_sensor_data(sensor_data_t *data) msg.set_type(CMD_LISTENER_GET_DATA); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); reply.disclose((char *)&buf); @@ -672,7 +672,7 @@ int sensor_listener::get_sensor_data_list(sensor_data_t **data, int *count) msg.set_type(CMD_LISTENER_GET_DATA_LIST); msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(&msg); + m_cmd_channel->send_sync(msg); m_cmd_channel->read_sync(reply); if (reply.header()->err < 0) { diff --git a/src/client/sensor_manager.cpp b/src/client/sensor_manager.cpp index f16601f..64b623c 100644 --- a/src/client/sensor_manager.cpp +++ b/src/client/sensor_manager.cpp @@ -207,7 +207,7 @@ bool sensor_manager::connect_channel(void) retvm_if(!m_mon_channel, false, "Failed to connect to server"); msg.set_type(CMD_MANAGER_CONNECT); - m_mon_channel->send_sync(&msg); + m_mon_channel->send_sync(msg); m_connected.store(true); @@ -290,7 +290,7 @@ bool sensor_manager::get_sensors_internal(void) msg.set_type(CMD_MANAGER_SENSOR_LIST); - ret = m_cmd_channel->send_sync(&msg); + ret = m_cmd_channel->send_sync(msg); retvm_if(!ret, false, "Failed to send message"); ret = m_cmd_channel->read_sync(reply); @@ -316,7 +316,7 @@ bool sensor_manager::has_privilege(std::string &uri) memcpy(buf.sensor, uri.c_str(), uri.size()); msg.enclose((const char *)&buf, sizeof(buf)); - ret = m_cmd_channel->send_sync(&msg); + ret = m_cmd_channel->send_sync(msg); retvm_if(!ret, false, "Failed to send message"); ret = m_cmd_channel->read_sync(reply); diff --git a/src/client/sensor_provider.cpp b/src/client/sensor_provider.cpp index a90f7c2..414e83f 100644 --- a/src/client/sensor_provider.cpp +++ b/src/client/sensor_provider.cpp @@ -100,7 +100,7 @@ int sensor_provider::serialize(sensor_info *info, char **bytes) info->serialize(*raw); - *bytes = new(std::nothrow) char[raw->size()]; + *bytes = (char *) malloc(raw->size()); retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory"); std::copy(raw->begin(), raw->end(), *bytes); @@ -121,7 +121,7 @@ int sensor_provider::send_sensor_info(sensor_info *info) ipc::message msg((const char *)bytes, size); msg.set_type(CMD_PROVIDER_CONNECT); - m_channel->send_sync(&msg); + m_channel->send_sync(msg); return OP_SUCCESS; } @@ -174,7 +174,7 @@ int sensor_provider::publish(const sensor_data_t &data) msg.set_type(CMD_PROVIDER_PUBLISH); msg.enclose((const void *)(&data), sizeof(data)); - m_channel->send_sync(&msg); + m_channel->send_sync(msg); return OP_SUCCESS; } @@ -185,7 +185,7 @@ int sensor_provider::publish(const sensor_data_t data[], const int count) msg.set_type(CMD_PROVIDER_PUBLISH); msg.enclose((const void *)data, sizeof(sensor_data_t) * count); - m_channel->send_sync(&msg); + m_channel->send_sync(msg); return OP_SUCCESS; } diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index 6fc6bf4..70050b0 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -355,6 +355,37 @@ TESTCASE(sensor_listener, set_get_attribute_string_1) return true; } +#define BUF_SIZE 4000 +TESTCASE(sensor_listener, set_get_attribute_string_2) +{ + int err = 0; + bool ret = true; + int handle = 0; + char *value = NULL; + int len = 0; + sensor_t sensor = NULL; + int attr = 1; + char attr_value[BUF_SIZE] = {1, }; + attr_value[BUF_SIZE - 1] = 1; + + err = sensord_get_default_sensor(ACCELEROMETER_SENSOR, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + err = sensord_set_attribute_str(handle, attr, attr_value, BUF_SIZE); + ASSERT_EQ(err, 0); + + err = sensord_get_attribute_str(handle, attr, &value, &len); + ASSERT_EQ(err, 0); + ASSERT_EQ(len, BUF_SIZE); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + free(value); + return true; +} + TESTCASE(sensor_listener, set_get_get_attribute_string_1) { int err; diff --git a/src/sensorctl/testcase/unit_ipc.cpp b/src/sensorctl/testcase/unit_ipc.cpp index c11d439..10e11e4 100644 --- a/src/sensorctl/testcase/unit_ipc.cpp +++ b/src/sensorctl/testcase/unit_ipc.cpp @@ -61,7 +61,7 @@ public: { char buf[MAX_BUF_SIZE]; - message *reply = new(std::nothrow) message(); + auto reply = message::create(); RETM_IF(!reply, "Failed to allocate memory"); msg.disclose(buf); @@ -117,7 +117,7 @@ static bool run_ipc_client_sleep_1s(const char *str, int size, int count) msg.enclose(buf, MAX_BUF_SIZE); SLEEP_1S; - ch->send_sync(&msg); + ch->send_sync(msg); /* Test */ SLEEP_1S; @@ -162,7 +162,7 @@ static bool run_ipc_client_small_buffer(const char *str, int size, int count) _I("After: Buffer size : %d\n", buf_size); for (int i = 0; i < 1024; ++i) { - ch->send_sync(&msg); + ch->send_sync(msg); ch->read_sync(reply); } @@ -197,7 +197,7 @@ static bool run_ipc_client_1M(const char *str, int size, int count) SLEEP_1S; for (int i = 0; i < 256; ++i) { - ch->send_sync(&msg); + ch->send_sync(msg); ch->read_sync(reply); } @@ -224,7 +224,7 @@ public: char buf[MAX_BUF_SIZE]; msg.disclose(buf); - message *reply = new(std::nothrow) message(); + auto reply = message::create(); if (!reply) return; reply->enclose("TEXTTEXTTEXTTEXT", 16); @@ -278,7 +278,7 @@ static bool run_ipc_client_2_channel_message(const char *str, int size, int coun ASSERT_NE(ch[0], 0); msg.enclose("TESTTESTTEST", 12); - ch[0]->send_sync(&msg); + ch[0]->send_sync(msg); SLEEP_1S; ch[0]->read_sync(reply); reply.disclose(buf); @@ -289,7 +289,7 @@ static bool run_ipc_client_2_channel_message(const char *str, int size, int coun ASSERT_NE(ch[1], 0); msg.enclose("TESTTESTTEST", 12); - ch[1]->send_sync(&msg); + ch[1]->send_sync(msg); SLEEP_1S; ch[1]->read_sync(reply); reply.disclose(buf); @@ -338,7 +338,7 @@ static bool run_ipc_client(const char *str, int size, int count) char buf[MAX_BUF_SIZE]; msg.enclose("TESTTESTTEST", 12); - ch->send_sync(&msg); + ch->send_sync(msg); SLEEP_1S; diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp index df5db08..fe1aac3 100644 --- a/src/server/application_sensor_handler.cpp +++ b/src/server/application_sensor_handler.cpp @@ -58,7 +58,7 @@ int application_sensor_handler::start(sensor_observer *ob) ipc::message msg; msg.set_type(CMD_PROVIDER_START); - m_ch->send_sync(&msg); + m_ch->send_sync(msg); m_started.store(true); _I("Started[%s]", m_info.get_uri().c_str()); @@ -75,7 +75,7 @@ int application_sensor_handler::stop(sensor_observer *ob) ipc::message msg; msg.set_type(CMD_PROVIDER_STOP); - m_ch->send_sync(&msg); + m_ch->send_sync(msg); m_started.store(false); _I("Stopped[%s]", m_info.get_uri().c_str()); @@ -119,7 +119,7 @@ int application_sensor_handler::set_interval(sensor_observer *ob, int32_t interv msg.set_type(CMD_PROVIDER_ATTR_INT); msg.enclose((const char *)&buf, sizeof(cmd_provider_attr_int_t)); - m_ch->send_sync(&msg); + m_ch->send_sync(msg); m_prev_interval = cur_interval; @@ -157,7 +157,7 @@ int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, msg.enclose((char *)buf, size); - m_ch->send_sync(&msg); + m_ch->send_sync(msg); _I("Set attribute[%d] to sensor[%s]", attr, m_info.get_uri().c_str()); update_attribute(attr, value, len); diff --git a/src/server/fusion_sensor_handler.cpp b/src/server/fusion_sensor_handler.cpp index 5d5a8d1..1ede44c 100644 --- a/src/server/fusion_sensor_handler.cpp +++ b/src/server/fusion_sensor_handler.cpp @@ -43,7 +43,7 @@ void fusion_sensor_handler::add_required_sensor(uint32_t id, sensor_handler *sen m_required_sensors.emplace(info.get_uri(), required_sensor(id, sensor)); } -int fusion_sensor_handler::update(const char *uri, ipc::message *msg) +int fusion_sensor_handler::update(const char *uri, std::shared_ptr msg) { retv_if(!m_sensor, -EINVAL); diff --git a/src/server/fusion_sensor_handler.h b/src/server/fusion_sensor_handler.h index 9feb67f..e5d6db3 100644 --- a/src/server/fusion_sensor_handler.h +++ b/src/server/fusion_sensor_handler.h @@ -50,7 +50,7 @@ public: void add_required_sensor(uint32_t id, sensor_handler *sensor); /* subscriber */ - int update(const char *uri, ipc::message *msg); + int update(const char *uri, std::shared_ptr msg); /* sensor interface */ const sensor_info &get_sensor_info(void); diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp index 843c794..9ae43a3 100644 --- a/src/server/sensor_handler.cpp +++ b/src/server/sensor_handler.cpp @@ -81,9 +81,8 @@ int sensor_handler::notify(const char *uri, sensor_data_t *data, int len) if (observer_count() == 0) return OP_ERROR; - ipc::message *msg; + auto msg = ipc::message::create((char *)data, len); - msg = new(std::nothrow) ipc::message((char *)data, len); retvm_if(!msg, OP_ERROR, "Failed to allocate memory"); for (auto it = m_observers.begin(); it != m_observers.end(); ++it) @@ -91,10 +90,6 @@ int sensor_handler::notify(const char *uri, sensor_data_t *data, int len) set_cache(data, len); - if (msg->ref_count() == 0) { - msg->unref(); - } - return OP_SUCCESS; } @@ -141,8 +136,8 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int va buf.attribute = attribute; buf.value = value; - ipc::message *msg; - msg = new(std::nothrow) ipc::message(); + auto msg = ipc::message::create(); + retvm_if(!msg, OP_ERROR, "Failed to allocate memory"); msg->set_type(CMD_LISTENER_SET_ATTR_INT); @@ -156,9 +151,6 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int va } } - if (msg->ref_count() == 0) - msg->unref(); - return OP_SUCCESS; } @@ -173,8 +165,7 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size]; retvm_if(!buf, -ENOMEM, "Failed to allocate memory"); - ipc::message *msg; - msg = new(std::nothrow) ipc::message(); + auto msg = ipc::message::create(); retvm_if(!msg, OP_ERROR, "Failed to allocate memory"); buf->listener_id = id; @@ -194,10 +185,6 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const } } - if (msg->ref_count() == 0) { - msg->unref(); - } - delete[] buf; return OP_SUCCESS; diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index f184e45..0862774 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -56,7 +56,7 @@ uint32_t sensor_listener_proxy::get_id(void) return m_id; } -int sensor_listener_proxy::update(const char *uri, ipc::message *msg) +int sensor_listener_proxy::update(const char *uri, std::shared_ptr msg) { retv_if(!m_ch || !m_ch->is_connected(), OP_CONTINUE); @@ -66,7 +66,7 @@ int sensor_listener_proxy::update(const char *uri, ipc::message *msg) return OP_CONTINUE; } -int sensor_listener_proxy::on_attribute_changed(ipc::message *msg) +int sensor_listener_proxy::on_attribute_changed(std::shared_ptr msg) { retv_if(!m_ch || !m_ch->is_connected(), OP_CONTINUE); _I("Proxy[%zu] call on_attribute_changed\n", get_id()); @@ -74,7 +74,7 @@ int sensor_listener_proxy::on_attribute_changed(ipc::message *msg) return OP_CONTINUE; } -void sensor_listener_proxy::update_event(ipc::message *msg) +void sensor_listener_proxy::update_event(std::shared_ptr msg) { /* TODO: check axis orientation */ msg->header()->type = CMD_LISTENER_EVENT; @@ -83,7 +83,7 @@ void sensor_listener_proxy::update_event(ipc::message *msg) m_ch->send(msg); } -void sensor_listener_proxy::update_accuracy(ipc::message *msg) +void sensor_listener_proxy::update_accuracy(std::shared_ptr msg) { sensor_data_t *data = reinterpret_cast(msg->body()); @@ -95,7 +95,8 @@ void sensor_listener_proxy::update_accuracy(ipc::message *msg) sensor_data_t acc_data; acc_data.accuracy = m_last_accuracy; - ipc::message *acc_msg = new(std::nothrow) ipc::message(); + auto acc_msg = ipc::message::create(); + retm_if(!acc_msg, "Failed to allocate memory"); acc_msg->header()->type = CMD_LISTENER_ACC_EVENT; diff --git a/src/server/sensor_listener_proxy.h b/src/server/sensor_listener_proxy.h index f87447b..084ffe2 100644 --- a/src/server/sensor_listener_proxy.h +++ b/src/server/sensor_listener_proxy.h @@ -38,8 +38,8 @@ public: uint32_t get_id(void); /* sensor observer */ - int update(const char *uri, ipc::message *msg); - int on_attribute_changed(ipc::message *msg); + int update(const char *uri, std::shared_ptr msg); + int on_attribute_changed(std::shared_ptr msg); int start(bool policy = false); int stop(bool policy = false); @@ -62,8 +62,8 @@ public: bool notify_attribute_changed(int attribute, const char *value, int len); private: - void update_event(ipc::message *msg); - void update_accuracy(ipc::message *msg); + void update_event(std::shared_ptr msg); + void update_accuracy(std::shared_ptr msg); uint32_t m_id; std::string m_uri; diff --git a/src/server/sensor_manager.cpp b/src/server/sensor_manager.cpp index f6cc1f5..6173800 100644 --- a/src/server/sensor_manager.cpp +++ b/src/server/sensor_manager.cpp @@ -115,7 +115,7 @@ int sensor_manager::serialize(sensor_info *info, char **bytes) info->serialize(*raw); - *bytes = new(std::nothrow) char[raw->size()]; + *bytes = (char *) malloc(raw->size()); retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory"); std::copy(raw->begin(), raw->end(), *bytes); @@ -129,7 +129,7 @@ int sensor_manager::serialize(sensor_info *info, char **bytes) void sensor_manager::send(ipc::message &msg) { for (auto it = m_channels.begin(); it != m_channels.end(); ++it) - (*it)->send_sync(&msg); + (*it)->send_sync(msg); } void sensor_manager::send_added_msg(sensor_info *info) @@ -410,8 +410,16 @@ void sensor_manager::register_handler(physical_sensor_handler *sensor) handler->add_sensor(sensor); m_event_handlers[fd] = handler; - m_loop->add_event(fd, - ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL, handler); + if (m_loop->add_event(fd, ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL, handler) == 0) { + _D("Failed to add sensor event handler"); + handler->remove_sensor(sensor); + + auto iter = m_event_handlers.find(fd); + if (iter != m_event_handlers.end()) { + m_event_handlers.erase(iter); + } + delete handler; + } } void sensor_manager::show(void) diff --git a/src/server/sensor_observer.h b/src/server/sensor_observer.h index ee04c20..9c86061 100644 --- a/src/server/sensor_observer.h +++ b/src/server/sensor_observer.h @@ -28,8 +28,7 @@ class sensor_observer { public: virtual ~sensor_observer() {} - /* for performance, use message */ - virtual int update(const char *uri, ipc::message *msg) = 0; + virtual int update(const char *uri, std::shared_ptr msg) = 0; }; } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 69f15f4..0058c17 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -112,7 +112,7 @@ void server_channel_handler::read(channel *ch, message &msg) if (err != 0) { message reply(err); - ch->send_sync(&reply); + ch->send_sync(reply); } } @@ -133,7 +133,7 @@ int server_channel_handler::manager_get_sensor_list(channel *ch, message &msg) reply.enclose((const char *)bytes, size); reply.header()->err = OP_SUCCESS; - ch->send_sync(&reply); + ch->send_sync(reply); delete [] bytes; @@ -161,7 +161,7 @@ int server_channel_handler::listener_connect(channel *ch, message &msg) reply.enclose((const char *)&buf, sizeof(buf)); reply.header()->err = OP_SUCCESS; - if (!ch->send_sync(&reply)) + if (!ch->send_sync(reply)) return OP_ERROR; _I("Connected sensor_listener[fd(%d) -> id(%u)]", ch->get_fd(), listener_id); @@ -316,9 +316,10 @@ int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message } if (ret == OP_SUCCESS) { - message reply((char *)&buf, sizeof(buf)); + message reply; + reply.enclose((char *)&buf, sizeof(buf)); reply.set_type(CMD_LISTENER_GET_ATTR_INT); - ret = ch->send_sync(&reply); + ret = ch->send_sync(reply); } else { ret = send_reply(ch, OP_ERROR); } @@ -369,7 +370,7 @@ int server_channel_handler::listener_get_attr_str(ipc::channel *ch, ipc::message reply.enclose((char *)reply_buf, size); reply.set_type(CMD_LISTENER_GET_ATTR_STR); - ret = ch->send_sync(&reply); + ret = ch->send_sync(reply); delete [] reply_buf; } else { ret = send_reply(ch, OP_ERROR); @@ -405,7 +406,7 @@ int server_channel_handler::listener_get_data(channel *ch, message &msg) reply.header()->err = OP_SUCCESS; reply.header()->type = CMD_LISTENER_GET_DATA; - ch->send_sync(&reply); + ch->send_sync(reply); free(data); @@ -447,7 +448,7 @@ int server_channel_handler::listener_get_data_list(ipc::channel *ch, ipc::messag reply.header()->err = OP_SUCCESS; reply.header()->type = CMD_LISTENER_GET_DATA_LIST; - ch->send_sync(&reply); + ch->send_sync(reply); free(data); free(reply_buf); @@ -514,7 +515,7 @@ int server_channel_handler::has_privileges(channel *ch, message &msg) int server_channel_handler::send_reply(channel *ch, int error) { message reply(error); - retvm_if(!ch->send_sync(&reply), OP_ERROR, "Failed to send reply"); + retvm_if(!ch->send_sync(reply), OP_ERROR, "Failed to send reply"); return OP_SUCCESS; } diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp index f27e1d4..6df1d2f 100644 --- a/src/shared/channel.cpp +++ b/src/shared/channel.cpp @@ -33,7 +33,7 @@ using namespace ipc; class send_event_handler : public event_handler { public: - send_event_handler(channel *ch, message *msg) + send_event_handler(channel *ch, std::shared_ptr msg) : m_ch(ch) , m_msg(msg) { } @@ -46,18 +46,15 @@ public: if (condition & (EVENT_IN | EVENT_HUP)) return false; - if (!m_ch->send_sync(m_msg)) + if (!m_ch->send_sync(*m_msg)) return false; - if (m_msg) - m_msg->unref(); - return false; } private: channel *m_ch; - message *m_msg; + std::shared_ptr m_msg; }; class read_event_handler : public event_handler @@ -173,7 +170,7 @@ void channel::disconnect(void) _D("Disconnected"); } -bool channel::send(message *msg) +bool channel::send(std::shared_ptr msg) { int retry_cnt = 0; int cur_buffer_size = 0; @@ -192,32 +189,32 @@ bool channel::send(message *msg) send_event_handler *handler = new(std::nothrow) send_event_handler(this, msg); retvm_if(!handler, false, "Failed to allocate memory"); - msg->ref(); - - m_loop->add_event(m_socket->get_fd(), - (EVENT_OUT | EVENT_HUP | EVENT_NVAL) , handler); + if (m_loop->add_event(m_socket->get_fd(), (EVENT_OUT | EVENT_HUP | EVENT_NVAL) , handler) == 0) { + _D("Failed to add send event handler"); + delete handler; + return false; + } return true; } -bool channel::send_sync(message *msg) +bool channel::send_sync(message &msg) { - retvm_if(!msg, false, "Invalid message"); - retvm_if(msg->size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg->size()); + retvm_if(msg.size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg.size()); ssize_t size = 0; - char *buf = msg->body(); + char *buf = msg.body(); /* header */ - size = m_socket->send(reinterpret_cast(msg->header()), + size = m_socket->send(reinterpret_cast(msg.header()), sizeof(message_header), true); retvm_if(size <= 0, false, "Failed to send header"); /* if body size is zero, skip to send body message */ - retv_if(msg->size() == 0, true); + retv_if(msg.size() == 0, true); /* body */ - size = m_socket->send(buf, msg->size(), true); + size = m_socket->send(buf, msg.size(), true); retvm_if(size <= 0, false, "Failed to send body"); return true; @@ -230,7 +227,11 @@ bool channel::read(void) read_event_handler *handler = new(std::nothrow) read_event_handler(this); retvm_if(!handler, false, "Failed to allocate memory"); - m_loop->add_event(m_socket->get_fd(), (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler); + if (m_loop->add_event(m_socket->get_fd(), (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler) == 0) { + _D("Failed to add read event handler"); + delete handler; + return false; + } return true; } diff --git a/src/shared/channel.h b/src/shared/channel.h index efdc481..615fd26 100644 --- a/src/shared/channel.h +++ b/src/shared/channel.h @@ -46,8 +46,8 @@ public: bool is_connected(void); - bool send(message *msg); - bool send_sync(message *msg); + bool send(std::shared_ptr msg); + bool send_sync(message &msg); bool read(void); bool read_sync(message &msg, bool select = true); diff --git a/src/shared/ipc_server.cpp b/src/shared/ipc_server.cpp index 66431da..f847c4d 100644 --- a/src/shared/ipc_server.cpp +++ b/src/shared/ipc_server.cpp @@ -98,6 +98,7 @@ void ipc_server::register_acceptor(void) (event_condition)(EVENT_IN | EVENT_HUP | EVENT_NVAL), m_accept_handler); if (id == 0) { + _D("Failed to add accept event handler"); delete m_accept_handler; m_accept_handler = NULL; } diff --git a/src/shared/message.cpp b/src/shared/message.cpp index d7455eb..f28780d 100644 --- a/src/shared/message.cpp +++ b/src/shared/message.cpp @@ -29,10 +29,9 @@ using namespace ipc; static std::atomic sequence(0); message::message(size_t capacity) -: m_size(0) -, m_capacity(capacity) -, m_msg((char *)malloc(sizeof(char) * capacity)) -, ref_cnt(0) + : m_size(0) + , m_capacity(capacity) + , m_msg((char *)malloc(sizeof(char) * capacity)) { m_header.id = sequence++; m_header.type = UNDEFINED_TYPE; @@ -41,10 +40,9 @@ message::message(size_t capacity) } message::message(const void *msg, size_t sz) -: m_size(sz) -, m_capacity(sz) -, m_msg((char *)msg) -, ref_cnt(0) + : m_size(sz) + , m_capacity(sz) + , m_msg((char *)msg) { m_header.id = sequence++; m_header.type = UNDEFINED_TYPE; @@ -53,20 +51,18 @@ message::message(const void *msg, size_t sz) } message::message(const message &msg) -: m_size(msg.m_size) -, m_capacity(msg.m_capacity) -, m_msg((char *)malloc(sizeof(char) * msg.m_capacity)) -, ref_cnt(0) + : m_size(msg.m_size) + , m_capacity(msg.m_capacity) + , m_msg((char *)malloc(sizeof(char) * msg.m_capacity)) { ::memcpy(&m_header, &msg.m_header, sizeof(message_header)); ::memcpy(m_msg, msg.m_msg, msg.m_size); } message::message(int error) -: m_size(0) -, m_capacity(0) -, m_msg(NULL) -, ref_cnt(0) + : m_size(0) + , m_capacity(0) + , m_msg(NULL) { m_header.id = sequence++; m_header.type = UNDEFINED_TYPE; @@ -76,7 +72,7 @@ message::message(int error) message::~message() { - if (m_msg && ref_cnt == 0) { + if (m_msg) { free(m_msg); m_msg = NULL; } @@ -125,29 +121,6 @@ size_t message::size(void) return m_size; } -/* TODO: remove ref/unref and use reference counting automatically */ -void message::ref(void) -{ - ref_cnt++; -} - -void message::unref(void) -{ - ref_cnt--; - - if (ref_cnt > 0 || !m_msg) - return; - - free(m_msg); - m_msg = NULL; - delete this; -} - -int message::ref_count(void) -{ - return ref_cnt; -} - message_header *message::header(void) { return &m_header; diff --git a/src/shared/message.h b/src/shared/message.h index 118cf13..0d932b6 100644 --- a/src/shared/message.h +++ b/src/shared/message.h @@ -22,6 +22,7 @@ #include /* size_t */ #include +#include #define MAX_MSG_CAPACITY (16*1024) #define MAX_HEADER_RESERVED 3 @@ -38,6 +39,13 @@ typedef struct message_header { class message { public: + template + static std::shared_ptr create(Args&&... args) + noexcept(noexcept(message(std::forward(args)...))) + { + return std::shared_ptr(new (std::nothrow) message(std::forward(args)...)); + } + message(size_t capacity = MAX_MSG_CAPACITY); message(const void *msg, size_t size); message(const message &msg); @@ -66,7 +74,6 @@ private: size_t m_capacity; char *m_msg; - std::atomic ref_cnt; }; } -- 2.7.4 From ed9bc433f485735dafcd248a5e35017669471594 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Thu, 5 Dec 2019 19:20:12 +0900 Subject: [PATCH 04/16] Delete pending events when disconnecting channel Change-Id: I1b7fb7dce4c14b31d18b9169f398571c34c67fbd Signed-off-by: Boram Bae --- src/shared/channel.cpp | 52 ++++++++++++++++++++++++++++++++++++++-------- src/shared/channel.h | 5 ++++- src/shared/event_handler.h | 13 ++++++++++++ src/shared/event_loop.cpp | 4 ++++ 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp index 6df1d2f..6ae8ed3 100644 --- a/src/shared/channel.cpp +++ b/src/shared/channel.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "sensor_log.h" #include "channel_event_handler.h" @@ -40,14 +41,23 @@ public: bool handle(int fd, event_condition condition) { - if (!m_ch || !m_ch->is_connected()) + if (!m_ch) { return false; + } - if (condition & (EVENT_IN | EVENT_HUP)) + m_ch->remove_pending_event_id(m_event_id); + + if (!m_ch->is_connected()) { + return false; + } + + if (condition & (EVENT_IN | EVENT_HUP)) { return false; + } - if (!m_ch->send_sync(*m_msg)) + if (!m_ch->send_sync(*m_msg)) { return false; + } return false; } @@ -66,16 +76,24 @@ public: bool handle(int fd, event_condition condition) { - message msg; + if (!m_ch) { + return false; + } + + m_ch->remove_pending_event_id(m_event_id); - if (!m_ch || !m_ch->is_connected()) + if (!m_ch->is_connected()) { return false; + } - if (condition & (EVENT_OUT | EVENT_HUP)) + if (condition & (EVENT_OUT | EVENT_HUP)) { return false; + } - if (!m_ch->read_sync(msg, false)) + message msg; + if (!m_ch->read_sync(msg, false)) { return false; + } return false; } @@ -155,6 +173,10 @@ void channel::disconnect(void) } if (m_loop) { + for(auto id : m_pending_event_id) { + _D("Remove pending event id[%llu]", id); + m_loop->remove_event(id, true); + } _D("Remove event[%llu]", m_event_id); m_loop->remove_event(m_event_id, true); m_loop = NULL; @@ -189,12 +211,14 @@ bool channel::send(std::shared_ptr msg) send_event_handler *handler = new(std::nothrow) send_event_handler(this, msg); retvm_if(!handler, false, "Failed to allocate memory"); - if (m_loop->add_event(m_socket->get_fd(), (EVENT_OUT | EVENT_HUP | EVENT_NVAL) , handler) == 0) { + uint64_t event_id = m_loop->add_event(m_socket->get_fd(), (EVENT_OUT | EVENT_HUP | EVENT_NVAL), handler); + if (event_id == 0) { _D("Failed to add send event handler"); delete handler; return false; } + m_pending_event_id.push_back(event_id); return true; } @@ -227,12 +251,14 @@ bool channel::read(void) read_event_handler *handler = new(std::nothrow) read_event_handler(this); retvm_if(!handler, false, "Failed to allocate memory"); - if (m_loop->add_event(m_socket->get_fd(), (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler) == 0) { + uint64_t event_id = m_loop->add_event(m_socket->get_fd(), (EVENT_IN | EVENT_HUP | EVENT_NVAL), handler); + if (event_id == 0) { _D("Failed to add read event handler"); delete handler; return false; } + m_pending_event_id.push_back(event_id); return true; } @@ -319,3 +345,11 @@ int channel::get_fd(void) const { return m_fd; } + +void channel::remove_pending_event_id(uint64_t id) +{ + auto it = std::find(m_pending_event_id.begin(), m_pending_event_id.end(), id); + if (it != m_pending_event_id.end()) { + m_pending_event_id.erase(it); + } +} diff --git a/src/shared/channel.h b/src/shared/channel.h index 615fd26..4aeefbc 100644 --- a/src/shared/channel.h +++ b/src/shared/channel.h @@ -22,6 +22,7 @@ #include #include +#include #include "socket.h" #include "message.h" @@ -55,7 +56,8 @@ public: bool get_option(int type, int &value) const; bool set_option(int type, int value); - int get_fd(void) const; + int get_fd(void) const; + void remove_pending_event_id(uint64_t id); private: int m_fd; @@ -63,6 +65,7 @@ private: socket *m_socket; channel_handler *m_handler; event_loop *m_loop; + std::vector m_pending_event_id; std::atomic m_connected; }; diff --git a/src/shared/event_handler.h b/src/shared/event_handler.h index 26ab899..dbe8c7d 100644 --- a/src/shared/event_handler.h +++ b/src/shared/event_handler.h @@ -20,15 +20,28 @@ #ifndef __EVENT_HANDLER_H__ #define __EVENT_HANDLER_H__ +#include namespace ipc { typedef unsigned int event_condition; class event_handler { public: + event_handler() + : m_event_id(0) + { + } + virtual ~event_handler() {} virtual bool handle(int fd, event_condition condition) = 0; + void set_event_id(int64_t event_id) + { + m_event_id = 0; + } + +protected: + int64_t m_event_id; }; } diff --git a/src/shared/event_loop.cpp b/src/shared/event_loop.cpp index d923d78..180b13e 100644 --- a/src/shared/event_loop.cpp +++ b/src/shared/event_loop.cpp @@ -129,10 +129,14 @@ uint64_t event_loop::add_event(const int fd, const event_condition cond, event_h } uint64_t id = m_sequence++; + if (m_sequence == 0) { + m_sequence = 1; + } handler_info *info = new(std::nothrow) handler_info(id, fd, ch, src, handler, this); retvm_if(!info, BAD_HANDLE, "Failed to allocate memory"); + handler->set_event_id(id); g_source_set_callback(src, (GSourceFunc) g_io_handler, info, NULL); g_source_attach(src, g_main_loop_get_context(m_mainloop)); -- 2.7.4 From 9b541a444fe6120588b66e99a57d7f367e9d6008 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Thu, 12 Dec 2019 14:31:33 +0900 Subject: [PATCH 05/16] Change signature of sensor_events_cb_t Change-Id: I66c9cb763dca3d1dea4de38802bb0325fec0a0fc Signed-off-by: Boram Bae --- include/sensor_internal.h | 2 +- src/client/sensor_internal.cpp | 7 +------ src/sensorctl/testcase/sensor_provider.cpp | 8 ++++---- src/sensorctl/tester_manual.cpp | 8 ++++---- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/include/sensor_internal.h b/include/sensor_internal.h index 1fbfabe..9c9a16d 100644 --- a/include/sensor_internal.h +++ b/include/sensor_internal.h @@ -38,7 +38,7 @@ extern "C" #endif typedef void (*sensor_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data); -typedef void (*sensor_events_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t* events[], int events_count, void *user_data); +typedef void (*sensor_events_cb_t)(sensor_t sensor, unsigned int event_type, sensor_data_t events[], int events_count, void *user_data); typedef void (*sensorhub_cb_t)(sensor_t sensor, unsigned int event_type, sensorhub_data_t *data, void *user_data); typedef void (*sensor_accuracy_changed_cb_t) (sensor_t sensor, unsigned long long timestamp, int accuracy, void *user_data); typedef void (*sensor_attribute_int_changed_cb_t)(sensor_t sensor, int attribute, int value, void *user_data); diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 0695e63..8cf5de1 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -69,12 +69,7 @@ static gboolean sensor_events_callback_dispatcher(gpointer data) if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) { size_t element_size = sizeof(sensor_data_t); size_t count = info->data_size / element_size; - sensor_data_t *events[count]; - char* p = (char*)info->data; - for (size_t i = 0 ; i < count; ++i) { - events[i] = (sensor_data_t *)(p + i * element_size); - } - ((sensor_events_cb_t)info->cb)(info->sensor, event_type, events, count, info->user_data); + ((sensor_events_cb_t)info->cb)(info->sensor, event_type, (sensor_data_t*)info->data, count, info->user_data); } delete [] info->data; diff --git a/src/sensorctl/testcase/sensor_provider.cpp b/src/sensorctl/testcase/sensor_provider.cpp index d7ed1bb..e302529 100644 --- a/src/sensorctl/testcase/sensor_provider.cpp +++ b/src/sensorctl/testcase/sensor_provider.cpp @@ -44,12 +44,12 @@ static void event_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *da _I("[%llu] %f %f %f\n", data->timestamp, data->values[0], data->values[1], data->values[2]); } -static void events_cb(sensor_t sensor, unsigned int event_type, sensor_data_t* datas[], int events_count, void *user_data) +static void events_cb(sensor_t sensor, unsigned int event_type, sensor_data_t datas[], int events_count, void *user_data) { for (int i = 0 ; i < events_count; i++) { - _I("[%llu]", datas[i]->timestamp); - for (int j = 0; j < datas[i]->value_count; j++) - _I(" %f", datas[i]->values[j]); + _I("[%llu]", datas[i].timestamp); + for (int j = 0; j < datas[i].value_count; j++) + _I(" %f", datas[i].values[j]); _I("\n"); } } diff --git a/src/sensorctl/tester_manual.cpp b/src/sensorctl/tester_manual.cpp index 1e48398..c1002e1 100644 --- a/src/sensorctl/tester_manual.cpp +++ b/src/sensorctl/tester_manual.cpp @@ -122,12 +122,12 @@ static void test_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *dat _N("\n"); } -static void test_events_cb(sensor_t sensor, unsigned int event_type, sensor_data_t* datas[], int events_count, void *user_data) +static void test_events_cb(sensor_t sensor, unsigned int event_type, sensor_data_t datas[], int events_count, void *user_data) { for (int i = 0 ; i < events_count; i++) { - _N("%llu ", datas[i]->timestamp); - for (int j = 0; j < datas[i]->value_count; j++) - _N(" %10f", datas[i]->values[j]); + _N("%llu ", datas[i].timestamp); + for (int j = 0; j < datas[i].value_count; j++) + _N(" %10f", datas[i].values[j]); _N("\n"); } } -- 2.7.4 From 9c33dc764285596524f92f915ac353a133362569 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Wed, 18 Dec 2019 14:49:33 +0900 Subject: [PATCH 06/16] Use vector to cache sensor_data_t in sensor_handler * This patch fixes the memory leak in the Sensord. Change-Id: I6a4f6751465a37e9a0bf71a6cd8cff8abc942e80 Signed-off-by: Boram Bae --- src/sensorctl/testcase/sensor_provider.cpp | 44 ++++++++++++++++++++++++++++++ src/server/sensor_handler.cpp | 33 +++++++++++----------- src/server/sensor_handler.h | 3 +- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/sensorctl/testcase/sensor_provider.cpp b/src/sensorctl/testcase/sensor_provider.cpp index e302529..397ab0e 100644 --- a/src/sensorctl/testcase/sensor_provider.cpp +++ b/src/sensorctl/testcase/sensor_provider.cpp @@ -515,4 +515,48 @@ TESTCASE(skip_sensor_provider, mysensor_get_data_list) ASSERT_TRUE(ret); return true; +} + +TESTCASE(skip_sensor_provider, mysensor_get_data) +{ + int err; + bool ret; + int handle; + sensor_t sensor; + sensor_type_t type; + + called = false; + + err = sensord_get_default_sensor_by_uri(MYSENSOR_BATCH_URI, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + + sensord_get_type(sensor, &type); + ASSERT_EQ(err, 0); + + ret = sensord_start(handle, 0); + ASSERT_TRUE(ret); + + sensor_data_t data ; + unsigned int data_id = type << SENSOR_SHIFT_TYPE | 0x1; + + ret = sensord_get_data(handle, data_id, &data); + ASSERT_TRUE(ret); + + _I("[%llu]", data.timestamp); + for (int j = 0; j < data.value_count; j++) + _I(" %f", data.values[j]); + _I("\n"); + + ret = sensord_stop(handle); + ASSERT_TRUE(ret); + + ret = sensord_unregister_events(handle, 1); + ASSERT_TRUE(ret); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + return true; } \ No newline at end of file diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp index 9ae43a3..33c3e53 100644 --- a/src/server/sensor_handler.cpp +++ b/src/server/sensor_handler.cpp @@ -30,8 +30,6 @@ using namespace sensor; sensor_handler::sensor_handler(const sensor_info &info) : m_info(info) -, m_last_data(NULL) -, m_last_data_size(0) { const char *priv = sensor::utils::get_privilege(m_info.get_uri()); m_info.set_privilege(priv); @@ -100,28 +98,29 @@ uint32_t sensor_handler::observer_count(void) void sensor_handler::set_cache(sensor_data_t *data, int size) { - if (m_last_data_size != size) { - m_last_data_size = size; - if (m_last_data) { - free(m_last_data); - } - m_last_data = (sensor_data_t*)malloc(m_last_data_size); - retm_if(m_last_data == NULL, "Memory allocation failed"); - } + char* p = (char*) data; - m_last_data_size = size; - memcpy(m_last_data, data, size); + try { + m_sensor_data_cache.reserve(size); + } catch (...) { + _E("Memory allocation failed"); + return; + } + m_sensor_data_cache.clear(); + m_sensor_data_cache.insert(m_sensor_data_cache.begin(), p, p + size); } int sensor_handler::get_cache(sensor_data_t **data, int *len) { - retv_if(m_last_data == NULL, -ENODATA); + auto size = m_sensor_data_cache.size(); + retv_if(size == 0, -ENODATA); - *data = (sensor_data_t *)malloc(m_last_data_size); - retvm_if(*data == NULL, -ENOMEM, "Memory allocation failed"); + char* temp = (char *)malloc(size); + retvm_if(temp == NULL, -ENOMEM, "Memory allocation failed"); + std::copy(m_sensor_data_cache.begin(), m_sensor_data_cache.end(), temp); - memcpy(*data, m_last_data, m_last_data_size); - *len = m_last_data_size; + *len = size; + *data = (sensor_data_t *)temp; return 0; } diff --git a/src/server/sensor_handler.h b/src/server/sensor_handler.h index e42a8e3..e7b3168 100644 --- a/src/server/sensor_handler.h +++ b/src/server/sensor_handler.h @@ -72,8 +72,7 @@ protected: private: std::list m_observers; - sensor_data_t *m_last_data; - int m_last_data_size; + std::vector m_sensor_data_cache; }; } -- 2.7.4 From a204e6a4f10e38aafaf55d7cbeae3fa1c2be1dd9 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Tue, 21 Jan 2020 14:19:06 +0900 Subject: [PATCH 07/16] Update for attribute changed callback and attribute getter * Do not update client attribute cache when calling attribute changed callback * Fix a bug related sensord_attribute_{int/str}_get * Fix build warrning related to type conversion * Notify all client(including self) that following attributes are changed SENSORD_ATTRIBUTE_INTERVAL SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY SENSORD_ATTRIBUTE_PAUSE_POLICY SENSORD_ATTRIBUTE_AXIS_ORIENTATION ALL_CUSTOM_ATTRIBUE_INT ALL_ATTRIBUTE_STR * Refactor some codes * Add more internal tests Change-Id: I0e7fb63cd9a44ce2306299afcb791fbac488afda Signed-off-by: Boram Bae --- src/client/sensor_internal.cpp | 6 +- src/client/sensor_listener.cpp | 108 +++++++++++++-------------- src/sensorctl/testcase/sensor_listener.cpp | 114 ++++++++++++++++++++++++++++- src/server/application_sensor_handler.cpp | 17 ++++- src/server/application_sensor_handler.h | 4 +- src/server/external_sensor_handler.cpp | 25 ++++++- src/server/external_sensor_handler.h | 4 + src/server/fusion_sensor_handler.cpp | 22 +++++- src/server/fusion_sensor_handler.h | 4 + src/server/physical_sensor_handler.cpp | 24 ++++-- src/server/physical_sensor_handler.h | 6 +- src/server/sensor_handler.cpp | 75 ++++++++++++++++--- src/server/sensor_handler.h | 18 ++++- src/server/sensor_listener_proxy.cpp | 82 +++++++++++++++++---- src/server/sensor_listener_proxy.h | 28 ++++--- src/server/server_channel_handler.cpp | 85 ++++++++++++--------- 16 files changed, 465 insertions(+), 157 deletions(-) diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 8cf5de1..a34bd97 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -36,7 +36,7 @@ #include "sensor_reader.h" -#define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11) +#define CONVERT_OPTION_TO_PAUSE_POLICY(option) ((option) ^ 0b11) #define MAX_LISTENER 100 using namespace sensor; @@ -575,7 +575,7 @@ API bool sensord_start(int handle, int option) listener = it->second; - pause = CONVERT_OPTION_PAUSE_POLICY(option); + pause = CONVERT_OPTION_TO_PAUSE_POLICY(option); prev_pause = listener->get_pause_policy(); if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) { @@ -678,7 +678,7 @@ API bool sensord_set_option(int handle, int option) listener = it->second; - pause = CONVERT_OPTION_PAUSE_POLICY(option); + pause = CONVERT_OPTION_TO_PAUSE_POLICY(option); if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) { _E("Failed to set option[%d(%d)] to listener", option, pause); diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index 612c1ad..ead43f6 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -62,17 +62,11 @@ public: if (m_listener->get_attribute_int_changed_handler()) { m_listener->get_attribute_int_changed_handler()->read(ch, msg); } - - 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); } - - 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"); @@ -200,11 +194,11 @@ void sensor_listener::restore(void) auto interval = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL); if (interval != m_attributes_int.end()) - set_interval( m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]); + set_interval(m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]); 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]); + set_max_batch_latency(m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]); _D("Restored listener[%d]", get_id()); } @@ -412,7 +406,7 @@ int sensor_listener::get_interval(void) auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_INTERVAL); retv_if(it == m_attributes_int.end(), -1); - return m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]; + return m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL]; } int sensor_listener::get_max_batch_latency(void) @@ -420,7 +414,7 @@ int sensor_listener::get_max_batch_latency(void) auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY); retv_if(it == m_attributes_int.end(), -1); - return m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]; + return m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]; } int sensor_listener::get_pause_policy(void) @@ -428,7 +422,7 @@ int sensor_listener::get_pause_policy(void) auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PAUSE_POLICY); retv_if(it == m_attributes_int.end(), -1); - return m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY]; + return m_attributes_int[SENSORD_ATTRIBUTE_PAUSE_POLICY]; } int sensor_listener::get_passive_mode(void) @@ -436,7 +430,7 @@ int sensor_listener::get_passive_mode(void) auto it = m_attributes_int.find(SENSORD_ATTRIBUTE_PASSIVE_MODE); retv_if(it == m_attributes_int.end(), -1); - return m_attributes_int[SENSORD_ATTRIBUTE_PASSIVE_MODE]; + return m_attributes_int[SENSORD_ATTRIBUTE_PASSIVE_MODE]; } int sensor_listener::set_interval(unsigned int interval) @@ -455,7 +449,7 @@ int sensor_listener::set_interval(unsigned int interval) /* If it is not started, store the value only */ if (!m_started.load()) { - m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL] = _interval; + m_attributes_int[SENSORD_ATTRIBUTE_INTERVAL] = _interval; return OP_SUCCESS; } @@ -468,7 +462,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_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency; + m_attributes_int[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY] = max_batch_latency; return OP_SUCCESS; } @@ -516,37 +510,37 @@ int sensor_listener::set_attribute(int attribute, int value) 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; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_int_t buf; - buf.listener_id = m_id; - buf.attribute = attribute; + retvm_if(!m_cmd_channel, -EIO, "Failed to connect to server"); - msg.set_type(CMD_LISTENER_GET_ATTR_INT); - msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(msg); + 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->read_sync(reply); + m_cmd_channel->send_sync(msg); + m_cmd_channel->read_sync(reply); - if (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); - } + if (reply.header()->err < 0) { + return reply.header()->err; } - *value = m_attributes_int[attribute]; - return OP_SUCCESS; + if (reply.header()->length && reply.body()) { + *value = ((cmd_listener_attr_int_t *)reply.body())->value; + return OP_SUCCESS; + } + + return OP_ERROR; } void sensor_listener::update_attribute(int attribute, int value) { + AUTOLOCK(lock); m_attributes_int[attribute] = value; - _I("listener[%d]'s attribues(int) size : %d", get_id(), m_attributes_int.size()); + _I("Update_attribute(int) listener[%d] attribute[%d] value[%d] attributes size[%d]", get_id(), attribute, value, m_attributes_int.size()); } int sensor_listener::set_attribute(int attribute, const char *value, int len) @@ -590,42 +584,40 @@ int sensor_listener::set_attribute(int attribute, const char *value, int len) 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; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_str_t buf; - msg.set_type(CMD_LISTENER_GET_ATTR_STR); - msg.enclose((char *)&buf, sizeof(buf)); - m_cmd_channel->send_sync(msg); + buf.listener_id = m_id; + buf.attribute = attribute; - m_cmd_channel->read_sync(reply); - if (reply.header()->err < 0) { - return reply.header()->err; - } + msg.set_type(CMD_LISTENER_GET_ATTR_STR); + msg.enclose((char *)&buf, sizeof(buf)); + m_cmd_channel->send_sync(msg); - 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); - } + m_cmd_channel->read_sync(reply); + if (reply.header()->err < 0) { + return reply.header()->err; } - *len = m_attributes_str[attribute].size(); - *value = (char *) malloc(*len); - std::copy(m_attributes_str[attribute].begin(), m_attributes_str[attribute].end(), *value); + if (reply.header()->length && reply.body()) { + cmd_listener_attr_str_t * recv_buf = (cmd_listener_attr_str_t *)reply.body(); + char* p = (char *)recv_buf->value; + *len = recv_buf->len; + *value = (char *) malloc(*len); + std::copy(p, p + recv_buf->len, *value); + return OP_SUCCESS; + } - return OP_SUCCESS; + return OP_ERROR; } void sensor_listener::update_attribute(int attribute, const char *value, int len) { + AUTOLOCK(lock); 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()); + _I("Update_attribute(str) listener[%d] attribute[%d] value[%s] attributes size[%zu]", get_id(), attribute, value, m_attributes_int.size()); } int sensor_listener::get_sensor_data(sensor_data_t *data) diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index 70050b0..517d0cc 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -278,6 +278,36 @@ TESTCASE(sensor_listener, set_get_attribute_int_2) return true; } +TESTCASE(sensor_listener, set_get_attribute_int_3) +{ + 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); + + for (int i = 0 ; i < 10; i ++) { + 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; @@ -386,6 +416,37 @@ TESTCASE(sensor_listener, set_get_attribute_string_2) return true; } +TESTCASE(sensor_listener, set_get_attribute_string_3) +{ + 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); + + for (int i = 0; i < 10; i++) { + 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, set_get_get_attribute_string_1) { int err; @@ -627,7 +688,7 @@ TESTCASE(skip_sensor_listener, register_attribute_str_changed) ret = sensord_stop(handle); ASSERT_TRUE(ret); - ret = sensord_unregister_attribute_int_changed_cb(handle); + ret = sensord_unregister_attribute_str_changed_cb(handle); ASSERT_TRUE(ret); ret = sensord_disconnect(handle); @@ -687,4 +748,53 @@ TESTCASE(skip_sensor_listener, attribute_str_changer) ASSERT_TRUE(ret); return true; -} \ No newline at end of file +} + +TESTCASE(skip_sensor_listener, light_sensor_set_attribute_int_1) +{ + int err = 0; + bool ret = true; + int handle = 0; + sensor_t sensor = NULL; + int attr = 2; + int value = 0; + + err = sensord_get_default_sensor(LIGHT_SENSOR, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + err = sensord_set_attribute_int(handle, attr, 2); + ASSERT_EQ(err, 0); + + err = sensord_get_attribute_int(handle, attr, &value); + ASSERT_EQ(err, 0); + ASSERT_EQ(value, 2); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + return true; +} + +TESTCASE(skip_sensor_listener, light_sensor_get_attribute_int_1) +{ + int err = 0; + bool ret = true; + int handle = 0; + sensor_t sensor = NULL; + int attr = 2; + int value = 0; + + err = sensord_get_default_sensor(LIGHT_SENSOR, &sensor); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensor); + err = sensord_get_attribute_int(handle, attr, &value); + ASSERT_EQ(err, 0); + ASSERT_EQ(value, 2); + + ret = sensord_disconnect(handle); + ASSERT_TRUE(ret); + + return true; +} diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp index fe1aac3..2bf1a07 100644 --- a/src/server/application_sensor_handler.cpp +++ b/src/server/application_sensor_handler.cpp @@ -30,7 +30,6 @@ application_sensor_handler::application_sensor_handler(const sensor_info &info, : sensor_handler(info) , m_ch(ch) , m_started(false) -, m_prev_interval(0) { } @@ -121,15 +120,25 @@ int application_sensor_handler::set_interval(sensor_observer *ob, int32_t interv msg.enclose((const char *)&buf, sizeof(cmd_provider_attr_int_t)); m_ch->send_sync(msg); - m_prev_interval = cur_interval; - - _I("Set interval[%d] to sensor[%s]", cur_interval, m_info.get_uri().c_str()); + update_prev_interval(cur_interval); + return OP_SUCCESS; +} +int application_sensor_handler::get_interval(sensor_observer *ob, int32_t& interval) +{ + interval = m_prev_interval; return OP_SUCCESS; } int application_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latency) { + update_prev_latency(latency); + return OP_SUCCESS; +} + +int application_sensor_handler::get_batch_latency(sensor_observer *ob, int32_t &latency) +{ + latency = m_prev_latency; return OP_SUCCESS; } diff --git a/src/server/application_sensor_handler.h b/src/server/application_sensor_handler.h index 8560451..5159bd5 100644 --- a/src/server/application_sensor_handler.h +++ b/src/server/application_sensor_handler.h @@ -45,7 +45,9 @@ public: int stop(sensor_observer *ob); int set_interval(sensor_observer *ob, int32_t interval); + int get_interval(sensor_observer *ob, int32_t& interval); int set_batch_latency(sensor_observer *ob, int32_t latency); + int get_batch_latency(sensor_observer *ob, int32_t &latency); int set_attribute(sensor_observer *ob, int32_t attr, int32_t value); int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len); int flush(sensor_observer *ob); @@ -54,12 +56,12 @@ public: private: ipc::channel *m_ch; std::atomic m_started; - int32_t m_prev_interval; int get_min_interval(void); std::vector m_required_sensors; std::unordered_map m_interval_map; + }; } diff --git a/src/server/external_sensor_handler.cpp b/src/server/external_sensor_handler.cpp index e0f74bf..8fd29ec 100644 --- a/src/server/external_sensor_handler.cpp +++ b/src/server/external_sensor_handler.cpp @@ -150,15 +150,22 @@ int external_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) retv_if(m_policy <= OP_ERROR, m_policy); } - m_interval_map[ob] = interval; + m_interval_map[ob] = _interval; + int ret = OP_SUCCESS; if (m_policy == OP_DEFAULT && observer_count() > 0) { _interval = get_min_interval(); - return m_sensor->set_interval(ob, _interval); + ret = m_sensor->set_interval(ob, _interval); } - _I("Set interval[%d] to sensor[%s]", _interval, m_info.get_uri().c_str()); + update_prev_interval(_interval); + return ret; +} +int external_sensor_handler::get_interval(sensor_observer *ob, int32_t& interval) +{ + retv_if(!m_sensor, -EINVAL); + interval = m_prev_interval; return OP_SUCCESS; } @@ -192,10 +199,20 @@ int external_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t late m_batch_latency_map[ob] = _latency; + int ret = OP_SUCCESS; if (m_policy == OP_DEFAULT && observer_count() > 0) { _latency = get_min_batch_latency(); - return m_sensor->set_batch_latency(ob, latency); + ret = m_sensor->set_batch_latency(ob, latency); } + + update_prev_latency(_latency); + return ret; +} + +int external_sensor_handler::get_batch_latency(sensor_observer *ob, int32_t &latency) +{ + retv_if(!m_sensor, -EINVAL); + latency = m_prev_latency; return OP_SUCCESS; } diff --git a/src/server/external_sensor_handler.h b/src/server/external_sensor_handler.h index 753a80d..c77a064 100644 --- a/src/server/external_sensor_handler.h +++ b/src/server/external_sensor_handler.h @@ -42,7 +42,11 @@ public: int stop(sensor_observer *ob); int set_interval(sensor_observer *ob, int32_t interval); + int get_interval(sensor_observer *ob, int32_t& interval); + int set_batch_latency(sensor_observer *ob, int32_t latency); + int get_batch_latency(sensor_observer *ob, int32_t &latency); + int set_attribute(sensor_observer *ob, int32_t attr, int32_t value); int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len); int flush(sensor_observer *ob); diff --git a/src/server/fusion_sensor_handler.cpp b/src/server/fusion_sensor_handler.cpp index 1ede44c..4a85de3 100644 --- a/src/server/fusion_sensor_handler.cpp +++ b/src/server/fusion_sensor_handler.cpp @@ -139,16 +139,24 @@ int fusion_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) policy = m_sensor->set_interval(ob, _interval); retv_if(policy <= OP_ERROR, policy); - m_interval_map[ob] = interval; + m_interval_map[ob] = _interval; if (policy == OP_DEFAULT) _interval = get_min_interval(); - _I("Set interval[%d] to sensor[%s]", _interval, m_info.get_uri().c_str()); + update_prev_interval(_interval); return set_interval_internal(_interval); } +int fusion_sensor_handler::get_interval(sensor_observer *ob, int32_t& interval) +{ + retv_if(!m_sensor, -EINVAL); + + interval = m_prev_interval; + return OP_SUCCESS; +} + int fusion_sensor_handler::get_min_batch_latency(void) { int batch_latency; @@ -183,9 +191,19 @@ int fusion_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latenc if (policy == OP_DEFAULT) _latency = get_min_batch_latency(); + update_prev_latency(_latency); + return set_batch_latency_internal(_latency); } +int fusion_sensor_handler::get_batch_latency(sensor_observer *ob, int32_t &latency) +{ + retv_if(!m_sensor, -EINVAL); + + latency = m_prev_latency; + return OP_SUCCESS; +} + int fusion_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value) { retv_if(!m_sensor, -EINVAL); diff --git a/src/server/fusion_sensor_handler.h b/src/server/fusion_sensor_handler.h index e5d6db3..cdccf1d 100644 --- a/src/server/fusion_sensor_handler.h +++ b/src/server/fusion_sensor_handler.h @@ -59,7 +59,11 @@ public: int stop(sensor_observer *ob); int set_interval(sensor_observer *ob, int32_t interval); + int get_interval(sensor_observer *ob, int32_t& interval); + int set_batch_latency(sensor_observer *ob, int32_t latency); + int get_batch_latency(sensor_observer *ob, int32_t &latency); + int set_attribute(sensor_observer *ob, int32_t attr, int32_t value); int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len); int flush(sensor_observer *ob); diff --git a/src/server/physical_sensor_handler.cpp b/src/server/physical_sensor_handler.cpp index da82314..d32efe8 100644 --- a/src/server/physical_sensor_handler.cpp +++ b/src/server/physical_sensor_handler.cpp @@ -33,8 +33,6 @@ physical_sensor_handler::physical_sensor_handler(const sensor_info &info, , m_device(device) , m_sensor(sensor) , m_hal_id(hal_id) -, m_prev_interval(0) -, m_prev_latency(0) { } @@ -179,13 +177,18 @@ int physical_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) ret = m_device->set_interval(m_hal_id, cur_interval); - m_prev_interval = cur_interval; - - _I("Set interval[%d] to sensor[%s]", cur_interval, m_info.get_uri().c_str()); + update_prev_interval(cur_interval); return (ret ? OP_SUCCESS : OP_ERROR); } +int physical_sensor_handler::get_interval(sensor_observer *ob, int32_t& interval) +{ + retv_if(!m_device, -EINVAL); + interval = m_prev_interval; + return OP_SUCCESS; +} + int physical_sensor_handler::get_min_batch_latency(void) { int batch_latency; @@ -224,13 +227,18 @@ int physical_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t late ret = m_device->set_batch_latency(m_hal_id, cur_latency); - m_prev_latency = cur_latency; - - _I("Set batch latency[%d] to sensor[%s]", cur_latency, m_info.get_uri().c_str()); + update_prev_latency(cur_latency); return (ret ? OP_SUCCESS : OP_ERROR); } +int physical_sensor_handler::get_batch_latency(sensor_observer *ob, int32_t &latency) +{ + retv_if(!m_device, -EINVAL); + latency = m_prev_latency; + return OP_SUCCESS; +} + int physical_sensor_handler::delete_batch_latency(sensor_observer *ob) { bool ret = false; diff --git a/src/server/physical_sensor_handler.h b/src/server/physical_sensor_handler.h index 608f854..0fca0fe 100644 --- a/src/server/physical_sensor_handler.h +++ b/src/server/physical_sensor_handler.h @@ -49,7 +49,11 @@ public: int stop(sensor_observer *ob); int set_interval(sensor_observer *ob, int32_t interval); + int get_interval(sensor_observer *ob, int32_t& interval); + int set_batch_latency(sensor_observer *ob, int32_t latency); + int get_batch_latency(sensor_observer *ob, int32_t &latency); + int delete_batch_latency(sensor_observer *ob); int set_attribute(sensor_observer *ob, int32_t attr, int32_t value); int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len); @@ -63,8 +67,6 @@ private: sensor_device *m_device; physical_sensor *m_sensor; uint32_t m_hal_id; - int32_t m_prev_interval; - int32_t m_prev_latency; std::unordered_map m_interval_map; std::unordered_map m_batch_latency_map; diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp index 33c3e53..d6ddc5f 100644 --- a/src/server/sensor_handler.cpp +++ b/src/server/sensor_handler.cpp @@ -30,6 +30,9 @@ using namespace sensor; sensor_handler::sensor_handler(const sensor_info &info) : m_info(info) +, m_prev_interval(0) +, m_prev_latency(0) +, m_need_to_notify_attribute_changed(false) { const char *priv = sensor::utils::get_privilege(m_info.get_uri()); m_info.set_privilege(priv); @@ -125,7 +128,7 @@ int sensor_handler::get_cache(sensor_data_t **data, int *len) return 0; } -bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int value) +bool sensor_handler::notify_attribute_changed(uint32_t id, int32_t attribute, int32_t value) { if (observer_count() == 0) return OP_ERROR; @@ -153,7 +156,7 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int va return OP_SUCCESS; } -bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const char *value, int len) +bool sensor_handler::notify_attribute_changed(uint32_t id, int32_t attribute, const char *value, int len) { if (observer_count() == 0) return OP_ERROR; @@ -179,7 +182,7 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const 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) { + if (proxy) { proxy->on_attribute_changed(msg); } } @@ -205,8 +208,18 @@ int sensor_handler::get_attribute(int32_t attr, int32_t* value) 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()); + auto it = m_attributes_int.find(attr); + if(it != m_attributes_int.end()) { + if (it->second != value) { + set_need_to_notify_attribute_changed(true); + } + } else { + set_need_to_notify_attribute_changed(true); + } + if (need_to_notify_attribute_changed()) { + m_attributes_int[attr] = value; + _I("[%s] attributes(int) attr[%d] value[%d] attributes size[%zu]", m_info.get_uri().c_str(), attr, value, m_attributes_int.size()); + } } int sensor_handler::get_attribute(int32_t attr, char **value, int *len) @@ -223,8 +236,52 @@ int sensor_handler::get_attribute(int32_t attr, char **value, int *len) 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()); + auto it = m_attributes_str.find(attr); + if(it != m_attributes_str.end()) { + if (it->second.size() != (size_t)len) { + set_need_to_notify_attribute_changed(true); + } else { + for(int i = 0 ; i < len; i++) { + if (value[i] != it->second[i]) { + set_need_to_notify_attribute_changed(true); + break; + } + } + } + } else { + set_need_to_notify_attribute_changed(true); + } + if (need_to_notify_attribute_changed()) { + m_attributes_str[attr].clear(); + m_attributes_str[attr].insert(m_attributes_str[attr].begin(), value, value + len); + _I("[%s] attributes(int) attr[%d] value[%s] attributes size[%zu]", m_info.get_uri().c_str(), attr, value, m_attributes_str.size()); + } +} -} \ No newline at end of file +bool sensor_handler::need_to_notify_attribute_changed() +{ + return m_need_to_notify_attribute_changed; +} + +void sensor_handler::set_need_to_notify_attribute_changed(bool value) +{ + m_need_to_notify_attribute_changed = value; +} + +void sensor_handler::update_prev_interval(int32_t interval) +{ + if (m_prev_interval != interval) { + m_prev_interval = interval; + set_need_to_notify_attribute_changed(true); + _I("Set interval[%d] to sensor[%s]", m_prev_interval, m_info.get_uri().c_str()); + } +} + +void sensor_handler::update_prev_latency(int32_t latency) +{ + if (m_prev_latency != latency) { + m_prev_latency = latency; + set_need_to_notify_attribute_changed(true); + _I("Set interval[%d] to sensor[%s]", m_prev_latency, m_info.get_uri().c_str()); + } +} diff --git a/src/server/sensor_handler.h b/src/server/sensor_handler.h index e7b3168..34a603c 100644 --- a/src/server/sensor_handler.h +++ b/src/server/sensor_handler.h @@ -48,7 +48,11 @@ public: virtual int stop(sensor_observer *ob) = 0; virtual int set_interval(sensor_observer *ob, int32_t interval) = 0; + virtual int get_interval(sensor_observer *ob, int32_t &interval) = 0; + virtual int set_batch_latency(sensor_observer *ob, int32_t latency) = 0; + virtual int get_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); @@ -61,14 +65,22 @@ public: void set_cache(sensor_data_t *data, int size); int get_cache(sensor_data_t **data, 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); - + bool notify_attribute_changed(uint32_t id, int32_t attribute, int32_t value); + bool notify_attribute_changed(uint32_t id, int32_t attribute, const char *value, int len); + bool need_to_notify_attribute_changed(); + void set_need_to_notify_attribute_changed(bool value); protected: + void update_prev_interval(int32_t interval); + void update_prev_latency(int32_t latency); + sensor_info m_info; + int32_t m_prev_interval; + int32_t m_prev_latency; + std::map m_attributes_int; std::map> m_attributes_str; + bool m_need_to_notify_attribute_changed; private: std::list m_observers; diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index 0862774..d47f362 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -41,6 +41,7 @@ sensor_listener_proxy::sensor_listener_proxy(uint32_t id, , m_pause_policy(SENSORD_PAUSE_ALL) , m_axis_orientation(SENSORD_AXIS_DISPLAY_ORIENTED) , m_last_accuracy(SENSOR_ACCURACY_UNDEFINED) +, m_need_to_notify_attribute_changed(false) { sensor_policy_monitor::get_instance().add_listener(this); } @@ -151,24 +152,49 @@ int sensor_listener_proxy::stop(bool policy) return OP_SUCCESS; } -int sensor_listener_proxy::set_interval(unsigned int interval) +int sensor_listener_proxy::set_interval(int32_t interval) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); _D("Listener[%d] try to set interval[%d]", get_id(), interval); - return sensor->set_interval(this, interval); + int ret = sensor->set_interval(this, interval); + apply_sensor_handler_need_to_notify_attribute_changed(sensor); + + return ret; +} + +int sensor_listener_proxy::get_interval(int32_t& interval) +{ + sensor_handler *sensor = m_manager->get_sensor(m_uri); + retv_if(!sensor, -EINVAL); + + _D("Listener[%d] try to get interval[%d]", get_id()); + + return sensor->get_interval(this, interval); } -int sensor_listener_proxy::set_max_batch_latency(unsigned int max_batch_latency) +int sensor_listener_proxy::set_max_batch_latency(int32_t max_batch_latency) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); _D("Listener[%d] try to set max batch latency[%d]", get_id(), max_batch_latency); + int ret = sensor->set_batch_latency(this, max_batch_latency); + apply_sensor_handler_need_to_notify_attribute_changed(sensor); - return sensor->set_batch_latency(this, max_batch_latency); + return ret; +} + +int sensor_listener_proxy::get_max_batch_latency(int32_t& max_batch_latency) +{ + sensor_handler *sensor = m_manager->get_sensor(m_uri); + retv_if(!sensor, -EINVAL); + + _D("Listener[%d] try to get max batch latency[%d]", get_id()); + + return sensor->get_batch_latency(this, max_batch_latency); } int sensor_listener_proxy::delete_batch_latency(void) @@ -188,7 +214,7 @@ int sensor_listener_proxy::set_passive_mode(bool passive) return OP_SUCCESS; } -int sensor_listener_proxy::set_attribute(int attribute, int value) +int sensor_listener_proxy::set_attribute(int32_t attribute, int32_t value) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); @@ -196,19 +222,28 @@ int sensor_listener_proxy::set_attribute(int attribute, int value) _D("Listener[%d] try to set attribute[%d, %d]", get_id(), attribute, value); if (attribute == SENSORD_ATTRIBUTE_PAUSE_POLICY) { - m_pause_policy = value; + if (m_pause_policy != value) { + m_pause_policy = value; + set_need_to_notify_attribute_changed(true); + } return OP_SUCCESS; } else if (attribute == SENSORD_ATTRIBUTE_AXIS_ORIENTATION) { - m_axis_orientation = value; + if (m_axis_orientation != value) { + m_axis_orientation = value; + set_need_to_notify_attribute_changed(true); + } return OP_SUCCESS; } else if (attribute == SENSORD_ATTRIBUTE_FLUSH) { return flush(); } - return sensor->set_attribute(this, attribute, value); + int ret = sensor->set_attribute(this, attribute, value); + apply_sensor_handler_need_to_notify_attribute_changed(sensor); + + return ret; } -int sensor_listener_proxy::get_attribute(int attribute, int *value) +int sensor_listener_proxy::get_attribute(int32_t attribute, int32_t *value) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); @@ -228,17 +263,20 @@ int sensor_listener_proxy::get_attribute(int attribute, int *value) return sensor->get_attribute(attribute, value); } -int sensor_listener_proxy::set_attribute(int attribute, const char *value, int len) +int sensor_listener_proxy::set_attribute(int32_t attribute, const char *value, int len) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); _D("Listener[%d] try to set string attribute[%d], len[%d]", get_id(), attribute, len); - return sensor->set_attribute(this, attribute, value, len); + int ret = sensor->set_attribute(this, attribute, value, len); + apply_sensor_handler_need_to_notify_attribute_changed(sensor); + + return ret; } -int sensor_listener_proxy::get_attribute(int attribute, char **value, int *len) +int sensor_listener_proxy::get_attribute(int32_t attribute, char **value, int *len) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); @@ -288,7 +326,7 @@ void sensor_listener_proxy::on_policy_changed(int policy, int value) start(true); } -bool sensor_listener_proxy::notify_attribute_changed(int attribute, int value) +bool sensor_listener_proxy::notify_attribute_changed(int32_t attribute, int32_t value) { sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); @@ -302,4 +340,20 @@ bool sensor_listener_proxy::notify_attribute_changed(int attribute, const char * retv_if(!sensor, -EINVAL); return sensor->notify_attribute_changed(m_id, attribute, value, len); -} \ No newline at end of file +} + +bool sensor_listener_proxy::need_to_notify_attribute_changed() +{ + return m_need_to_notify_attribute_changed; +} + +void sensor_listener_proxy::set_need_to_notify_attribute_changed(bool value) +{ + m_need_to_notify_attribute_changed = value; +} + +void sensor_listener_proxy::apply_sensor_handler_need_to_notify_attribute_changed(sensor_handler *handler) +{ + set_need_to_notify_attribute_changed(handler->need_to_notify_attribute_changed()); + handler->set_need_to_notify_attribute_changed(false); +} diff --git a/src/server/sensor_listener_proxy.h b/src/server/sensor_listener_proxy.h index 084ffe2..526e543 100644 --- a/src/server/sensor_listener_proxy.h +++ b/src/server/sensor_listener_proxy.h @@ -44,26 +44,31 @@ public: int start(bool policy = false); int stop(bool policy = false); - int set_interval(unsigned int interval); - int set_max_batch_latency(unsigned int max_batch_latency); + int set_interval(int32_t interval); + int get_interval(int32_t& interval); + int set_max_batch_latency(int32_t max_batch_latency); + int get_max_batch_latency(int32_t& max_batch_latency); 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 set_attribute(int32_t attribute, int32_t value); + int get_attribute(int32_t attribute, int32_t *value); + int set_attribute(int32_t attribute, const char *value, int len); + int get_attribute(int32_t attribute, char **value, int *len); int flush(void); int get_data(sensor_data_t **data, int *len); std::string get_required_privileges(void); /* sensor_policy_listener interface */ void on_policy_changed(int policy, int value); - bool notify_attribute_changed(int attribute, int value); - bool notify_attribute_changed(int attribute, const char *value, int len); + bool notify_attribute_changed(int32_t attribute, int32_t value); + bool notify_attribute_changed(int32_t attribute, const char *value, int len); + bool need_to_notify_attribute_changed(); + void set_need_to_notify_attribute_changed(bool value); private: void update_event(std::shared_ptr msg); void update_accuracy(std::shared_ptr msg); + void apply_sensor_handler_need_to_notify_attribute_changed(sensor_handler* handler); uint32_t m_id; std::string m_uri; @@ -73,9 +78,10 @@ private: bool m_started; bool m_passive; - int m_pause_policy; - int m_axis_orientation; - int m_last_accuracy; + int32_t m_pause_policy; + int32_t m_axis_orientation; + int32_t m_last_accuracy; + bool m_need_to_notify_attribute_changed; }; } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 0058c17..1be2686 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -235,9 +235,6 @@ int server_channel_handler::listener_set_attr_int(channel *ch, message &msg) case SENSORD_ATTRIBUTE_AXIS_ORIENTATION: default: ret = m_listeners[id]->set_attribute(buf.attribute, buf.value); - if (ret == OP_SUCCESS) { - need_notify = true; - } } /* TODO : check return value */ if (ret < 0) @@ -245,8 +242,9 @@ int server_channel_handler::listener_set_attr_int(channel *ch, message &msg) ret = send_reply(ch, OP_SUCCESS); - if (need_notify) { + if (m_listeners[id]->need_to_notify_attribute_changed()) { m_listeners[id]->notify_attribute_changed(buf.attribute, buf.value); + m_listeners[id]->set_need_to_notify_attribute_changed(false); } return ret; @@ -282,7 +280,11 @@ int server_channel_handler::listener_set_attr_str(channel *ch, message &msg) } ret = send_reply(ch, OP_SUCCESS); - m_listeners[id]->notify_attribute_changed(buf->attribute, buf->value, buf->len); + + if (m_listeners[id]->need_to_notify_attribute_changed()) { + m_listeners[id]->notify_attribute_changed(buf->attribute, buf->value, buf->len); + m_listeners[id]->set_need_to_notify_attribute_changed(false); + } delete [] buf; return ret; @@ -293,7 +295,8 @@ int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message cmd_listener_attr_int_t buf; msg.disclose((char *)&buf); uint32_t id = buf.listener_id; - + int attr = buf.attribute; + int value = 0; int ret = OP_SUCCESS; auto it = m_listeners.find(id); @@ -302,9 +305,11 @@ int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message -EACCES, "Permission denied[%d, %s]", id, m_listeners[id]->get_required_privileges().c_str()); - switch (buf.attribute) { + switch (attr) { case SENSORD_ATTRIBUTE_INTERVAL: + ret = m_listeners[id]->get_interval(value); break; case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY: + ret = m_listeners[id]->get_max_batch_latency(value); break; case SENSORD_ATTRIBUTE_PASSIVE_MODE: // TODO : Are these features required? ret = OP_ERROR; @@ -312,19 +317,26 @@ int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message case SENSORD_ATTRIBUTE_PAUSE_POLICY: case SENSORD_ATTRIBUTE_AXIS_ORIENTATION: default: - ret = m_listeners[id]->get_attribute(buf.attribute, &buf.value); + ret = m_listeners[id]->get_attribute(attr, &value); } - if (ret == OP_SUCCESS) { - message reply; - reply.enclose((char *)&buf, sizeof(buf)); - reply.set_type(CMD_LISTENER_GET_ATTR_INT); - ret = ch->send_sync(reply); - } else { - ret = send_reply(ch, OP_ERROR); + if (ret != OP_SUCCESS) { + _E("Failed to listener_get_attr_int"); + return ret; } + message reply; + cmd_listener_attr_int_t ret_buf; - return ret; + ret_buf.listener_id = id; + ret_buf.attribute = attr; + ret_buf.value = value; + + reply.enclose((char *)&ret_buf, sizeof(ret_buf)); + reply.header()->err = OP_SUCCESS; + reply.set_type(CMD_LISTENER_GET_ATTR_INT); + ret = ch->send_sync(reply); + + return OP_SUCCESS; } int server_channel_handler::listener_get_attr_str(ipc::channel *ch, ipc::message &msg) @@ -355,28 +367,29 @@ int server_channel_handler::listener_get_attr_str(ipc::channel *ch, ipc::message 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); + if (ret != OP_SUCCESS) { + _E("Failed to listener_get_attr_str"); + return ret; } - return ret; + 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; + + return OP_SUCCESS; } int server_channel_handler::listener_get_data(channel *ch, message &msg) -- 2.7.4 From e8b61a829530f84b64d3a2e562a381050ee85b37 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Tue, 28 Jan 2020 13:10:07 +0900 Subject: [PATCH 08/16] Fix coverity issue Change-Id: I5418fd4563bad87b89ccf5a013e9a6d6fa23cdf8 Signed-off-by: Boram Bae --- .../rotation_vector/fusion_utils/orientation_filter.cpp | 1 - .../rotation_vector/fusion_utils/sensor_data.h | 2 +- src/sensorctl/info.cpp | 3 ++- src/sensorctl/sensor_adapter.cpp | 15 +++++++++++++-- src/sensorctl/test_bench.h | 3 +++ src/sensorctl/testcase/sensor_listener.cpp | 8 ++++++++ src/server/server_channel_handler.cpp | 2 -- src/shared/message.h | 10 +++++----- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp b/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp index 43ea867..a725093 100644 --- a/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp +++ b/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp @@ -64,7 +64,6 @@ orientation_filter::orientation_filter() m_var_pitch = vec; m_var_azimuth = vec; - m_gyro.m_time_stamp = 0; } template diff --git a/src/fusion-sensor/rotation_vector/fusion_utils/sensor_data.h b/src/fusion-sensor/rotation_vector/fusion_utils/sensor_data.h index f266760..151d655 100644 --- a/src/fusion-sensor/rotation_vector/fusion_utils/sensor_data.h +++ b/src/fusion-sensor/rotation_vector/fusion_utils/sensor_data.h @@ -29,7 +29,7 @@ template class sensor_data { public: vect m_data; - unsigned long long m_time_stamp; + unsigned long long m_time_stamp { 0 }; sensor_data(); sensor_data(const TYPE x, const TYPE y, const TYPE z, diff --git a/src/sensorctl/info.cpp b/src/sensorctl/info.cpp index 149b98c..c5c25d4 100644 --- a/src/sensorctl/info.cpp +++ b/src/sensorctl/info.cpp @@ -20,6 +20,7 @@ #include "info.h" #include +#include #include #include @@ -44,7 +45,7 @@ bool info_manager::run(int argc, char *argv[]) sensord_get_sensor_list(type, &sensors, &count); show_info(sensors, count); - delete sensors; + free(sensors); return true; } diff --git a/src/sensorctl/sensor_adapter.cpp b/src/sensorctl/sensor_adapter.cpp index 979db25..2af7398 100644 --- a/src/sensorctl/sensor_adapter.cpp +++ b/src/sensorctl/sensor_adapter.cpp @@ -55,30 +55,39 @@ bool sensor_adapter::get_handle(sensor_info info, int &handle) { int err; int count; - sensor_t *sensors; + sensor_t *sensors = NULL; err = sensord_get_sensors(info.type, &sensors, &count); ASSERT_EQ(err, 0); handle = sensord_connect(sensors[info.index]); + ASSERT_FREE((handle < 0), sensors); ASSERT_GE(handle, 0); + free(sensors); + sensors = NULL; + return true; } bool sensor_adapter::start(sensor_info info, int &handle) { - sensor_t *sensors; + sensor_t *sensors = NULL; int count; int err; bool ret; err = sensord_get_sensors(info.type, &sensors, &count); ASSERT_EQ(err, 0); + + ASSERT_FREE((info.index >= count), sensors); ASSERT_LT(info.index, count); + + ASSERT_FREE((info.index < 0), sensors); ASSERT_GE(info.index, 0); handle = sensord_connect(sensors[info.index]); + ASSERT_FREE((handle < 0), sensors); ASSERT_GE(handle, 0); if (is_batch_mode) { @@ -89,9 +98,11 @@ bool sensor_adapter::start(sensor_info info, int &handle) ASSERT_TRUE(ret); ret = sensord_start(handle, info.powersave); + ASSERT_FREE((ret != true), sensors); ASSERT_TRUE(ret); free(sensors); + sensors = NULL; return true; } diff --git a/src/sensorctl/test_bench.h b/src/sensorctl/test_bench.h index 4e04b85..9f51622 100644 --- a/src/sensorctl/test_bench.h +++ b/src/sensorctl/test_bench.h @@ -67,6 +67,9 @@ do { \ } \ } while (0) +#define ASSERT_FREE(expr, X) \ + do { if (expr) { free (X); X = NULL; } } while (0) + #define ASSERT_TRUE(condition) ASSERT(condition, ==, true) #define ASSERT_FALSE(condition) ASSERT(condition, ==, false) #define ASSERT_EQ(left, right) ASSERT(left, ==, right) diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index 517d0cc..ac3b12f 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -59,6 +59,7 @@ TESTCASE(sensor_listener, get_sensors_p_1) err = sensord_get_sensors(ACCELEROMETER_SENSOR, &sensors, &count); ASSERT_EQ(err, 0); + ASSERT_FREE((count < 0), sensors); ASSERT_GT(count, 0); free(sensors); @@ -105,26 +106,33 @@ TESTCASE(sensor_listener, all_api_p_1) ASSERT_EQ(err, 0); ret = sensord_register_event(handle, 1, 100, 100, event_cb, NULL); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); ret = sensord_start(handle, 0); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); ret = sensord_change_event_interval(handle, 0, 100); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); ret = sensord_change_event_max_batch_latency(handle, 0, 100); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); mainloop::run(); ret = sensord_stop(handle); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); ret = sensord_unregister_event(handle, 1); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); ret = sensord_disconnect(handle); + ASSERT_FREE(((ret != true) && list), list); ASSERT_TRUE(ret); free(list); diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 1be2686..3bec9cc 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -222,8 +222,6 @@ int server_channel_handler::listener_set_attr_int(channel *ch, message &msg) -EACCES, "Permission denied[%d, %s]", id, m_listeners[id]->get_required_privileges().c_str()); - bool need_notify = false; - switch (buf.attribute) { case SENSORD_ATTRIBUTE_INTERVAL: ret = m_listeners[id]->set_interval(buf.value); break; diff --git a/src/shared/message.h b/src/shared/message.h index 0d932b6..d9ac2eb 100644 --- a/src/shared/message.h +++ b/src/shared/message.h @@ -30,11 +30,11 @@ namespace ipc { typedef struct message_header { - uint64_t id; - uint32_t type; - size_t length; - int32_t err; - void *ancillary[MAX_HEADER_RESERVED]; + uint64_t id { 0 }; + uint32_t type { 0 }; + size_t length { 0 }; + int32_t err { 0 }; + void *ancillary[MAX_HEADER_RESERVED] { nullptr }; } message_header; class message { -- 2.7.4 From bd1a22260ddd31e08a2af91201da05e01e90571d Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Mon, 3 Feb 2020 17:02:19 +0900 Subject: [PATCH 09/16] Initialize uninitialized pointers Change-Id: If831237a9e04965f20161ce2285d45978b2af19f Signed-off-by: Boram Bae --- src/sensorctl/info.cpp | 2 +- src/sensorctl/sensor_adapter.cpp | 2 +- src/sensorctl/testcase/sensor_basic.cpp | 2 +- src/sensorctl/testcase/sensor_interval.cpp | 6 +++--- src/sensorctl/testcase/sensor_listener.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sensorctl/info.cpp b/src/sensorctl/info.cpp index c5c25d4..db4eed5 100644 --- a/src/sensorctl/info.cpp +++ b/src/sensorctl/info.cpp @@ -31,7 +31,7 @@ bool info_manager::run(int argc, char *argv[]) { sensor_type_t type; - sensor_t *sensors; + sensor_t *sensors = nullptr; int count; if (argc < INFO_ARGC) { diff --git a/src/sensorctl/sensor_adapter.cpp b/src/sensorctl/sensor_adapter.cpp index 2af7398..68de53d 100644 --- a/src/sensorctl/sensor_adapter.cpp +++ b/src/sensorctl/sensor_adapter.cpp @@ -42,7 +42,7 @@ bool sensor_adapter::is_supported(sensor_type_t type) int sensor_adapter::get_count(sensor_type_t type) { - sensor_t *sensors; + sensor_t *sensors = nullptr; int count = 0; if (sensord_get_sensors(type, &sensors, &count) == 0) diff --git a/src/sensorctl/testcase/sensor_basic.cpp b/src/sensorctl/testcase/sensor_basic.cpp index ef6b139..d7db130 100644 --- a/src/sensorctl/testcase/sensor_basic.cpp +++ b/src/sensorctl/testcase/sensor_basic.cpp @@ -50,7 +50,7 @@ TESTCASE(sensor_basic, all_sensor_p) { int err, count, handle; bool ret; - sensor_t *sensors; + sensor_t *sensors = nullptr; sensor_type_t type; err = sensord_get_sensors(ALL_SENSOR, &sensors, &count); diff --git a/src/sensorctl/testcase/sensor_interval.cpp b/src/sensorctl/testcase/sensor_interval.cpp index 7a1e254..b285c89 100644 --- a/src/sensorctl/testcase/sensor_interval.cpp +++ b/src/sensorctl/testcase/sensor_interval.cpp @@ -35,7 +35,7 @@ TESTCASE(interval_test, 20ms_p) { int err, count, handle; bool ret; - sensor_t *sensors; + sensor_t *sensors = nullptr; sensor_type_t type; err = sensord_get_sensors(ACCELEROMETER_SENSOR, &sensors, &count); @@ -63,7 +63,7 @@ TESTCASE(interval_test, 100ms_p) { int err, count, handle; bool ret; - sensor_t *sensors; + sensor_t *sensors = nullptr; sensor_type_t type; err = sensord_get_sensors(ACCELEROMETER_SENSOR, &sensors, &count); @@ -91,7 +91,7 @@ TESTCASE(interval_test, 200ms_p) { int err, count, handle; bool ret; - sensor_t *sensors; + sensor_t *sensors = nullptr; sensor_type_t type; err = sensord_get_sensors(ACCELEROMETER_SENSOR, &sensors, &count); diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index ac3b12f..ecbdde3 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -55,7 +55,7 @@ TESTCASE(sensor_listener, get_sensors_p_1) { int err; int count; - sensor_t *sensors; + sensor_t *sensors = nullptr; err = sensord_get_sensors(ACCELEROMETER_SENSOR, &sensors, &count); ASSERT_EQ(err, 0); -- 2.7.4 From e9d01d8724bf5cb2030da377041e453553484cc2 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Wed, 5 Feb 2020 16:31:51 +0900 Subject: [PATCH 10/16] Do not update client's attribute cache when attribute is SENSORD_ATTRIBUTE_FLUSH Change-Id: If91bbdae0e777927b2a930d494fcc0126fbffccf Signed-off-by: Boram Bae --- src/client/sensor_listener.cpp | 4 +++- src/sensorctl/testcase/sensor_provider.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index ead43f6..d94ed7c 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -503,7 +503,9 @@ int sensor_listener::set_attribute(int attribute, int value) if (reply.header()->err < 0) return reply.header()->err; - update_attribute(attribute, value); + if (attribute != SENSORD_ATTRIBUTE_FLUSH) { + update_attribute(attribute, value); + } return OP_SUCCESS; } diff --git a/src/sensorctl/testcase/sensor_provider.cpp b/src/sensorctl/testcase/sensor_provider.cpp index 397ab0e..59e76de 100644 --- a/src/sensorctl/testcase/sensor_provider.cpp +++ b/src/sensorctl/testcase/sensor_provider.cpp @@ -92,8 +92,10 @@ static gboolean publish(gpointer gdata) static gboolean publish_batch_event(gpointer gdata) { - if (!started) return FALSE; - + if (!started) { + _N("[ WAITING ] ...\n"); + return TRUE; + } sensord_provider_h *provider = reinterpret_cast(gdata); sensor_data_t data[NUMBER_OF_EVENT]; -- 2.7.4 From bb4718caa1f1ff4aa42edccfdd932207f6e5c05c Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Thu, 6 Feb 2020 13:36:15 +0900 Subject: [PATCH 11/16] Use pass by reference instead of by value * This patch fixes Svace issue Change-Id: I5b276f2cac8c9703e218e2262a06eb827f3ee06b Signed-off-by: Boram Bae --- .gitignore | 1 + .../rotation_vector/fusion_utils/matrix.cpp | 26 +++++++++++----------- .../rotation_vector/fusion_utils/matrix.h | 26 +++++++++++----------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index ca9cbd7..fa43b1a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .cproject .*.swp nbproject +.vscode \ No newline at end of file diff --git a/src/fusion-sensor/rotation_vector/fusion_utils/matrix.cpp b/src/fusion-sensor/rotation_vector/fusion_utils/matrix.cpp index 2b1c177..ad584da 100644 --- a/src/fusion-sensor/rotation_vector/fusion_utils/matrix.cpp +++ b/src/fusion-sensor/rotation_vector/fusion_utils/matrix.cpp @@ -26,7 +26,7 @@ TYPE_ROW_COL matrix::matrix(void) m_mat[i][j] = 0; } -TYPE_ROW_COL matrix::matrix(const matrix& m) +TYPE_ROW_COL matrix::matrix(const matrix &m) { for (int p = 0; p < ROW; p++) for (int q = 0; q < COL; q++) @@ -44,7 +44,7 @@ TYPE_ROW_COL matrix::~matrix() { } -TYPE_ROW_COL matrix matrix::operator =(const matrix& m) +TYPE_ROW_COL matrix matrix::operator =(const matrix &m) { if (this == &m) { @@ -58,7 +58,7 @@ TYPE_ROW_COL matrix matrix::operator =(const mat return *this; } -T_R_C ostream& operator <<(ostream& dout, matrix& m) +T_R_C ostream& operator <<(ostream& dout, matrix &m) { for (int i = 0; i < R; i++) { @@ -71,7 +71,7 @@ T_R_C ostream& operator <<(ostream& dout, matrix& m) return dout; } -T_R_C matrix operator +(const matrix m1, const matrix m2) +T_R_C matrix operator +(const matrix &m1, const matrix &m2) { matrix m3; @@ -82,7 +82,7 @@ T_R_C matrix operator +(const matrix m1, const matrix return m3; } -T_R_C matrix operator +(const matrix m, const T val) +T_R_C matrix operator +(const matrix &m, const T &val) { matrix m1; @@ -93,7 +93,7 @@ T_R_C matrix operator +(const matrix m, const T val) return m1; } -T_R_C matrix operator -(const matrix m1, const matrix m2) +T_R_C matrix operator -(const matrix &m1, const matrix &m2) { matrix m3; @@ -104,7 +104,7 @@ T_R_C matrix operator -(const matrix m1, const matrix return m3; } -T_R_C matrix operator -(const matrix m, const T val) +T_R_C matrix operator -(const matrix &m, const T &val) { matrix m1; @@ -115,7 +115,7 @@ T_R_C matrix operator -(const matrix m, const T val) return m1; } -T_R_C_C2 matrix operator *(const matrix m1, const matrix m2) +T_R_C_C2 matrix operator *(const matrix &m1, const matrix &m2) { matrix m3; @@ -132,7 +132,7 @@ T_R_C_C2 matrix operator *(const matrix m1, const matrix operator *(const matrix m, const T val) +T_R_C matrix operator *(const matrix &m, const T &val) { matrix m1; @@ -143,7 +143,7 @@ T_R_C matrix operator *(const matrix m, const T val) return m1; } -T_R_C matrix operator /(const matrix m1, const T val) +T_R_C matrix operator /(const matrix &m1, const T &val) { matrix m3; @@ -154,7 +154,7 @@ T_R_C matrix operator /(const matrix m1, const T val) return m3; } -T_R1_C1_R2_C2 bool operator ==(const matrix m1, const matrix m2) +T_R1_C1_R2_C2 bool operator ==(const matrix &m1, const matrix &m2) { if ((R1 == R2) && (C1 == C2)) { for (int i = 0; i < R1; i++) @@ -167,12 +167,12 @@ T_R1_C1_R2_C2 bool operator ==(const matrix m1, const matrix m1, const matrix m2) +T_R1_C1_R2_C2 bool operator !=(const matrix &m1, const matrix &m2) { return (!(m1 == m2)); } -T_R_C matrix tran(const matrix m) +T_R_C matrix tran(const matrix &m) { matrix m1; diff --git a/src/fusion-sensor/rotation_vector/fusion_utils/matrix.h b/src/fusion-sensor/rotation_vector/fusion_utils/matrix.h index b2c47bb..bed7754 100644 --- a/src/fusion-sensor/rotation_vector/fusion_utils/matrix.h +++ b/src/fusion-sensor/rotation_vector/fusion_utils/matrix.h @@ -38,19 +38,19 @@ public: matrix(const matrix& m); ~matrix(); - matrix operator =(const matrix& m); - - T_R_C friend ostream& operator << (ostream& dout, matrix& m); - T_R_C friend matrix operator +(const matrix m1, const matrix m2); - T_R_C friend matrix operator +(const matrix m, const T val); - T_R_C friend matrix operator -(const matrix m1, const matrix m2); - T_R_C friend matrix operator -(const matrix m, const T val); - T_R_C_C2 friend matrix operator *(const matrix m1, const matrix m2); - T_R_C friend matrix operator *(const matrix m, const T val); - T_R_C friend matrix operator /(const matrix m1, const T val); - T_R1_C1_R2_C2 friend bool operator ==(const matrix m1, const matrix m2); - T_R1_C1_R2_C2 friend bool operator !=(const matrix m1, const matrix m2); - T_R_C friend matrix tran(const matrix m); + matrix operator =(const matrix &m); + + T_R_C friend ostream& operator << (ostream& dout, matrix &m); + T_R_C friend matrix operator +(const matrix &m1, const matrix &m2); + T_R_C friend matrix operator +(const matrix &m, const T &val); + T_R_C friend matrix operator -(const matrix &m1, const matrix &m2); + T_R_C friend matrix operator -(const matrix &m, const T &val); + T_R_C_C2 friend matrix operator *(const matrix &m1, const matrix &m2); + T_R_C friend matrix operator *(const matrix &m, const T &val); + T_R_C friend matrix operator /(const matrix &m1, const T &val); + T_R1_C1_R2_C2 friend bool operator ==(const matrix &m1, const matrix &m2); + T_R1_C1_R2_C2 friend bool operator !=(const matrix &m1, const matrix &m2); + T_R_C friend matrix tran(const matrix &m); }; #include "matrix.cpp" -- 2.7.4 From 0a807ba131638fb88a68b2ec3d08ad835b379c1d Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Mon, 10 Feb 2020 14:11:11 +0900 Subject: [PATCH 12/16] Fix coverity issue Change-Id: I0d25afbfb7391209bbd0c0691b462bc9e77509df Signed-off-by: Boram Bae --- src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp | 2 +- src/sensorctl/sensor_adapter.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp b/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp index a725093..2a27fd6 100644 --- a/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp +++ b/src/fusion-sensor/rotation_vector/fusion_utils/orientation_filter.cpp @@ -63,7 +63,7 @@ orientation_filter::orientation_filter() m_var_roll = vec; m_var_pitch = vec; m_var_azimuth = vec; - + m_gyro_dt = TYPE(); } template diff --git a/src/sensorctl/sensor_adapter.cpp b/src/sensorctl/sensor_adapter.cpp index 68de53d..9cf0a32 100644 --- a/src/sensorctl/sensor_adapter.cpp +++ b/src/sensorctl/sensor_adapter.cpp @@ -95,6 +95,7 @@ bool sensor_adapter::start(sensor_info info, int &handle) } else { ret = sensord_register_event(handle, SENSOR_EVENT(info.type), info.interval, info.batch_latency, info.cb, NULL); } + ASSERT_FREE((ret != true), sensors); ASSERT_TRUE(ret); ret = sensord_start(handle, info.powersave); -- 2.7.4 From 8c207edb60c1b5672d2b310bdb99eaf23ebd9560 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Mon, 17 Feb 2020 14:45:22 +0900 Subject: [PATCH 13/16] Fix coverity issues Change-Id: Ib449e448c9d12bf66fd2dee02d05654d208e8d72 Signed-off-by: Boram Bae --- src/client/sensor_internal.cpp | 4 ++-- src/client/sensor_listener.h | 2 +- src/client/sensor_provider.cpp | 7 ++++++- src/sensorctl/injector.h | 2 +- src/sensorctl/testcase/sensor_listener.cpp | 1 - src/server/application_sensor_handler.cpp | 6 +++++- src/server/sensor_handler.cpp | 6 +++++- src/server/sensor_listener_proxy.cpp | 4 ++-- src/server/sensor_manager.cpp | 6 +++++- src/shared/cbase_lock.cpp | 2 +- 10 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index a34bd97..14844b5 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -103,8 +103,8 @@ static gboolean sensor_accuracy_changed_callback_dispatcher(gpointer data) AUTOLOCK(lock); if (info->cb && info->sensor && listeners.find(info->listener_id) != listeners.end()) { - sensor_data_t * data = (sensor_data_t *)info->data; - ((sensor_accuracy_changed_cb_t)info->cb)(info->sensor, data->timestamp, data->accuracy, info->user_data); + sensor_data_t * sensor_data = (sensor_data_t *)info->data; + ((sensor_accuracy_changed_cb_t)info->cb)(info->sensor, sensor_data->timestamp, sensor_data->accuracy, info->user_data); } delete [] info->data; diff --git a/src/client/sensor_listener.h b/src/client/sensor_listener.h index 581b2a1..c83133c 100644 --- a/src/client/sensor_listener.h +++ b/src/client/sensor_listener.h @@ -100,7 +100,7 @@ private: ipc::channel_handler *m_attr_int_changed_handler; ipc::channel_handler *m_attr_str_changed_handler; - ipc::event_loop *m_loop; + ipc::event_loop *m_loop { nullptr }; std::atomic m_connected; std::atomic m_started; std::map m_attributes_int; diff --git a/src/client/sensor_provider.cpp b/src/client/sensor_provider.cpp index 414e83f..78a0593 100644 --- a/src/client/sensor_provider.cpp +++ b/src/client/sensor_provider.cpp @@ -101,7 +101,12 @@ int sensor_provider::serialize(sensor_info *info, char **bytes) info->serialize(*raw); *bytes = (char *) malloc(raw->size()); - retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory"); + + if (!(*bytes)) { + delete(raw); + _E("Failed to allocate memory"); + return -ENOMEM; + } std::copy(raw->begin(), raw->end(), *bytes); diff --git a/src/sensorctl/injector.h b/src/sensorctl/injector.h index b487c91..d6a18c5 100644 --- a/src/sensorctl/injector.h +++ b/src/sensorctl/injector.h @@ -39,7 +39,7 @@ public: virtual bool teardown(void) { return true; } const std::string& name() const { return m_name; } - const sensor_type_t type() const { return m_type; } + sensor_type_t type() const { return m_type; } virtual bool inject(int argc, char *argv[]) = 0; diff --git a/src/sensorctl/testcase/sensor_listener.cpp b/src/sensorctl/testcase/sensor_listener.cpp index ecbdde3..e646594 100644 --- a/src/sensorctl/testcase/sensor_listener.cpp +++ b/src/sensorctl/testcase/sensor_listener.cpp @@ -555,7 +555,6 @@ TESTCASE(sensor_listener, get_data_list) ret = sensord_get_data_list(handle, data_id, &data_list, &count); ASSERT_TRUE(ret); - ASSERT_EQ(count, 1); for (int i = 0 ; i < count; i++) { _I("[%llu]", data_list[i].timestamp); diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp index 2bf1a07..80e73d9 100644 --- a/src/server/application_sensor_handler.cpp +++ b/src/server/application_sensor_handler.cpp @@ -156,7 +156,8 @@ int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, size = sizeof(cmd_provider_attr_str_t) + len; - buf = (cmd_provider_attr_str_t *) malloc(sizeof(char) * size); + buf = (cmd_provider_attr_str_t *) new(std::nothrow) char[size]; + retvm_if(!buf, -ENOMEM, "Failed to allocate memory"); msg.set_type(CMD_PROVIDER_ATTR_STR); @@ -170,6 +171,9 @@ int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, _I("Set attribute[%d] to sensor[%s]", attr, m_info.get_uri().c_str()); update_attribute(attr, value, len); + + delete[] buf; + return OP_SUCCESS; } diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp index d6ddc5f..6c1de44 100644 --- a/src/server/sensor_handler.cpp +++ b/src/server/sensor_handler.cpp @@ -168,7 +168,11 @@ bool sensor_handler::notify_attribute_changed(uint32_t id, int32_t attribute, co retvm_if(!buf, -ENOMEM, "Failed to allocate memory"); auto msg = ipc::message::create(); - retvm_if(!msg, OP_ERROR, "Failed to allocate memory"); + if (!msg) { + delete[] buf; + _E("Failed to allocate memory"); + return OP_ERROR; + } buf->listener_id = id; buf->attribute = attribute; diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index d47f362..268158a 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -170,7 +170,7 @@ int sensor_listener_proxy::get_interval(int32_t& interval) sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); - _D("Listener[%d] try to get interval[%d]", get_id()); + _D("Listener[%d] try to get interval", get_id()); return sensor->get_interval(this, interval); } @@ -192,7 +192,7 @@ int sensor_listener_proxy::get_max_batch_latency(int32_t& max_batch_latency) sensor_handler *sensor = m_manager->get_sensor(m_uri); retv_if(!sensor, -EINVAL); - _D("Listener[%d] try to get max batch latency[%d]", get_id()); + _D("Listener[%d] try to get max batch latency", get_id()); return sensor->get_batch_latency(this, max_batch_latency); } diff --git a/src/server/sensor_manager.cpp b/src/server/sensor_manager.cpp index 6173800..64413ba 100644 --- a/src/server/sensor_manager.cpp +++ b/src/server/sensor_manager.cpp @@ -116,7 +116,11 @@ int sensor_manager::serialize(sensor_info *info, char **bytes) info->serialize(*raw); *bytes = (char *) malloc(raw->size()); - retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory"); + if (!(*bytes)) { + delete raw; + _E("Failed to allocate memory"); + return -ENOMEM; + } std::copy(raw->begin(), raw->end(), *bytes); diff --git a/src/shared/cbase_lock.cpp b/src/shared/cbase_lock.cpp index 38f2f84..5a3350b 100644 --- a/src/shared/cbase_lock.cpp +++ b/src/shared/cbase_lock.cpp @@ -80,7 +80,7 @@ void cbase_lock::lock(lock_type type, const char* expr, const char *module, cons waiting_time = lock_acquired_time - lock_waiting_start_time; pthread_mutex_lock(&m_history_mutex); - _I("%s acquires lock after waiting %lluus, %s(%#x) was previously owned in %s", + _I("%s acquires lock after waiting %lluus, %s(%#p) was previously owned in %s", m_curent_info, waiting_time, expr, this, m_owner_info); snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info); pthread_mutex_unlock(&m_history_mutex); -- 2.7.4 From 2bd1f9f399f631ff9f80821457e8eb5484a737e5 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Tue, 18 Feb 2020 19:56:28 +0900 Subject: [PATCH 14/16] Add a command type to indicate that the listener is connected. Change-Id: I97775d6f9685294c06ac6551434c13a4cf1b3883 Signed-off-by: Boram Bae --- src/client/sensor_listener.cpp | 3 +++ src/server/server_channel_handler.cpp | 1 + src/shared/command_types.h | 1 + 3 files changed, 5 insertions(+) diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index d94ed7c..0c12928 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -68,6 +68,9 @@ public: m_listener->get_attribute_str_changed_handler()->read(ch, msg); } } break; + case CMD_LISTENER_CONNECTED: { + // Do nothing + } break; default: _W("Invalid command message"); } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 3bec9cc..4f8abae 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -158,6 +158,7 @@ int server_channel_handler::listener_connect(channel *ch, message &msg) buf.listener_id = listener_id; message reply; + reply.set_type(CMD_LISTENER_CONNECTED); reply.enclose((const char *)&buf, sizeof(buf)); reply.header()->err = OP_SUCCESS; diff --git a/src/shared/command_types.h b/src/shared/command_types.h index 7acf878..29aaf86 100644 --- a/src/shared/command_types.h +++ b/src/shared/command_types.h @@ -49,6 +49,7 @@ enum cmd_type_e { CMD_LISTENER_GET_ATTR_INT, CMD_LISTENER_GET_ATTR_STR, CMD_LISTENER_GET_DATA_LIST, + CMD_LISTENER_CONNECTED, /* Provider */ CMD_PROVIDER_CONNECT = 0x300, -- 2.7.4 From 1eb04ba6d14c9a3bd8d8299dcef105a00a22da80 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Fri, 21 Feb 2020 12:38:08 +0900 Subject: [PATCH 15/16] Add a lock at channel Change-Id: Ied812242c1eda6b0adb1878b3fbc2a9bc85b2d1f Signed-off-by: Boram Bae --- src/shared/channel.cpp | 17 ++++++++++++++++- src/shared/channel.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp index 6ae8ed3..7077723 100644 --- a/src/shared/channel.cpp +++ b/src/shared/channel.cpp @@ -116,7 +116,9 @@ channel::channel(socket *sock) channel::~channel() { _D("Destroyed[%llu]", m_event_id); - disconnect(); + if (is_connected()) { + disconnect(); + } } uint64_t channel::bind(void) @@ -158,6 +160,7 @@ uint64_t channel::connect(channel_handler *handler, event_loop *loop, bool loop_ void channel::disconnect(void) { + AUTOLOCK(m_cmutex); if (!is_connected()) { _D("Channel is not connected"); return; @@ -224,6 +227,12 @@ bool channel::send(std::shared_ptr msg) bool channel::send_sync(message &msg) { + AUTOLOCK(m_cmutex); + if (!is_connected()) { + _D("Channel is not connected"); + return false; + } + retvm_if(msg.size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg.size()); ssize_t size = 0; @@ -264,6 +273,12 @@ bool channel::read(void) bool channel::read_sync(message &msg, bool select) { + AUTOLOCK(m_cmutex); + if (!is_connected()) { + _D("Channel is not connected"); + return false; + } + message_header header; ssize_t size = 0; char buf[MAX_MSG_CAPACITY]; diff --git a/src/shared/channel.h b/src/shared/channel.h index 4aeefbc..719dca2 100644 --- a/src/shared/channel.h +++ b/src/shared/channel.h @@ -28,6 +28,7 @@ #include "message.h" #include "event_loop.h" #include "channel_handler.h" +#include "cmutex.h" namespace ipc { @@ -68,6 +69,7 @@ private: std::vector m_pending_event_id; std::atomic m_connected; + cmutex m_cmutex; }; } -- 2.7.4 From 5ed0c66fd29edadde4bbb0bcc0c92e325e6a5990 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Wed, 26 Feb 2020 11:32:49 +0900 Subject: [PATCH 16/16] Implement add_idle_event at event_loop * This patch also fixe memory leak Change-Id: I070d08a10dd9c02ec6df15602d3a4e37a9618404 Signed-off-by: Boram Bae --- src/server/sensor_listener_proxy.cpp | 2 ++ src/server/server_channel_handler.cpp | 13 +++++++++++ src/shared/channel.cpp | 23 +++++++++---------- src/shared/channel.h | 5 ++++ src/shared/channel_event_handler.cpp | 4 +++- src/shared/event_loop.cpp | 43 +++++++++++++++++++++++++++++------ src/shared/event_loop.h | 2 +- src/shared/ipc_server.cpp | 2 +- 8 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index 268158a..8148577 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -43,11 +43,13 @@ sensor_listener_proxy::sensor_listener_proxy(uint32_t id, , m_last_accuracy(SENSOR_ACCURACY_UNDEFINED) , m_need_to_notify_attribute_changed(false) { + _D("Create [%p][%s]", this, m_uri.data()); sensor_policy_monitor::get_instance().add_listener(this); } sensor_listener_proxy::~sensor_listener_proxy() { + _D("Delete [%p][%s]", this, m_uri.data()); sensor_policy_monitor::get_instance().remove_listener(this); stop(); } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 4f8abae..af7db0c 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "permission_checker.h" #include "application_sensor_handler.h" @@ -40,10 +41,12 @@ std::unordered_map server_channel_ server_channel_handler::server_channel_handler(sensor_manager *manager) : m_manager(manager) { + _I("Create[%p]", this); } server_channel_handler::~server_channel_handler() { + _I("Destroy[%p]", this); } void server_channel_handler::connected(channel *ch) @@ -52,6 +55,7 @@ void server_channel_handler::connected(channel *ch) void server_channel_handler::disconnected(channel *ch) { + _I("Disconnect[%p] using channel[%p]", this, ch); m_manager->deregister_channel(ch); auto it_asensor = m_app_sensors.find(ch); @@ -72,6 +76,15 @@ void server_channel_handler::disconnected(channel *ch) m_listeners.erase(it_listener->second); m_listener_ids.erase(ch); } + + if (ch->loop()) { + ch->loop()->add_idle_event(0, [](size_t, void* data) { + channel* ch = (channel*)data; + delete ch; + }, ch); + } else { + _D("Should not be here : channel[%p]", ch); + } } void server_channel_handler::read(channel *ch, message &msg) diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp index 7077723..923bc91 100644 --- a/src/shared/channel.cpp +++ b/src/shared/channel.cpp @@ -110,12 +110,12 @@ channel::channel(socket *sock) , m_loop(NULL) , m_connected(false) { - _D("Created"); + _D("Create[%p]", this); } channel::~channel() { - _D("Destroyed[%llu]", m_event_id); + _D("Destroy[%p]", this); if (is_connected()) { disconnect(); } @@ -128,7 +128,7 @@ uint64_t channel::bind(void) (EVENT_IN | EVENT_HUP | EVENT_NVAL), dynamic_cast(m_handler)); - _D("Bound[%llu]", m_event_id); + _D("Bind channel[%p] : handler[%p] event_id[%llu]", this, m_handler, m_event_id); return m_event_id; } @@ -154,7 +154,7 @@ uint64_t channel::connect(channel_handler *handler, event_loop *loop, bool loop_ bind(handler, loop, loop_bind); - _D("Connected[%llu]", m_event_id); + _D("Connect channel[%p] : event id[%llu]", this, m_event_id); return m_event_id; } @@ -162,37 +162,36 @@ void channel::disconnect(void) { AUTOLOCK(m_cmutex); if (!is_connected()) { - _D("Channel is not connected"); + _D("Channel[%p] is not connected", this); return; } m_connected.store(false); - _D("Disconnecting..[%llu]", m_event_id); + _D("Disconnect channel[%p]", this); if (m_handler) { + _D("Disconnect channel[%p] handler[%p]", this, m_handler); m_handler->disconnected(this); m_handler = NULL; } if (m_loop) { for(auto id : m_pending_event_id) { - _D("Remove pending event id[%llu]", id); + _D("Remove channel[%p] pending event id[%llu]", this, id); m_loop->remove_event(id, true); } - _D("Remove event[%llu]", m_event_id); + _D("Remove channel[%p] event[%llu]",this, m_event_id); m_loop->remove_event(m_event_id, true); - m_loop = NULL; m_event_id = 0; } if (m_socket) { - _D("Release socket[%d]", m_socket->get_fd()); + _D("Release channel[%p] socket[%d]", this, m_socket->get_fd()); delete m_socket; m_socket = NULL; } - - _D("Disconnected"); + _D("Channel[%p] is disconnected"); } bool channel::send(std::shared_ptr msg) diff --git a/src/shared/channel.h b/src/shared/channel.h index 719dca2..bc8444f 100644 --- a/src/shared/channel.h +++ b/src/shared/channel.h @@ -60,6 +60,11 @@ public: int get_fd(void) const; void remove_pending_event_id(uint64_t id); + event_loop *loop() + { + return m_loop; + } + private: int m_fd; uint64_t m_event_id; diff --git a/src/shared/channel_event_handler.cpp b/src/shared/channel_event_handler.cpp index 9c48c0d..28f3398 100644 --- a/src/shared/channel_event_handler.cpp +++ b/src/shared/channel_event_handler.cpp @@ -29,10 +29,12 @@ channel_event_handler::channel_event_handler(channel *ch, channel_handler *handl : m_ch(ch) , m_handler(handler) { + _D("Create[%p]", this); } channel_event_handler::~channel_event_handler() { + _D("Destroy[%p]", this); m_ch = NULL; m_handler = NULL; } @@ -45,7 +47,7 @@ bool channel_event_handler::handle(int fd, event_condition condition) return false; if (condition & (EVENT_HUP)) { - _D("The other proccess is dead"); + _D("Disconnect[%p] : The other proccess is dead", this); m_ch->disconnect(); m_ch = NULL; return false; diff --git a/src/shared/event_loop.cpp b/src/shared/event_loop.cpp index 180b13e..f265d7b 100644 --- a/src/shared/event_loop.cpp +++ b/src/shared/event_loop.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "channel_event_handler.h" #include "sensor_log.h" #include "event_handler.h" @@ -58,16 +59,16 @@ static gboolean g_io_handler(GIOChannel *ch, GIOCondition condition, gpointer da term = loop->is_terminator(fd); if (cond & G_IO_NVAL) - return FALSE; + return G_SOURCE_REMOVE; ret = handler->handle(fd, (event_condition)cond); if (!ret && !term) { loop->remove_event(id); - return FALSE; + return G_SOURCE_REMOVE; } - return TRUE; + return G_SOURCE_CONTINUE; } static gint on_timer(gpointer data) @@ -146,7 +147,12 @@ uint64_t event_loop::add_event(const int fd, const event_condition cond, event_h return id; } -uint64_t event_loop::add_idle_event(unsigned int priority, idle_handler *handler) +struct idler_data { + void (*m_fn)(size_t, void*); + void* m_data; +}; + +size_t event_loop::add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data) { GSource *src; @@ -156,10 +162,21 @@ uint64_t event_loop::add_idle_event(unsigned int priority, idle_handler *handler src = g_idle_source_new(); retvm_if(!src, 0, "Failed to allocate memory"); + idler_data *id = new idler_data(); + id->m_fn = fn; + id->m_data = data; + + g_source_set_callback(src, [](gpointer data) -> gboolean { + idler_data *id = (idler_data *)data; + id->m_fn((size_t)id, id->m_data); + delete id; + return G_SOURCE_REMOVE; + }, id, NULL); + + g_source_attach(src, g_main_loop_get_context (m_mainloop)); g_source_unref(src); - /* Not Supported yet */ - return 0; + return (size_t)id; } bool event_loop::remove_event(uint64_t id, bool close_channel) @@ -195,9 +212,21 @@ void event_loop::release_info(handler_info *info) g_source_unref(info->g_src); g_io_channel_unref(info->g_ch); + info->g_ch = NULL; + channel_event_handler *ce_handler = nullptr; + ce_handler = dynamic_cast(info->handler); + if (ce_handler) { + _D("Add idle event for lazy release : handler[%p]", ce_handler); + add_idle_event(0, [](size_t, void *data) { + channel_event_handler *handler = (channel_event_handler *)data; + delete handler; + }, ce_handler); + } else { + _D("Release handler[%p]", info->handler); + delete info->handler; + } - delete info->handler; info->handler = NULL; delete info; diff --git a/src/shared/event_loop.h b/src/shared/event_loop.h index f785c65..d0d16d1 100644 --- a/src/shared/event_loop.h +++ b/src/shared/event_loop.h @@ -75,7 +75,7 @@ public: void set_mainloop(GMainLoop *mainloop); uint64_t add_event(const int fd, const event_condition cond, event_handler *handler); - uint64_t add_idle_event(unsigned int priority, idle_handler *handler); + size_t add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data); bool remove_event(uint64_t id, bool close_channel = false); void remove_all_events(void); diff --git a/src/shared/ipc_server.cpp b/src/shared/ipc_server.cpp index f847c4d..0019bf1 100644 --- a/src/shared/ipc_server.cpp +++ b/src/shared/ipc_server.cpp @@ -84,7 +84,7 @@ void ipc_server::register_channel(int fd, channel *ch) if (id == 0) delete ev_handler; - _D("Registered event[%llu]", id); + _D("Register channel[%p] : event_id[%llu]", ch, id); } void ipc_server::register_acceptor(void) -- 2.7.4