*/
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
*
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.
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;
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;
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;
{
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");
}
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..");
}
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());
}
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)
/* 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;
}
/* 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;
}
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);
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;
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;
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;
_D("Listener[%d] read sensor data", get_id());
return OP_SUCCESS;
-}
-
+}
\ No newline at end of file
#include <sensor_types.h>
#include <map>
#include <atomic>
+#include <vector>
namespace sensor {
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);
ipc::event_loop *m_loop;
std::atomic<bool> m_connected;
std::atomic<bool> m_started;
- std::map<int, int> m_attributes;
+ std::map<int, int> m_attributes_int;
+ std::map<int, std::vector<char>> m_attributes_str;
};
}
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);
int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value)
{
+ update_attribute(attr, value);
return OP_SUCCESS;
}
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;
}
if (m_policy == OP_DEFAULT) {
/* default logic */
}
+
+ update_attribute(attr, value);
+
return OP_SUCCESS;
}
if (m_policy == OP_DEFAULT) {
/* default logic */
}
+
+ update_attribute(attr, value, len);
+
return OP_SUCCESS;
}
/* default logic */
}
+ update_attribute(attr, value);
+
return set_attribute_internal(attr, value);
}
/* default logic */
}
+ update_attribute(attr, value, len);
+
return set_attribute_internal(attr, value, len);
}
/* 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);
ret = m_device->set_attribute_int(m_hal_id, attr, value);
+ if (ret) {
+ update_attribute(attr, value);
+ }
return (ret ? OP_SUCCESS : OP_ERROR);
}
ret = m_device->set_attribute_str(m_hal_id, attr, const_cast<char *>(value), len);
+ if (ret) {
+ update_attribute(attr, value, len);
+ }
+
return (ret ? OP_SUCCESS : OP_ERROR);
}
#include <sensor_utils.h>
#include <sensor_types_private.h>
#include <command_types.h>
+#include <sensor_listener_proxy.h>
using namespace sensor;
set_cache(data, len);
- if (msg->ref_count() == 0)
+ if (msg->ref_count() == 0) {
msg->unref();
+ }
return OP_SUCCESS;
}
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;
msg = new(std::nothrow) ipc::message();
retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
- msg->set_type(CMD_LISTENER_ATTR_INT);
+ msg->set_type(CMD_LISTENER_SET_ATTR_INT);
msg->enclose((char *)&buf, sizeof(buf));
- for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
- (*it)->on_attribute_changed(msg);
+ sensor_listener_proxy *proxy = NULL;
+ for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
+ proxy = dynamic_cast<sensor_listener_proxy *>(*it);
+ if (proxy && proxy->get_id() != id) {
+ proxy->on_attribute_changed(msg);
+ }
+ }
if (msg->ref_count() == 0)
msg->unref();
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;
msg = new(std::nothrow) ipc::message();
retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
+ buf->listener_id = id;
buf->attribute = attribute;
memcpy(buf->value, value, len);
buf->len = len;
- msg->set_type(CMD_LISTENER_ATTR_STR);
+ msg->set_type(CMD_LISTENER_SET_ATTR_STR);
msg->enclose((char *)buf, size);
- for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
- (*it)->on_attribute_changed(msg);
+ _I("notify attribute changed by listener[%zu]\n", id);
+ sensor_listener_proxy *proxy = NULL;
+ for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
+ proxy = dynamic_cast<sensor_listener_proxy *>(*it);
+ if (proxy && proxy->get_id() != id) {
+ proxy->on_attribute_changed(msg);
+ }
+ }
- if (msg->ref_count() == 0)
+ if (msg->ref_count() == 0) {
msg->unref();
+ }
delete[] buf;
{
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
#include <sensor_types.h>
#include <sensor_info.h>
#include <list>
+#include <map>
+#include <vector>
namespace sensor {
virtual int set_batch_latency(sensor_observer *ob, int32_t latency) = 0;
virtual int delete_batch_latency(sensor_observer *ob);
virtual int set_attribute(sensor_observer *ob, int32_t attr, int32_t value) = 0;
+ virtual int get_attribute(int32_t attr, int32_t* value);
+ void update_attribute(int32_t attr, int32_t value);
virtual int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) = 0;
+ virtual int get_attribute(int32_t attr, char **value, int *len);
+ void update_attribute(int32_t attr, const char *value, int len);
virtual int flush(sensor_observer *ob) = 0;
virtual int get_data(sensor_data_t **data, int *len) = 0;
void set_cache(sensor_data_t *data, int size);
int get_cache(sensor_data_t **data, int *len);
- bool notify_attribute_changed(int attribute, int value);
- bool notify_attribute_changed(int attribute, const char *value, int len);
+ bool notify_attribute_changed(uint32_t id, int attribute, int value);
+ bool notify_attribute_changed(uint32_t id, int attribute, const char *value, int len);
protected:
sensor_info m_info;
+ std::map<int32_t, int32_t> m_attributes_int;
+ std::map<int32_t, std::vector<char>> m_attributes_str;
private:
std::list<sensor_observer *> m_observers;
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;
}
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);
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);
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)
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
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);
/* for performance, use message */
virtual int update(const char *uri, ipc::message *msg) = 0;
- virtual int on_attribute_changed(ipc::message *msg) = 0;
};
}
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:
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);
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;
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;
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);
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,
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;