From 25258ab1eb05bea3075a697b0009e4937d525e36 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 5 Apr 2017 16:20:26 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 11/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 From 9041f160c57acacf7445e4008ef3a4337c2ef305 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:52:33 +0900 Subject: [PATCH 12/16] sensord: add sensor_listener_proxy class - sensor_listener_proxy is a proxy of client's listener - it listens sensor event as observer and controls sensors Change-Id: I40b398f0701e7940a9893f54b896568debb3ed36 Signed-off-by: kibak.yoon --- src/server/sensor_listener_proxy.cpp | 129 +++++++++++++++++++++++++++++++++++ src/server/sensor_listener_proxy.h | 65 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/server/sensor_listener_proxy.cpp create mode 100644 src/server/sensor_listener_proxy.h diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp new file mode 100644 index 0000000..29608b0 --- /dev/null +++ b/src/server/sensor_listener_proxy.cpp @@ -0,0 +1,129 @@ +/* + * 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_proxy.h" + +#include +#include +#include +#include +#include + +using namespace sensor; + +sensor_listener_proxy::sensor_listener_proxy( + uint32_t id, sensor_handler *sensor, ipc::channel *ch) +: m_id(id) +, m_sensor(sensor) +, m_ch(ch) +, m_passive(false) +, m_pause_policy(SENSORD_PAUSE_ALL) +, m_axis_orientation(SENSORD_AXIS_DISPLAY_ORIENTED) +{ +} + +sensor_listener_proxy::~sensor_listener_proxy() +{ + stop(); +} + +uint32_t sensor_listener_proxy::get_id(void) +{ + return m_id; +} + +int sensor_listener_proxy::update(const char *uri, ipc::message *msg) +{ + retv_if(!m_ch || !m_ch->is_connected(), OP_CONTINUE); + + /* TODO: check axis orientation */ + msg->header()->type = CMD_LISTENER_EVENT; + msg->header()->err = OP_SUCCESS; + + m_ch->send(msg); + + return OP_CONTINUE; +} + +int sensor_listener_proxy::start(void) +{ + /* TODO: listen pause policy */ + return m_sensor->start(this); +} + +int sensor_listener_proxy::stop(void) +{ + /* TODO: listen pause policy */ + int ret; + + ret = m_sensor->stop(this); + retv_if(ret < 0, OP_ERROR); + + /* unset attributes */ + set_interval(POLL_1HZ_MS); + set_max_batch_latency(0); + + return OP_SUCCESS; +} + +int sensor_listener_proxy::set_interval(unsigned int interval) +{ + return m_sensor->set_interval(this, interval); +} + +int sensor_listener_proxy::set_max_batch_latency(unsigned int max_batch_latency) +{ + return m_sensor->set_batch_latency(this, max_batch_latency); +} + +int sensor_listener_proxy::set_passive_mode(bool passive) +{ + /* TODO: passive mode */ + m_passive = passive; + return OP_SUCCESS; +} + +int sensor_listener_proxy::set_attribute(int attribute, int value) +{ + if (attribute == SENSORD_ATTRIBUTE_PAUSE_POLICY) { + m_pause_policy = value; + return OP_SUCCESS; + } else if (attribute == SENSORD_ATTRIBUTE_AXIS_ORIENTATION) { + m_axis_orientation = value; + return OP_SUCCESS; + } + + return m_sensor->set_attribute(this, attribute, value); +} + +int sensor_listener_proxy::set_attribute(int attribute, const char *value, int len) +{ + return m_sensor->set_attribute(this, attribute, value, len); +} + +int sensor_listener_proxy::flush(void) +{ + return m_sensor->flush(this); +} + +int sensor_listener_proxy::get_data(sensor_data_t **data, int *len) +{ + /* TODO : caching the last data & retry logic if there is no data */ + return m_sensor->get_data(data, len); +} diff --git a/src/server/sensor_listener_proxy.h b/src/server/sensor_listener_proxy.h new file mode 100644 index 0000000..709f057 --- /dev/null +++ b/src/server/sensor_listener_proxy.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 __SENSOR_LISTENER_PROXY_H__ +#define __SENSOR_LISTENER_PROXY_H__ + +#include +#include + +#include "sensor_handler.h" +#include "sensor_observer.h" + +namespace sensor { + +class sensor_listener_proxy : public sensor_observer { +public: + sensor_listener_proxy(uint32_t id, sensor_handler *sensor, ipc::channel *ch); + ~sensor_listener_proxy(); + + uint32_t get_id(void); + + /* sensor observer */ + int update(const char *uri, ipc::message *msg); + + int start(void); + int stop(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 flush(void); + int get_data(sensor_data_t **data, int *len); + +private: + uint32_t m_id; + + sensor_handler *m_sensor; + ipc::channel *m_ch; + + bool m_passive; + int m_pause_policy; + int m_axis_orientation; +}; + +} + +#endif /* __SENSOR_LISTENER_PROXY_H__ */ -- 2.7.4 From 0b6a81e4e5441f6487f35a274282ae569356bc2d Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 19:04:16 +0900 Subject: [PATCH 13/16] sensord: pass observer handle to flush() Change-Id: I4c95531c5461324c41c1ac5eb63cfb4ed00dea99 Signed-off-by: kibak.yoon --- src/server/sensor_handler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/sensor_handler.h b/src/server/sensor_handler.h index 68672ab..a5e6fd5 100644 --- a/src/server/sensor_handler.h +++ b/src/server/sensor_handler.h @@ -48,8 +48,8 @@ public: 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 flush(sensor_observer *ob) = 0; virtual int get_data(sensor_data_t **data, int *len) = 0; - virtual int flush(void) = 0; private: std::list m_observers; -- 2.7.4 From d1c961c50f1dd18eb24072ff3f2f49b5ca84fc54 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 18:55:11 +0900 Subject: [PATCH 14/16] sensord: add sensor_manager to create and manage sensor_handlers - add sensor_event_handler which is to listen events from physical sensor Change-Id: I6854ee874c52c003e4e1daa37a57974ee4b434e4 Signed-off-by: kibak.yoon --- src/server/sensor_event_handler.cpp | 72 +++++++++ src/server/sensor_event_handler.h | 41 ++++++ src/server/sensor_manager.cpp | 283 ++++++++++++++++++++++++++++++++++++ src/server/sensor_manager.h | 31 ++++ 4 files changed, 427 insertions(+) create mode 100644 src/server/sensor_event_handler.cpp create mode 100644 src/server/sensor_event_handler.h diff --git a/src/server/sensor_event_handler.cpp b/src/server/sensor_event_handler.cpp new file mode 100644 index 0000000..de13006 --- /dev/null +++ b/src/server/sensor_event_handler.cpp @@ -0,0 +1,72 @@ +/* + * 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_event_handler.h" + +#include +#include +#include + +using namespace sensor; + +static std::vector ids; + +sensor_event_handler::sensor_event_handler(physical_sensor_handler *sensor) +: m_sensor(sensor) +{ +} + +bool sensor_event_handler::handle(int fd, ipc::event_condition condition) +{ + sensor_info info; + sensor_data_t *data; + int length = 0; + int remains = 1; + + if (m_sensor->read_fd(ids) < 0) + return true; + + auto result = std::find(std::begin(ids), std::end(ids), m_sensor->get_hal_id()); + + if (result == std::end(ids)) + return true; + + while (remains > 0) { + remains = m_sensor->get_data(&data, &length); + if (remains < 0) { + _E("Failed to get sensor data"); + break; + } + + if (m_sensor->on_event(data, length, remains) < 0) { + free(data); + continue; + } + + info = m_sensor->get_sensor_info(); + + //_I("[Data] allocate %p", data); + if (m_sensor->notify(info.get_type_uri().c_str(), data, length) < 0) { + free(data); + } + info.clear(); + } + + return true; +} diff --git a/src/server/sensor_event_handler.h b/src/server/sensor_event_handler.h new file mode 100644 index 0000000..53b5cd6 --- /dev/null +++ b/src/server/sensor_event_handler.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_EVENT_HANDLER__ +#define __SENSOR_EVENT_HANDLER__ + +#include +#include "physical_sensor_handler.h" + +namespace sensor { + +class sensor_event_handler : public ipc::event_handler +{ +public: + sensor_event_handler(physical_sensor_handler *sensor); + + bool handle(int fd, ipc::event_condition condition); + +private: + physical_sensor_handler *m_sensor; +}; + +} + +#endif /* __SENSOR_EVENT_DISPATCHER__ */ diff --git a/src/server/sensor_manager.cpp b/src/server/sensor_manager.cpp index 6944e86..7a0ccc9 100644 --- a/src/server/sensor_manager.cpp +++ b/src/server/sensor_manager.cpp @@ -26,8 +26,26 @@ #include #include +#include "sensor_event_handler.h" +#include "permission_checker.h" +#include "sensor_loader.h" +#include "physical_sensor_handler.h" +#include "fusion_sensor_handler.h" +#include "external_sensor_handler.h" +#include "fusion_sensor_handler.h" + using namespace sensor; +#define DEVICE_HAL_DIR_PATH LIBDIR "/sensor/hal" +#define PHYSICAL_SENSOR_DIR_PATH LIBDIR "/sensor/physical" +#define VIRTUAL_SENSOR_DIR_PATH LIBDIR "/sensor/fusion" +#define EXTERNAL_SENSOR_DIR_PATH LIBDIR "/sensor/external" + +static device_sensor_registry_t devices; +static physical_sensor_registry_t physical_sensors; +static fusion_sensor_registry_t fusion_sensors; +static external_sensor_registry_t external_sensors; + sensor_manager::sensor_manager(ipc::event_loop *loop) : m_loop(loop) { @@ -39,11 +57,276 @@ sensor_manager::~sensor_manager() bool sensor_manager::init(void) { + m_loader.load_hal(DEVICE_HAL_DIR_PATH, devices); + m_loader.load_physical_sensor(PHYSICAL_SENSOR_DIR_PATH, physical_sensors); + m_loader.load_fusion_sensor(VIRTUAL_SENSOR_DIR_PATH, fusion_sensors); + m_loader.load_external_sensor(EXTERNAL_SENSOR_DIR_PATH, external_sensors); + + retvm_if(devices.empty(), false, "There is no sensors"); + + /* TODO: support dynamic sensor */ + create_physical_sensors(devices, physical_sensors); + create_fusion_sensors(fusion_sensors); + create_external_sensors(external_sensors); + + init_sensors(); + + show(); + return true; } bool sensor_manager::deinit(void) { + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) + delete it->second; + m_sensors.clear(); + + external_sensors.clear(); + fusion_sensors.clear(); + physical_sensors.clear(); + devices.clear(); + + m_loader.unload(); + + return true; +} + +bool sensor_manager::is_supported(std::string uri) +{ + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) { + sensor_info info = it->second->get_sensor_info(); + + if (info.get_uri() == uri) + return true; + } + + return false; +} + +bool sensor_manager::register_sensor(sensor_handler *sensor) +{ + retvm_if(!sensor, false, "Invalid sensor"); + + sensor_info info = sensor->get_sensor_info(); + + auto it = m_sensors.find(info.get_uri()); + retvm_if(it != m_sensors.end(), false, "There is already a sensor with the same name"); + + m_sensors[info.get_uri()] = sensor; + + _I("Registered[%s]", info.get_uri().c_str()); + return true; } +void sensor_manager::deregister_sensor(const std::string uri) +{ + auto it = m_sensors.find(uri); + ret_if(it == m_sensors.end()); + + delete it->second; + m_sensors.erase(it); + + _I("Deregistered[%s]", uri.c_str()); +} + +sensor_handler *sensor_manager::get_sensor_by_type(const std::string uri) +{ + auto it = m_sensors.begin(); + for (; it != m_sensors.end(); ++it) { + std::size_t found = it->first.rfind(uri); + if (found != std::string::npos) + return it->second; + } + + return NULL; +} + +sensor_handler *sensor_manager::get_sensor(const std::string uri) +{ + auto it = m_sensors.find(uri); + retv_if(it == m_sensors.end(), NULL); + + return m_sensors[uri]; +} + +std::vector sensor_manager::get_sensors(void) +{ + std::vector sensors; + + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) + sensors.push_back(it->second); + + return sensors; +} + +void sensor_manager::create_physical_sensors(device_sensor_registry_t &devices, + physical_sensor_registry_t &psensors) +{ + const sensor_info_t *info; + physical_sensor_handler *psensor; + + for (auto it = devices.begin(); it != devices.end(); ++it) { + int count = (*it)->get_sensors(&info); + + for (int i = 0; i < count; ++i) { + /* TODO: psensors */ + psensor = new(std::nothrow) physical_sensor_handler( + info[i], it->get(), info[i].id, NULL); + retm_if(!psensor, "Failed to allocate memory"); + + sensor_info sinfo = psensor->get_sensor_info(); + m_sensors[sinfo.get_uri()] = psensor; + } + } + +} + +void sensor_manager::create_fusion_sensors(fusion_sensor_registry_t &fsensors) +{ + const sensor_info2_t *info; + fusion_sensor_handler *fsensor; + std::vector req_names; + + for (auto it = fsensors.begin(); it != fsensors.end(); ++it) { + int count = (*it)->get_sensors(&info); + + for (int i = 0; i < count; ++i) { + bool support = true; + req_names.clear(); + + fsensor = new(std::nothrow) fusion_sensor_handler(info[i], it->get()); + retm_if(!fsensor, "Failed to allocate memory"); + + (*it)->get_required_sensors(req_names); + for (unsigned int j = 0; j < req_names.size(); ++j) { + sensor_handler *sensor; + sensor = get_sensor_by_type(req_names[j]); + + if (sensor == NULL) { + support = false; + break; + } + + fsensor->add_required_sensor(sensor); + } + + if (!support) { + delete fsensor; + /* TODO: remove plugin */ + continue; + } + + sensor_info sinfo = fsensor->get_sensor_info(); + m_sensors[sinfo.get_uri()] = fsensor; + } + } +} + +void sensor_manager::create_external_sensors(external_sensor_registry_t &esensors) +{ + const sensor_info2_t *info; + external_sensor_handler *esensor; + + for (auto it = esensors.begin(); it != esensors.end(); ++it) { + int count = (*it)->get_sensors(&info); + + for (int i = 0; i < count; ++i) { + esensor = new(std::nothrow) external_sensor_handler(info[i], it->get()); + retm_if(!esensor, "Failed to allocate memory"); + + sensor_info sinfo = esensor->get_sensor_info(); + m_sensors[sinfo.get_uri()] = esensor; + } + } +} + +static void put_int_to_vec(std::vector &data, int value) +{ + char buf[sizeof(value)]; + + int *temp = (int *)buf; + *temp = value; + + std::copy(&buf[0], &buf[sizeof(buf)], back_inserter(data)); +} + +/* packet format : + * [count:4] {[size:4] [info:n] [size:4] [info:n] ...} + */ +size_t sensor_manager::serialize(int sock_fd, char **bytes) +{ + static permission_checker checker; + + sensor_info info; + std::vector raw_list; + + put_int_to_vec(raw_list, m_sensors.size()); + + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) { + info = it->second->get_sensor_info(); + + if (!checker.has_permission(sock_fd, info.get_permission())) + info.set_uri(SENSOR_URI_PERMISSION_DENIED); + + raw_data_t *raw = new(std::nothrow) raw_data_t(); + retvm_if(!raw, -ENOMEM, "Failed to allocated memory"); + + info.serialize(*raw); + + /* copy size */ + put_int_to_vec(raw_list, raw->size()); + + /* copy info */ + std::copy(raw->begin(), raw->end(), std::back_inserter(raw_list)); + + delete raw; + } + + *bytes = new(std::nothrow) char[raw_list.size()]; + retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory"); + + std::copy(raw_list.begin(), raw_list.end(), *bytes); + + return raw_list.size(); +} + +void sensor_manager::init_sensors(void) +{ + physical_sensor_handler *sensor; + + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) { + sensor = dynamic_cast(it->second); + if (sensor == NULL) + continue; + + /* it doesn't need to deregister handlers, they are consumed in event_loop */ + register_handler(sensor); + } +} + +void sensor_manager::register_handler(physical_sensor_handler *sensor) +{ + ret_if(sensor->get_poll_fd() < 0); + + sensor_event_handler *handler = new(std::nothrow) sensor_event_handler(sensor); + retm_if(!handler, "Failed to allocate memory"); + + m_loop->add_event(sensor->get_poll_fd(), + ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL, handler); +} + +void sensor_manager::show(void) +{ + int index = 0; + + _I("========== Loaded sensor information ==========\n"); + for (auto it = m_sensors.begin(); it != m_sensors.end(); ++it) { + sensor_info info = it->second->get_sensor_info(); + + _I("Sensor #%d[%s]: ", ++index, it->first.c_str()); + info.show(); + } + _I("===============================================\n"); +} diff --git a/src/server/sensor_manager.h b/src/server/sensor_manager.h index 31236af..5c09b0e 100644 --- a/src/server/sensor_manager.h +++ b/src/server/sensor_manager.h @@ -26,8 +26,14 @@ #include "event_loop.h" +#include "sensor_handler.h" +#include "sensor_observer.h" #include "sensor_loader.h" +#include "physical_sensor_handler.h" +#include "fusion_sensor_handler.h" +#include "external_sensor_handler.h" + namespace sensor { class sensor_manager { @@ -38,9 +44,34 @@ public: bool init(void); bool deinit(void); + bool is_supported(const std::string uri); + + bool register_sensor(sensor_handler *sensor); + void deregister_sensor(const std::string uri); + + sensor_handler *get_sensor_by_type(const std::string uri); + sensor_handler *get_sensor(const std::string uri); + std::vector get_sensors(void); + + size_t serialize(int sock_fd, char **bytes); + private: + typedef std::map sensor_map_t; + + void create_physical_sensors( + device_sensor_registry_t &devices, + physical_sensor_registry_t &psensors); + void create_fusion_sensors(fusion_sensor_registry_t &vsensors); + void create_external_sensors(external_sensor_registry_t &vsensors); + + void init_sensors(void); + void register_handler(physical_sensor_handler *sensor); + + void show(void); + ipc::event_loop *m_loop; sensor_loader m_loader; + sensor_map_t m_sensors; }; } -- 2.7.4 From a868eee02e8707fccab8db7810df501d3d28b171 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 19:12:15 +0900 Subject: [PATCH 15/16] sensord: add calibration node setting - read calibration file path from configuration file(/etc/sensor_cal.conf) Change-Id: Ic256a0352e1e047dc4d7a3cc091a0b7cdaf106be Signed-off-by: kibak.yoon --- src/server/server.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++------ src/server/server.h | 1 - 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/server/server.cpp b/src/server/server.cpp index fee9abf..a7a2f03 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -28,7 +28,13 @@ #include "sensor_manager.h" #include "server_channel_handler.h" +#define MAX_CONFIG_PATH 255 +#define CAL_CONFIG_PATH "/etc/sensor_cal.conf" +#define SET_CAL 1 +//#define CAL_NODE_PATH "/sys/class/sensors/ssp_sensor/set_cal_data" + #define TIMEOUT_TERM 10 +#define MAX_CONNECTION 1000 using namespace sensor; @@ -42,10 +48,6 @@ server::server() { } -server::~server() -{ -} - server &server::instance(void) { static server inst; @@ -83,6 +85,7 @@ bool server::init(void) m_handler = new(std::nothrow) server_channel_handler(m_manager); retvm_if(!m_handler, false, "Failed to allocate memory"); + init_calibration(); init_server(); init_termination(); @@ -109,19 +112,52 @@ void server::deinit(void) is_running.store(false); } +static void set_cal_data(const char *path) +{ + FILE *fp = fopen(path, "w"); + retm_if(!fp, "There is no calibration file[%s]", path); + + fprintf(fp, "%d", SET_CAL); + fclose(fp); + + _I("Succeeded to set calibration data"); +} + +void server::init_calibration(void) +{ + char path[MAX_CONFIG_PATH]; + + FILE *fp = fopen(CAL_CONFIG_PATH, "r"); + retm_if(!fp, "There is no config file[%s]", CAL_CONFIG_PATH); + + while (!feof(fp)) { + if (fgets(path, sizeof(path), fp) == NULL) + break; + set_cal_data(path); + } + + fclose(fp); +} + void server::init_server(void) { m_manager->init(); /* TODO: setting socket option */ - m_server->set_option("max_connection", 1000); + m_server->set_option("max_connection", MAX_CONNECTION); 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 */ + sensor_manager *mgr = reinterpret_cast(data); + std::vector sensors = mgr->get_sensors(); + + if (sensors.size() <= 0) { + _I("Terminating.. because there is no sensors"); + server::stop(); + } return FALSE; } diff --git a/src/server/server.h b/src/server/server.h index 98d99c1..99856a1 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -40,7 +40,6 @@ private: static std::atomic is_running; server(); - ~server(); bool init(void); void deinit(void); -- 2.7.4 From 26eff59fb807a5f0a943f3cb96392ae8f7d0485f Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Thu, 6 Apr 2017 19:14:20 +0900 Subject: [PATCH 16/16] sensord: implement server_channel_handler - server_channel_handler is a handler that responds to client request. Change-Id: I788010896384f686fa271d61662cd09ae48ca4c2 Signed-off-by: kibak.yoon --- src/server/server_channel_handler.cpp | 128 +++++++++++++++++++++++++++++++--- src/server/server_channel_handler.h | 12 +++- 2 files changed, 128 insertions(+), 12 deletions(-) diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index afcfa4e..a34f58f 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -21,6 +21,7 @@ #include #include +#include #include using namespace sensor; @@ -41,6 +42,13 @@ void server_channel_handler::connected(channel *ch) void server_channel_handler::disconnected(channel *ch) { + auto it = m_listeners.find(ch); + ret_if(it == m_listeners.end()); + + _I("Disconnected listener[%u]", it->second->get_id()); + + delete it->second; + m_listeners.erase(ch); } void server_channel_handler::read(channel *ch, message &msg) @@ -81,55 +89,153 @@ void server_channel_handler::read(channel *ch, message &msg) int server_channel_handler::manager_get_sensor_list(channel *ch, message &msg) { - return OP_ERROR; + ipc::message reply; + char *bytes; + int size; + + size = m_manager->serialize(ch->get_fd(), &bytes); + retv_if(size < 0, size); + + reply.enclose((const char *)bytes, size); + ch->send_sync(&reply); + + delete [] bytes; + + return OP_SUCCESS; } int server_channel_handler::listener_connect(channel *ch, message &msg) { - return OP_ERROR; + static uint32_t listener_id = 1; + sensor_handler *sensor; + cmd_listener_connect_t buf; + + msg.disclose((char *)&buf); + + sensor = m_manager->get_sensor(buf.sensor); + retv_if(!sensor, OP_ERROR); + + sensor_listener_proxy *listener = + new(std::nothrow) sensor_listener_proxy(listener_id, sensor, ch); + retvm_if(!listener, OP_ERROR, "Failed to allocate memory"); + + buf.listener_id = listener_id; + + message reply; + reply.enclose((const char *)&buf, sizeof(buf)); + reply.header()->err = OP_SUCCESS; + + if (!ch->send_sync(&reply)) + return OP_ERROR; + + _I("Connected sensor_listener[fd(%d) -> id(%u)]", ch->get_fd(), listener_id); + listener_id++; + m_listeners[ch] = listener; + + return OP_SUCCESS; } int server_channel_handler::listener_disconnect(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + uint32_t id = m_listeners[ch]->get_id(); + + delete m_listeners[ch]; + m_listeners.erase(ch); + + _D("Disconnected sensor_listener[%u]", id); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_start(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + int ret = m_listeners[ch]->start(); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_stop(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + int ret = m_listeners[ch]->stop(); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_attr_int(channel *ch, message &msg) { - return OP_ERROR; + int ret = OP_SUCCESS; + + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + cmd_listener_attr_int_t buf; + msg.disclose((char *)&buf); + + switch (buf.attribute) { + case SENSORD_ATTRIBUTE_INTERVAL: + ret = m_listeners[ch]->set_interval(buf.value); break; + case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY: + ret = m_listeners[ch]->set_max_batch_latency(buf.value); break; + case SENSORD_ATTRIBUTE_PASSIVE_MODE: + ret = m_listeners[ch]->set_passive_mode(buf.value); break; + case SENSORD_ATTRIBUTE_PAUSE_POLICY: + case SENSORD_ATTRIBUTE_AXIS_ORIENTATION: + default: + ret = m_listeners[ch]->set_attribute(buf.attribute, buf.value); + } + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_attr_str(channel *ch, message &msg) { - return OP_ERROR; + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + + cmd_listener_attr_str_t buf; + msg.disclose((char *)&buf); + + int ret = m_listeners[ch]->set_attribute(buf.attribute, buf.value, buf.len); + retv_if(ret < 0, ret); + + return send_reply(ch, OP_SUCCESS); } int server_channel_handler::listener_get_data(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_connect(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_disconnect(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); } int server_channel_handler::provider_post(channel *ch, message &msg) { - return OP_ERROR; + return send_reply(ch, OP_ERROR); +} + +int server_channel_handler::send_reply(channel *ch, int error) +{ + message reply(error); + retvm_if(!ch->send_sync(&reply), OP_ERROR, "Failed to send reply"); + return OP_SUCCESS; } diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index 76ea4a3..d48ff7e 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -26,10 +26,11 @@ #include #include "sensor_manager.h" +#include "sensor_listener_proxy.h" +#include "application_sensor_handler.h" namespace sensor { -/* TODO: this class seems to be able to split */ class server_channel_handler : public ipc::channel_handler { public: @@ -57,7 +58,16 @@ private: int provider_disconnect(ipc::channel *ch, ipc::message &msg); int provider_post(ipc::channel *ch, ipc::message &msg); + int send_reply(ipc::channel *ch, int error); + sensor_manager *m_manager; + + /* {fd, listener} */ + std::unordered_map m_listeners; + + /* {name, application_sensor_handler} */ + /* TODO: move it to sensor_manager */ + std::unordered_map m_sensors; }; } -- 2.7.4