tests/settings_test
config.*
!plugins/connman/config.h
+plugins/connman/settings-agent.conf
!packaging/settingsd.socket
*.tar.*
doc/doxygen
%{_libdir}/libsettings.so.*
%{pkglibdir}/*.so
%config %{_sysconfdir}/%{name}/*
+%config %{_sysconfdir}/dbus-1/system.d/settings-agent.conf
%{_unitdir_user}/settingsd.service
%{_unitdir_user}/weston.target.wants/settingsd.service
IVI_SETTINGS_PLUGIN_LIBRARY = $(top_builddir)/lib/libsettings.la
+## The D-Bus name that will be owned by the settings daemon's connman
+## Agent.
+IVI_SETTINGS_CONNMAN_AGENT_DBUS_NAME = \
+ "$(IVI_SETTINGS_DBUS_NAME).connman.Agent"
+
connman_la_SOURCES = \
dbus_connection.cpp \
connman.cpp \
clock.cpp \
ethernet.cpp \
wifi.cpp \
+ agent.cpp \
registration.cpp \
$(BUILT_SOURCES)
connman_la_CXXFLAGS = \
connman_la_CFLAGS = \
$(IVI_SETTINGS_PLUGIN_CFLAGS) \
$(GIO_CFLAGS)
-connman_la_CPPFLAGS = $(IVI_SETTINGS_PLUGIN_CPPFLAGS)
+connman_la_CPPFLAGS = \
+ $(IVI_SETTINGS_PLUGIN_CPPFLAGS) \
+ -DIVI_SETTINGS_CONNMAN_AGENT_DBUS_NAME='$(IVI_SETTINGS_CONNMAN_AGENT_DBUS_NAME)'
connman_la_LIBADD = $(IVI_SETTINGS_PLUGIN_LIBRARY)
connman_la_LDFLAGS = -no-undefined \
-module \
bluetooth.hpp \
clock.hpp \
ethernet.hpp \
- wifi.hpp
+ wifi.hpp \
+ agent.hpp
dbus_codegen_verbose = $(dbus_codegen_verbose_$(V))
dbus_codegen_verbose_ = $(dbus_codegen_verbose_$(AM_DEFAULT_VERBOSITY))
agent-glue.c \
agent-glue.h
-CLEANFILES = $(BUILT_SOURCES)
+dbussystemconf_DATA = settings-agent.conf
+dbussystemconfdir = $(sysconfdir)/dbus-1/system.d/
+
+## Silent mode output for settingsd config file generation.
+config_verbose = $(config_verbose_$(V))
+config_verbose_ = $(config_verbose_$(AM_DEFAULT_VERBOSITY))
+config_verbose_0 = @echo CONFGEN $@;
+
+agent_name = $(IVI_SETTINGS_CONNMAN_AGENT_DBUS_NAME)
+
+## The configure script won't fully expand $libdir so leverage `make'
+## based variable expansion instead.
+settings-agent.conf: Makefile settings-agent.conf.in
+ $(config_verbose)rm -f $@ $@.tmp; \
+ srcdir=''; \
+ test -f ./$@.in || srcdir=$(srcdir)/; \
+ sed \
+ -e 's,@agent_name[@],$(agent_name),g' \
+ $${srcdir}$@.in >$@.tmp; \
+ chmod 644 $@.tmp; \
+ mv $@.tmp $@
+
+
+CLEANFILES = $(BUILT_SOURCES) settings-agent.conf
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
-EXTRA_DIST = agent.xml
+EXTRA_DIST = agent.xml settings-agent.conf.in
--- /dev/null
+/**
+ * @file agent.cpp
+ *
+ * @brief Settings daemon D-Bus connection adapter.
+ *
+ * @author Michael Leibowitz @<michael.leibowitz@@intel.com@>
+ * @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 "agent.hpp"
+#include "../../lib/config.hpp"
+
+#include <settingsd/glib_traits.hpp>
+#include <settingsd/unique_ptr.hpp>
+
+#include <string>
+#include <algorithm>
+#include <stdexcept>
+
+
+namespace
+{
+ // --------------------------------------------------------------
+ // D-Bus Name Acquisition
+ // --------------------------------------------------------------
+ /**
+ * @brief Callback function invoked when a D-Bus name is acquired.
+ *
+ * @param[in] connection The D-Bus connection on which the name was
+ * acquired.
+ * @param[in] name The name being owned.
+ * @param[in] user_data User-provided data.
+ */
+ void
+ on_name_acquired(GDBusConnection * /* connection */,
+ gchar const * name,
+ gpointer /* user_data */)
+ {
+ g_debug("Name \"%s\" acquired on D-Bus.\n", name);
+ }
+
+ /**
+ * @brief Callback function invoked when a D-Bus name is no longer
+ * owned or the D-Bus connection has been closed.
+ *
+ * @param[in] connection The D-Bus connection on which the name was
+ * acquired.
+ * @param[in] name The name being owned.
+ * @param[in] user_data User-provided data.
+ *
+ */
+ void
+ on_name_lost(GDBusConnection * /* connection */,
+ gchar const * name,
+ gpointer /* user_data */)
+ {
+ // This can happen if the appropriate D-Bus policy is not
+ // installed, for example.
+ throw std::runtime_error(std::string("Lost name \"")
+ + name + "\" on D-Bus!");
+ }
+
+ // --------------------------------------------------------------
+ // Connman Agent Handlers
+ // --------------------------------------------------------------
+ gboolean
+ on_handle_release(Agent * /* object */,
+ GDBusMethodInvocation * /* invocation */)
+ {
+ return true;
+ }
+
+ gboolean
+ on_handle_report_error(Agent * /* object */,
+ GDBusMethodInvocation * /* invocation */,
+ gchar const * /* service */,
+ gchar const * /* error */)
+ {
+ return true;
+ }
+
+ gboolean
+ on_handle_request_browser(Agent * /* object */,
+ GDBusMethodInvocation * /* invocation */,
+ gchar const * /* service */,
+ gchar const * /* url */)
+ {
+ return true;
+ }
+
+ gboolean
+ on_handle_request_input(Agent * /* object */,
+ GDBusMethodInvocation * /* invocation */,
+ gchar const * /* service */,
+ GVariant * /* fields */)
+ {
+ // The method return value will contain a dictionary of the
+ // requested input fields.
+
+ return true;
+ }
+
+ gboolean
+ on_handle_cancel(Agent * /* object */,
+ GDBusMethodInvocation * /* invocation */)
+ {
+ return true;
+ }
+}
+
+// ----------------------------------------------------------------
+
+ivi::settings::agent::agent(GDBusConnection * connection)
+ : owner_id_(
+ // The bus name will be of the form:
+ // "org.tizen.settingsd.connman.Agent"
+ g_bus_own_name_on_connection(connection,
+ IVI_SETTINGS_CONNMAN_AGENT_DBUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_name_acquired,
+ on_name_lost,
+ nullptr, // user_data,
+ nullptr))
+ , interface_(agent_skeleton_new())
+ , object_path_("/" IVI_SETTINGS_DBUS_NAME "/connman/Agent")
+{
+ // Construct object path of the form:
+ // /org/tizen/settingsd/connman/Agent"
+ std::replace(object_path_.begin(), object_path_.end(), '.', '/');
+
+ // Connect the signal handlers corresponding to the Agent
+ // interface.
+ g_signal_connect(interface_,
+ "handle-release",
+ G_CALLBACK(on_handle_release),
+ nullptr);
+
+ g_signal_connect(interface_,
+ "handle-report-error",
+ G_CALLBACK(on_handle_report_error),
+ nullptr);
+
+ g_signal_connect(interface_,
+ "handle-request-browser",
+ G_CALLBACK(on_handle_request_browser),
+ nullptr);
+
+ g_signal_connect(interface_,
+ "handle-request-input",
+ G_CALLBACK(on_handle_request_input),
+ nullptr);
+
+ g_signal_connect(interface_,
+ "handle-cancel",
+ G_CALLBACK(on_handle_cancel),
+ nullptr);
+
+ GError * error = nullptr;
+ if (!g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(interface_),
+ connection,
+ object_path_.c_str(),
+ &error)) {
+ unique_ptr<GError> safe_error(error);
+ throw std::runtime_error(error->message);
+ }
+}
+
+ivi::settings::agent::~agent()
+{
+ if (interface_ != nullptr) {
+ g_dbus_interface_skeleton_unexport(
+ G_DBUS_INTERFACE_SKELETON(interface_));
+ g_object_unref(interface_);
+ }
+
+ g_bus_unown_name(owner_id_);
+}
+
+char const *
+ivi::settings::agent::object_path() const
+{
+ return object_path_.c_str();
+}
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
--- /dev/null
+/**
+ * @file agent.hpp
+ *
+ * @brief Connman agent implementation 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; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * @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_AGENT_HPP
+#define IVI_SETTINGS_AGENT_HPP
+
+#include "agent-glue.h"
+
+#include <string>
+
+#include <gio/gio.h>
+
+namespace ivi
+{
+ namespace settings
+ {
+ class agent
+ {
+ public:
+
+ /**
+ * Constructor.
+ *
+ * @param[in] connection D-Bus connection on which agent will be
+ * exported.
+ */
+ agent(GDBusConnection *connection);
+
+ /// Destructor.
+ ~agent();
+
+ /// Get D-Bus object path for this @c Agent.
+ char const * object_path() const;
+
+ private:
+
+ /**
+ * @name Prevent copying
+ */
+ //@{
+ agent(agent const &) = delete;
+ agent & operator=(agent const &) = delete;
+ //@}
+
+ private:
+
+ /// ID corresponding to owned name on D-Bus system bus.
+ guint const owner_id_;
+
+ /// GDBus Agent skeleton object.
+ Agent * const interface_;
+
+ /// D-Bus object path for this @c Agent.
+ std::string object_path_;
+
+ };
+ }
+}
+
+#endif /* IVI_SETTINGS_AGENT_HPP */
+
+
+// Local Variables:
+// mode:c++
+// c-basic-offset:2
+// indent-tabs-mode: nil
+// End:
*/
#include "connman_manager.hpp"
-#include "dbus_connection.hpp"
#include <settingsd/dbus_signal_callback.hpp>
#include <settingsd/glib_traits.hpp>
#include <settingsd/unique_ptr.hpp>
#include <cstring>
+#include <stdexcept>
ivi::settings::connman_manager::connman_manager(
"/", // Object path
connection,
e)
+ , agent_(connection)
, event_callback_(e)
, subscription_id_(
g_dbus_connection_signal_subscribe(
&event_callback_,
nullptr))
{
- // The ServicesChanged signal parameters are:
- //
- // array{object, dict}, array{object})
- //
- // where "object" is the D-Bus object path, and "dict" is a
- // dictionary of object-specific properties. The first parameter is
- // list of changed services. The second is a list of removed
- // services.
+ // Register the Agent implementation responsible for handling input
+ // requests for secure and hidden networks.
+ if (!g_variant_is_object_path(agent_.object_path())) {
+ throw std::runtime_error(std::string("Invalid Agent object path: ")
+ + agent_.object_path());
+ }
+
+ GError * error = nullptr;
+
+ unique_ptr<GVariant> const ret(
+ call_method("RegisterAgent",
+ g_variant_new("(o)",
+ agent_.object_path()),
+ error));
+
+ if (ret == nullptr) {
+ unique_ptr<GError> const safe_error(error);
+
+ throw std::runtime_error(
+ std::string("Unable to register agent: ") + error->message);
+ }
}
ivi::settings::connman_manager::~connman_manager()
{
+ // Unregister agent.
+ if (g_variant_is_object_path(agent_.object_path())) {
+ GError * error = nullptr;
+
+ unique_ptr<GVariant> const ret(
+ call_method("UnregisterAgent",
+ g_variant_new("(o)",
+ agent_.object_path()),
+ error));
+
+ if (ret == nullptr) {
+ unique_ptr<GError> const safe_error(error);
+
+ g_warning("Unable to unregister agent: %s\n", error->message);
+ }
+ }
+
+ // Unsubscribe from ServicesChanged signal.
g_dbus_connection_signal_unsubscribe(connman_.connection(),
subscription_id_);
}
std::string const & technology,
GError *& error) const
{
- constexpr gint const timeout = 5000; // milliseconds
-
unique_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));
+ call_method("GetTechnologies",
+ nullptr, // No parameters,
+ error));
if (dictionary != nullptr) {
GVariantIter * i = nullptr;
GVariant *
ivi::settings::connman_manager::get_services(GError *& error) const
{
+ return call_method("GetServices",
+ nullptr, // No parameters,
+ error);
+}
+
+GVariant *
+ivi::settings::connman_manager::call_method(char const * name,
+ GVariant * parameters,
+ 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);
-}
+ GVariant * const ret =
+ g_dbus_proxy_call_sync(connman_.proxy(),
+ name, // "GetTechnologies", ...
+ parameters,
+ G_DBUS_CALL_FLAGS_NONE,
+ timeout,
+ nullptr, // Not cancellable
+ &error);
+
+ if (ret == nullptr)
+ g_critical("THE ERROR: %s\n", error->message);
+ return ret;
+}
// Local Variables:
// mode:c++
#define IVI_SETTINGS_CONNMAN_MANAGER_HPP
#include "connman.hpp"
+#include "agent.hpp"
#include <settingsd/event_callback.hpp>
private:
+ /**
+ * Call the method @a name on the connman Manager object.
+ *
+ * @param[in] name The connman Manager object method
+ * name.
+ * @param[in] parameters Method parameters.
+ * @param[inout] error Pointer to error object containing
+ * failure related information. Caller
+ * must deallocate if it is not null.
+ */
+ GVariant * call_method(char const * name,
+ GVariant * parameters,
+ GError *& error) const;
+
+ private:
+
/// The proxy used to access the connman Manager D-Bus API.
connman connman_;
+ /**
+ * The connman Agent implemention that handles secure and
+ * hidden network related requests.
+ */
+ agent agent_;
+
/// Callback through which events will be sent to clients.
event_callback event_callback_;
--- /dev/null
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!-- D-Bus policy for settingsd connman Agent implementation. -->
+<busconfig>
+ <policy context="default">
+ <allow own=@agent_name@/>
+ <allow send_destination=@agent_name@/>
+ <allow send_destination="net.connman"
+ send_interface="net.connman.Manager"/>
+ </policy>
+</busconfig>