diff options
author | Ossama Othman <ossama.othman@intel.com> | 2013-10-03 13:35:02 -0700 |
---|---|---|
committer | Ossama Othman <ossama.othman@intel.com> | 2013-10-03 14:10:29 -0700 |
commit | 9481ce3c822a1c9734068f8902e79547afc0d38b (patch) | |
tree | 096aa0fc6eba1c8449281385476f795924d94802 /src | |
parent | 38bb9a71ff04daff8702f20fed901831b690e29b (diff) | |
download | settings-daemon-tizen_ivi_genivi.tar.gz settings-daemon-tizen_ivi_genivi.tar.bz2 settings-daemon-tizen_ivi_genivi.zip |
TIVI-1924: Initial commit of IVI settings daemon.submit/tizen_ivi_release/20131120.032742submit/tizen_ivi_milestone/20131113.054518submit/tizen_ivi_genivi/20140131.070647submit/tizen_ivi_generic/20140131.065503submit/tizen/20131003.211152ivi_oct_m2accepted/tizen_ivi_release/20131120.050012accepted/tizen/ivi/genivi/20140131.070902accepted/tizen/20131003.220350accepted/tizen/20131003.215933tizen_ivi_genivi
This daemon provides a native backend to the Settings app.
It fills functionality gaps in the Web API, such as WiFi and
date/time, required by the Settings app.
This version contains support for unsecured WiFi connections
and setting the date and time.
Change-Id: I2810d0910029c4ed146e9ff740c246d428767649
Signed-off-by: Ossama Othman <ossama.othman@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 74 | ||||
-rw-r--r-- | src/configurator.cpp | 251 | ||||
-rw-r--r-- | src/configurator.hpp | 125 | ||||
-rw-r--r-- | src/daemon.cpp | 78 | ||||
-rw-r--r-- | src/websocket_server.cpp | 172 | ||||
-rw-r--r-- | src/websocket_server.hpp | 92 |
6 files changed, 792 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..d3c7b01 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,74 @@ +## Copyright 2012, 2013 Intel Corporation All Rights Reserved. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, +## Boston, MA 02110-1301 USA + +## --------------------------------------------------------- +## settings daemon +## --------------------------------------------------------- + +# The settingsd stand-alone binary. +bin_PROGRAMS = settingsd + +## Note that we define some preprocessor symbols on the command line +## since the required shell variables cannot be fully expanded at +## configure-time. +settingsd_CPPFLAGS = \ + $(BOOST_CPPFLAGS) \ + $(GIO_CFLAGS) \ + $(JSON_GLIB_CFLAGS) \ + $(LIBWEBSOCKETS_CFLAGS) \ + -I$(top_srcdir)/include \ + -DIVI_SETTINGS_CONFIG_DIR='"$(sysconfdir)/@PACKAGE@"' \ + -DIVI_SETTINGS_DEFAULT_SETTINGS_DIR='"$(pkglibdir)"' + +settingsd_SOURCES = \ + configurator.cpp \ + daemon.cpp \ + websocket_server.cpp + +settingsd_LDFLAGS = $(BOOST_LDFLAGS) + +settingsd_LDADD = \ + $(top_builddir)/lib/libsettings.la \ + $(BOOST_PROGRAM_OPTIONS_LIB) \ + $(JSON_GLIB_LIBS) \ + $(GIO_LIBS) \ + $(LIBWEBSOCKETS_LIBS) \ + @IVI_SETTINGS_DLOPEN_LIBS@ + +noinst_HEADERS = \ + configurator.hpp \ + websocket_server.hpp + + +## Silent mode output for D-bus related code generation. +dbus_codegen_verbose = $(dbus_codegen_verbose_$(V)) +dbus_codegen_verbose_ = $(dbus_codegen_verbose_$(AM_DEFAULT_VERBOSITY)) +dbus_codegen_verbose_0 = @echo 'CODEGEN ' $@; + +## Geocoding related D-bus glue code generation. +%-glue.c %-glue.h: %.xml Makefile + $(dbus_codegen_verbose)gdbus-codegen --generate-c-code $*-glue \ + --interface-prefix org.tizen. $< + +BUILT_SOURCES = + +CLEANFILES = $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + +EXTRA_DIST = diff --git a/src/configurator.cpp b/src/configurator.cpp new file mode 100644 index 0000000..bcf374b --- /dev/null +++ b/src/configurator.cpp @@ -0,0 +1,251 @@ +/** + * @file configurator.cpp + * + * @brief Source file containing implementation of the settingsd + * configuration manager. + * + * @author Ossama Othman @<ossama.othman@@intel.com@> + * + * @copyright @par + * Copyright 2012, 2013 Intel Corporation All Rights Reserved. + * @par + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * @par + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * @par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + +#include "../lib/config.hpp" +#include "configurator.hpp" + +#include <unistd.h> +#include <fstream> +#include <cstdlib> + + +namespace po = boost::program_options; + +ivi::settings::configurator::configurator(int & argc, + char * argv[], + char const * /* logger_name */) + : vm_() +{ + parse_config(argc, argv); +} + +std::string +ivi::settings::configurator::settings_dir() const +{ + return vm_["settings-dir"].as<std::string>(); +} + +int +ivi::settings::configurator::websocket_port() const +{ + return vm_["websocket-port"].as<int>(); +} + +char const * +ivi::settings::configurator::ssl_cert_file() const +{ + return libwebsocket_ssl_filepath("ssl-cert-file"); +} + +char const * +ivi::settings::configurator::ssl_private_key_file() const +{ + return libwebsocket_ssl_filepath("ssl-private-key-file"); +} + +char const * +ivi::settings::configurator::ssl_ca_file() const +{ + return libwebsocket_ssl_filepath("ssl-ca-file"); +} + +void +ivi::settings::configurator::parse_config(int & argc, char * argv[]) +{ + /// Options recognized by settingsd. + boost::program_options::options_description desc( + "Allowed " PACKAGE " options"); + + desc.add_options() + ("settings-dir", + po::value<std::string>()->default_value(IVI_SETTINGS_DEFAULT_SETTINGS_DIR), + "settings plugin directory") + ("websocket-port", + po::value<int>()->default_value(IVI_SETTINGS_DEFAULT_WEBSOCKET_PORT), + "settings web socket server TCP/IP port") + ("ssl-cert-file", + po::value<std::string>(), + "SSL server certificate file") + ("ssl-private-key-file", + po::value<std::string>(), + "SSL private key file") + ("ssl-ca-file", + po::value<std::string>(), + "SSL CA certificate file") + ("version", "display version information") + ("help", "display help message"); + + // Option precedence - high to low: + // + // 1. Command line + // 2. User config + // 3. System config + // + // The store() function will only assign a value once, and will + // not change it's value subsequently. + po::store(po::parse_command_line(argc, argv, desc), vm_); + + /** + * @todo Check for config in $XDG_CONFIG_DIRS and $XDG_CONFIG_HOME. + */ + // User config is stored in ~/.config/ivi_settings. + std::ifstream user_config_file(std::string(std::getenv("HOME")) + + "/.config/" PACKAGE); + if (user_config_file) + po::store(po::parse_config_file(user_config_file, desc), vm_); + + // Configuration file name such as + // "/etc/settingsd/settingsd.conf" + static char const config_filename[] = + IVI_SETTINGS_CONFIG_DIR "/" PACKAGE ".conf"; + + std::ifstream system_config_file(config_filename); + if (system_config_file) + po::store(po::parse_config_file(system_config_file, desc), vm_); + + po::notify(vm_); + + if (vm_.count("version")) { + display_version_info(); + std::exit(EXIT_SUCCESS); + } else if (vm_.count("help")) { + std::cout << desc << std::endl; + std::exit(EXIT_SUCCESS); + } +} + +void +ivi::settings::configurator::display_version_info() const +{ + static char const copyright[] = + PACKAGE_STRING "\n" + "Copyright (c) 2012, 2013 Intel Corporation.\n" + "\n" + "This " PACKAGE_NAME " (\"Software\") is furnished under " + "license and may only be\n" + "used or copied in accordance with the terms of that license.\n" + "No license, express or implied, by estoppel or otherwise, to any\n" + "intellectual property rights is granted by this document. The\n" + "Software is subject to change without notice, and should not be\n" + "construed as a commitment by Intel Corporation to market, license,\n" + "sell or support any product or technology. Unless otherwise provided\n" + "for in the license under which this Software is provided, the\n" + "Software is provided AS IS, with no warranties of any kind, express\n" + "or implied. Except as expressly permitted by the Software license,\n" + "neither Intel Corporation nor its suppliers assumes any\n" + "responsibility or liability for any errors or inaccuracies that may\n" + "appear herein. Except as expressly permitted by the Software\n" + "license, no part of the Software may be reproduced, stored in a\n" + "retrieval system, transmitted in any form, or distributed by any\n" + "means without the express written consent of Intel Corporation.\n"; + + std::cout << copyright << std::endl; +} + +void +ivi::settings::configurator::configure_logger( + char const * /* logger_name */) +{ + // Start with log configuration file, if it exists, and override as + // needed with command line specifed options. + std::string const log_config_filename = + vm_["log-config-file"].as<std::string>(); + + if (access(log_config_filename.c_str(), R_OK) == 0) { + /** + * @bug There is a TOCTOU race here since the config file may + * be yanked out from under us before the + * @c log4plus::PropertyConfigurator pulls the config from + * the file. + */ + + // Reset configuration before pulling configuration from file. + // log4cplus::Logger::getDefaultHierarchy().resetConfiguration(); + + // Now pull the configuration from the file. + // log4cplus::PropertyConfigurator::doConfigure(log_config_filename); + } + + // logger_ = log4cplus::Logger::getInstance(logger_name); + + /// @todo Set the log file. + + // We have a logger. Now set the log level. + set_log_level(); +} + +void +ivi::settings::configurator::set_log_level() +{ +/* + log4cplus::LogLevel level; + + std::string const l = vm_["log-level"].as<std::string>(); + + if (l == "FATAL") + level = log4cplus::FATAL_LOG_LEVEL; + else if (l == "ERROR") + level = log4cplus::ERROR_LOG_LEVEL; + else if (l == "WARN") + level = log4cplus::WARN_LOG_LEVEL; + else if (l == "INFO") + level = log4cplus::INFO_LOG_LEVEL; + else if (l == "DEBUG") + level = log4cplus::DEBUG_LOG_LEVEL; + else if (l == "TRACE") + level = log4cplus::TRACE_LOG_LEVEL; + else if (l == "ALL") + level = log4cplus::ALL_LOG_LEVEL; + else if (l == "OFF") + level = log4cplus::OFF_LOG_LEVEL; + else { + LOG4CPLUS_WARN(logger_, "Unknown log option: \"" + l + "\""); + return; + } + + logger_.setLogLevel(level); +*/ +} + +char const * +ivi::settings::configurator::libwebsocket_ssl_filepath( + std::string const & option) const +{ + using boost::program_options::variable_value; + + variable_value const & value = vm_[option]; + + return value.empty() ? nullptr : value.as<std::string>().c_str(); +} + + +// Local Variables: +// mode:c++ +// c-basic-offset:2 +// indent-tabs-mode: nil +// End: diff --git a/src/configurator.hpp b/src/configurator.hpp new file mode 100644 index 0000000..7187aad --- /dev/null +++ b/src/configurator.hpp @@ -0,0 +1,125 @@ +/** + * @file configurator.hpp + * + * @brief settingsd configuration manager header. + * + * @author Ossama Othman @<ossama.othman@@intel.com@> + * + * @copyright @par + * Copyright 2012, 2013 Intel Corporation All Rights Reserved. + * @par + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * @par + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * @par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * @note This is an internal header. + */ + +#ifndef IVI_SETTINGS_CONFIGURATOR_HPP +#define IVI_SETTINGS_CONFIGURATOR_HPP + +#include <string> +#include <boost/program_options.hpp> + + +namespace ivi { + namespace settings{ + /** + * @class configurator + * + * @brief Settingsd configuration manager + * + * The @c configurator class parses command line and file based + * settingsd configuration options. + */ + class configurator + { + public: + + /// Constructor. + configurator(int & argc, char * argv[], char const * logger_name); + + /// Get directory containing the settings plugins. + std::string settings_dir() const; + + /// The port on which the web socket server should listen. + int websocket_port() const; + + + /// Websocket server SSL certificate file. + char const * ssl_cert_file() const; + + /// Websocket server SSL private key file. + char const * ssl_private_key_file() const; + + /// Websocket server SSL CA certificate file. + char const * ssl_ca_file() const; + + private: + + /** + * @name Prevent copying + */ + //@{ + configurator(configurator const &) = delete; + configurator & operator=(configurator const &) = delete; + //@} + + /** + * @brief Parse the settingsd configuration. + * + * Configuration options are obtained from the command line, the + * user configuration file and the system configuration file, in + * order of decreasing precedence. + */ + void parse_config(int & argc, char * argv[]); + + /// Display settingsd's version and copyright notices. + void display_version_info() const; + + /// Configure the underlying logger. + void configure_logger(char const * logger_name); + + /// Set the log level in the underlying logger. + void set_log_level(); + + /** + * libwebsockets wants a @c nullptr for SSL certificate/key + * paths if they won't be used. + * + * @param[in] option SSL certificate relate program option. + * + * @returns C string if @a option is not empty, @c nullptr + * otherwise. + */ + char const * libwebsocket_ssl_filepath( + std::string const & option) const; + + private: + + /// Map of settingsd program options. + boost::program_options::variables_map vm_; + + }; + } +} + +#endif /* IVI_SETTINGS_CONFIGURATOR_HPP */ + + +// Local Variables: +// mode:c++ +// c-basic-offset:2 +// indent-tabs-mode: nil +// End: diff --git a/src/daemon.cpp b/src/daemon.cpp new file mode 100644 index 0000000..a657483 --- /dev/null +++ b/src/daemon.cpp @@ -0,0 +1,78 @@ +/** + * @file daemon.cpp + * + * @brief Main settingsd source file. + * + * @copyright @par + * Copyright 2012, 2013 Intel Corporation All Rights Reserved. + * @par + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * @par + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * @par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "../lib/config.hpp" +#include "../lib/manager.hpp" + +#include "configurator.hpp" +#include "websocket_server.hpp" + +#include <settingsd/glib_traits.hpp> +#include <settingsd/smart_ptr.hpp> + +#include <glib.h> +#include <iostream> + + +/** + * settingsd program entry point. + * + * @param[in] argc The number of settingsd command line arguments. + * @param[in] argv The settingsd command line option/argument vector. + */ +int +main(int argc, char * argv[]) +{ + std::cerr << PACKAGE_STRING << '\n'; + + try { + using namespace ivi; + + settings::configurator config(argc, argv, IVI_SETTINGS_DBUS_NAME); + + settings::manager manager(config.settings_dir()); + + // The websocket server will run in its own thread. + settings::websocket_server server(config, manager); + server.run(); + + // Glib related events, including GDbus related signal handlers, + // will handled in this (main) thread. + settings::smart_ptr<GMainLoop> const loop(g_main_loop_new(nullptr, false)); + g_main_loop_run(loop.get()); + } + catch (std::exception & e) { + std::cerr << e.what(); + return -1; + } + + return 0; +} + + +// Local Variables: +// mode:c++ +// c-basic-offset:2 +// indent-tabs-mode: nil +// End: diff --git a/src/websocket_server.cpp b/src/websocket_server.cpp new file mode 100644 index 0000000..e454839 --- /dev/null +++ b/src/websocket_server.cpp @@ -0,0 +1,172 @@ +/** + * @file websocket_server.cpp + * + * @brief Settings daemon WebSocket server source. + * + * @author Ossama Othman @<ossama.othman@@intel.com@> + * + * @copyright @par + * Copyright 2013 Intel Corporation All Rights Reserved. + * @par + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * @par + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * @par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "websocket_server.hpp" +#include "configurator.hpp" +#include "../lib/config.hpp" +#include "../lib/manager.hpp" + +#include <stdexcept> +#include <thread> + + +namespace +{ + // -------------------------------------------------------------------- + // libwebsockets callbacks and related data. + // -------------------------------------------------------------------- + + int + callback_ivi_settings(libwebsocket_context * context, + libwebsocket * wsi, + enum libwebsocket_callback_reasons reason, + void * /* user */, + void * in, + size_t /* len */) + { + using namespace ivi::settings; + + manager * const mgr = static_cast<manager *>( + libwebsocket_context_user(context)); + + switch(reason) { + case LWS_CALLBACK_RECEIVE: + // Request has come in from Settings app. Pass it on to the + // settings manager. + mgr->dispatch(static_cast<char const *>(in), wsi); + break; + + default: + break; + } + + return 0; + } + + struct ws_session_data_type + { + }; + + libwebsocket_protocols settings_protocols[] = { + { + "http-only",//"ivi-settings-protocol", + callback_ivi_settings, + sizeof(ws_session_data_type), + 0, + nullptr, + 0 + }, + { + nullptr, + nullptr, + 0, + 0, + nullptr, + 0 + } + }; + +} + +// ---------------------------------------------------------------------- + +ivi::settings::websocket_server::websocket_server( + ivi::settings::configurator const & config, + ivi::settings::manager & mgr) + : context_(nullptr) +{ + lws_context_creation_info info; + info.port = config.websocket_port(); + info.iface = "lo"; // Only allow communication over the loopback + // interface. + + info.protocols = settings_protocols; + info.extensions = libwebsocket_get_internal_extensions(); + + info.ssl_cert_filepath = config.ssl_cert_file(); + info.ssl_private_key_filepath = config.ssl_private_key_file(); + info.ssl_ca_filepath = config.ssl_ca_file(); + info.ssl_cipher_list = nullptr; + + info.gid = -1; + info.uid = -1; + + info.options = 0; + + info.user = &mgr; + + info.ka_time = 0; + info.ka_probes = 0; + info.ka_interval = 0; + + lws_set_log_level(LLL_INFO, lwsl_emit_syslog); + + context_ = libwebsocket_create_context(&info); + if (context_ == nullptr) + throw std::runtime_error("Unable to initialize websocket.\n"); + + std::cout << "\n" PACKAGE_NAME " listening for requests on port " + << info.port << ".\n"; +} + +ivi::settings::websocket_server::~websocket_server() +{ + libwebsocket_context_destroy(context_); +} + +void +ivi::settings::websocket_server::run() +{ + // Run the websocket event loop in its own thread. + std::thread( + [](libwebsocket_context * context){ + try { + // Run the libwebsockets event loop with an infinite timeout. + // The negative timeout causes the underlying call poll() to + // block indefinitely until an event occurs. + constexpr int const timeout = -1; + while (libwebsocket_service(context, timeout) >= 0) { + } + + std::cerr << "WebSocket event loop ended.\n"; + } catch(std::exception & e) { + std::cerr << e.what() << std::endl; + } + }, + context_).detach(); +} + + +/** + * @todo Add 'state' event do determine whether technology is + * enabled/disabled. + */ + +// Local Variables: +// mode:c++ +// c-basic-offset:2 +// indent-tabs-mode: nil +// End: diff --git a/src/websocket_server.hpp b/src/websocket_server.hpp new file mode 100644 index 0000000..c7a6e09 --- /dev/null +++ b/src/websocket_server.hpp @@ -0,0 +1,92 @@ +/** + * @file websocket_server.hpp + * + * @brief Settings daemon WebSocket server header. + * + * @author Ossama Othman @<ossama.othman@@intel.com@> + * + * @copyright @par + * Copyright 2013 Intel Corporation All Rights Reserved. + * @par + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * @par + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * @par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * @note This header is internal. + */ + +#ifndef IVI_SETTINGS_WEBSOCKET_SERVER_HPP +#define IVI_SETTINGS_WEBSOCKET_SERVER_HPP + +#include <libwebsockets.h> + + +namespace ivi +{ + namespace settings + { + class configurator; + class manager; + + /** + * @class websocket_server + * + * @brief IVI Settings web socket server + * + * This class implements the server that listens for and handles + * web socket events. + */ + class websocket_server + { + public: + + /// Constructor. + websocket_server(configurator const & config, + manager & manager); + + /// Destructor. + ~websocket_server(); + + /// Run the websocket server event loop in its own thread. + void run(); + + private: + + /** + * @name Prevent copying + */ + //@{ + websocket_server(websocket_server const &) = delete; + websocket_server & operator=(websocket_server const &) = delete; + //@} + + private: + + /// Our libwebsocket state. + libwebsocket_context * context_; + + }; + + } +} + + +#endif /* IVI_SETTINGS_WEBSOCKET_SERVER_HPP */ + + +// Local Variables: +// mode:c++ +// c-basic-offset:2 +// indent-tabs-mode: nil +// End: |