sensord: implement sensor_manager class for clients 61/123261/6
authorkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 05:42:25 +0000 (14:42 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Wed, 5 Apr 2017 09:47:51 +0000 (18:47 +0900)
- sensor_manager provides:
  - store sensor information and manages all sensor handles
  - check whether the sensor is supported or not

- [TBD]listen an event that the application sensor is connected or disconnected

Change-Id: Icd38a74058170162bbfa8c7df6d1bdcc41d80e2d
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
include/sensor_types.h
src/client/sensor_manager.cpp

index 5266450..2253a29 100644 (file)
@@ -60,6 +60,8 @@ extern "C"
 #define SENSOR_UNKNOWN_TYPE "http://tizen.org/sensor/unknown"
 #define SENSOR_UNKNOWN_NAME "Unknown"
 
+#define SENSOR_URI_PERMISSION_DENIED "http://tizen.org/sensor/EACCES"
+
 typedef int64_t sensor_id_t;
 typedef void *sensor_t;
 
index 3a4742b..9a93cb5 100644 (file)
@@ -36,8 +36,18 @@ public:
        : m_manager(manager)
        {}
        void connected(ipc::channel *ch) {}
-       void disconnected(ipc::channel *ch) {}
-       void read(ipc::channel *ch, ipc::message &msg) {}
+       void disconnected(ipc::channel *ch)
+       {
+               /* If channel->disconnect() is not explicitly called, it will be restored */
+               m_manager->restore();
+       }
+
+       void read(ipc::channel *ch, ipc::message &msg)
+       {
+               /* TODO: if dynamic sensor is loaded,
+                * it will be called with the sensor information */
+       }
+
        void read_complete(ipc::channel *ch) {}
        void error_caught(ipc::channel *ch, int error) {}
 
@@ -61,56 +71,134 @@ sensor_manager::~sensor_manager()
 
 int sensor_manager::get_sensor(sensor_type_t type, sensor_t *sensor)
 {
-       return OP_ERROR;
+       return get_sensor(utils::get_uri(type), sensor);
 }
 
 int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count)
 {
-       return OP_ERROR;
+       return get_sensors(utils::get_uri(type), list, count);
 }
 
 int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
 {
-       return OP_ERROR;
+       sensor_info *info;
+
+       info = get_info(uri);
+       if (!info) {
+               *sensor = NULL;
+               return -ENODATA;
+       }
+
+       if (info->get_uri() == SENSOR_URI_PERMISSION_DENIED)
+               return -EACCES;
+
+       *sensor = (sensor_t)info;
+       return OP_SUCCESS;
 }
 
 int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
 {
-       return OP_ERROR;
+       std::vector<sensor_info *> infos;
+       int size;
+
+       infos = get_infos(uri);
+       size = infos.size();
+
+       if (size == 0) {
+               *count = 0;
+               return -ENODATA;
+       }
+
+       if (infos[0]->get_uri() == SENSOR_URI_PERMISSION_DENIED)
+               return -EACCES;
+
+       *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
+       retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
+
+       for (int i = 0; i < size; ++i)
+               *(*list + i) = infos[i];
+
+       *count = size;
+       return OP_SUCCESS;
 }
 
 bool sensor_manager::is_supported(sensor_t sensor)
 {
+       retvm_if(!sensor, false, "Invalid parameter[%#x]", sensor);
+
+       for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
+               if (&*it == sensor)
+                       return true;
+       }
+
        return false;
 }
 
 bool sensor_manager::is_supported(const char *uri)
 {
+       for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
+               if ((*it).get_uri() == uri)
+                       return true;
+       }
+
        return false;
 }
 
 bool sensor_manager::init(void)
 {
+       m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
+       retvm_if(!m_client, false, "Failed to allocate memory");
+
+       m_handler = new(std::nothrow) manager_handler(this);
+       if (!m_handler) {
+               delete m_client;
+               m_client = NULL;
+               return false;
+       }
+
        return true;
 }
 
 void sensor_manager::deinit(void)
 {
+       disconnect();
+
+       delete m_handler;
+       m_handler = NULL;
+
+       delete m_client;
+       m_client = NULL;
 }
 
 bool sensor_manager::connect_channel(void)
 {
+       m_channel = m_client->connect(m_handler, &m_loop);
+       retvm_if(!m_channel, false, "Failed to connect to server");
+
+       m_connected.store(true);
+
        _D("Connected");
        return true;
 }
 
 bool sensor_manager::connect(void)
 {
-       return false;
+       retv_if(is_connected(), true);
+       retv_if(!connect_channel(), false);
+
+       return get_sensors_internal();
 }
 
 void sensor_manager::disconnect(void)
 {
+       ret_if(!is_connected());
+
+       m_connected.store(false);
+       m_channel->disconnect();
+
+       delete m_channel;
+       m_channel = NULL;
+
        _D("Disconnected");
 }
 
@@ -121,28 +209,89 @@ bool sensor_manager::is_connected(void)
 
 void sensor_manager::restore(void)
 {
+       ret_if(!is_connected());
+
+       m_connected.store(false);
+       retm_if(!connect_channel(), "Failed to restore manager");
+
        _D("Restored manager");
 }
 
 void sensor_manager::decode_sensors(const char *buf, std::vector<sensor_info> &infos)
 {
        int count = 0;
+       sensor_info info;
+       const size_t *size;
+       const char *data;
+       cmd_manager_sensor_list_t *raw;
+
+       raw = (cmd_manager_sensor_list_t *)buf;
+       count = raw->sensor_cnt;
+       size = (const size_t *)raw->data;
+       data = (const char *)raw->data + sizeof(size_t);
+
+       for (int i = 0; i < count; ++i) {
+               info.clear();
+               info.deserialize(data, size[0]);
+               infos.push_back(info);
+
+               size = (const size_t *)((const char *)data + size[0]);
+               data = (const char *)size + sizeof(size_t);
+       }
+
        _D("Sensor count : %d", count);
 }
 
 bool sensor_manager::get_sensors_internal(void)
 {
+       retvm_if(!is_connected(), false, "Failed to get sensors");
+
+       bool ret;
+       ipc::message msg;
+       ipc::message reply;
+       char buf[MAX_BUF_SIZE];
+
+       msg.set_type(CMD_MANAGER_SENSOR_LIST);
+
+       ret = m_channel->send_sync(&msg);
+       retvm_if(!ret, false, "Failed to send message");
+
+       ret = m_channel->read_sync(reply);
+       retvm_if(!ret, false, "Failed to receive message");
+
+       reply.disclose(buf);
+
+       decode_sensors(buf, m_infos);
+
        return true;
 }
 
 sensor_info *sensor_manager::get_info(const char *uri)
 {
+       if (strncmp(uri, utils::get_uri(ALL_SENSOR), 27) == 0)
+               return &m_infos[0];
+
+       for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
+               if ((*it).get_uri() == uri)
+                       return &*it;
+       }
+
        return NULL;
 }
 
 std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
 {
        std::vector<sensor_info *> infos;
+       bool all = false;
+
+       if (strncmp(uri, utils::get_uri(ALL_SENSOR), 27) == 0)
+               all = true;
+
+       for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
+               if (all || (*it).get_type_uri() == uri)
+                       infos.push_back(&*it);
+       }
+
        return infos;
 }