From c5b5c233520c5c4246ca257dd4a7fe3a5b0472c6 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 13:06:01 +0900 Subject: [PATCH 01/16] sensord: api: add skeleton code of internal apis - sensor_manager can stores and manages all of sensors. - sensor_listener can listen sensor event and modify sensor configuation (interval, option, batch_latency, attributes and so on) - rename client.cpp to sensor_internal.cpp Change-Id: I15b74b777ba70d9c7b7d7a2c597fabf91f259b2c Signed-off-by: kibak.yoon --- src/client/{client.cpp => sensor_internal.cpp} | 0 src/client/sensor_listener.cpp | 201 +++++++++++++++++++++++++ src/client/sensor_listener.h | 95 ++++++++++++ src/client/sensor_manager.cpp | 148 ++++++++++++++++++ src/client/sensor_manager.h | 82 ++++++++++ 5 files changed, 526 insertions(+) rename src/client/{client.cpp => sensor_internal.cpp} (100%) create mode 100644 src/client/sensor_listener.cpp create mode 100644 src/client/sensor_listener.h create mode 100644 src/client/sensor_manager.cpp create mode 100644 src/client/sensor_manager.h diff --git a/src/client/client.cpp b/src/client/sensor_internal.cpp similarity index 100% rename from src/client/client.cpp rename to src/client/sensor_internal.cpp diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp new file mode 100644 index 0000000..83145ef --- /dev/null +++ b/src/client/sensor_listener.cpp @@ -0,0 +1,201 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sensor_listener.h" + +#include +#include +#include +#include +#include + +using namespace sensor; + +class listener_handler : public ipc::channel_handler +{ +public: + listener_handler(sensor_listener *listener) + : m_listener(listener) + {} + void connected(ipc::channel *ch) {} + void disconnected(ipc::channel *ch) {} + void read(ipc::channel *ch, ipc::message &msg) {} + void read_complete(ipc::channel *ch) {} + void error_caught(ipc::channel *ch, int error) {} + +private: + sensor_listener *m_listener; +}; + +sensor_listener::sensor_listener(sensor_t sensor) +: m_id(0) +, m_sensor(reinterpret_cast(sensor)) +, m_client(NULL) +, m_channel(NULL) +, m_handler(NULL) +, m_evt_handler(NULL) +, m_acc_handler(NULL) +, m_connected(false) +, m_started(false) +{ + init(); +} + +sensor_listener::~sensor_listener() +{ + deinit(); +} + +bool sensor_listener::init(void) +{ + return true; +} + +void sensor_listener::deinit(void) +{ +} + +int sensor_listener::get_id(void) +{ + return m_id; +} + +sensor_t sensor_listener::get_sensor(void) +{ + return static_cast(m_sensor); +} + +void sensor_listener::restore(void) +{ + _D("Restored listener[%d]", get_id()); +} + +bool sensor_listener::connect(void) +{ + _I("Listener ID[%d]", get_id()); + + return true; +} + +void sensor_listener::disconnect(void) +{ + _I("Disconnected[%d]", get_id()); +} + +bool sensor_listener::is_connected(void) +{ + return m_connected.load(); +} + +ipc::channel_handler *sensor_listener::get_event_handler(void) +{ + return m_evt_handler; +} + +void sensor_listener::set_event_handler(ipc::channel_handler *handler) +{ + m_evt_handler = handler; +} + +void sensor_listener::unset_event_handler(void) +{ + delete m_evt_handler; + m_evt_handler = NULL; +} + +ipc::channel_handler *sensor_listener::get_accuracy_handler(void) +{ + return m_acc_handler; +} + +void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler) +{ + m_acc_handler = handler; +} + +void sensor_listener::unset_accuracy_handler(void) +{ + m_acc_handler = NULL; +} + +int sensor_listener::start(void) +{ + return OP_ERROR; +} + +int sensor_listener::stop(void) +{ + return OP_ERROR; +} + +int sensor_listener::get_interval(void) +{ + return OP_ERROR; +} + +int sensor_listener::get_max_batch_latency(void) +{ + return OP_ERROR; +} + +int sensor_listener::get_pause_policy(void) +{ + return OP_ERROR; +} + +int sensor_listener::get_passive_mode(void) +{ + return OP_ERROR; +} + +int sensor_listener::set_interval(unsigned int interval) +{ + return OP_ERROR; +} + +int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency) +{ + return OP_ERROR; +} + +int sensor_listener::set_passive_mode(bool passive) +{ + return OP_ERROR; +} + +int sensor_listener::flush(void) +{ + return OP_ERROR; +} + +int sensor_listener::set_attribute(int attribute, int value) +{ + return OP_ERROR; +} + +int sensor_listener::set_attribute(int attribute, const char *value, int len) +{ + return OP_ERROR; +} + +int sensor_listener::get_sensor_data(sensor_data_t *data) +{ + return OP_ERROR; +} + diff --git a/src/client/sensor_listener.h b/src/client/sensor_listener.h new file mode 100644 index 0000000..ea30092 --- /dev/null +++ b/src/client/sensor_listener.h @@ -0,0 +1,95 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_LISTENER_H__ +#define __SENSOR_LISTENER_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sensor { + +class sensor_listener { +public: + sensor_listener(sensor_t sensor); + virtual ~sensor_listener(); + + int get_id(void); + sensor_t get_sensor(void); + + ipc::channel_handler *get_event_handler(void); + ipc::channel_handler *get_accuracy_handler(void); + + /* TODO: modify the listener so that it can register multiple handlers(1:n) */ + void set_event_handler(ipc::channel_handler *handler); + void set_accuracy_handler(ipc::channel_handler *handler); + + void unset_event_handler(void); + void unset_accuracy_handler(void); + + int start(void); + int stop(void); + + int get_interval(void); + int get_max_batch_latency(void); + int get_pause_policy(void); + int get_passive_mode(void); + + int set_interval(unsigned int interval); + int set_max_batch_latency(unsigned int max_batch_latency); + int set_passive_mode(bool passive); + int set_attribute(int attribute, int value); + int set_attribute(int attribute, const char *value, int len); + + int get_sensor_data(sensor_data_t *data); + int flush(void); + + void restore(void); + +private: + bool init(void); + void deinit(void); + + bool connect(void); + void disconnect(void); + bool is_connected(void); + + int m_id; + sensor_info *m_sensor; + + ipc::ipc_client *m_client; + ipc::channel *m_channel; + ipc::channel_handler *m_handler; + ipc::channel_handler *m_evt_handler; + ipc::channel_handler *m_acc_handler; + ipc::event_loop m_loop; + std::atomic m_connected; + std::atomic m_started; + std::map m_attributes; +}; + +} + +#endif /* __SENSOR_LISTENER_H__ */ diff --git a/src/client/sensor_manager.cpp b/src/client/sensor_manager.cpp new file mode 100644 index 0000000..3a4742b --- /dev/null +++ b/src/client/sensor_manager.cpp @@ -0,0 +1,148 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sensor_manager.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace sensor; + +class manager_handler : public ipc::channel_handler +{ +public: + manager_handler(sensor_manager *manager) + : m_manager(manager) + {} + void connected(ipc::channel *ch) {} + void disconnected(ipc::channel *ch) {} + void read(ipc::channel *ch, ipc::message &msg) {} + void read_complete(ipc::channel *ch) {} + void error_caught(ipc::channel *ch, int error) {} + +private: + sensor_manager *m_manager; +}; + +sensor_manager::sensor_manager() +: m_client(NULL) +, m_handler(NULL) +, m_channel(NULL) +, m_connected(false) +{ + init(); +} + +sensor_manager::~sensor_manager() +{ + deinit(); +} + +int sensor_manager::get_sensor(sensor_type_t type, sensor_t *sensor) +{ + return OP_ERROR; +} + +int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count) +{ + return OP_ERROR; +} + +int sensor_manager::get_sensor(const char *uri, sensor_t *sensor) +{ + return OP_ERROR; +} + +int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count) +{ + return OP_ERROR; +} + +bool sensor_manager::is_supported(sensor_t sensor) +{ + return false; +} + +bool sensor_manager::is_supported(const char *uri) +{ + return false; +} + +bool sensor_manager::init(void) +{ + return true; +} + +void sensor_manager::deinit(void) +{ +} + +bool sensor_manager::connect_channel(void) +{ + _D("Connected"); + return true; +} + +bool sensor_manager::connect(void) +{ + return false; +} + +void sensor_manager::disconnect(void) +{ + _D("Disconnected"); +} + +bool sensor_manager::is_connected(void) +{ + return m_connected.load(); +} + +void sensor_manager::restore(void) +{ + _D("Restored manager"); +} + +void sensor_manager::decode_sensors(const char *buf, std::vector &infos) +{ + int count = 0; + _D("Sensor count : %d", count); +} + +bool sensor_manager::get_sensors_internal(void) +{ + return true; +} + +sensor_info *sensor_manager::get_info(const char *uri) +{ + return NULL; +} + +std::vector sensor_manager::get_infos(const char *uri) +{ + std::vector infos; + return infos; +} + diff --git a/src/client/sensor_manager.h b/src/client/sensor_manager.h new file mode 100644 index 0000000..35ae863 --- /dev/null +++ b/src/client/sensor_manager.h @@ -0,0 +1,82 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_MANAGER_H__ +#define __SENSOR_MANAGER_H__ + +#include +#include +#include +#include +#include +#include + +#include "sensor_internal.h" + +namespace sensor { + +class sensor_manager { +public: + sensor_manager(); + virtual ~sensor_manager(); + + bool connect(void); + void disconnect(void); + + int get_sensor(sensor_type_t type, sensor_t *sensor); + int get_sensors(sensor_type_t type, sensor_t **list, int *count); + int get_sensor(const char *uri, sensor_t *sensor); + int get_sensors(const char *uri, sensor_t **list, int *count); + + bool is_supported(sensor_t sensor); + bool is_supported(const char *uri); + + void restore(void); + + /* TODO: register sensor_provider by using manager */ + /* int register_sensor(sensor_provider *provider); */ + /* int unregister_sensor(const char *uri) */ + +private: + typedef std::vector sensor_infos_t; + + bool init(void); + void deinit(void); + + bool connect_channel(void); + bool is_connected(void); + + void decode_sensors(const char *buf, std::vector &infos); + bool get_sensors_internal(void); + + sensor_info *get_info(const char *uri); + std::vector get_infos(const char *uri); + + ipc::ipc_client *m_client; + ipc::channel_handler *m_handler; + ipc::channel *m_channel; + ipc::event_loop m_loop; + std::atomic m_connected; + + sensor_infos_t m_infos; +}; + +} + +#endif /* __SENSOR_MANAGER_H__ */ -- 2.7.4 From f192807171708e30d467c3a11cea4855f6bcd947 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 13:50:49 +0900 Subject: [PATCH 02/16] sensor: api: implement internal api using classes - check invalid parameters. - call proper operations/functions. Change-Id: I61b9813a3f77cfd116a8ea72ee417f4cb7356640 Signed-off-by: kibak.yoon --- src/client/sensor_internal.cpp | 532 +++++++++++++++++++++++++++++------------ 1 file changed, 373 insertions(+), 159 deletions(-) diff --git a/src/client/sensor_internal.cpp b/src/client/sensor_internal.cpp index 0864b14..f9b2698 100644 --- a/src/client/sensor_internal.cpp +++ b/src/client/sensor_internal.cpp @@ -17,184 +17,270 @@ * */ -#include "sensor_internal.h" -#include +#include +#include +#include + +#include +#include +#include #include +#include + +#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)) + , 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(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)) + , 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(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 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, -EPERM, "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)->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)->get_uri().c_str(); } API const char* sensord_get_vendor(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)->get_vendor().c_str(); } 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(), false, "Failed to connect"); + retvm_if(!privilege, false, "Invalid parameter[%#x]", privilege); + retvm_if(!manager.is_supported(sensor), false, + "Invalid sensor[%#x]", sensor); + + /* TODO: + * sensor_permission_t perm = static_cast(sensor)->get_permission(); + * *privilege = static_cast(perm); */ + *privilege = SENSOR_PRIVILEGE_PUBLIC; return true; } 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)->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)->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)->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)->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)->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)->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; } @@ -202,148 +288,270 @@ API bool sensord_disconnect(int handle) 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; } @@ -387,7 +595,12 @@ API bool sensord_external_post(int handle, unsigned long long timestamp, const f /* 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 */ @@ -417,10 +630,11 @@ API bool sensord_get_supported_event_types(sensor_t sensor, unsigned int **event /* 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; } -- 2.7.4 From c5fe24434065b980e9cccd728454d06b8ae04fd5 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 14:42:25 +0900 Subject: [PATCH 03/16] sensord: implement sensor_manager class for clients - 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 --- include/sensor_types.h | 2 + src/client/sensor_manager.cpp | 163 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 158 insertions(+), 7 deletions(-) diff --git a/include/sensor_types.h b/include/sensor_types.h index 5266450..2253a29 100644 --- a/include/sensor_types.h +++ b/include/sensor_types.h @@ -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; diff --git a/src/client/sensor_manager.cpp b/src/client/sensor_manager.cpp index 3a4742b..9a93cb5 100644 --- a/src/client/sensor_manager.cpp +++ b/src/client/sensor_manager.cpp @@ -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 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 &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_manager::get_infos(const char *uri) { std::vector 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; } -- 2.7.4 From d1e1914574deef5df62b3a3c38f11c1658e79ae9 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 15:33:47 +0900 Subject: [PATCH 04/16] sensord: implement sensor_listener class for clients - sensor_listener provides: - controls for sensor actions such as start and stop. - controls for changing sensor settings - listening for sensor events from server Change-Id: I7216b282cc3429d0864b4343d65ff192951b1038 Signed-off-by: kibak.yoon --- src/client/sensor_listener.cpp | 238 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 222 insertions(+), 16 deletions(-) diff --git a/src/client/sensor_listener.cpp b/src/client/sensor_listener.cpp index 83145ef..da9dbe8 100644 --- a/src/client/sensor_listener.cpp +++ b/src/client/sensor_listener.cpp @@ -34,8 +34,25 @@ public: : m_listener(listener) {} 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, + * listener will be restored */ + m_listener->restore(); + } + + void read(ipc::channel *ch, ipc::message &msg) + { + switch (msg.header()->type) { + case CMD_LISTENER_EVENT: + if (m_listener->get_event_handler()) + m_listener->get_event_handler()->read(ch, msg); + case CMD_LISTENER_ACC_EVENT: + if (m_listener->get_accuracy_handler()) + m_listener->get_accuracy_handler()->read(ch, msg); + } + } + void read_complete(ipc::channel *ch) {} void error_caught(ipc::channel *ch, int error) {} @@ -64,11 +81,37 @@ sensor_listener::~sensor_listener() bool sensor_listener::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) listener_handler(this); + if (!m_handler) { + delete m_client; + return false; + } + + if (!connect()) { + delete m_handler; + delete m_client; + m_handler = NULL; + m_client = NULL; + return false; + } + return true; } void sensor_listener::deinit(void) { + disconnect(); + + delete m_handler; + m_handler = NULL; + + delete m_client; + m_client = NULL; + + m_attributes.clear(); } int sensor_listener::get_id(void) @@ -83,18 +126,66 @@ sensor_t sensor_listener::get_sensor(void) void sensor_listener::restore(void) { + ret_if(!is_connected()); + retm_if(!connect(), "Failed to restore listener"); + + /* Restore attributes/status */ + 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 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]); + _D("Restored listener[%d]", get_id()); } bool sensor_listener::connect(void) { - _I("Listener ID[%d]", get_id()); + m_channel = m_client->connect(m_handler, &m_loop); + retvm_if(!m_channel, false, "Failed to connect to server"); + + ipc::message msg; + ipc::message reply; + cmd_listener_connect_t buf = {0, }; + + 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_channel->send_sync(&msg); + + m_channel->read_sync(reply); + reply.disclose((char *)&buf); + + m_id = buf.listener_id; + m_connected.store(true); + + _D("Listener ID[%d]", get_id()); return true; } void sensor_listener::disconnect(void) { + ret_if(!is_connected()); + m_connected.store(false); + + ipc::message msg; + ipc::message reply; + + msg.set_type(CMD_LISTENER_DISCONNECT); + m_channel->send_sync(&msg); + + m_channel->read_sync(reply); + m_channel->disconnect(); + + delete m_channel; + m_channel = NULL; + _I("Disconnected[%d]", get_id()); } @@ -131,71 +222,186 @@ void sensor_listener::set_accuracy_handler(ipc::channel_handler *handler) void sensor_listener::unset_accuracy_handler(void) { + delete m_acc_handler; m_acc_handler = NULL; } int sensor_listener::start(void) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_start_t buf; + + retvm_if(!m_channel, -EINVAL, "Failed to connect to server"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_START); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_started.store(true); + + return OP_SUCCESS; } int sensor_listener::stop(void) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_stop_t buf; + + retvm_if(!m_channel, -EINVAL, "Failed to connect to server"); + retvm_if(!m_started.load(), -EAGAIN, "Already stopped"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_STOP); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_started.store(false); + + return OP_SUCCESS; } int sensor_listener::get_interval(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_INTERVAL); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_INTERVAL]; } int sensor_listener::get_max_batch_latency(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY]; } int sensor_listener::get_pause_policy(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_PAUSE_POLICY); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_PAUSE_POLICY]; } int sensor_listener::get_passive_mode(void) { - return OP_ERROR; + auto it = m_attributes.find(SENSORD_ATTRIBUTE_PASSIVE_MODE); + retv_if(it == m_attributes.end(), -1); + + return m_attributes[SENSORD_ATTRIBUTE_PASSIVE_MODE]; } int sensor_listener::set_interval(unsigned int interval) { - return OP_ERROR; + int _interval; + + /* TODO: move this logic to server */ + if (interval == 0) + _interval = DEFAULT_INTERVAL; + else if (interval < (unsigned int)m_sensor->get_min_interval()) + _interval = m_sensor->get_min_interval(); + else + _interval = interval; + + return set_attribute(SENSORD_ATTRIBUTE_INTERVAL, _interval); } int sensor_listener::set_max_batch_latency(unsigned int max_batch_latency) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY, max_batch_latency); } int sensor_listener::set_passive_mode(bool passive) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_PASSIVE_MODE, passive); } int sensor_listener::flush(void) { - return OP_ERROR; + return set_attribute(SENSORD_ATTRIBUTE_FLUSH, 1); } int sensor_listener::set_attribute(int attribute, int value) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_int_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + buf.listener_id = m_id; + buf.attribute = attribute; + buf.value = value; + msg.set_type(CMD_LISTENER_ATTR_INT); + msg.enclose((char *)&buf, sizeof(buf)); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + if (reply.header()->err < 0) + return reply.header()->err; + + m_attributes[attribute] = value; + + return OP_SUCCESS; } int sensor_listener::set_attribute(int attribute, const char *value, int len) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_attr_str_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + msg.set_type(CMD_LISTENER_ATTR_STR); + buf.listener_id = m_id; + buf.attribute = attribute; + memcpy(buf.value, value, len); + buf.len = len; + + msg.enclose((char *)&buf, sizeof(buf) + len); + + m_channel->send_sync(&msg); + m_channel->read_sync(reply); + + return reply.header()->err; } int sensor_listener::get_sensor_data(sensor_data_t *data) { - return OP_ERROR; + ipc::message msg; + ipc::message reply; + cmd_listener_get_data_t buf; + + retvm_if(!m_channel, false, "Failed to connect to server"); + + buf.listener_id = m_id; + msg.set_type(CMD_LISTENER_GET_DATA); + msg.enclose((char *)&buf, sizeof(buf)); + m_channel->send_sync(&msg); + + m_channel->read_sync(reply); + /* TODO */ + /* + reply.disclose((char *)&buf); + memcpy(data, buf.data, sizeof(buf.len)); + */ + + return OP_SUCCESS; } -- 2.7.4 From 665a5cf24e0fceae5c50f2fd9a8f5b6123020dd3 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 16:15:30 +0900 Subject: [PATCH 05/16] sensord: move dbus_listener from client to server - dbus_listener is a helper class for listening dbus signal. - it will listen AXIS_ORIENTATED policy from other framework. Change-Id: I1705d87ebd0ab0a231f7bfccba28ba217ead9b70 Signed-off-by: kibak.yoon --- src/server/dbus_listener.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++ src/server/dbus_listener.h | 45 +++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 src/server/dbus_listener.cpp create mode 100644 src/server/dbus_listener.h diff --git a/src/server/dbus_listener.cpp b/src/server/dbus_listener.cpp new file mode 100644 index 0000000..c417586 --- /dev/null +++ b/src/server/dbus_listener.cpp @@ -0,0 +1,134 @@ +/* + * sensord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include "dbus_listener.h" + +#define HANDLE_GERROR(Err) \ + do { \ + if ((Err)) { \ + _E("GError: %s", Err->message); \ + g_error_free(Err); \ + Err = NULL; \ + } \ + } while (0) + +#define ROTATION_DBUS_DEST "org.tizen.system.coord" +#define ROTATION_DBUS_OBJ_PATH "/Org/Tizen/System/Coord/Rotation" +#define ROTATION_DBUS_IFACE "org.tizen.system.coord.rotation" +#define ROTATION_DBUS_SIGNAL "Changed" +#define ROTATION_DBUS_METHOD "Degree" + +static void rotation_signal_cb(GDBusConnection *conn, const gchar *sender, + const gchar *obj_path, const gchar *iface, const gchar *signal_name, + GVariant *param, gpointer user_data) +{ + gint state; + g_variant_get(param, "(i)", &state); + //sensor_event_listener::get_instance().set_display_rotation(state); +} + +static void rotation_read_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *conn = G_DBUS_CONNECTION(source_object); + GVariant *result = g_dbus_connection_call_finish(conn, res, &error); + HANDLE_GERROR(error); + ret_if(result == NULL); + + gint state; + g_variant_get(result, "(i)", &state); + g_variant_unref(result); + //sensor_event_listener::get_instance().set_display_rotation(state); +} + +dbus_listener::dbus_listener() +: m_connection(NULL) +{ +#ifndef GLIB_VERSION_2_36 + g_type_init(); +#endif +} + +dbus_listener::~dbus_listener() +{ + disconnect(); +} + +void dbus_listener::init(void) +{ + static dbus_listener listener; + static bool done = false; + ret_if(done); + listener.connect(); + done = true; +} + +void dbus_listener::connect(void) +{ + GError *gerr = NULL; + + gchar *addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr); + HANDLE_GERROR(gerr); + retm_if(addr == NULL, "Getting address failed"); + + g_dbus_connection_new_for_address(addr, + (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), + NULL, NULL, on_connection_ready, this); + g_free(addr); +} + +void dbus_listener::on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *gerr = NULL; + dbus_listener *listener = static_cast(user_data); + + GDBusConnection *conn = g_dbus_connection_new_finish(res, &gerr); + HANDLE_GERROR(gerr); + + retm_if(conn == NULL, "Connection failed"); + _D("Dbus connection established: %s", g_dbus_connection_get_unique_name(conn)); + + listener->m_connection = conn; + listener->get_current_state(); + listener->subscribe(); +} + +void dbus_listener::disconnect(void) +{ + ret_if(!m_connection); + g_dbus_connection_close_sync(m_connection, NULL, NULL); + g_object_unref(m_connection); +} + +void dbus_listener::subscribe(void) +{ + /* Diplay rotation */ + g_dbus_connection_signal_subscribe(m_connection, + ROTATION_DBUS_DEST, ROTATION_DBUS_IFACE, ROTATION_DBUS_SIGNAL, ROTATION_DBUS_OBJ_PATH, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)rotation_signal_cb, NULL, NULL); +} + +void dbus_listener::get_current_state(void) +{ + /* Display rotation */ + g_dbus_connection_call(m_connection, + ROTATION_DBUS_DEST, ROTATION_DBUS_OBJ_PATH, ROTATION_DBUS_IFACE, ROTATION_DBUS_METHOD, + NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback)rotation_read_cb, NULL); +} diff --git a/src/server/dbus_listener.h b/src/server/dbus_listener.h new file mode 100644 index 0000000..6b045f3 --- /dev/null +++ b/src/server/dbus_listener.h @@ -0,0 +1,45 @@ +/* + * sensord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _DBUS_LISTENER_H_ +#define _DBUS_LISTENER_H_ + +#include +#include + +class dbus_listener { +public: + static void init(void); + +private: + GDBusConnection *m_connection; + + dbus_listener(); + ~dbus_listener(); + + void connect(void); + void disconnect(void); + + void subscribe(void); + void get_current_state(void); + + static void on_connection_ready(GObject *source_object, GAsyncResult *res, gpointer user_data); +}; + +#endif /* _DBUS_LISTENER_H_ */ -- 2.7.4 From 25258ab1eb05bea3075a697b0009e4937d525e36 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 16:20:26 +0900 Subject: [PATCH 06/16] sensord: add permission_checker for checking privileges - permission_checker provides two way to check privilege: - by string - by sensor_permission_t(enum) - [TBD] in the future, we will only check privilege with string. - [TBD] since there is a direct dependency on cynara, it will be separated. Change-Id: Ic7ddac594bebb669a9643992ef7f52f1c36dcdfb Signed-off-by: kibak.yoon --- src/server/permission_checker.cpp | 101 ++++++++++++++++++++++++++++++++++++-- src/server/permission_checker.h | 25 +++++++--- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/src/server/permission_checker.cpp b/src/server/permission_checker.cpp index 20b03ec..644ce61 100644 --- a/src/server/permission_checker.cpp +++ b/src/server/permission_checker.cpp @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,22 +17,113 @@ * */ -#include +#include "permission_checker.h" + #include #include #include +#include +#include #define CACHE_SIZE 16 -static bool check_privilege_by_sockfd(int sock_fd, const char *priv, const char *access) +using namespace sensor; + +static cynara *cynara_env = NULL; +static std::unordered_map permissions; + +permission_checker::permission_checker() +{ + init_cynara(); +} + +permission_checker::~permission_checker() +{ + deinit_cynara(); +} + +void permission_checker::init(void) +{ + /* if needed, add privilege to permissions */ + permissions[SENSOR_PERMISSION_HEALTH_INFO] = "http://tizen.org/privilege/healthinfo"; +} + +void permission_checker::init_cynara(void) +{ + int err; + cynara_configuration *conf; + + err = cynara_configuration_create(&conf); + retm_if(err != CYNARA_API_SUCCESS, "Failed to create cynara configuration"); + + err = cynara_configuration_set_cache_size(conf, CACHE_SIZE); + if (err != CYNARA_API_SUCCESS) { + _E("Failed to set cynara cache"); + cynara_configuration_destroy(conf); + return; + } + + err = cynara_initialize(&cynara_env, conf); + cynara_configuration_destroy(conf); + + if (err != CYNARA_API_SUCCESS) { + _E("Failed to initialize cynara"); + cynara_env = NULL; + return; + } + + _I("Initialized"); +} + +void permission_checker::deinit_cynara(void) +{ + if (cynara_env) { + cynara_finish(cynara_env); + cynara_env = NULL; + } + + _I("Deinitialized"); +} + +bool permission_checker::has_permission_cynara(int sock_fd, std::string &perm) { + retvm_if(cynara_env == NULL, false, "Cynara not initialized"); + + int pid = -1; + char *client = NULL; + char *session = NULL; + char *user = NULL; + + retvm_if(cynara_creds_socket_get_pid(sock_fd, &pid) != CYNARA_API_SUCCESS, + false, "Failed to get pid"); + + if (cynara_creds_socket_get_client(sock_fd, + CLIENT_METHOD_DEFAULT, &client) != CYNARA_API_SUCCESS || + cynara_creds_socket_get_user(sock_fd, + USER_METHOD_DEFAULT, &user) != CYNARA_API_SUCCESS || + (session = cynara_session_from_pid(pid)) == NULL) { + _E("Failed to get client information"); + free(client); + free(user); + free(session); + return false; + } + return true; } -permission_checker::permission_checker() +bool permission_checker::has_permission(int sock_fd, std::string &perm) { + retv_if(perm.empty(), true); + + return has_permission_cynara(sock_fd, perm); } -permission_checker::~permission_checker() +/* TODO: remove sensor_permission_t and this function */ +bool permission_checker::has_permission(int sock_fd, sensor_permission_t perm) { + auto it = permissions.find(perm); + retv_if(it == permissions.end(), true); + + return has_permission(sock_fd, permissions[perm]); } diff --git a/src/server/permission_checker.h b/src/server/permission_checker.h index 01cc8b4..b307dc0 100644 --- a/src/server/permission_checker.h +++ b/src/server/permission_checker.h @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,29 @@ * */ -#ifndef _PERMISSION_CHECKER_H_ -#define _PERMISSION_CHECKER_H_ +#ifndef __PERMISSION_CHECKER_H__ +#define __PERMISSION_CHECKER_H__ +#include #include -#include -#include + +namespace sensor { class permission_checker { +public: permission_checker(); ~permission_checker(); + + void init(void); + + void init_cynara(void); + void deinit_cynara(void); + bool has_permission_cynara(int sock_fd, std::string &perm); + + bool has_permission(int sock_fd, std::string &perm); + bool has_permission(int sock_fd, sensor_permission_t perm); }; -#endif /* _PERMISSION_CHECKER_H_ */ +} + +#endif /* __PERMISSION_CHECKER_H__ */ -- 2.7.4 From 84993de67f4119d47b66014fc70f316e507e2027 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 17:04:32 +0900 Subject: [PATCH 07/16] sensord: add handlers to main for new failures - if new(memory allocation) is failed, on_new_failed will be called. - this patch refers to https://review.tizen.org/gerrit/#/c/123204/ Change-Id: I1817e376fb256992266a78d078cdc15ad00b6a58 Signed-off-by: kibak.yoon --- src/server/main.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/server/main.cpp b/src/server/main.cpp index 2ce210c..90b6cf4 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -17,10 +17,58 @@ * */ -/* TODO: create conf file for calibration paths */ -#define CAL_NODE_PATH "/sys/class/sensors/ssp_sensor/set_cal_data" +#include +#include +#include +#include +#include + +#include "server.h" + +#define NEW_FAIL_LIMIT 3 + +using namespace sensor; + +static void on_signal(int signum) +{ + _W("Received SIGNAL(%d : %s)", signum, strsignal(signum)); + server::stop(); +} + +static void on_new_failed(void) +{ + static unsigned fail_count = 0; + _E("Failed to allocate memory"); + + fail_count += 1; + if (fail_count >= NEW_FAIL_LIMIT) { + raise(SIGTERM); + return; + } + + usleep(100000); +} int main(int argc, char *argv[]) { + _I("Started"); + std::signal(SIGINT, on_signal); + std::signal(SIGHUP, on_signal); + std::signal(SIGTERM, on_signal); + std::signal(SIGQUIT, on_signal); + std::signal(SIGABRT, on_signal); + std::signal(SIGCHLD, SIG_IGN); + std::signal(SIGPIPE, SIG_IGN); + + std::set_new_handler(on_new_failed); + + init_dbus(); + + server::run(); + + fini_dbus(); + + _I("Stopped"); + return 0; } -- 2.7.4 From d8513d84462bbfb573fc2e104917d12f481f884d Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 18:26:20 +0900 Subject: [PATCH 08/16] sensord: add the basic implementation of the server-side - server provides: - controls for the event_loop which manages all I/O events. - server has: - event_loop - sensor_manager - server_channel_handler * it is singleton class. Change-Id: I6d7266f3ec68a4f576428bf4d7c2e91b699a4064 Signed-off-by: kibak.yoon --- src/server/sensor_loader.h | 10 +-- src/server/sensor_manager.cpp | 49 ++++++++++++ src/server/sensor_manager.h | 48 ++++++++++++ src/server/server.cpp | 102 ++++++++++++++++++++++++- src/server/server.h | 41 +++++++++-- src/server/server_channel_handler.cpp | 135 ++++++++++++++++++++++++++++++++++ src/server/server_channel_handler.h | 65 ++++++++++++++++ 7 files changed, 437 insertions(+), 13 deletions(-) create mode 100644 src/server/sensor_manager.cpp create mode 100644 src/server/sensor_manager.h create mode 100644 src/server/server_channel_handler.cpp create mode 100644 src/server/server_channel_handler.h diff --git a/src/server/sensor_loader.h b/src/server/sensor_loader.h index 22efa62..ab9b9b0 100644 --- a/src/server/sensor_loader.h +++ b/src/server/sensor_loader.h @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ * */ -#ifndef _SENSOR_LOADER_H_ -#define _SENSOR_LOADER_H_ +#ifndef __SENSOR_LOADER_H__ +#define __SENSOR_LOADER_H__ class sensor_loader { -private: +public: sensor_loader(); virtual ~sensor_loader(); }; -#endif /* _SENSOR_LOADER_H_ */ +#endif /* __SENSOR_LOADER_H__ */ diff --git a/src/server/sensor_manager.cpp b/src/server/sensor_manager.cpp new file mode 100644 index 0000000..6944e86 --- /dev/null +++ b/src/server/sensor_manager.cpp @@ -0,0 +1,49 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sensor_manager.h" + +#include +#include +#include +#include +#include +#include + +using namespace sensor; + +sensor_manager::sensor_manager(ipc::event_loop *loop) +: m_loop(loop) +{ +} + +sensor_manager::~sensor_manager() +{ +} + +bool sensor_manager::init(void) +{ + return true; +} + +bool sensor_manager::deinit(void) +{ + return true; +} + diff --git a/src/server/sensor_manager.h b/src/server/sensor_manager.h new file mode 100644 index 0000000..31236af --- /dev/null +++ b/src/server/sensor_manager.h @@ -0,0 +1,48 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_MANAGER_H__ +#define __SENSOR_MANAGER_H__ + +#include +#include +#include + +#include "event_loop.h" + +#include "sensor_loader.h" + +namespace sensor { + +class sensor_manager { +public: + sensor_manager(ipc::event_loop *loop); + ~sensor_manager(); + + bool init(void); + bool deinit(void); + +private: + ipc::event_loop *m_loop; + sensor_loader m_loader; +}; + +} + +#endif /* __SENSOR_MANAGER_H__ */ diff --git a/src/server/server.cpp b/src/server/server.cpp index 0c1e624..fee9abf 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,26 @@ #include "server.h" +#include +#include +#include +#include +#include + +#include "sensor_manager.h" +#include "server_channel_handler.h" + +#define TIMEOUT_TERM 10 + +using namespace sensor; + +ipc::event_loop server::m_loop; +std::atomic server::is_running(false); + server::server() +: m_server(NULL) +, m_manager(NULL) +, m_handler(NULL) { } @@ -27,8 +46,87 @@ server::~server() { } -server& server::get_instance(void) +server &server::instance(void) { static server inst; return inst; } + +void server::run(void) +{ + _I("Starting.."); + + retm_if(is_running.load(), "Server is running"); + retm_if(!instance().init(), "Failed to initialize server"); + + m_loop.run(); +} + +void server::stop(void) +{ + _I("Stopping.."); + + retm_if(!is_running.load(), "Server is not running"); + + m_loop.stop(); + instance().deinit(); +} + +bool server::init(void) +{ + m_server = new(std::nothrow) ipc::ipc_server(SENSOR_CHANNEL_PATH); + retvm_if(!m_server, false, "Failed to allocate memory"); + + m_manager = new(std::nothrow) sensor_manager(&m_loop); + retvm_if(!m_manager, false, "Failed to allocate memory"); + + m_handler = new(std::nothrow) server_channel_handler(m_manager); + retvm_if(!m_handler, false, "Failed to allocate memory"); + + init_server(); + init_termination(); + + is_running.store(true); + sd_notify(0, "READY=1"); + + return true; +} + +void server::deinit(void) +{ + m_manager->deinit(); + m_server->close(); + + delete m_server; + m_server = NULL; + + delete m_manager; + m_manager = NULL; + + delete m_handler; + m_handler = NULL; + + is_running.store(false); +} + +void server::init_server(void) +{ + m_manager->init(); + + /* TODO: setting socket option */ + m_server->set_option("max_connection", 1000); + m_server->set_option(SO_TYPE, SOCK_STREAM); + m_server->bind(m_handler, &m_loop); +} + +static gboolean terminate(gpointer data) +{ + /* TODO: if there is no sensor, sensord will be terminated */ + + return FALSE; +} + +void server::init_termination(void) +{ + g_timeout_add_seconds(TIMEOUT_TERM, terminate, m_manager); +} diff --git a/src/server/server.h b/src/server/server.h index 017f461..b8bb2f6 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,44 @@ * */ -#ifndef _SERVER_H_ -#define _SERVER_H_ +#ifndef __SERVER_H__ +#define __SERVER_H__ + +#include +#include +#include +#include +#include +#include + +namespace sensor { class server { public: + static void run(void); + static void stop(void); + +private: + static server &instance(void); + + static ipc::event_loop m_loop; + static std::atomic is_running; + server(); - virtual ~server(); + ~server(); + + bool init(void); + void deinit(void); - static server& get_instance(void); + void init_calibration(void); + void init_server(void); + void init_termination(void); + + ipc::ipc_server *m_server; + sensor_manager *m_manager; + server_channel_handler *m_handler; }; -#endif /* _SERVER_H_ */ +} + +#endif /* __SERVER_H__ */ diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp new file mode 100644 index 0000000..afcfa4e --- /dev/null +++ b/src/server/server_channel_handler.cpp @@ -0,0 +1,135 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "server_channel_handler.h" + +#include +#include +#include + +using namespace sensor; +using namespace ipc; + +server_channel_handler::server_channel_handler(sensor_manager *manager) +: m_manager(manager) +{ +} + +server_channel_handler::~server_channel_handler() +{ +} + +void server_channel_handler::connected(channel *ch) +{ +} + +void server_channel_handler::disconnected(channel *ch) +{ +} + +void server_channel_handler::read(channel *ch, message &msg) +{ + int err = -EINVAL; + + switch (msg.type()) { + case CMD_MANAGER_SENSOR_LIST: + err = manager_get_sensor_list(ch, msg); break; + case CMD_LISTENER_CONNECT: + err = listener_connect(ch, msg); break; + case CMD_LISTENER_DISCONNECT: + err = listener_disconnect(ch, msg); break; + case CMD_LISTENER_START: + 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_GET_DATA: + err = listener_get_data(ch, msg); break; + case CMD_PROVIDER_CONNECT: + err = provider_connect(ch, msg); break; + case CMD_PROVIDER_DISCONNECT: + err = provider_disconnect(ch, msg); break; + case CMD_PROVIDER_POST: + err = provider_post(ch, msg); break; + default: break; + } + + if (err != 0) { + message reply(err); + ch->send_sync(&reply); + } +} + +int server_channel_handler::manager_get_sensor_list(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_connect(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_disconnect(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_start(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_stop(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_attr_int(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_attr_str(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::listener_get_data(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::provider_connect(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::provider_disconnect(channel *ch, message &msg) +{ + return OP_ERROR; +} + +int server_channel_handler::provider_post(channel *ch, message &msg) +{ + return OP_ERROR; +} diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h new file mode 100644 index 0000000..76ea4a3 --- /dev/null +++ b/src/server/server_channel_handler.h @@ -0,0 +1,65 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SERVER_CHANNEL_HANDLER_H__ +#define __SERVER_CHANNEL_HANDLER_H__ + +#include +#include +#include +#include + +#include "sensor_manager.h" + +namespace sensor { + +/* TODO: this class seems to be able to split */ +class server_channel_handler : public ipc::channel_handler +{ +public: + server_channel_handler(sensor_manager *manager); + ~server_channel_handler(); + + void connected(ipc::channel *ch); + void disconnected(ipc::channel *ch); + void read(ipc::channel *ch, ipc::message &msg); + void read_complete(ipc::channel *ch) {} + void error_caught(ipc::channel *ch, int error) {} + +private: + int manager_get_sensor_list(ipc::channel *ch, ipc::message &msg); + + int listener_connect(ipc::channel *ch, ipc::message &msg); + 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_get_data(ipc::channel *ch, ipc::message &msg); + + int provider_connect(ipc::channel *ch, ipc::message &msg); + int provider_disconnect(ipc::channel *ch, ipc::message &msg); + int provider_post(ipc::channel *ch, ipc::message &msg); + + sensor_manager *m_manager; +}; + +} + +#endif /* __SERVER_CHANNEL_HANDLER_H__ */ -- 2.7.4 From 98bc10f25673e914b73f571e5c0bc984f10b8624 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 19:54:34 +0900 Subject: [PATCH 09/16] sensord: add sensor_publisher and sensor_observer interfaces - observer pattern Change-Id: I7c0f859a48faca21f1cf51fede816cc84c9b016e Signed-off-by: kibak.yoon --- src/server/sensor_observer.h | 37 +++++++++++++++++++++++++++++++++++++ src/server/sensor_publisher.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/server/sensor_observer.h create mode 100644 src/server/sensor_publisher.h diff --git a/src/server/sensor_observer.h b/src/server/sensor_observer.h new file mode 100644 index 0000000..ee04c20 --- /dev/null +++ b/src/server/sensor_observer.h @@ -0,0 +1,37 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_OBSERVER_H__ +#define __SENSOR_OBSERVER_H__ + +#include + +namespace sensor { + +class sensor_observer { +public: + virtual ~sensor_observer() {} + + /* for performance, use message */ + virtual int update(const char *uri, ipc::message *msg) = 0; +}; + +} + +#endif /* __SENSOR_OBSERVER_H__ */ diff --git a/src/server/sensor_publisher.h b/src/server/sensor_publisher.h new file mode 100644 index 0000000..58bb996 --- /dev/null +++ b/src/server/sensor_publisher.h @@ -0,0 +1,41 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_PUBLISHER_H__ +#define __SENSOR_PUBLISHER_H__ + +#include + +namespace sensor { + +class sensor_observer; + +class sensor_publisher { +public: + virtual ~sensor_publisher() {} + + virtual bool has_observer(sensor_observer *ob) = 0; + virtual void add_observer(sensor_observer *ob) = 0; + virtual void remove_observer(sensor_observer *ob) = 0; + virtual int notify(const char *type, sensor_data_t *data, int len) = 0; +}; + +} + +#endif /* __SENSOR_PUBLISHER_H__ */ -- 2.7.4 From bed2c7f2284884c7672193c6a028e6463b9693de Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 16:45:06 +0900 Subject: [PATCH 10/16] sensord: implement sensor_handler class - sensor_handler has: - a common logic of publisher - sensor control interface Change-Id: Ifbc32db62b96996d01041f6b7855b07ae07115b0 Signed-off-by: kibak.yoon --- src/server/sensor_handler.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++ src/server/sensor_handler.h | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/server/sensor_handler.cpp create mode 100644 src/server/sensor_handler.h diff --git a/src/server/sensor_handler.cpp b/src/server/sensor_handler.cpp new file mode 100644 index 0000000..e567c22 --- /dev/null +++ b/src/server/sensor_handler.cpp @@ -0,0 +1,70 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include "sensor_handler.h" + +using namespace sensor; + +bool sensor_handler::has_observer(sensor_observer *ob) +{ + for (auto it = m_observers.begin(); it != m_observers.end(); ++it) { + if ((*it) == ob) + return true; + } + + return false; +} + +void sensor_handler::add_observer(sensor_observer *ob) +{ + ret_if(has_observer(ob)); + + m_observers.push_back(ob); +} + +void sensor_handler::remove_observer(sensor_observer *ob) +{ + m_observers.remove(ob); +} + +int sensor_handler::notify(const char *uri, sensor_data_t *data, int len) +{ + if (observer_count() == 0) + return OP_ERROR; + + ipc::message *msg; + + 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) + (*it)->update(uri, msg); + + if (msg->ref_count() == 0) + msg->unref(); + + return OP_SUCCESS; +} + +uint32_t sensor_handler::observer_count(void) +{ + return m_observers.size(); +} diff --git a/src/server/sensor_handler.h b/src/server/sensor_handler.h new file mode 100644 index 0000000..68672ab --- /dev/null +++ b/src/server/sensor_handler.h @@ -0,0 +1,60 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __SENSOR_HANDLER_H__ +#define __SENSOR_HANDLER_H__ + +#include +#include +#include +#include +#include + +namespace sensor { + +class sensor_handler : public sensor_publisher { +public: + virtual ~sensor_handler() {} + + /* publisher */ + bool has_observer(sensor_observer *ob); + void add_observer(sensor_observer *ob); + void remove_observer(sensor_observer *ob); + int notify(const char *type, sensor_data_t *data, int len); + uint32_t observer_count(void); + + virtual const sensor_info &get_sensor_info(void) = 0; + + virtual int start(sensor_observer *ob) = 0; + virtual int stop(sensor_observer *ob) = 0; + + virtual int set_interval(sensor_observer *ob, int32_t interval) = 0; + virtual int set_batch_latency(sensor_observer *ob, int32_t latency) = 0; + virtual int set_attribute(sensor_observer *ob, int32_t attr, int32_t value) = 0; + virtual int set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) = 0; + virtual int get_data(sensor_data_t **data, int *len) = 0; + virtual int flush(void) = 0; + +private: + std::list m_observers; +}; + +} + +#endif /* __SENSOR_HANDLER_H__ */ -- 2.7.4 From dafee1429b30bd0c744fdf4cbaab56ffda38019c Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 16:58:05 +0900 Subject: [PATCH 11/16] sensord: add physical_sensor/fusion_sensor/external_sensor interfaces - add sensor information structure(sensor_info2_t).. Change-Id: I9daca248bc3671b77c3f37c8547575a9ab2903f5 Signed-off-by: kibak.yoon --- include/external_sensor.h | 111 +++++++++++++++++++++++++++++++++++++++++ include/fusion_sensor.h | 104 ++++++++++++++++++++++++++++++++++++++ include/physical_sensor.h | 96 +++++++++++++++++++++++++++++++++++ include/sensor_types.h | 14 ++++++ src/server/physical_sensor.cpp | 29 ----------- src/server/physical_sensor.h | 29 ----------- src/server/server.h | 1 - src/server/virtual_sensor.cpp | 28 ----------- src/server/virtual_sensor.h | 29 ----------- src/shared/sensor_info.cpp | 27 +++++++++- src/shared/sensor_info.h | 1 + 11 files changed, 352 insertions(+), 117 deletions(-) create mode 100644 include/external_sensor.h create mode 100644 include/fusion_sensor.h create mode 100644 include/physical_sensor.h delete mode 100644 src/server/physical_sensor.cpp delete mode 100644 src/server/physical_sensor.h delete mode 100644 src/server/virtual_sensor.cpp delete mode 100644 src/server/virtual_sensor.h diff --git a/include/external_sensor.h b/include/external_sensor.h new file mode 100644 index 0000000..d34cf96 --- /dev/null +++ b/include/external_sensor.h @@ -0,0 +1,111 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __EXTERNAL_SENSOR_H__ +#define __EXTERNAL_SENSOR_H__ + +#include +#include +#include +#include + +#ifndef EXTERNAL_SENSOR_VERSION +#define EXTERNAL_SENSOR_VERSION(maj, min) \ + ((((maj) & 0xFFFF) << 24) | ((min) & 0xFFFF)) +#endif + +#ifndef OP_SUCCESS +#define OP_SUCCESS 0 +#endif +#ifndef OP_ERROR +#define OP_ERROR -1 +#endif +#ifndef OP_DEFAULT +#define OP_DEFAULT 1 +#endif + +/* + * Create sensor + */ +typedef void *external_sensor_t; +typedef int (*create_external_t)(external_sensor_t **sensors); + +typedef void *observer_h; + +/* + * Sensor event notifier + * External Sensor has to call notify() function if data is ready. + */ +class sensor_notifier { +public: + virtual ~sensor_notifier() {} + + virtual int notify(void) = 0; +}; + +/* + * Sensor interface + */ +class external_sensor { +public: + virtual ~external_sensor() {} + + inline uint32_t get_version(void) { return EXTERNAL_SENSOR_VERSION(1, 0); } + + virtual int get_sensors(const sensor_info2_t **sensors) = 0; + virtual void set_notifier(sensor_notifier *notifier) = 0; + virtual int get_data(sensor_data_t **data, int *len) = 0; + + virtual int start(observer_h ob) + { + return OP_DEFAULT; + } +; + virtual int stop(observer_h ob) + { + return OP_DEFAULT; + } + + virtual int set_interval(observer_h ob, int32_t &interval) + { + return OP_DEFAULT; + } + + virtual int set_batch_latency(observer_h ob, int32_t &latency) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, int32_t value) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, const char *value, int len) + { + return OP_DEFAULT; + } + + virtual int flush(observer_h ob) + { + return OP_DEFAULT; + } +}; + +#endif /* __EXTERNAL_SENSOR_H__ */ diff --git a/include/fusion_sensor.h b/include/fusion_sensor.h new file mode 100644 index 0000000..6fa6d09 --- /dev/null +++ b/include/fusion_sensor.h @@ -0,0 +1,104 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FUSION_SENSOR_H__ +#define __FUSION_SENSOR_H__ + +#include +#include +#include +#include +#include + +#ifndef FUSION_SENSOR_VERSION +#define FUSION_SENSOR_VERSION(maj, min) \ + ((((maj) & 0xFFFF) << 24) | ((min) & 0xFFFF)) +#endif + +#ifndef OP_SUCCESS +#define OP_SUCCESS 0 +#endif +#ifndef OP_ERROR +#define OP_ERROR -1 +#endif +#ifndef OP_DEFAULT +#define OP_DEFAULT 1 +#endif + +/* + * Create sensor + */ +typedef void *fusion_sensor_t; +typedef int (*create_fusion_t)(fusion_sensor_t **sensors); + +typedef void *observer_h; + +/* + * Sensor interface + */ +class fusion_sensor { +public: + virtual ~fusion_sensor() {} + + inline uint32_t get_version(void) { return FUSION_SENSOR_VERSION(1, 0); } + + virtual int get_sensors(const sensor_info2_t **sensors) = 0; + virtual void get_required_sensors(std::vector &sensors) = 0; + + /* if update() returns positive value, then get_data() is called */ + virtual int update(const char *uri, sensor_data_t *data, int len) = 0; + virtual int get_data(sensor_data_t **data, int *len) = 0; + + virtual int start(observer_h ob) + { + return OP_DEFAULT; + } +; + virtual int stop(observer_h ob) + { + return OP_DEFAULT; + } + + virtual int set_interval(observer_h ob, int32_t &interval) + { + return OP_DEFAULT; + } + + virtual int set_batch_latency(observer_h ob, int32_t &latency) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, int32_t value) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, const char *value, int len) + { + return OP_DEFAULT; + } + + virtual int flush(observer_h ob) + { + return OP_DEFAULT; + } +}; + +#endif /* __FUSION_SENSOR_H__ */ diff --git a/include/physical_sensor.h b/include/physical_sensor.h new file mode 100644 index 0000000..6009167 --- /dev/null +++ b/include/physical_sensor.h @@ -0,0 +1,96 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __PHYSICAL_SENSOR_H__ +#define __PHYSICAL_SENSOR_H__ + +#include +#include +#include +#include + +#ifndef SENSOR_VERSION +#define PHYSICAL_SENSOR_VERSION(maj, min) \ + ((((maj) & 0xFFFF) << 24) | ((min) & 0xFFFF)) +#endif + +#ifndef OP_SUCCESS +#define OP_SUCCESS 1 +#endif +#ifndef OP_ERROR +#define OP_ERROR -1 +#endif +#ifndef OP_DEFAULT +#define OP_DEFAULT 1 +#endif + +/* + * Create sensor + */ +typedef void *physical_sensor_t; +typedef int (*create_physical_t)(physical_sensor_t **sensors); + +typedef void *observer_h; + +/* + * Sensor interface + */ +class physical_sensor { +public: + virtual ~physical_sensor() {} + + inline uint32_t get_version(void) { return PHYSICAL_SENSOR_VERSION(1, 0); } + + /* TODO */ + virtual std::string get_privilege(void) { return ""; } + + virtual int start(observer_h ob) = 0; + virtual int stop(observer_h ob) = 0; + virtual int set_interval(observer_h ob, uint32_t interval) + { + return OP_DEFAULT; + } + + virtual int set_batch_latency(observer_h ob, uint32_t latency) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, int32_t value) + { + return OP_DEFAULT; + } + + virtual int set_attribute(observer_h ob, int32_t attr, const char *value, int len) + { + return OP_DEFAULT; + } + + virtual int flush(observer_h ob) + { + return OP_DEFAULT; + } + + virtual int on_event(sensor_data_t *data, int32_t len, int32_t remains) + { + return OP_DEFAULT; + } +}; + +#endif /* __PHYSICAL_SENSOR_H__ */ diff --git a/include/sensor_types.h b/include/sensor_types.h index 2253a29..3da9cfc 100644 --- a/include/sensor_types.h +++ b/include/sensor_types.h @@ -164,6 +164,20 @@ typedef enum sensor_type_t { CUSTOM_SENSOR = 0X9000, } sensor_type_t; +typedef struct sensor_info2_t { + uint32_t id; + sensor_type_t type; + const char *uri; + const char *vendor; + float min_range; + float max_range; + float resolution; + int min_interval; + int max_batch_count; + bool wakeup_supported; + const char *privilege; + void *reserved[8]; +} sensor_info2_t; typedef enum sensor_permission_t { SENSOR_PERMISSION_NONE = 0, diff --git a/src/server/physical_sensor.cpp b/src/server/physical_sensor.cpp deleted file mode 100644 index f1943f6..0000000 --- a/src/server/physical_sensor.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -physical_sensor::physical_sensor() -{ -} - -physical_sensor::~physical_sensor() -{ -} - diff --git a/src/server/physical_sensor.h b/src/server/physical_sensor.h deleted file mode 100644 index 669bbeb..0000000 --- a/src/server/physical_sensor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef _PHYSICAL_SENSOR_H_ -#define _PHYSICAL_SENSOR_H_ - -class physical_sensor { -public: - physical_sensor(); - virtual ~physical_sensor(); -}; - -#endif /* _PHYSICAL_SENSOR_H_ */ diff --git a/src/server/server.h b/src/server/server.h index b8bb2f6..98d99c1 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -24,7 +24,6 @@ #include #include #include -#include #include namespace sensor { diff --git a/src/server/virtual_sensor.cpp b/src/server/virtual_sensor.cpp deleted file mode 100644 index 59546b6..0000000 --- a/src/server/virtual_sensor.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "virtual_sensor.h" - -virtual_sensor::virtual_sensor() -{ -} - -virtual_sensor::~virtual_sensor() -{ -} diff --git a/src/server/virtual_sensor.h b/src/server/virtual_sensor.h deleted file mode 100644 index 745a0b4..0000000 --- a/src/server/virtual_sensor.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * sensord - * - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef _VIRTUAL_SENSOR_H_ -#define _VIRTUAL_SENSOR_H_ - -class virtual_sensor { -public: - virtual_sensor(); - virtual ~virtual_sensor(); -}; - -#endif /* _VIRTUAL_SENSOR_H_ */ diff --git a/src/shared/sensor_info.cpp b/src/shared/sensor_info.cpp index f634c50..808c07f 100644 --- a/src/shared/sensor_info.cpp +++ b/src/shared/sensor_info.cpp @@ -81,6 +81,31 @@ sensor_info::sensor_info(const sensor_info_t &info) set_permission(SENSOR_PERMISSION_STANDARD); } +sensor_info::sensor_info(const sensor_info2_t &info) +{ + std::string uri(info.uri); + std::size_t found = uri.find_last_of("/\\"); + + set_type(info.type); + set_type_uri(uri.substr(0, found).c_str()); + set_uri(uri.c_str()); + set_model(uri.substr(found + 1, uri.length()).c_str()); + set_vendor(info.vendor); + set_min_range(info.min_range); + set_max_range(info.max_range); + set_resolution(info.resolution); + set_min_interval(info.min_interval); + set_max_batch_count(info.max_batch_count); + set_wakeup_supported(info.wakeup_supported); + + /* TODO : store string just itself */ + std::string privilege = info.privilege; + if (privilege == "http://tizen.org/privilege/healthinfo") + set_permission(SENSOR_PERMISSION_HEALTH_INFO); + else + set_permission(SENSOR_PERMISSION_STANDARD); +} + sensor_type_t sensor_info::get_type(void) { return m_type; @@ -245,7 +270,7 @@ void sensor_info::deserialize(const char *data, int data_len) void sensor_info::show(void) { _I("Type = %s", m_type_uri.c_str()); - _I("Name = %s", m_uri.c_str()); + _I("URI = %s", m_uri.c_str()); _I("Model = %s", m_model.c_str()); _I("Vendor = %s", m_vendor.c_str()); _I("Min_range = %f", m_min_range); diff --git a/src/shared/sensor_info.h b/src/shared/sensor_info.h index 4fbabe8..93ae3aa 100644 --- a/src/shared/sensor_info.h +++ b/src/shared/sensor_info.h @@ -37,6 +37,7 @@ public: sensor_info(); sensor_info(const sensor_info &info); sensor_info(const sensor_info_t &info); + sensor_info(const sensor_info2_t &info); /* TODO: it would be better to get_type() returns type(URI) */ sensor_type_t get_type(void); -- 2.7.4 From c06b50771a5dab13af5398a17d0254d2dcd1477c Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 17:54:20 +0900 Subject: [PATCH 12/16] sensord: add loader to load sensor plugins - it loads sensor_device/physical_sensor/fusion_sensor/external_sensor Change-Id: Ia340e4041900d9a69a0553acc34473cf218a0f95 Signed-off-by: kibak.yoon --- src/server/sensor_loader.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++- src/server/sensor_loader.h | 33 +++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/src/server/sensor_loader.cpp b/src/server/sensor_loader.cpp index 7676f40..d46a5cf 100644 --- a/src/server/sensor_loader.cpp +++ b/src/server/sensor_loader.cpp @@ -1,7 +1,7 @@ /* * sensord * - * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,16 @@ #include "sensor_loader.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace sensor; + sensor_loader::sensor_loader() { } @@ -26,3 +36,103 @@ sensor_loader::sensor_loader() sensor_loader::~sensor_loader() { } + +void sensor_loader::load_hal(const std::string &path, device_sensor_registry_t &devices) +{ + load(path, devices); +} + +void sensor_loader::load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors) +{ + load(path, sensors); +} + +void sensor_loader::load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors) +{ + load(path, sensors); +} + +void sensor_loader::load_external_sensor(const std::string &path, external_sensor_registry_t &sensors) +{ + load(path, sensors); +} + +void sensor_loader::unload(void) +{ + for (auto it = m_modules.begin(); it != m_modules.end(); ++it) + dlclose(it->second); +} + +template +bool sensor_loader::load(const std::string &dir_path, std::vector> &sensors) +{ + bool ret; + void *handle; + std::vector module_paths; + void **results; + T *sensor; + + ret = get_module_paths(dir_path, module_paths); + retv_if(!ret, false); + + for (auto &path : module_paths) { + handle = dlopen(path.c_str(), RTLD_NOW); + retvm_if(!handle, false, "Failed to dlopen from %s because %s", path.c_str(), dlerror()); + + /* TODO: out-param of the create function should be const */ + create_t create = reinterpret_cast(dlsym(handle, "create")); + if (!create) { + _E("Failed to find symbols from %s", path.c_str()); + dlclose(handle); + return false; + } + + int size = create(&results); + if (size <= 0 || !results) { + _E("Failed to create sensors from %s", path.c_str()); + dlclose(handle); + return false; + } + + for (int i = 0; i < size; ++i) { + sensor = static_cast(results[i]); + std::shared_ptr sensor_ptr(sensor); + sensors.push_back(sensor_ptr); + } + + m_modules[path.c_str()] = handle; + } + + return true; +} + +bool sensor_loader::get_module_paths(const std::string &dir_path, std::vector &paths) +{ + int ret; + DIR *dir = NULL; + struct dirent entry; + struct dirent *result; + std::string filename; + + dir = opendir(dir_path.c_str()); + retvm_if(!dir, false, "Failed to open directory[%s]", dir_path.c_str()); + + while (true) { + ret = readdir_r(dir, &entry, &result); + + if (ret != 0) + continue; + if (!result) + break; + + filename = std::string(entry.d_name); + + if (filename == "." || filename == "..") + continue; + + paths.push_back(dir_path + "/" + filename); + } + closedir(dir); + + return true; +} diff --git a/src/server/sensor_loader.h b/src/server/sensor_loader.h index ab9b9b0..6aee6fe 100644 --- a/src/server/sensor_loader.h +++ b/src/server/sensor_loader.h @@ -20,10 +20,43 @@ #ifndef __SENSOR_LOADER_H__ #define __SENSOR_LOADER_H__ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sensor { + +typedef std::vector> device_sensor_registry_t; +typedef std::vector> physical_sensor_registry_t; +typedef std::vector> fusion_sensor_registry_t; +typedef std::vector> external_sensor_registry_t; + class sensor_loader { public: sensor_loader(); virtual ~sensor_loader(); + + void load_hal(const std::string &path, device_sensor_registry_t &devices); + void load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors); + void load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors); + void load_external_sensor(const std::string &path, external_sensor_registry_t &sensors); + + void unload(void); + +private: + template + bool load(const std::string &path, std::vector> &sensors); + + bool get_module_paths(const std::string &dir_path, std::vector &paths); + + std::map m_modules; }; +} + #endif /* __SENSOR_LOADER_H__ */ -- 2.7.4 From 4bda8c3cabb4d650d03cd4ae7ce83094afa65547 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:43:32 +0900 Subject: [PATCH 13/16] sensord: add physical_sensor_handler class - physical_sensor_handler provides: - controls for operating sensor HAL(sensor_device) - controls for operation policy Change-Id: I4c5d6b2d99847485ffd8beec1a9634b20ce45e71 Signed-off-by: kibak.yoon --- src/server/physical_sensor_handler.cpp | 286 +++++++++++++++++++++++++++++++++ src/server/physical_sensor_handler.h | 73 +++++++++ 2 files changed, 359 insertions(+) create mode 100644 src/server/physical_sensor_handler.cpp create mode 100644 src/server/physical_sensor_handler.h diff --git a/src/server/physical_sensor_handler.cpp b/src/server/physical_sensor_handler.cpp new file mode 100644 index 0000000..00cf361 --- /dev/null +++ b/src/server/physical_sensor_handler.cpp @@ -0,0 +1,286 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "physical_sensor_handler.h" + +#include +#include +#include +#include + +using namespace sensor; + +physical_sensor_handler::physical_sensor_handler(const sensor_info &info, + sensor_device *device, int hal_id, + physical_sensor *sensor) +: m_info(info) +, m_device(device) +, m_sensor(sensor) +, m_hal_id(hal_id) +{ +} + +physical_sensor_handler::~physical_sensor_handler() +{ +} + +const sensor_info &physical_sensor_handler::get_sensor_info(void) +{ + return m_info; +} + +int physical_sensor_handler::get_hal_id(void) +{ + return m_hal_id; +} + +int physical_sensor_handler::get_poll_fd(void) +{ + retv_if(!m_device, -EINVAL); + + return m_device->get_poll_fd(); +} + +int physical_sensor_handler::read_fd(std::vector &ids) +{ + int size; + uint32_t *_ids; + + retv_if(!m_device, -EINVAL); + + size = m_device->read_fd(&_ids); + retv_if(size == 0, -ENODATA); + + for (int i = 0; i < size; ++i) + ids.push_back(_ids[i]); + + return OP_SUCCESS; +} + +int physical_sensor_handler::on_event(const sensor_data_t *data, int32_t len, int32_t remains) +{ + retv_if(!m_device, -EINVAL); + + if (m_sensor) { + int ret = m_sensor->on_event(const_cast(data), len, remains); + retv_if(ret <= OP_ERROR, ret); + } + + return OP_SUCCESS; +} +int physical_sensor_handler::start(sensor_observer *ob) +{ + retv_if(!m_device, -EINVAL); + + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->start(ob); + retv_if(policy <= OP_ERROR, policy); + } + + add_observer(ob); + + if (policy == OP_DEFAULT) { + if (observer_count() > 1) + return OP_SUCCESS; /* already started */ + } + + return m_device->enable(m_hal_id); +} + +int physical_sensor_handler::stop(sensor_observer *ob) +{ + retv_if(!m_device, -EINVAL); + + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->stop(ob); + retv_if(policy <= OP_ERROR, policy); + } + + remove_observer(ob); + + if (policy == OP_DEFAULT) { + if (observer_count() >= 1) + return OP_SUCCESS; /* already stopped */ + } + + return m_device->disable(m_hal_id); +} + +int physical_sensor_handler::get_min_interval(void) +{ + int interval; + std::vector temp; + + for (auto it = m_interval_map.begin(); it != m_interval_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return m_info.get_min_interval(); + + interval = *std::min_element(temp.begin(), temp.end()); + + if (interval < m_info.get_min_interval()) + return m_info.get_min_interval(); + + return interval; +} + +int physical_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) +{ + retv_if(!m_device, -EINVAL); + + bool ret = false; + int _interval = interval; + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->set_interval(ob, interval); + retv_if(policy <= OP_ERROR, policy); + } + + m_interval_map[ob] = interval; + + if (policy == OP_DEFAULT) + _interval = get_min_interval(); + + ret = m_device->set_interval(m_hal_id, _interval); + + return (ret ? OP_SUCCESS : OP_SUCCESS); +} + +int physical_sensor_handler::get_min_batch_latency(void) +{ + int batch_latency; + std::vector temp; + + for (auto it = m_batch_latency_map.begin(); it != m_batch_latency_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return 0; + + batch_latency = *std::min_element(temp.begin(), temp.end()); + + return batch_latency; +} + +int physical_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latency) +{ + retv_if(!m_device, -EINVAL); + + bool ret = false; + int _latency = latency; + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->set_batch_latency(ob, latency); + retv_if(policy <= OP_ERROR, policy); + } + + m_batch_latency_map[ob] = _latency; + + if (_latency <= latency) + return OP_SUCCESS; + + ret = m_device->set_batch_latency(m_hal_id, _latency); + + return (ret ? OP_SUCCESS : OP_SUCCESS); +} + +int physical_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value) +{ + retv_if(!m_device, -EINVAL); + + bool ret = false; + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->set_attribute(ob, attr, value); + retv_if(policy <= OP_ERROR, policy); + } + + /* + * TODO: default policy for attribute? + if (policy == OP_DEFAULT) { + if (observer_count() > 1) + return OP_SUCCESS; + } + */ + + ret = m_device->set_attribute_int(m_hal_id, attr, value); + + return (ret ? OP_SUCCESS : OP_SUCCESS); +} + +int physical_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) +{ + retv_if(!m_device, -EINVAL); + + bool ret = false; + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->set_attribute(ob, attr, value, len); + retv_if(policy <= OP_ERROR, policy); + } + + /* + * TODO: default policy for attribute? + if (policy == OP_DEFAULT) { + if (observer_count() > 1) + return OP_SUCCESS; + } + */ + + ret = m_device->set_attribute_str(m_hal_id, attr, const_cast(value), len); + + return (ret ? OP_SUCCESS : OP_SUCCESS); +} + +int physical_sensor_handler::flush(sensor_observer *ob) +{ + retv_if(!m_device, -EINVAL); + int ret = false; + + if (m_sensor) { + ret = m_sensor->flush(ob); + retv_if(ret <= OP_ERROR, ret); + } + + ret = m_device->flush(m_hal_id); + + return (ret ? OP_SUCCESS : OP_ERROR); +} + +int physical_sensor_handler::get_data(sensor_data_t **data, int *len) +{ + retv_if(!m_device, -EINVAL); + + int remains = m_device->get_data(m_hal_id, data, len); + retvm_if(*len <= 0, OP_ERROR, "Failed to get sensor event"); + + return remains; +} + diff --git a/src/server/physical_sensor_handler.h b/src/server/physical_sensor_handler.h new file mode 100644 index 0000000..1983dbd --- /dev/null +++ b/src/server/physical_sensor_handler.h @@ -0,0 +1,73 @@ +/* + * sensord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __PHYSICAL_SENSOR_HANDLER_H__ +#define __PHYSICAL_SENSOR_HANDLER_H__ + +#include +#include +#include + +#include "sensor_handler.h" +#include "sensor_observer.h" + +namespace sensor { + +class physical_sensor_handler : public sensor_handler { +public: + physical_sensor_handler(const sensor_info &info, + sensor_device *device, int hal_id, + physical_sensor *sensor); + virtual ~physical_sensor_handler(); + + /* functions for sensor device(HAL) */ + int get_hal_id(void); + int get_poll_fd(void); + int read_fd(std::vector &hal_ids); + int on_event(const sensor_data_t *data, int32_t len, int32_t remains); + + /* sensor interface */ + const sensor_info &get_sensor_info(void); + + int start(sensor_observer *ob); + int stop(sensor_observer *ob); + + int set_interval(sensor_observer *ob, int32_t interval); + int set_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); + int get_data(sensor_data_t **data, int *len); + +private: + int get_min_interval(void); + int get_min_batch_latency(void); + + sensor_info m_info; + sensor_device *m_device; + physical_sensor *m_sensor; + int m_hal_id; + + std::unordered_map m_interval_map; + std::unordered_map m_batch_latency_map; +}; + +} + +#endif /* __PHYSICAL_SENSOR_HANDLER_H__ */ -- 2.7.4 From 31c592d8d53d9b4bb450d61694a64bc722e3593d Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:45:57 +0900 Subject: [PATCH 14/16] sensord: add fusion_sensor_handler class - fusion_sensor_handler provides: - sensor information - controls for operating required sensors - controls for operation policy Change-Id: Id1f6d7d6dce67611a00c5f9e2880f4d2178cb145 Signed-off-by: kibak.yoon --- src/server/fusion_sensor_handler.cpp | 292 +++++++++++++++++++++++++++++++++++ src/server/fusion_sensor_handler.h | 79 ++++++++++ 2 files changed, 371 insertions(+) create mode 100644 src/server/fusion_sensor_handler.cpp create mode 100644 src/server/fusion_sensor_handler.h diff --git a/src/server/fusion_sensor_handler.cpp b/src/server/fusion_sensor_handler.cpp new file mode 100644 index 0000000..44c794a --- /dev/null +++ b/src/server/fusion_sensor_handler.cpp @@ -0,0 +1,292 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "fusion_sensor_handler.h" + +#include +#include +#include + +using namespace sensor; + +fusion_sensor_handler::fusion_sensor_handler(const sensor_info &info, + fusion_sensor *sensor) +: m_info(info) +, m_sensor(sensor) +, m_policy(OP_DEFAULT) +{ +} + +fusion_sensor_handler::~fusion_sensor_handler() +{ +} + +void fusion_sensor_handler::add_required_sensor(sensor_handler *sensor) +{ + m_required_sensors.push_back(sensor); +} + +int fusion_sensor_handler::update(const char *uri, ipc::message *msg) +{ + retv_if(!m_sensor, -EINVAL); + + if (m_sensor->update(uri, (sensor_data_t *)msg->body(), msg->size()) < 0) + return OP_SUCCESS; + + sensor_data_t *data; + int len; + + if (m_sensor->get_data(&data, &len) < 0) + return OP_ERROR; + + std::string fsensor_uri = m_info.get_type_uri(); + + return notify(fsensor_uri.c_str(), data, len); +} + +const sensor_info &fusion_sensor_handler::get_sensor_info(void) +{ + return m_info; +} + +int fusion_sensor_handler::start(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = OP_DEFAULT; + + policy = m_sensor->start(ob); + retv_if(policy <= OP_ERROR, policy); + + add_observer(ob); + + if (policy == OP_DEFAULT) { + if (observer_count() > 1) + return OP_SUCCESS; + } + + return start_internal(); +} + +int fusion_sensor_handler::stop(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = OP_DEFAULT; + + policy = m_sensor->stop(ob); + retv_if(policy <= OP_ERROR, policy); + + remove_observer(ob); + + if (policy == OP_DEFAULT) { + if (observer_count() >= 1) + return OP_SUCCESS; /* already started */ + } + + return stop_internal(); +} + +int fusion_sensor_handler::get_min_interval(void) +{ + int interval; + std::vector temp; + + for (auto it = m_interval_map.begin(); it != m_interval_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return m_info.get_min_interval(); + + interval = *std::min_element(temp.begin(), temp.end()); + + if (interval < m_info.get_min_interval()) + return m_info.get_min_interval(); + + return interval; +} + +int fusion_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) +{ + retv_if(!m_sensor, -EINVAL); + + int _interval = interval; + int policy = OP_DEFAULT; + + policy = m_sensor->set_interval(ob, _interval); + retv_if(policy <= OP_ERROR, policy); + + m_interval_map[ob] = interval; + + if (policy == OP_DEFAULT) + _interval = get_min_interval(); + + return set_interval_internal(_interval); +} + +int fusion_sensor_handler::get_min_batch_latency(void) +{ + int batch_latency; + std::vector temp; + + for (auto it = m_batch_latency_map.begin(); it != m_batch_latency_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return 0; + + batch_latency = *std::min_element(temp.begin(), temp.end()); + + return batch_latency; +} + +int fusion_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latency) +{ + retv_if(!m_sensor, -EINVAL); + + int _latency = latency; + int policy = OP_DEFAULT; + + if (m_sensor) { + policy = m_sensor->set_batch_latency(ob, _latency); + retv_if(policy <= OP_ERROR, policy); + } + + m_batch_latency_map[ob] = _latency; + + if (policy == OP_DEFAULT) + _latency = get_min_batch_latency(); + + return set_batch_latency_internal(_latency); +} + +int fusion_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = OP_DEFAULT; + + policy = m_sensor->set_attribute(ob, attr, value); + retv_if(policy <= OP_ERROR, policy); + + if (m_policy == OP_DEFAULT) { + /* default logic */ + } + + return set_attribute_internal(attr, value); +} + +int fusion_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = OP_DEFAULT; + + policy = m_sensor->set_attribute(ob, attr, value, len); + retv_if(policy <= OP_ERROR, policy); + + if (m_policy == OP_DEFAULT) { + /* default logic */ + } + + return set_attribute_internal(attr, value, len); +} + +int fusion_sensor_handler::get_data(sensor_data_t **data, int *len) +{ + /* TODO */ + return OP_SUCCESS; +} + +int fusion_sensor_handler::flush(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + m_sensor->flush(this); + + return OP_SUCCESS; +} + +int fusion_sensor_handler::start_internal(void) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->start(this) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} + +int fusion_sensor_handler::stop_internal(void) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->stop(this) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} + +int fusion_sensor_handler::set_interval_internal(int32_t interval) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->set_interval(this, interval) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} + +int fusion_sensor_handler::set_batch_latency_internal(int32_t latency) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->set_batch_latency(this, latency) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} + +int fusion_sensor_handler::set_attribute_internal(int32_t attr, int32_t value) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->set_attribute(this, attr, value) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} + +int fusion_sensor_handler::set_attribute_internal(int32_t attr, const char *value, int len) +{ + int size = m_required_sensors.size(); + for (int i = 0; i < size; ++i) { + if (m_required_sensors[i]->set_attribute(this, attr, value, len) < 0) + return OP_ERROR; + } + + return OP_SUCCESS; +} diff --git a/src/server/fusion_sensor_handler.h b/src/server/fusion_sensor_handler.h new file mode 100644 index 0000000..d16278f --- /dev/null +++ b/src/server/fusion_sensor_handler.h @@ -0,0 +1,79 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FUSION_SENSOR_HANDLER_H__ +#define __FUSION_SENSOR_HANDLER_H__ + +#include +#include +#include +#include + +#include "sensor_handler.h" +#include "sensor_observer.h" + +namespace sensor { + +class fusion_sensor_handler : public sensor_handler, public sensor_observer { +public: + fusion_sensor_handler(const sensor_info &info, + fusion_sensor *sensor); + ~fusion_sensor_handler(); + + void add_required_sensor(sensor_handler *sensor); + + /* subscriber */ + int update(const char *uri, ipc::message *msg); + + /* sensor interface */ + const sensor_info &get_sensor_info(void); + + int start(sensor_observer *ob); + int stop(sensor_observer *ob); + + int set_interval(sensor_observer *ob, int32_t interval); + int set_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); + int get_data(sensor_data_t **data, int *len); + +private: + int start_internal(void); + int stop_internal(void); + int set_interval_internal(int32_t interval); + int set_batch_latency_internal(int32_t latency); + int set_attribute_internal(int32_t attr, int32_t value); + int set_attribute_internal(int32_t attr, const char *value, int len); + + int get_min_interval(void); + int get_min_batch_latency(void); + + sensor_info m_info; + fusion_sensor *m_sensor; + std::vector m_required_sensors; + + std::unordered_map m_interval_map; + std::unordered_map m_batch_latency_map; + int m_policy; +}; + +} + +#endif /* __FUSION_SENSOR_HANDLER_H__ */ -- 2.7.4 From 551f945381ec727b27f23b77787635d9670d227b Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:47:29 +0900 Subject: [PATCH 15/16] sensord: add external_sensor_handler class - external_sensor_handler provides: - controls for operating external_sensor - controls for operation policy - listening event from notifier and notify it to observers Change-Id: I3213c7798873833b8bb5e0307275fd2a3bd52bf6 Signed-off-by: kibak.yoon --- src/server/external_sensor_handler.cpp | 236 +++++++++++++++++++++++++++++++++ src/server/external_sensor_handler.h | 69 ++++++++++ 2 files changed, 305 insertions(+) create mode 100644 src/server/external_sensor_handler.cpp create mode 100644 src/server/external_sensor_handler.h diff --git a/src/server/external_sensor_handler.cpp b/src/server/external_sensor_handler.cpp new file mode 100644 index 0000000..110e15b --- /dev/null +++ b/src/server/external_sensor_handler.cpp @@ -0,0 +1,236 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "external_sensor_handler.h" + +#include +#include +#include +#include + +using namespace sensor; + +class external_sensor_notifier : public sensor_notifier { +public: + external_sensor_notifier(external_sensor_handler *sensor); + + int notify(void); + +private: + external_sensor_handler *m_sensor; +}; + +external_sensor_notifier::external_sensor_notifier(external_sensor_handler *sensor) +: m_sensor(sensor) +{ +} + +int external_sensor_notifier::notify(void) +{ + /* TODO: Change thread-safe function(add handler to event-loop) */ + sensor_data_t *data; + int len; + + if (m_sensor->get_data(&data, &len) < 0) + return OP_ERROR; + + /* TODO: pointer would be better */ + sensor_info info = m_sensor->get_sensor_info(); + std::string uri = info.get_type_uri(); + + return m_sensor->notify(uri.c_str(), data, len); +} + +external_sensor_handler::external_sensor_handler(const sensor_info &info, + external_sensor *sensor) +: m_info(info) +, m_sensor(sensor) +, m_notifier(NULL) +{ + init(); +} + +external_sensor_handler::~external_sensor_handler() +{ + deinit(); +} + +bool external_sensor_handler::init(void) +{ + m_notifier = new(std::nothrow) external_sensor_notifier(this); + retvm_if(!m_notifier, false, "Failed to allocate memory"); + + m_sensor->set_notifier(m_notifier); + return true; +} + +void external_sensor_handler::deinit(void) +{ + delete m_notifier; + m_notifier = NULL; +} + +const sensor_info &external_sensor_handler::get_sensor_info(void) +{ + return m_info; +} + +int external_sensor_handler::start(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = m_sensor->start(ob); + retv_if(policy <= OP_ERROR, policy); + + return OP_SUCCESS; +} + +int external_sensor_handler::stop(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + int policy = m_sensor->stop(ob); + retv_if(policy <= OP_ERROR, policy); + + remove_observer(ob); + + return OP_SUCCESS; +} + +int external_sensor_handler::get_min_interval(void) +{ + int interval; + std::vector temp; + + for (auto it = m_interval_map.begin(); it != m_interval_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return m_info.get_min_interval(); + + interval = *std::min_element(temp.begin(), temp.end()); + + if (interval < m_info.get_min_interval()) + return m_info.get_min_interval(); + + return interval; +} + +int external_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) +{ + retv_if(!m_sensor, -EINVAL); + + int _interval = interval; + + if ((m_policy == OP_DEFAULT && observer_count() == 0) || m_policy == OP_SUCCESS) { + m_policy = m_sensor->set_interval(ob, interval); + retv_if(m_policy <= OP_ERROR, m_policy); + } + + m_interval_map[ob] = interval; + + if (m_policy == OP_DEFAULT && observer_count() > 0) { + _interval = get_min_interval(); + return m_sensor->set_interval(ob, _interval); + } + + return OP_SUCCESS; +} + +int external_sensor_handler::get_min_batch_latency(void) +{ + int batch_latency; + std::vector temp; + + for (auto it = m_batch_latency_map.begin(); it != m_batch_latency_map.end(); ++it) + if (it->second > 0) + temp.push_back(it->second); + + if (temp.empty()) + return 0; + + batch_latency = *std::min_element(temp.begin(), temp.end()); + + return batch_latency; +} + +int external_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latency) +{ + retv_if(!m_sensor, -EINVAL); + + int _latency = latency; + + if ((m_policy == OP_DEFAULT && observer_count() == 0) || m_policy == OP_SUCCESS) { + m_policy = m_sensor->set_batch_latency(ob, latency); + retv_if(m_policy <= OP_ERROR, m_policy); + } + + m_batch_latency_map[ob] = _latency; + + if (m_policy == OP_DEFAULT && observer_count() > 0) { + _latency = get_min_batch_latency(); + return m_sensor->set_batch_latency(ob, latency); + } + return OP_SUCCESS; +} + +int external_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value) +{ + retv_if(!m_sensor, -EINVAL); + + if ((m_policy == OP_DEFAULT && observer_count() == 0) || m_policy == OP_SUCCESS) { + m_policy = m_sensor->set_attribute(ob, attr, value); + retv_if(m_policy <= OP_ERROR, m_policy); + } + + if (m_policy == OP_DEFAULT) { + /* default logic */ + } + return OP_SUCCESS; +} + +int external_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) +{ + retv_if(!m_sensor, -EINVAL); + + if ((m_policy == OP_DEFAULT && observer_count() == 0) || m_policy == OP_SUCCESS) { + m_policy = m_sensor->set_attribute(ob, attr, value, len); + retv_if(m_policy <= OP_ERROR, m_policy); + } + + if (m_policy == OP_DEFAULT) { + /* default logic */ + } + return OP_SUCCESS; +} + +int external_sensor_handler::get_data(sensor_data_t **data, int *len) +{ + return m_sensor->get_data(data, len); +} + +int external_sensor_handler::flush(sensor_observer *ob) +{ + retv_if(!m_sensor, -EINVAL); + + m_sensor->flush(this); + + return OP_SUCCESS; +} diff --git a/src/server/external_sensor_handler.h b/src/server/external_sensor_handler.h new file mode 100644 index 0000000..6fe386a --- /dev/null +++ b/src/server/external_sensor_handler.h @@ -0,0 +1,69 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __EXTERNAL_SENSOR_HANDLER_H__ +#define __EXTERNAL_SENSOR_HANDLER_H__ + +#include +#include +#include +#include + +#include "sensor_handler.h" + +namespace sensor { + +class external_sensor_handler : public sensor_handler { +public: + external_sensor_handler(const sensor_info &info, + external_sensor *sensor); + ~external_sensor_handler(); + + /* sensor interface */ + const sensor_info &get_sensor_info(void); + + int start(sensor_observer *ob); + int stop(sensor_observer *ob); + + int set_interval(sensor_observer *ob, int32_t interval); + int set_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); + int get_data(sensor_data_t **data, int *len); + +private: + bool init(); + void deinit(); + + int get_min_interval(void); + int get_min_batch_latency(void); + + sensor_info m_info; + external_sensor *m_sensor; + sensor_notifier *m_notifier; + int m_policy; + + std::unordered_map m_interval_map; + std::unordered_map m_batch_latency_map; +}; + +} + +#endif /* __EXTERNAL_SENSOR_HANDLER_H__ */ -- 2.7.4 From 33a86529ceced3ba0b6d69e12523d5dd1fdd0c1a Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:49:55 +0900 Subject: [PATCH 16/16] sensord: add application_sensor_handler skeleton class - application_sensor_handler will be created by application - application_sensor_handler provides: - events from application to observers(listeners) Change-Id: Ic33e1c164ddfc98766eec6e82b2b537ccf4c5a6a Signed-off-by: kibak.yoon --- src/server/application_sensor_handler.cpp | 90 +++++++++++++++++++++++++++++++ src/server/application_sensor_handler.h | 60 +++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/server/application_sensor_handler.cpp create mode 100644 src/server/application_sensor_handler.h diff --git a/src/server/application_sensor_handler.cpp b/src/server/application_sensor_handler.cpp new file mode 100644 index 0000000..48e50be --- /dev/null +++ b/src/server/application_sensor_handler.cpp @@ -0,0 +1,90 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "application_sensor_handler.h" + +#include +#include + +using namespace sensor; + +application_sensor_handler::application_sensor_handler(const sensor_info &info) +: m_info(info) +{ +} + +application_sensor_handler::~application_sensor_handler() +{ +} + +int application_sensor_handler::post(sensor_data_t *data, int len) +{ + std::string uri = m_info.get_type_uri(); + + return notify(uri.c_str(), data, len); +} + +const sensor_info &application_sensor_handler::get_sensor_info(void) +{ + return m_info; +} + +int application_sensor_handler::start(sensor_observer *ob) +{ + add_observer(ob); + + return OP_SUCCESS; +} + +int application_sensor_handler::stop(sensor_observer *ob) +{ + remove_observer(ob); + + return OP_SUCCESS; +} + +int application_sensor_handler::set_interval(sensor_observer *ob, int32_t interval) +{ + return OP_SUCCESS; +} + +int application_sensor_handler::set_batch_latency(sensor_observer *ob, int32_t latency) +{ + return OP_SUCCESS; +} + +int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, int32_t value) +{ + return OP_SUCCESS; +} + +int application_sensor_handler::set_attribute(sensor_observer *ob, int32_t attr, const char *value, int len) +{ + return OP_SUCCESS; +} + +int application_sensor_handler::flush(sensor_observer *ob) +{ + return OP_SUCCESS; +} + +int application_sensor_handler::get_data(sensor_data_t **data, int *len) +{ + return OP_SUCCESS; +} diff --git a/src/server/application_sensor_handler.h b/src/server/application_sensor_handler.h new file mode 100644 index 0000000..87d07fd --- /dev/null +++ b/src/server/application_sensor_handler.h @@ -0,0 +1,60 @@ +/* + * sensord + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __APPLICATION_SENSOR_HANDLER_H__ +#define __APPLICATION_SENSOR_HANDLER_H__ + +#include +#include +#include + +#include "sensor_handler.h" +#include "sensor_observer.h" + +namespace sensor { + +class application_sensor_handler : public sensor_handler { +public: + application_sensor_handler(const sensor_info &info); + ~application_sensor_handler(); + + /* TODO: const */ + int post(sensor_data_t *data, int len); + + /* sensor interface */ + const sensor_info &get_sensor_info(void); + + int start(sensor_observer *ob); + int stop(sensor_observer *ob); + + int set_interval(sensor_observer *ob, int32_t interval); + int set_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); + int get_data(sensor_data_t **data, int *len); + +private: + sensor_info m_info; + std::vector m_required_sensors; +}; + +} + +#endif /* __APPLICATION_SENSOR_HANDLER_H__ */ -- 2.7.4