*
*/
-#include "sensor_internal.h"
-#include <stdlib.h>
+#include <sensor_internal.h>
+#include <sensor_internal_deprecated.h>
+#include <sensor_types.h>
+
+#include <channel_handler.h>
+#include <sensor_manager.h>
+#include <sensor_listener.h>
#include <sensor_log.h>
+#include <unordered_map>
+
+#define CONVERT_OPTION_PAUSE_POLICY(option) ((option) ^ 0b11)
+
+using namespace sensor;
+
+class sensor_event_handler : public ipc::channel_handler
+{
+public:
+ sensor_event_handler(sensor_t sensor, sensor_cb_t cb, void *user_data)
+ : m_sensor(reinterpret_cast<sensor_info *>(sensor))
+ , m_cb(cb)
+ , m_user_data(user_data)
+ {}
+
+ void connected(ipc::channel *ch) {}
+ void disconnected(ipc::channel *ch) {}
+ void read(ipc::channel *ch, ipc::message &msg)
+ {
+ int event_type;
+ sensor_data_t *data;
+
+ data = reinterpret_cast<sensor_data_t *>(msg.body());
+ event_type = CONVERT_TYPE_EVENT(m_sensor->get_type());
+
+ m_cb(m_sensor, event_type, data, m_user_data);
+ }
+
+ void read_complete(ipc::channel *ch) {}
+ void error_caught(ipc::channel *ch, int error) {}
+
+private:
+ sensor_info *m_sensor;
+ sensor_cb_t m_cb;
+ void *m_user_data;
+};
+
+class sensor_accuracy_handler : public ipc::channel_handler
+{
+public:
+ sensor_accuracy_handler(sensor_t sensor, sensor_accuracy_changed_cb_t cb, void *user_data)
+ : m_sensor(reinterpret_cast<sensor_info *>(sensor))
+ , m_cb(cb)
+ , m_user_data(user_data)
+ {}
+
+ void connected(ipc::channel *ch) {}
+ void disconnected(ipc::channel *ch) {}
+ void read(ipc::channel *ch, ipc::message &msg)
+ {
+ sensor_data_t *data;
+ data = reinterpret_cast<sensor_data_t *>(msg.body());
+
+ m_cb(m_sensor, data->timestamp, data->accuracy, m_user_data);
+ }
+
+ void read_complete(ipc::channel *ch) {}
+ void error_caught(ipc::channel *ch, int error) {}
+
+private:
+ sensor_info *m_sensor;
+ sensor_accuracy_changed_cb_t m_cb;
+ void *m_user_data;
+};
+
+static sensor::sensor_manager manager;
+static std::unordered_map<int, sensor::sensor_listener *> listeners;
/*
* TO-DO-LIST:
- * 1. restore session
- * 1.1 close socket
- * 1.2 listener : start, interval, batch latency, attributes
- * 2. power save option / lcd vconf : move to server
- * 3. clean up data
- * 4. thread-safe : ipc_client
- * 5. client-id
- * 6. cmd_hello
- * 7. stop : unset interval, batch
- * 8. get sensor list
+ * 1. power save option / lcd vconf : move to server
+ * 2. thread-safe : ipc_client
*/
API int sensord_get_sensors(sensor_type_t type, sensor_t **list, int *count)
{
- /*
- * 1. get sensor list()
- * 2. if sensor list is empty, return -ENODATA
- * 3. if id is -EACCESS, return -EACCESS (except ALL_SENSOR)
- * 4. list : memory allocation
- * 5. return list, count
- */
+ int ret = OP_ERROR;
+
+ retvm_if((!list || !count), -EINVAL,
+ "Invalid parameter[%#x, %#x]", list, count);
+ retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+ ret = manager.get_sensors(type, list, count);
+ retv_if(ret < 0, ret);
return OP_SUCCESS;
}
API int sensord_get_default_sensor(sensor_type_t type, sensor_t *sensor)
{
- /*
- * 1. get sensor list()
- * 2. if there is no sensor, return -ENODATA
- * 3. if id is -EACCESS, return -EACCESS
- * 4. if SENSOR_ALL, ???
- * 5. return sensor
- */
+ int ret = OP_ERROR;
+
+ retvm_if(!sensor, -EINVAL, "Invalid parameter[%#x]", sensor);
+ retvm_if(!manager.connect(), -EIO, "Failed to connect");
+
+ ret = manager.get_sensor(type, sensor);
+ retv_if(ret < 0, ret);
return OP_SUCCESS;
}
API bool sensord_get_type(sensor_t sensor, sensor_type_t *type)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!type, false, "Invalid parameter[%#x]", type);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *type = static_cast<sensor_info *>(sensor)->get_type();
return true;
}
API const char* sensord_get_name(sensor_t sensor)
{
- /*
- * 1. if there is no sensor, return NULL
- */
+ retvm_if(!manager.connect(), NULL, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), NULL,
+ "Invalid sensor[%#x]", sensor);
- return NULL;
+ return static_cast<sensor_info *>(sensor)->get_uri().c_str();
}
API const char* sensord_get_vendor(sensor_t sensor)
{
- /*
- * 1. if there is no sensor, return NULL
- */
-
- return NULL;
-}
-
-API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
-{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!manager.connect(), NULL, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), NULL,
+ "Invalid sensor[%#x]", sensor);
- return true;
+ return static_cast<sensor_info *>(sensor)->get_vendor().c_str();
}
API bool sensord_get_min_range(sensor_t sensor, float *min_range)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!min_range, false, "Invalid parameter[%#x]", min_range);
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *min_range = static_cast<sensor_info *>(sensor)->get_min_range();
return true;
}
API bool sensord_get_max_range(sensor_t sensor, float *max_range)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!max_range, false, "Invalid parameter[%#x]", max_range);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *max_range = static_cast<sensor_info *>(sensor)->get_max_range();
return true;
}
API bool sensord_get_resolution(sensor_t sensor, float *resolution)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!resolution, false, "Invalid parameter[%#x]", resolution);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *resolution = static_cast<sensor_info *>(sensor)->get_resolution();
return true;
}
API bool sensord_get_min_interval(sensor_t sensor, int *min_interval)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!min_interval, false, "Invalid parameter[%#x]", min_interval);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *min_interval = static_cast<sensor_info *>(sensor)->get_min_interval();
return true;
}
API bool sensord_get_fifo_count(sensor_t sensor, int *fifo_count)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!fifo_count, false, "Invalid parameter[%#x]", fifo_count);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *fifo_count = 0;
return true;
}
API bool sensord_get_max_batch_count(sensor_t sensor, int *max_batch_count)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!max_batch_count, false, "Invalid parameter[%#x]", max_batch_count);
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
+
+ *max_batch_count = static_cast<sensor_info *>(sensor)->get_max_batch_count();
return true;
}
API bool sensord_is_wakeup_supported(sensor_t sensor)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ retvm_if(!manager.connect(), false, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), false,
+ "Invalid sensor[%#x]", sensor);
- return true;
+ return static_cast<sensor_info *>(sensor)->is_wakeup_supported();
}
API int sensord_connect(sensor_t sensor)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return -EPERM
- * 3. sensor is already registered(sensor), it doesn't need to connect server
- * 4. create integer handle for only this client
- * 5. if it is first connection(client), get client id from server
- * 6. if it is first connection(client), start sensor event listener
- * 7. sensor initialization : stop, pause_all
- * 8. if it is first connection(client), send cmd hello
- * 9. if cmd hello is failed and it is first connection(client) stop listener, remove id
- */
+ retvm_if(!manager.connect(), -EIO, "Failed to connect");
+ retvm_if(!manager.is_supported(sensor), -EINVAL,
+ "Invalid sensor[%#x]", sensor);
- return 0;
+ sensor::sensor_listener *listener;
+
+ listener = new(std::nothrow) sensor::sensor_listener(sensor);
+ retvm_if(!listener, -ENOMEM, "Failed to allocate memory");
+
+ listeners[listener->get_id()] = listener;
+
+ return listener->get_id();
}
API bool sensord_disconnect(int handle)
{
- /*
- * 1. check parameter(check handle???)
- * 2. check state of this handle
- * 3. if it is on passive mode, unregister event and unset interval/latency
- * 4. if it is not stop, stop it
- * 5. if there is no active sensor(client), reset id & byebye and stop listener
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+ retvm_if(!listener, false, "Invalid handle[%d]", handle);
+
+ delete listener;
+ listeners.erase(handle);
return true;
}
API bool sensord_register_event(int handle, unsigned int event_type,
unsigned int interval, unsigned int max_batch_latency, sensor_cb_t cb, void *user_data)
{
- /*
- * 1. check parameter
- * 2. if interval is 0, default interval
- * ** if cb is null, how to handle it?
- * ** event type is deprecated
- */
+ sensor::sensor_listener *listener;
+ int prev_interval;
+ int prev_max_batch_latency;
+ sensor_event_handler *handler;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ prev_interval = listener->get_interval();
+ prev_max_batch_latency = listener->get_max_batch_latency();
+
+ if (listener->set_interval(interval) < 0) {
+ _E("Failed to set interval");
+ return false;
+ }
+
+ if (listener->set_max_batch_latency(max_batch_latency) < 0) {
+ listener->set_interval(prev_interval);
+ _E("Failed to set max_batch_latency");
+ return false;
+ }
+
+ handler = new(std::nothrow) sensor_event_handler(listener->get_sensor(), cb, user_data);
+ if (!handler) {
+ listener->set_max_batch_latency(prev_max_batch_latency);
+ listener->set_interval(prev_interval);
+ _E("Failed to allocate memory");
+ return false;
+ }
+
+ listener->set_event_handler(handler);
return true;
}
API bool sensord_unregister_event(int handle, unsigned int event_type)
{
- /*
- * 1. check parameter
- * 2. check previous interval, latency, cb, user_data
- * 3. if passive mode is true, set false
- * 4. if ret is false, register event
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ listener->unset_event_handler();
return true;
}
API bool sensord_register_accuracy_cb(int handle, sensor_accuracy_changed_cb_t cb, void *user_data)
{
- /*
- * 1. check parameter
- */
+ sensor::sensor_listener *listener;
+ sensor_accuracy_handler *handler;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ handler = new(std::nothrow) sensor_accuracy_handler(listener->get_sensor(), cb, user_data);
+ retvm_if(!handler, false, "Failed to allocate memory");
+
+ listener->set_accuracy_handler(handler);
return true;
}
API bool sensord_unregister_accuracy_cb(int handle)
{
- /*
- * 1. check parameter
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ listener->unset_accuracy_handler();
return true;
}
API bool sensord_start(int handle, int option)
{
- /*
- * 1. check parameter
- * 2. pause = CONVERT_OPTION_PAUSE_POLICY(option)
- * 3. start listener
- */
+ sensor::sensor_listener *listener;
+ int prev_pause;
+ int pause;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ pause = CONVERT_OPTION_PAUSE_POLICY(option);
+ prev_pause = listener->get_pause_policy();
+
+ if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
+ _E("Failed to set pause policy[%d]", pause);
+ return false;
+ }
+
+ if (listener->start() < 0) {
+ listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, prev_pause);
+ _E("Failed to start listener");
+ return false;
+ }
return true;
}
API bool sensord_stop(int handle)
{
- /*
- * 1. check parameter
- * 2. check sensor state, id
- * 2.1. if sensor is already stopped, return true
- * 3. stop listener
- */
+ int ret;
+ sensor::sensor_listener *listener;
- return true;
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ ret = listener->stop();
+
+ if (ret == -EAGAIN || ret == OP_SUCCESS)
+ return true;
+
+ return false;
}
API bool sensord_change_event_interval(int handle, unsigned int event_type, unsigned int interval)
{
- /*
- * 1. check parameter
- * 2. if interval is 0, default interval
- * 3. if previous interval is lower than interval, return true
- * 4. change interval
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->set_interval(interval) < 0) {
+ _E("Failed to set interval to listener");
+ return false;
+ }
return true;
}
API bool sensord_change_event_max_batch_latency(int handle, unsigned int event_type, unsigned int max_batch_latency)
{
- /*
- * 1. check parameter
- * 2. if previous interval is lower than interval, return true
- * 3. change batch latency
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->set_max_batch_latency(max_batch_latency) < 0) {
+ _E("Failed to set max_batch_latency to listener");
+ return false;
+ }
return true;
}
API bool sensord_set_option(int handle, int option)
{
- /*
- * change option, always-on/power save option/lcd off/default
- */
+ sensor::sensor_listener *listener;
+ int pause;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ pause = CONVERT_OPTION_PAUSE_POLICY(option);
+
+ if (listener->set_attribute(SENSORD_ATTRIBUTE_PAUSE_POLICY, pause) < 0) {
+ _E("Failed to set option[%d(%d)] to listener", option, pause);
+ return false;
+ }
return true;
}
API int sensord_set_attribute_int(int handle, int attribute, int value)
{
- /*
- * 1. if ATTRIBUTE_PAUSE_POLICY
- * 2. if ATTRIBUTE_AXIS_ORIENTATION
- * 3. else attribute
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->set_attribute(attribute, value) < 0) {
+ _E("Failed to set attribute[%d, %d]", attribute, value);
+ return -EIO;
+ }
return OP_SUCCESS;
}
API int sensord_set_attribute_str(int handle, int attribute, const char *value, int len)
{
- /*
- * 1. check parameter
- * 2. if client id is invalid, return -EPERM
- * 3. if there is other problems, return -EPERM
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), -EINVAL, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->set_attribute(attribute, value, len) < 0) {
+ _E("Failed to set attribute[%d, %s]", attribute, value);
+ return -EIO;
+ }
return OP_SUCCESS;
}
API bool sensord_get_data(int handle, unsigned int data_id, sensor_data_t* sensor_data)
{
- /*
- * 1. check parameter
- * 2. check sensor state(is it really needed?)
- * 3. get data
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->get_sensor_data(sensor_data) < 0) {
+ _E("Failed to get sensor data from listener");
+ return false;
+ }
return true;
}
API bool sensord_flush(int handle)
{
- /*
- * 1. check parameter
- * 2. check sensor state(is it really needed?)
- * 3. flush sensor
- */
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->flush() < 0) {
+ _E("Failed to flush sensor");
+ return false;
+ }
return true;
}
API bool sensord_set_passive_mode(int handle, bool passive)
{
- /* set passive mode*/
+ sensor::sensor_listener *listener;
+
+ auto it = listeners.find(handle);
+ retvm_if(it == listeners.end(), false, "Invalid handle[%d]", handle);
+
+ listener = it->second;
+
+ if (listener->set_passive_mode(passive) < 0) {
+ _E("Failed to set passive mode");
+ return false;
+ }
return true;
}
* 3. first connection(client)
* 4. cmd_connect for external sensor with key
*/
- retvm_if(!key, -EPERM, "Invalid key");
+ retvm_if(!key, -EINVAL, "Invalid key");
return 0;
}
/* deperecated */
API sensor_t sensord_get_sensor(sensor_type_t type)
{
- return NULL;
+ sensor_t sensor;
+
+ if (sensord_get_default_sensor(type, &sensor) < 0)
+ return NULL;
+
+ return sensor;
}
/* deprecated */
/* deprecated(BUT it is used in C-API....) */
API bool sensord_is_supported_event_type(sensor_t sensor, unsigned int event_type, bool *supported)
{
- /*
- * 1. check parameter
- * 2. if there is no sensor, return false
- */
+ if (!manager.is_supported(sensor))
+ *supported = false;
+ else
+ *supported = true;
+
return true;
}
return (sensord_set_attribute_str(handle, 0, command, command_len) == OP_SUCCESS);
}
+/* deprecated */
+API bool sensord_get_privilege(sensor_t sensor, sensor_privilege_t *privilege)
+{
+ *privilege = SENSOR_PRIVILEGE_PUBLIC;
+
+ return true;
+}
+