summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorOssama Othman <ossama.othman@intel.com>2013-10-03 13:35:02 -0700
committerOssama Othman <ossama.othman@intel.com>2013-10-03 14:10:29 -0700
commit9481ce3c822a1c9734068f8902e79547afc0d38b (patch)
tree096aa0fc6eba1c8449281385476f795924d94802 /plugins
parent38bb9a71ff04daff8702f20fed901831b690e29b (diff)
downloadsettings-daemon-9481ce3c822a1c9734068f8902e79547afc0d38b.tar.gz
settings-daemon-9481ce3c822a1c9734068f8902e79547afc0d38b.tar.bz2
settings-daemon-9481ce3c822a1c9734068f8902e79547afc0d38b.zip
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 'plugins')
-rw-r--r--plugins/Makefile.am18
-rw-r--r--plugins/connman/Makefile.am64
-rw-r--r--plugins/connman/bluetooth.cpp66
-rw-r--r--plugins/connman/bluetooth.hpp96
-rw-r--r--plugins/connman/clock.cpp336
-rw-r--r--plugins/connman/clock.hpp136
-rw-r--r--plugins/connman/connman.cpp197
-rw-r--r--plugins/connman/connman.hpp198
-rw-r--r--plugins/connman/connman_api.hpp66
-rw-r--r--plugins/connman/connman_manager.cpp228
-rw-r--r--plugins/connman/connman_manager.hpp175
-rw-r--r--plugins/connman/ethernet.cpp66
-rw-r--r--plugins/connman/ethernet.hpp96
-rw-r--r--plugins/connman/registration.cpp65
-rw-r--r--plugins/connman/service.cpp87
-rw-r--r--plugins/connman/service.hpp97
-rw-r--r--plugins/connman/technology.cpp357
-rw-r--r--plugins/connman/technology.hpp139
-rw-r--r--plugins/connman/wifi.cpp66
-rw-r--r--plugins/connman/wifi.hpp98
20 files changed, 2651 insertions, 0 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644
index 0000000..8e03c1c
--- /dev/null
+++ b/plugins/Makefile.am
@@ -0,0 +1,18 @@
+## Copyright 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
+
+SUBDIRS = connman
diff --git a/plugins/connman/Makefile.am b/plugins/connman/Makefile.am
new file mode 100644
index 0000000..2f6b3b6
--- /dev/null
+++ b/plugins/connman/Makefile.am
@@ -0,0 +1,64 @@
+## Copyright 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
+
+
+pkglib_LTLIBRARIES = connman.la
+
+if SETTINGS_USE_GCC_SYMBOL_VISIBILITY
+ IVI_SETTINGS_PLUGIN_CXXFLAGS = -fvisibility=hidden -fvisibility-inlines-hidden
+else
+ IVI_SETTINGS_PLUGIN_CXXFLAGS =
+endif
+
+IVI_SETTINGS_PLUGIN_CPPFLAGS = \
+ -DIVI_SETTINGS_CONNMAN_BUILDING_DLL \
+ -I$(top_srcdir)/include
+
+IVI_SETTINGS_PLUGIN_LIBRARY = $(top_builddir)/lib/libsettings.la
+
+connman_la_SOURCES = \
+ connman.cpp \
+ connman_manager.cpp \
+ service.cpp \
+ technology.cpp \
+ bluetooth.cpp \
+ clock.cpp \
+ ethernet.cpp \
+ wifi.cpp \
+ registration.cpp
+connman_la_CXXFLAGS = \
+ $(IVI_SETTINGS_PLUGIN_CXXFLAGS) \
+ $(GIO_CFLAGS) \
+ $(JSON_GLIB_CFLAGS)
+connman_la_CPPFLAGS = $(IVI_SETTINGS_PLUGIN_CPPFLAGS)
+connman_la_LIBADD = $(IVI_SETTINGS_PLUGIN_LIBRARY)
+connman_la_LDFLAGS = -no-undefined \
+ -module \
+ -avoid-version \
+ $(GIO_LIBS) \
+ $(JSON_GLIB_LIBS)
+
+noinst_HEADERS = \
+ connman_api.hpp \
+ connman.hpp \
+ connman_manager.hpp \
+ service.hpp \
+ technology.hpp \
+ bluetooth.hpp \
+ clock.hpp \
+ ethernet.hpp \
+ wifi.hpp
diff --git a/plugins/connman/bluetooth.cpp b/plugins/connman/bluetooth.cpp
new file mode 100644
index 0000000..576eb4e
--- /dev/null
+++ b/plugins/connman/bluetooth.cpp
@@ -0,0 +1,66 @@
+/**
+ * @file bluetooth.cpp
+ *
+ * @brief Connman-based bluetooth settings.
+ *
+ * @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 "bluetooth.hpp"
+#include <settingsd/response_callback.hpp>
+
+// ----------------------------------------------------------------------
+
+namespace
+{
+ std::string const technology_name("bluetooth");
+}
+
+// ----------------------------------------------------------------------
+
+ivi::settings::bluetooth::bluetooth()
+ : technology_(technology_name)
+{
+}
+
+ivi::settings::bluetooth::~bluetooth()
+{
+}
+
+std::string const &
+ivi::settings::bluetooth::id() const
+{
+ return technology_name;
+}
+
+void
+ivi::settings::bluetooth::handle_request(std::string request,
+ response_callback response)
+{
+ technology_.handle_request(request, response);
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/bluetooth.hpp b/plugins/connman/bluetooth.hpp
new file mode 100644
index 0000000..31741c0
--- /dev/null
+++ b/plugins/connman/bluetooth.hpp
@@ -0,0 +1,96 @@
+/**
+ * @file bluetooth.hpp
+ *
+ * @brief Bluetooth settings plugin.
+ *
+ * Connman-based bluetooth settings plugin.
+ *
+ * @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 header is internal. Settings provider plugin implementors
+ * should write their own library/symbol export macros as
+ * needed.
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_BLUETOOTH_HPP
+#define IVI_SETTINGS_CONNMAN_BLUETOOTH_HPP
+
+#include <settingsd/plugin.hpp>
+
+#include "technology.hpp"
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ /**
+ * @class bluetooth
+ *
+ * @brief Connman-based bluetooth settings.
+ *
+ * This class implements all connman-based bluetooth settings.
+ */
+ class bluetooth : public plugin
+ {
+ public:
+
+ /// Constructor.
+ bluetooth();
+
+ /// Destructor.
+ virtual ~bluetooth();
+
+ /**
+ * @name Settings Plugin API
+ *
+ * Interface defined by the @c ivi::settings::plugin abstract
+ * base class.
+ *
+ * @see settingsd/plugin.hpp
+ */
+ //@{
+ virtual std::string const & id() const;
+ virtual void handle_request(std::string request,
+ response_callback response);
+ //@}
+
+ private:
+
+ /// Underlying connman proxy.
+ technology technology_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_BLUETOOTH_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
+
diff --git a/plugins/connman/clock.cpp b/plugins/connman/clock.cpp
new file mode 100644
index 0000000..9ff91ea
--- /dev/null
+++ b/plugins/connman/clock.cpp
@@ -0,0 +1,336 @@
+/**
+ * @file clock.cpp
+ *
+ * @brief Connman-based clock settings.
+ *
+ * @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 "clock.hpp"
+
+#include <settingsd/response_callback.hpp>
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/json_glib_traits.hpp>
+#include <settingsd/smart_ptr.hpp>
+
+#include <cstring>
+#include <boost/lexical_cast.hpp>
+
+
+ivi::settings::clock::clock()
+ : connman_("net.connman.Clock", "/")
+{
+}
+
+ivi::settings::clock::~clock()
+{
+}
+
+std::string const &
+ivi::settings::clock::id() const
+{
+ static std::string const the_id("clock");
+
+ return the_id;
+}
+
+void
+ivi::settings::clock::handle_request(std::string request,
+ response_callback response)
+{
+ smart_ptr<JsonParser> const parser(json_parser_new());
+ json_parser_load_from_data(parser.get(), request.c_str(), -1, nullptr);
+
+ JsonReader * const reader =
+ json_reader_new(json_parser_get_root(parser.get()));
+
+ smart_ptr<JsonReader> safe_reader(reader);
+
+ char const * name = nullptr;
+ if (json_reader_read_member(reader, "name")) {
+ name = json_reader_get_string_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (name != nullptr) {
+ GError * error = nullptr;
+ bool success = false;
+
+ if (strcmp(name, "time") == 0)
+ success = set_time(reader, response, error);
+ else if (strcmp(name, "time_updates") == 0)
+ success = set_updates("TimeUpdates", reader, response, error);
+ else if (strcmp(name, "timezone") == 0)
+ success = set_timezone(reader, response, error);
+ else if (strcmp(name, "timezone_updates") == 0)
+ success = set_updates("TimezoneUpdates", reader, response, error);
+ else if (strcmp(name, "is_time_updates_auto") == 0)
+ is_updates_auto("TimeUpdates", reader, response, error);
+ else if (strcmp(name, "is_timezone_updates_auto") == 0)
+ is_updates_auto("TimezoneUpdates", reader, response, error);
+ else {
+ response.send_error(
+ "Unrecognized " + id() + " request name: " + name);
+ }
+
+ smart_ptr<GError> safe_error(error);
+
+ if (success) {
+
+ // Nothing to add to successful response.
+ response.send_response(
+ [](JsonBuilder * /* builder */) {});
+
+ } else if (error != nullptr) {
+ response.send_error(
+ std::string("Unable to set ") + name + ": " + error->message);
+ }
+
+ // If success is false and error == nullptr a succesful response
+ // was sent by one of the functions above, e.g. is_update_auto().
+
+ } else {
+ response.send_error(
+ "Malformed " + id() + " request: \"name\" is missing.");
+ }
+}
+
+bool
+ivi::settings::clock::set_time(JsonReader * reader,
+ response_callback response,
+ GError *& error)
+{
+ int64_t time;
+ if (json_reader_read_member(reader, "value")) {
+ /**
+ * @bug @c json_read_get_int_value() returns a signed 64 bit
+ * integer. However, the connman clock API expects an
+ * unsigned 64 bit integer. This means we cannot set time
+ * values before the Unix epoch (< 0) or greater than
+ * (2^63)-1, i.e the largest signed 64 bit integer.
+ */
+ time = json_reader_get_int_value(reader);
+ }
+
+ json_reader_end_member(reader);
+
+ bool success = false;
+
+ if (time >= 0) {
+ // Note that the connman clock API expects an unsigned 64 bit
+ // integer containing seconds since the Unix epoch. We cast the
+ // positive int64_t value to an uint64_t value. There is no
+ // chance of overflow in this case.
+ success =
+ set_property("Time",
+ g_variant_new_uint64(static_cast<uint64_t>(time)),
+ response,
+ error);
+ } else {
+ response.send_error("Time value is earlier than epoch (negative): "
+ + boost::lexical_cast<std::string>(time));
+ }
+
+ return success;
+}
+
+bool
+ivi::settings::clock::set_timezone(JsonReader * reader,
+ response_callback response,
+ GError *& error)
+{
+ bool success = false;
+
+ if (json_reader_read_member(reader, "value")) {
+ char const * const timezone = json_reader_get_string_value(reader);
+ success = this->set_property("Timezone",
+ g_variant_new_string(timezone),
+ response,
+ error);
+ }
+
+ json_reader_end_member(reader);
+
+ return success;
+}
+
+bool
+ivi::settings::clock::set_updates(char const * name,
+ JsonReader * reader,
+ response_callback response,
+ GError *& error)
+{
+ bool success = false;
+
+ char const * updates = nullptr;
+ if (json_reader_read_member(reader, "value")) {
+ updates = json_reader_get_string_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (updates == nullptr
+ || (strcmp(updates, "manual") != 0
+ && strcmp(updates, "auto") != 0)) {
+ response.send_error(id()
+ + ": updates value not \"manual\" "
+ "or \"auto\": "
+ + (updates == nullptr
+ ? "<invalid_string>"
+ : updates));
+ } else {
+ smart_ptr<GVariant> const current_value(get_property(name, error));
+
+ if (current_value != nullptr) {
+ char const * value =
+ g_variant_get_string(current_value.get(), nullptr);
+
+ if (strcmp(value, updates) == 0) {
+ // Already set. Just return success, otherwise we'll timeout
+ // waiting for a PropertyChanged signal that'll never come.
+ return true;
+ }
+ }
+
+ success = set_property(name,
+ g_variant_new_string(updates),
+ response,
+ error);
+ }
+
+ return success;
+}
+
+void
+ivi::settings::clock::is_updates_auto(char const * name,
+ JsonReader * reader,
+ response_callback response,
+ GError *& error)
+{
+ bool null = false;
+ if (json_reader_read_member(reader, "value")) {
+ null = json_reader_get_null_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (!null) {
+ response.send_error(std::string(name) + " query parameter is not null.");
+ return;
+ }
+
+ smart_ptr<GVariant> const current_value(get_property(name, error));
+
+ if (current_value != nullptr) {
+ char const * value =
+ g_variant_get_string(current_value.get(), nullptr);
+
+ bool const is_auto = (strcmp(value, "auto") == 0);
+
+ response.send_response(
+ [is_auto](JsonBuilder * builder)
+ {
+ json_builder_set_member_name(builder, "value");
+ json_builder_add_boolean_value(builder, is_auto);
+ });
+ }
+}
+
+bool
+ivi::settings::clock::set_property(char const * name,
+ GVariant * value,
+ response_callback response,
+ GError *& error)
+{
+ bool success = false;
+
+ // Get notified when the clock property has changed.
+ auto property_promise = connman_.get_property_changed_promise(name);
+ auto property_future = property_promise->get_future();
+
+ smart_ptr<GVariant> const ret(
+ connman_.set_property(name, value, error));
+
+ if (ret != nullptr) {
+ static int const timeout = 5000; // milliseconds
+
+ // Block until the clock property has changed..
+ std::future_status const status =
+ property_future.wait_for(std::chrono::milliseconds(timeout));
+
+ if (status == std::future_status::ready) {
+ smart_ptr<GVariant> const value(property_future.get());
+ success = true;
+ } else {
+ response.send_error(
+ std::string("Wait for clock property \"")
+ + name + "\" set failed: "
+ + (status == std::future_status::timeout
+ ? "timeout"
+ : "deferred"));
+ }
+ }
+
+ return success;
+}
+
+GVariant *
+ivi::settings::clock::get_property(char const * property,
+ GError *& error) const
+{
+ constexpr gint const timeout = 5000; // milliseconds
+
+ smart_ptr<GVariant> const dictionary(
+ g_dbus_proxy_call_sync(connman_.proxy(),
+ "GetProperties",
+ nullptr, // No parameters
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error));
+
+ smart_ptr<GVariant> value;
+
+ if (dictionary != nullptr) {
+ GVariantIter * i = nullptr;
+ g_variant_get(dictionary.get(), "(a{sv})", &i);
+ smart_ptr<GVariantIter> const iter(i);
+
+ gchar * pname = nullptr;
+ GVariant * pvalue = nullptr;
+
+ while (g_variant_iter_next(i, "{sv}", &pname, &pvalue)) {
+ smart_ptr<gchar> const name(pname);
+ value.reset(pvalue);
+
+ // Check if this is the property we want.
+ if (strcmp(name.get(), property) == 0)
+ break;
+ }
+ }
+
+ return value.release();
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/clock.hpp b/plugins/connman/clock.hpp
new file mode 100644
index 0000000..e902af4
--- /dev/null
+++ b/plugins/connman/clock.hpp
@@ -0,0 +1,136 @@
+/**
+ * @file clock.hpp
+ *
+ * @brief Clock settings plugin.
+ *
+ * Connman-based clock settings plugin.
+ *
+ * @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 header is internal. Settings provider plugin implementors
+ * should write their own library/symbol export macros as
+ * needed.
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_CLOCK_HPP
+#define IVI_SETTINGS_CONNMAN_CLOCK_HPP
+
+#include "connman.hpp"
+#include <settingsd/plugin.hpp>
+
+#include <json-glib/json-glib.h>
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ class response_callback;
+
+ /**
+ * @class clock
+ *
+ * @brief Connman-based clock settings.
+ *
+ * This class implements all connman-based clock settings.
+ */
+ class clock : public plugin
+ {
+ public:
+
+ /// Constructor.
+ clock();
+
+ /// Destructor.
+ virtual ~clock();
+
+ /**
+ * @name Settings Plugin API
+ *
+ * Interface defined by the @c ivi::settings::plugin abstract
+ * base class.
+ *
+ * @see settingsd/plugin.hpp
+ */
+ //@{
+ virtual std::string const & id() const;
+ virtual void handle_request(std::string request,
+ response_callback response);
+ //@}
+
+ private:
+
+ /// Set the time.
+ bool set_time(JsonReader * reader,
+ response_callback response,
+ GError *& error);
+
+ /// Set the timezone.
+ bool set_timezone(JsonReader * reader,
+ response_callback response,
+ GError *& error);
+
+ /// Set time or timezone updates to manual or auto.
+ bool set_updates(char const * name,
+ JsonReader * reader,
+ response_callback response,
+ GError *& error);
+
+ /**
+ * Check if the TimeUpdates or TimezoneUpdate property is set
+ * to "auto".
+ */
+ void is_updates_auto(char const * name,
+ JsonReader * reader,
+ response_callback response,
+ GError *& error);
+
+ /// Set the clock property.
+ bool set_property(char const * name,
+ GVariant * value,
+ response_callback response,
+ GError *& error);
+
+ /// Get the clock property.
+ GVariant * get_property(char const * name,
+ GError *& error) const;
+
+ private:
+
+ /// Underlying connman proxy.
+ connman connman_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_CLOCK_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
+
diff --git a/plugins/connman/connman.cpp b/plugins/connman/connman.cpp
new file mode 100644
index 0000000..a3864c8
--- /dev/null
+++ b/plugins/connman/connman.cpp
@@ -0,0 +1,197 @@
+/**
+ * @file connman.cpp
+ *
+ * @brief Connman-based settings plugin.
+ *
+ * @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 "connman.hpp"
+
+#include <settingsd/reverse_lock.hpp>
+
+#include <cstring>
+#include <string>
+#include <stdexcept>
+
+
+namespace
+{
+ void
+ on_property_changed(GDBusConnection * /* connection */,
+ char const * /* sender_name */,
+ char const * /* object_path */,
+ char const * /* interface_name */,
+ char const * /* signal_name */,
+ GVariant * parameters,
+ gpointer user_data)
+ {
+ // Notify callers about the scan results.
+ typedef ivi::settings::connman::user_data user_data_type;
+
+ user_data_type * const data = static_cast<user_data_type *>(user_data);
+
+ std::lock_guard<std::mutex> lock(data->mutex);
+ auto const end = data->promises.end();
+ for (auto i = data->promises.begin(); i != end; ) {
+ gchar * pname = nullptr;
+ GVariant * pvalue = nullptr;
+
+ g_variant_get(parameters, "(sv)", &pname, &pvalue);
+
+ using namespace ivi::settings;
+
+ smart_ptr<gchar> name(pname);
+ smart_ptr<GVariant> value(pvalue);
+
+ auto & p = *i;
+
+ // Set the value in the promise if the desired property name
+ // matches.
+ if (strcmp(p.first, pname) == 0) {
+ {
+ // Release the mutex during the promise::set_value()
+ // call/notification so that we don't unnecessarily block
+ // threads attempting to get a property_changed promise.
+ typedef ivi::settings::reverse_lock<std::mutex> reverse_lock;
+ reverse_lock reverse(data->mutex);
+
+ std::lock_guard<reverse_lock> kcol(reverse);
+
+ p.second->set_value(std::move(value));
+ }
+
+ // Done with the pointer to the promise. Remove it from the
+ // list now since we already have an iterator to it.
+ i = data->promises.erase(i);
+ } else {
+ // Nothing to erase. Advance to the next list element.
+ ++i;
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------------------
+
+ivi::settings::connman::connman(char const * interface,
+ char const * path)
+ : proxy_(nullptr)
+ , mutex_()
+ , promises_()
+ , data_(mutex_, promises_)
+ , subscription_id_(0)
+{
+ static char const name[] = "net.connman"; // Service
+
+ GError * error = nullptr;
+
+ proxy_ =
+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ nullptr, // GDBusInterfaceInfo
+ name,
+ path,
+ interface,
+ nullptr, // GCancellable
+ &error);
+
+ smart_ptr<GError> safe_error(error);
+
+ if (proxy_ == nullptr) {
+ g_printerr("Unable to create D-Bus proxy for (\"%s\", \"%s\"): %s\n",
+ interface,
+ path,
+ error->message);
+
+ throw std::runtime_error(error->message);
+ }
+
+ // Listen for changes to properties.
+ subscription_id_ =
+ g_dbus_connection_signal_subscribe(
+ g_dbus_proxy_get_connection(G_DBUS_PROXY(proxy_)),
+ nullptr,
+ interface,
+ "PropertyChanged",
+ path,
+ nullptr,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_property_changed,
+ &data_,
+ nullptr);
+}
+
+ivi::settings::connman::~connman()
+{
+ if (proxy_ != nullptr) {
+ g_dbus_connection_signal_unsubscribe(
+ g_dbus_proxy_get_connection(G_DBUS_PROXY(proxy_)),
+ subscription_id_);
+
+ g_object_unref(proxy_);
+ }
+}
+
+GVariant *
+ivi::settings::connman::set_property(char const * property,
+ GVariant * value,
+ GError *& error)
+{
+ static gint const timeout = 5000; // milliseconds
+
+ return g_dbus_proxy_call_sync(proxy_,
+ "SetProperty", // Method name
+ g_variant_new("(sv)",
+ property,
+ value),
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error);
+}
+
+ivi::settings::connman::shared_promise_type
+ivi::settings::connman::get_property_changed_promise(
+ char const * property)
+{
+ // This promise must exist long enough for the value to retrieved
+ // from the future. Use a shared_ptr<> to make that possible.
+ shared_promise_type promise = std::make_shared<promise_type>();
+
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ // Add a new std::promise to the promises list. The promise will
+ // only be used once, and will be removed once its value has been
+ // set.
+ promises_.push_back(std::make_pair(property, promise));
+ }
+
+ return promise;
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/connman.hpp b/plugins/connman/connman.hpp
new file mode 100644
index 0000000..fa51caa
--- /dev/null
+++ b/plugins/connman/connman.hpp
@@ -0,0 +1,198 @@
+/**
+ * @file connman.hpp
+ *
+ * @brief Connman-based settings plugin 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
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_HPP
+#define IVI_SETTINGS_CONNMAN_HPP
+
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/smart_ptr.hpp>
+
+#include <gio/gio.h>
+
+#include <future>
+#include <utility>
+#include <list>
+#include <memory>
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ /**
+ * @class connman
+ *
+ * @brief Common connman-based settings functionality.
+ *
+ * This class implements functionality common to all connman-based
+ * settings, such as bluetooth, wifi, date/time, etc.
+ */
+ class connman
+ {
+ public:
+
+ /**
+ * Constructor.
+ *
+ * @param[in] interface Connman D-Bus interface.
+ * @param[in] path Connman D-Bus object path.
+ */
+ connman(char const * interface,
+ char const * path);
+
+ /// Destructor.
+ ~connman();
+
+ /// The type held by the @c future containing the async result.
+ typedef smart_ptr<GVariant> future_value_type;
+
+ /// The @c future type returned by the @c promise.
+ typedef std::future<future_value_type> future_type;
+
+ /// The @c promise that provides the async result.
+ typedef std::promise<future_value_type> promise_type;
+
+ /**
+ * Smart pointer to the @c promise that provides the async
+ * result.
+ */
+ typedef std::shared_ptr<promise_type> shared_promise_type;
+
+ /**
+ * Property Name/value pair type held by the @c future
+ * containing the async result. Both values will be populated
+ * when retrieving the value from the @c PropertyChanged
+ * signal.
+ *
+ * @note The property name is meant for internal use.
+ */
+ typedef std::pair<char const *,
+ shared_promise_type> promise_value_type;
+
+ /// List type for promises to be updated with async result.
+ typedef std::list<promise_value_type> promise_list_type;
+
+ /**
+ * Set @a property to given @a value on the underlying connman
+ * object.
+ *
+ * @param[in] property The name of the property to be set.
+ * @param[in] value The property value to be set.
+ * @param[inout] error The error object containing information
+ * on a failed connman @c SetProperty method
+ * call.
+ *
+ * @returns @c nullptr on a failed call to the connman
+ * @c SetProperty method.
+ */
+ GVariant * set_property(char const * property,
+ GVariant * value,
+ GError *& error);
+
+ /**
+ * Get a promise that will contain the changed connman property
+ * when it becomes available. The user must obtain the value
+ * from the corresponding future object.
+ */
+ shared_promise_type get_property_changed_promise(
+ char const * property);
+
+ /// Get pointer to underlying GDBusProxy.
+ GDBusProxy * proxy() const { return proxy_; }
+
+ /// Convenience function to get D-Bus interface name.
+ char const *
+ interface_name() const
+ {
+ return g_dbus_proxy_get_interface_name(proxy_);
+ }
+
+ /// Convenience function to get D-Bus object path.
+ char const *
+ object_path() const
+ {
+ return g_dbus_proxy_get_object_path(proxy_);
+ }
+
+ /**
+ * @struct user_data
+ *
+ * @brief Struct passed to @c ServicesChanged signal handler.
+ */
+ struct user_data
+ {
+ /// Constructor.
+ user_data(std::mutex & m, promise_list_type & p)
+ : mutex(m)
+ , promises(p)
+ {
+ }
+
+ /**
+ * References to mutex used to synchronize access to the list
+ * of promises.
+ */
+ std::mutex & mutex;
+
+ /// List of promises to be updated with the changed services.
+ promise_list_type & promises;
+ };
+
+ private:
+
+ /// The proxy used to access the Connman D-Bus API.
+ GDBusProxy * proxy_;
+
+ /// Mutex used to synchronize access to the promises list.
+ std::mutex mutex_;
+
+ /**
+ * List of promises that will be updated with the
+ * PropertyChanged signal results.
+ */
+ promise_list_type promises_;
+
+ /// User data passed to @c PropertyChanged signal handler.
+ user_data data_;
+
+ /// PropertyChanged signal subscription ID.
+ guint subscription_id_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/connman_api.hpp b/plugins/connman/connman_api.hpp
new file mode 100644
index 0000000..232fb56
--- /dev/null
+++ b/plugins/connman/connman_api.hpp
@@ -0,0 +1,66 @@
+/**
+ * @file connman_api.hpp
+ *
+ * @brief @c Connman-based settings plugin export macros.
+ *
+ * The IVI connman settings plugin uses these macros to
+ * export the settings plugin API from the plugin as needed.
+ *
+ * @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
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_API_HPP
+#define IVI_SETTINGS_CONNMAN_API_HPP
+
+# if defined _WIN32 || defined __CYGWIN__
+# ifdef IVI_SETTINGS_CONNMAN_BUILDING_DLL
+# ifdef __GNUC__
+# define IVI_SETTINGS_CONNMAN_API __attribute__ ((dllexport))
+# else
+# define IVI_SETTINGS_CONNMAN_API __declspec(dllexport)
+# endif
+# else
+# ifdef __GNUC__
+# define IVI_SETTINGS_CONNMAN_API __attribute__ ((dllimport))
+# else
+# define IVI_SETTINGS_CONNMAN_API __declspec(dllimport)
+# endif
+# endif
+# define IVI_SETTINGS_CONNMAN_LOCAL
+# else
+# if __GNUC__ >= 4
+# define IVI_SETTINGS_CONNMAN_API __attribute__ ((visibility ("default")))
+# define IVI_SETTINGS_CONNMAN_LOCAL __attribute__ ((visibility ("hidden")))
+# else
+# define IVI_SETTINGS_CONNMAN_API
+# define IVI_SETTINGS_CONNMAN_LOCAL
+# endif
+# endif
+
+#endif /* IVI_SETTINGS_CONNMAN_API_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/connman_manager.cpp b/plugins/connman/connman_manager.cpp
new file mode 100644
index 0000000..0be40e8
--- /dev/null
+++ b/plugins/connman/connman_manager.cpp
@@ -0,0 +1,228 @@
+/**
+ * @file connman_manager.cpp
+ *
+ * @brief Connman_Manager-based settings plugin.
+ *
+ * @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 "connman_manager.hpp"
+
+#include <settingsd/json_glib_traits.hpp>
+#include <settingsd/reverse_lock.hpp>
+
+#include <cstring>
+
+
+namespace
+{
+ void
+ on_services_changed(GDBusConnection * /* connection */,
+ char const * /* sender_name */,
+ char const * /* object_path */,
+ char const * /* interface_name */,
+ char const * /* signal_name */,
+ GVariant * parameters,
+ gpointer user_data)
+ {
+ gsize const num_params = g_variant_n_children(parameters);
+ if (num_params != 2) {
+ // We should never get here!
+ g_printerr("Number of ServicesChanged signal parameters "
+ "is not 2: %" G_GSIZE_FORMAT "\n",
+ num_params);
+
+ return;
+ }
+
+ using namespace ivi::settings;
+
+ // Changed services are found in the first ServicesChanged
+ // argument.
+ smart_ptr<GVariant> const changed_services(
+ g_variant_get_child_value(parameters, 0));
+
+ // Serialize the changed services into a JSON tree. This will be
+ // an array of [object, dict], where "object" is the D-Bus object
+ // path, and "dict" is a dictionary of object-specific
+ // properties.
+ smart_ptr<JsonNode> services(
+ json_gvariant_serialize(changed_services.get()));
+
+ // Notify callers about the scan results.
+ typedef connman_manager::user_data user_data_type;
+
+ user_data_type * const p = static_cast<user_data_type *>(user_data);
+ connman_manager::promise_list_type & promises = p->promises;
+
+ // Synchronize access to the promises list.
+ std::lock_guard<std::mutex> lock(p->mutex);
+
+ // Note that the end() iterator must be retrieved during each loop
+ // iteration in case another thread caused another promise to be
+ // added to the list when the lock was temporarily unlocked during
+ // the promise::set_value() call below.
+ for (auto i = promises.begin(); i != promises.end(); ) {
+ auto & promise = *i;
+
+ {
+ // Release the mutex during the promise::set_value()
+ // call/notification so that we don't unnecessarily block
+ // threads attempting to get a services_changed promise.
+ typedef ivi::settings::reverse_lock<std::mutex> reverse_lock;
+ reverse_lock reverse(p->mutex);
+
+ std::lock_guard<reverse_lock> kcol(reverse);
+
+ // Thread that owns the corresponding future must transfer
+ // ownership of the JsonNode to something that will release
+ // the underlying JsonNode, e.g. a JsonBuilder via
+ // json_builder_add_value() or another smart_ptr<JsonNode>.
+ promise->set_value(std::move(services));
+ }
+
+ // Done with the pointer to the promise. Remove it from the
+ // list now since we already have an iterator to it.
+ i = promises.erase(i);
+ }
+ }
+
+}
+
+// ---------------------------------------------------------------
+
+ivi::settings::connman_manager::connman_manager()
+ : connman_("net.connman.Manager", // Interface
+ "/") // Object path
+ , mutex_()
+ , promises_()
+ , data_(mutex_, promises_)
+ , subscription_id_(
+ g_dbus_connection_signal_subscribe(
+ g_dbus_proxy_get_connection(G_DBUS_PROXY(connman_.proxy())),
+ nullptr,
+ connman_.interface_name(),
+ "ServicesChanged",
+ connman_.object_path(),
+ nullptr,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_services_changed,
+ &data_,
+ nullptr))
+{
+}
+
+ivi::settings::connman_manager::~connman_manager()
+{
+ g_dbus_connection_signal_unsubscribe(
+ g_dbus_proxy_get_connection(G_DBUS_PROXY(connman_.proxy())),
+ subscription_id_);
+}
+
+GVariant *
+ivi::settings::connman_manager::get_properties(
+ std::string const & technology,
+ GError *& error) const
+{
+ constexpr gint const timeout = 5000; // milliseconds
+
+ smart_ptr<GVariant> const dictionary(
+ g_dbus_proxy_call_sync(connman_.proxy(),
+ "GetTechnologies",
+ nullptr, // No parameters
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error));
+
+ if (dictionary != nullptr) {
+ GVariantIter * i = nullptr;
+ g_variant_get(dictionary.get(), "(a(oa{sv}))", &i);
+ smart_ptr<GVariantIter> const safe_i(i);
+
+ for (smart_ptr<GVariant> child(g_variant_iter_next_value(i));
+ child != nullptr;
+ child.reset(g_variant_iter_next_value(i))) {
+
+ // The object path is the first tuple element.
+ smart_ptr<GVariant> const tmp(
+ g_variant_get_child_value(child.get(), 0));
+
+ char const * object =
+ g_variant_get_string(tmp.get(), nullptr);
+
+ // The technology is found at end the object path,
+ // e.g. "/net/connman/technology/wifi" for the wifi.
+ char const * tech = strrchr(object, '/');
+
+ if (tech != nullptr) {
+ ++tech; // Skip the found '/'.
+
+ if (technology == tech) {
+ // The property dictionary is the second tuple element.
+ return g_variant_get_child_value(child.get(), 1);
+ }
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+GVariant *
+ivi::settings::connman_manager::get_services(GError *& error) const
+{
+ constexpr gint const timeout = 5000; // milliseconds
+
+ return g_dbus_proxy_call_sync(connman_.proxy(),
+ "GetServices",
+ nullptr, // No parameters
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error);
+}
+
+ivi::settings::connman_manager::shared_promise_type
+ivi::settings::connman_manager::get_services_changed_promise()
+{
+ // This promise must exist long enough for the value to retrieved
+ // from the future. Use a shared_ptr<> to make that possible.
+ shared_promise_type p = std::make_shared<promise_type>();
+
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ // Add a new std::promise to the promises list. The promise will
+ // only be used once, and will be removed once its value has been
+ // set.
+ promises_.push_back(p);
+ }
+
+ return p;
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/connman_manager.hpp b/plugins/connman/connman_manager.hpp
new file mode 100644
index 0000000..352b9fe
--- /dev/null
+++ b/plugins/connman/connman_manager.hpp
@@ -0,0 +1,175 @@
+/**
+ * @file connman_manager.hpp
+ *
+ * @brief Connman connman_manager-based settings plugin 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
+ */
+
+#ifndef IVI_SETTINGS_CONNMAN_MANAGER_HPP
+#define IVI_SETTINGS_CONNMAN_MANAGER_HPP
+
+#include "connman.hpp"
+
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/smart_ptr.hpp>
+
+#include <gio/gio.h>
+#include <json-glib/json-glib.h>
+
+#include <future>
+#include <list>
+#include <memory>
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ /**
+ * @class connman_manager
+ *
+ * @brief Common connman-based settings functionality.
+ *
+ * This class implements functionality common to all connman-based
+ * settings, such as bluetooth, wifi, date/time, etc.
+ */
+ class connman_manager
+ {
+ public:
+
+ /// Constructor.
+ connman_manager();
+
+ /// Destructor.
+ ~connman_manager();
+
+ /**
+ * Get the properties for a specific technology.
+ *
+ * @param[in] technology Connman technology for which properties
+ * are being retrieved.
+ * @param[inout] error Glib error object that contains
+ * additional error information if
+ * non-null if the call completes.
+ *
+ * @return @c GVariant containing a dictionary of properties
+ * specific to @a technology.
+ */
+ GVariant * get_properties(std::string const & technology,
+ GError *& error) const;
+
+ /**
+ * Get connman services and their properties.
+ *
+ * @param[inout] error Glib error object that contains
+ * additional error information if
+ * non-null if the call completes.
+ *
+ * @return @c GVariant containing a dictionary services and
+ * corresponding properties.
+ */
+ GVariant * get_services(GError *& error) const;
+
+ /// The type held by the @c future containing the async result.
+ typedef smart_ptr<JsonNode> future_value_type;
+
+ /// The @c future type returned by the @c promise.
+ typedef std::future<future_value_type> future_type;
+
+ /// The @c promise that provides the async result.
+ typedef std::promise<future_value_type> promise_type;
+
+ /**
+ * Smart pointer to the @c promise that provides the async
+ * result.
+ */
+ typedef std::shared_ptr<promise_type> shared_promise_type;
+
+ /// List type for promises to be updated with async result.
+ typedef std::list<shared_promise_type> promise_list_type;
+
+ /**
+ * Get a promise that will contain changed connman services when
+ * they become available. The user must obtain the value from
+ * the corresponding future object and release the @c JsonNode*
+ * value contained within that future with @c json_node_free().
+ */
+ shared_promise_type get_services_changed_promise();
+
+ /**
+ * @struct user_data
+ *
+ * @brief Struct passed to @c ServicesChanged signal handler.
+ */
+ struct user_data
+ {
+ /// Constructor.
+ user_data(std::mutex & m, promise_list_type & p)
+ : mutex(m)
+ , promises(p)
+ {
+ }
+
+ /**
+ * References to mutex used to synchronize access to the list
+ * of promises.
+ */
+ std::mutex & mutex;
+
+ /// List of promises to be updated with the changed services.
+ promise_list_type & promises;
+ };
+
+ private:
+
+ /// The proxy used to access the connman Manager D-Bus API.
+ connman connman_;
+
+ /// Mutex used to synchronize access to the promises list.
+ std::mutex mutex_;
+
+ /**
+ * List of promises that will be updated with the
+ * ServicesChanged signal results.
+ */
+ promise_list_type promises_;
+
+ /// User data passed to @c ServicesChanged signal handler.
+ user_data data_;
+
+ /// ServicesChanged signal subscription ID.
+ guint const subscription_id_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_MANAGER_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/ethernet.cpp b/plugins/connman/ethernet.cpp
new file mode 100644
index 0000000..3e8699c
--- /dev/null
+++ b/plugins/connman/ethernet.cpp
@@ -0,0 +1,66 @@
+/**
+ * @file ethernet.cpp
+ *
+ * @brief Connman-based ethernet settings.
+ *
+ * @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 "ethernet.hpp"
+#include <settingsd/response_callback.hpp>
+
+// ----------------------------------------------------------------------
+
+namespace
+{
+ std::string const technology_name("ethernet");
+}
+
+// ----------------------------------------------------------------------
+
+ivi::settings::ethernet::ethernet()
+ : technology_(technology_name)
+{
+}
+
+ivi::settings::ethernet::~ethernet()
+{
+}
+
+std::string const &
+ivi::settings::ethernet::id() const
+{
+ return technology_name;
+}
+
+void
+ivi::settings::ethernet::handle_request(std::string request,
+ response_callback response)
+{
+ technology_.handle_request(request, response);
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/ethernet.hpp b/plugins/connman/ethernet.hpp
new file mode 100644
index 0000000..65bf7fe
--- /dev/null
+++ b/plugins/connman/ethernet.hpp
@@ -0,0 +1,96 @@
+/**
+ * @file ethernet.hpp
+ *
+ * @brief Ethernet settings plugin.
+ *
+ * Connman-based ethernet settings plugin.
+ *
+ * @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 header is internal. Settings provider plugin implementors
+ * should write their own library/symbol export macros as
+ * needed.
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_ETHERNET_HPP
+#define IVI_SETTINGS_CONNMAN_ETHERNET_HPP
+
+#include <settingsd/plugin.hpp>
+
+#include "technology.hpp"
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ /**
+ * @class ethernet
+ *
+ * @brief Connman-based ethernet settings.
+ *
+ * This class implements all connman-based ethernet settings.
+ */
+ class ethernet : public plugin
+ {
+ public:
+
+ /// Constructor.
+ ethernet();
+
+ /// Destructor.
+ virtual ~ethernet();
+
+ /**
+ * @name Settings Plugin API
+ *
+ * Interface defined by the @c ivi::settings::plugin abstract
+ * base class.
+ *
+ * @see settingsd/plugin.hpp
+ */
+ //@{
+ virtual std::string const & id() const;
+ virtual void handle_request(std::string request,
+ response_callback response);
+ //@}
+
+ private:
+
+ /// Underlying connman proxy.
+ technology technology_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_ETHERNET_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
+
diff --git a/plugins/connman/registration.cpp b/plugins/connman/registration.cpp
new file mode 100644
index 0000000..2719f3d
--- /dev/null
+++ b/plugins/connman/registration.cpp
@@ -0,0 +1,65 @@
+/**
+ * @file registration.cpp
+ *
+ * @brief Connman-based settings plugin registration.
+ *
+ * @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 "connman_api.hpp"
+#include "bluetooth.hpp"
+#include "clock.hpp"
+#include "ethernet.hpp"
+#include "wifi.hpp"
+
+#include <settingsd/registrar.hpp>
+
+#include <memory>
+
+
+/// Plugin factory/registration function.
+extern "C" IVI_SETTINGS_CONNMAN_API bool
+register_settings(ivi::settings::registrar & r)
+{
+ std::unique_ptr<ivi::settings::plugin> bt(
+ new ivi::settings::bluetooth);
+
+ std::unique_ptr<ivi::settings::plugin> clk(
+ new ivi::settings::clock);
+
+ std::unique_ptr<ivi::settings::plugin> eth(
+ new ivi::settings::ethernet);
+
+ std::unique_ptr<ivi::settings::plugin> wifi(
+ new ivi::settings::wifi);
+
+ return
+ r.register_setting(std::move(bt))
+ && r.register_setting(std::move(clk))
+ && r.register_setting(std::move(eth))
+ && r.register_setting(std::move(wifi));
+}
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/service.cpp b/plugins/connman/service.cpp
new file mode 100644
index 0000000..ecf267d
--- /dev/null
+++ b/plugins/connman/service.cpp
@@ -0,0 +1,87 @@
+/**
+ * @file service.cpp
+ *
+ * @brief Connman service request handling.
+ *
+ * @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 "service.hpp"
+
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/smart_ptr.hpp>
+#include <settingsd/response_callback.hpp>
+
+#include <chrono>
+
+
+ivi::settings::service::service(std::string service_path)
+ : connman_("net.connman.Service", // Interface
+ service_path.c_str()) // Object path
+{
+}
+
+void
+ivi::settings::service::connect(response_callback response)
+{
+ call_method("Connect", response);
+}
+
+void
+ivi::settings::service::disconnect(response_callback response)
+{
+ call_method("Disconnect", response);
+}
+
+void
+ivi::settings::service::call_method(char const * name,
+ response_callback response)
+{
+ constexpr gint const timeout = 10000; // milliseconds
+ GError * error = nullptr;
+
+ smart_ptr<GVariant> const ret(
+ g_dbus_proxy_call_sync(connman_.proxy(),
+ name, // "Connect", "Disconect", ...
+ nullptr, // No parameters
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error));
+
+ smart_ptr<GError> safe_error;
+
+ if (ret != nullptr) {
+ // Nothing to add to successful response.
+ response.send_response(
+ [](JsonBuilder * /* builder */) {});
+
+ } else if (error != nullptr) {
+ response.send_error(std::string(name) + " failed: " + error->message);
+ }
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/service.hpp b/plugins/connman/service.hpp
new file mode 100644
index 0000000..a10268e
--- /dev/null
+++ b/plugins/connman/service.hpp
@@ -0,0 +1,97 @@
+/**
+ * @file service.hpp
+ *
+ * @brief Connman service request handling.
+ *
+ * @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
+ */
+
+#ifndef IVI_SETTINGS_CONNMAN_SERVICE_HPP
+#define IVI_SETTINGS_CONNMAN_SERVICE_HPP
+
+#include "connman.hpp"
+#include "connman_manager.hpp"
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ class response_callback;
+
+ /**
+ * @class service
+ *
+ * @brief Connman Service object proxy.
+ *
+ * This class exposes functionality found in the connman
+ * @c Service interface to the caller.
+ */
+ class service
+ {
+ public:
+
+ /**
+ * Constructor.
+ *
+ * @param[in] service_path The D-Bus object path for connman
+ * service.
+ */
+ service(std::string service_path);
+
+ /// Connect to the service.
+ void connect(response_callback response);
+
+ /// Disconnect from the service.
+ void disconnect(response_callback response);
+
+ private:
+
+ /**
+ * Call the method @a name on the connman Service object.
+ *
+ * @param[in] name The connman Service object method
+ * name.
+ * @param[inout] response Callback used to inform the caller of
+ * success or failure.
+ */
+ void call_method(char const * name,
+ response_callback response);
+
+ private:
+
+ /// The proxy used to access the connman Service D-Bus API.
+ connman connman_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_SERVICE_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/technology.cpp b/plugins/connman/technology.cpp
new file mode 100644
index 0000000..bda9a1e
--- /dev/null
+++ b/plugins/connman/technology.cpp
@@ -0,0 +1,357 @@
+/**
+ * @file technology.cpp
+ *
+ * @brief Connman technology request handling.
+ *
+ * @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 "technology.hpp"
+#include "service.hpp"
+#include <settingsd/response_callback.hpp>
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/json_glib_traits.hpp>
+#include <settingsd/smart_ptr.hpp>
+
+#include <cstring>
+#include <chrono>
+
+
+ivi::settings::technology::technology(std::string tech)
+ : connman_("net.connman.Technology", // Interface
+ ("/net/connman/technology/"
+ + tech).c_str()) // Object path
+ , manager_()
+ , technology_(tech)
+{
+}
+
+void
+ivi::settings::technology::handle_request(std::string request,
+ response_callback response)
+{
+ smart_ptr<JsonParser> const parser(json_parser_new());
+ json_parser_load_from_data(parser.get(), request.c_str(), -1, nullptr);
+
+ smart_ptr<JsonReader> const safe_reader(
+ json_reader_new(json_parser_get_root(parser.get())));
+ JsonReader * const reader = safe_reader.get();
+
+ char const * name = nullptr;
+ if (json_reader_read_member(reader, "name"))
+ name = json_reader_get_string_value(reader);
+ else
+ response.send_error(
+ "Malformed " + technology_ + " request: missing 'name' element");
+
+ json_reader_end_member(reader);
+
+ if (name != nullptr) {
+ if (strcmp(name, "is_enabled") == 0)
+ get_powered(reader, response);
+ else if (strcmp(name, "enable") == 0)
+ set_powered(reader, response);
+ else if (strcmp(name, "scan") == 0)
+ scan(reader, response);
+ else if (strcmp(name, "connect") == 0)
+ connect(reader, response);
+ else if (strcmp(name, "disconnect") == 0)
+ disconnect(reader, response);
+ else {
+ response.send_error(
+ "Unrecognized " + technology_ + " request name: "
+ + name);
+ }
+ } else {
+ response.send_error(
+ "Operation name for " + technology_ + " request is not a string.");
+ }
+}
+
+void
+ivi::settings::technology::get_powered(JsonReader * reader,
+ response_callback response)
+{
+ bool null = false;
+ if (json_reader_read_member(reader, "value")) {
+ null = json_reader_get_null_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (!null) {
+ response.send_error(
+ technology_ + " is_enabled parameter is not null.");
+ return;
+ }
+
+ smart_ptr<GVariant> const property(
+ get_property("Powered", G_VARIANT_TYPE_BOOLEAN, response));
+
+ if (property != nullptr) {
+ bool const powered = g_variant_get_boolean(property.get());
+
+ response.send_response(
+ [powered](JsonBuilder * builder)
+ {
+ json_builder_set_member_name(builder, "value");
+ json_builder_add_boolean_value(builder, powered);
+ });
+ }
+
+ // Error responses handled in get_property() method.
+}
+
+void
+ivi::settings::technology::set_powered(JsonReader * reader,
+ response_callback response)
+{
+ bool enable = false;
+ if (json_reader_read_member(reader, "value")) {
+ enable = json_reader_get_boolean_value(reader);
+ }
+
+ json_reader_end_member(reader);
+
+ constexpr char const name[] = "Powered";
+
+ // Get notified when the technology property has changed.
+ auto property_promise = connman_.get_property_changed_promise(name);
+ auto property_future = property_promise->get_future();
+
+ GError * error = nullptr;
+
+ smart_ptr<GVariant> ret(
+ connman_.set_property(name,
+ g_variant_new_boolean(enable),
+ error));
+
+ smart_ptr<GError> safe_error(error);
+
+ if (ret != nullptr) {
+ constexpr int const timeout = 5000; // milliseconds
+
+ // Block until the technology property has changed..
+ std::future_status const status =
+ property_future.wait_for(std::chrono::milliseconds(timeout));
+
+ if (status == std::future_status::ready) {
+
+ // Nothing to add to successful response.
+ response.send_response(
+ [](JsonBuilder * /* builder */) {});
+
+ } else {
+
+ response.send_error(
+ std::string("Wait for enable status failed: ")
+ + (status == std::future_status::timeout
+ ? "timeout"
+ : "deferred"));
+
+ }
+ } else if (error != nullptr) {
+ response.send_error(
+ "Unable to set " + technology_ + " powered state: "
+ + error->message);
+ } else {
+ response.send_error(
+ "Malformed " + technology_ + " enable request value.");
+ }
+}
+
+void
+ivi::settings::technology::scan(JsonReader * reader,
+ response_callback response)
+{
+ bool null = false;
+ if (json_reader_read_member(reader, "value")) {
+ null = json_reader_get_null_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (!null) {
+ response.send_error(technology_ + " scan parameter is not null.");
+ return;
+ }
+
+ // Get notified when scan results are available.
+ auto services_promise = manager_.get_services_changed_promise();
+ auto services_future = services_promise->get_future();
+
+ // The scan could take a while.
+ constexpr gint const timeout = 10000; // milliseconds
+ GError * error = nullptr;
+
+ smart_ptr<GVariant> const ret(
+ g_dbus_proxy_call_sync(connman_.proxy(),
+ "Scan",
+ nullptr, // No parameters
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error));
+
+ smart_ptr<GError> safe_error(error);
+
+ if (ret != nullptr) {
+ constexpr gint const future_timeout = 5000; // milliseconds
+
+ // Block until the scan results are in.
+ std::future_status const status =
+ services_future.wait_for(std::chrono::milliseconds(future_timeout));
+
+ if (status != std::future_status::deferred) {
+ // Don't call get() if the future isn't ready. Otherwise this
+ // will be a blocking call.
+ if (status == std::future_status::ready) {
+ smart_ptr<JsonNode> const changed_services(services_future.get());
+ }
+
+ send_services(response, error);
+
+ // A timeout is okay since some services may not have changed
+ // within the timeout period but log it just in case.
+ if (status == std::future_status::timeout)
+ g_debug("%s settings: Timed out waiting for changed services.\n",
+ technology_.c_str());
+ } else {
+ // We only get here if the future status is
+ // std::future_status::deferred, meaning the result hasn't been
+ // determined yet. That should never happen in our case.
+ response.send_error("Wait for scan results failed: deferred");
+ }
+ } else if (error != nullptr) {
+ response.send_error(
+ "Unable to scan " + technology_ + ": "
+ + error->message);
+ } else {
+ response.send_error(
+ "Malformed " + technology_ + " scan request value.");
+ }
+}
+
+void
+ivi::settings::technology::connect(JsonReader * reader,
+ response_callback response)
+{
+ char const * service_path = nullptr;
+ if (json_reader_read_member(reader, "value")) {
+ service_path = json_reader_get_string_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ /// @todo Refactor malformed JSON request handling code.
+ if (service_path != nullptr) {
+ service s(service_path);
+ s.connect(response);
+ } else {
+ response.send_error(
+ "Malformed " + technology_ + " connect request value.");
+ }
+}
+
+void
+ivi::settings::technology::disconnect(JsonReader * reader,
+ response_callback response)
+{
+ char const * service_path = nullptr;
+ if (json_reader_read_member(reader, "value")) {
+ service_path = json_reader_get_string_value(reader);
+ }
+ json_reader_end_member(reader);
+
+ if (service_path != nullptr) {
+ service s(service_path);
+ s.disconnect(response);
+ } else {
+ response.send_error(
+ "Malformed " + technology_ + " disconnect request value.");
+ }
+}
+
+void
+ivi::settings::technology::send_services(response_callback response,
+ GError *& error)
+{
+ smart_ptr<GVariant> const services(manager_.get_services(error));
+
+ if (services != nullptr) {
+ response.send_response(
+ [&services](JsonBuilder * builder)
+ {
+ /**
+ * @todo Can @c json_gvariant_serialize() ever return a nullptr?
+ */
+ JsonNode * const value =
+ json_gvariant_serialize(services.get());
+
+ json_builder_set_member_name(builder, "value");
+ json_builder_add_value(builder, value);
+
+ // No need to free the JsonNode. The builder will take
+ // ownership of it.
+ });
+ }
+}
+
+GVariant *
+ivi::settings::technology::get_property(char const * name,
+ GVariantType const * type,
+ response_callback response)
+{
+ GError * error = nullptr;
+
+ smart_ptr<GVariant> const properties(
+ manager_.get_properties(technology_, error));
+
+ smart_ptr<GError> safe_error(error);
+
+ smart_ptr<GVariant> property;
+ if (properties != nullptr) {
+ property.reset(
+ g_variant_lookup_value(properties.get(), name, type));
+
+ if (property == nullptr) {
+ response.send_error(
+ "Internal " + technology_
+ + "error: \"" + name + "\" property lookup failed.");
+ }
+ } else if (error != nullptr) {
+ response.send_error(
+ "Unable to get " + technology_ + "properties: "
+ + error->message);
+ } else {
+ // This scenario will occur if the technology doesn't exist on
+ // the platform. For example, attempting to retrieve the wifi
+ // "Powered" property on a platform without supported hardware
+ // will result in this error.
+ response.send_error(technology_ + " properties are not available.");
+ }
+
+ return property.release();
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/technology.hpp b/plugins/connman/technology.hpp
new file mode 100644
index 0000000..44fdef6
--- /dev/null
+++ b/plugins/connman/technology.hpp
@@ -0,0 +1,139 @@
+/**
+ * @file technology.hpp
+ *
+ * @brief Connman technology request handling.
+ *
+ * @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
+ */
+
+#ifndef IVI_SETTINGS_CONNMAN_TECHNOLOGY_HPP
+#define IVI_SETTINGS_CONNMAN_TECHNOLOGY_HPP
+
+#include "connman.hpp"
+#include "connman_manager.hpp"
+
+#include <json-glib/json-glib.h>
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ class response_callback;
+
+ /**
+ * @class technology
+ *
+ * @brief Common technology-based settings functionality.
+ *
+ * This class implements functionality common to all technology-based
+ * settings, such as bluetooth, wifi, date/time, etc.
+ */
+ class technology
+ {
+ public:
+
+ /**
+ * Constructor.
+ *
+ * @param[in] tech The connman technology, e.g. "bluetooth".
+ */
+ technology(std::string tech);
+
+ /// Handle requests common to all connman technologies.
+ void handle_request(std::string request,
+ response_callback response);
+
+ private:
+
+ /// Get technology "Powered" state.
+ void get_powered(JsonReader * reader,
+ response_callback response);
+
+ /// Set technology "Powered" state.
+ void set_powered(JsonReader * reader,
+ response_callback response);
+
+ /**
+ * Scan for services that implement the technology, e.g. WiFi
+ * access points.
+ */
+ void scan(JsonReader * reader,
+ response_callback response);
+
+ /**
+ * Connect to service whose object path is found in the JSON
+ * request.
+ */
+ void connect(JsonReader * reader,
+ response_callback response);
+
+ /**
+ * Disconnect from service whose object path is found in the
+ * JSON request.
+ */
+ void disconnect(JsonReader * reader,
+ response_callback response);
+
+ /// Send list of services to caller.
+ void send_services(response_callback response,
+ GError *& error);
+
+ /**
+ * Get property for this technology.
+ *
+ * @param[in] name Name of the connman technology property
+ * to retrieve.
+ * @param[in] type The type of property being retrieved.
+ * @param[in] response The response callback through errors will
+ * be sent to the caller.
+ *
+ * @returns A @c GVariant containing the retrieved property.
+ */
+ GVariant * get_property(char const * name,
+ GVariantType const * type,
+ response_callback response);
+
+ private:
+
+ /// The proxy used to access the connman Technology D-Bus API.
+ connman connman_;
+
+ /// The proxy used to access the connman Manager D-Bus API.
+ connman_manager manager_;
+
+ /// Technology name, e.g. "bluetooth" or "wifi".
+ std::string const technology_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_TECHNOLOGY_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/wifi.cpp b/plugins/connman/wifi.cpp
new file mode 100644
index 0000000..15bebe6
--- /dev/null
+++ b/plugins/connman/wifi.cpp
@@ -0,0 +1,66 @@
+/**
+ * @file wifi.cpp
+ *
+ * @brief Connman-based wifi settings.
+ *
+ * @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 "wifi.hpp"
+#include <settingsd/response_callback.hpp>
+
+// ----------------------------------------------------------------------
+
+namespace
+{
+ std::string const technology_name("wifi");
+}
+
+// ----------------------------------------------------------------------
+
+ivi::settings::wifi::wifi()
+ : technology_(technology_name)
+{
+}
+
+ivi::settings::wifi::~wifi()
+{
+}
+
+std::string const &
+ivi::settings::wifi::id() const
+{
+ return technology_name;
+}
+
+void
+ivi::settings::wifi::handle_request(std::string request,
+ response_callback response)
+{
+ technology_.handle_request(request, response);
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
diff --git a/plugins/connman/wifi.hpp b/plugins/connman/wifi.hpp
new file mode 100644
index 0000000..d82c82b
--- /dev/null
+++ b/plugins/connman/wifi.hpp
@@ -0,0 +1,98 @@
+/**
+ * @file wifi.hpp
+ *
+ * @brief Wifi settings plugin.
+ *
+ * Connman-based wifi settings plugin.
+ *
+ * @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 header is internal. Settings provider plugin implementors
+ * should write their own library/symbol export macros as
+ * needed.
+ */
+
+
+#ifndef IVI_SETTINGS_CONNMAN_WIFI_HPP
+#define IVI_SETTINGS_CONNMAN_WIFI_HPP
+
+#include <settingsd/plugin.hpp>
+
+#include "technology.hpp"
+
+
+namespace ivi
+{
+ namespace settings
+ {
+ class response_callback;
+
+ /**
+ * @class wifi
+ *
+ * @brief Connman-based wifi settings.
+ *
+ * This class implements all connman-based wifi settings.
+ */
+ class wifi : public plugin
+ {
+ public:
+
+ /// Constructor.
+ wifi();
+
+ /// Destructor.
+ virtual ~wifi();
+
+ /**
+ * @name Settings Plugin API
+ *
+ * Interface defined by the @c ivi::settings::plugin abstract
+ * base class.
+ *
+ * @see settingsd/plugin.hpp
+ */
+ //@{
+ virtual std::string const & id() const;
+ virtual void handle_request(std::string request,
+ response_callback response);
+ //@}
+
+ private:
+
+ /// Underlying connman proxy.
+ technology technology_;
+
+ };
+
+ }
+}
+
+
+#endif /* IVI_SETTINGS_CONNMAN_WIFI_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
+