*/
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
*
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;
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;
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()) {
m_cmd_channel->read_sync(reply);
if (reply.header()->err < 0) {
- _D("reply.header()->err < 0");
return reply.header()->err;
}
_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;
+}
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);
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);
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
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:
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;
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);
CMD_LISTENER_GET_DATA,
CMD_LISTENER_GET_ATTR_INT,
CMD_LISTENER_GET_ATTR_STR,
+ CMD_LISTENER_GET_DATA_LIST,
/* Provider */
CMD_PROVIDER_CONNECT = 0x300,
sensor_data_t data;
} 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;