--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "common/dbus_client.h"
+
+#include "common/logger.h"
+
+namespace wrt {
+
+DBusClient::DBusClient()
+ : connection_(NULL) {
+}
+
+DBusClient::~DBusClient() {
+ if (connection_) {
+ g_dbus_connection_close_sync(connection_, NULL, NULL);
+ }
+}
+
+bool DBusClient::ConnectByName(const std::string& name) {
+ std::string address("unix:path=");
+ address.append(g_get_user_runtime_dir());
+ address.append("/.");
+ address.append(name);
+ return Connect(address);
+}
+
+bool DBusClient::Connect(const std::string& address) {
+ GError *err = NULL;
+ connection_ = g_dbus_connection_new_for_address_sync(
+ address.c_str(),
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, NULL, &err);
+ if (!connection_) {
+ LoggerE("Failed to connect to bus address %s : %s",
+ address.c_str(), err->message);
+ g_error_free(err);
+ return false;
+ }
+ return true;
+}
+
+GVariant* DBusClient::CallSync(const std::string& iface,
+ const std::string& method,
+ GVariant* parameters,
+ const GVariantType* reply_type) {
+ if (!connection_) {
+ return NULL;
+ }
+
+ GError *err = NULL;
+ GVariant* reply = g_dbus_connection_call_sync(
+ connection_, NULL, "/", iface.c_str(), method.c_str(), parameters,
+ reply_type, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+ if (!reply) {
+ LoggerE("Failed to CallSync : %s", err->message);
+ g_error_free(err);
+ }
+ return reply;
+}
+
+} // namespace wrt
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "common/dbus_server.h"
+
+#include "common/logger.h"
+
+namespace wrt {
+
+namespace {
+
+static void OnMethodCall(GDBusConnection* /*connection*/,
+ const gchar* /*sender*/,
+ const gchar* /*object_path*/,
+ const gchar* interface_name,
+ const gchar* method_name,
+ GVariant* parameters,
+ GDBusMethodInvocation* invocation,
+ gpointer user_data) {
+ DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
+ if (!self) {
+ LoggerE("DBusServer is NULL.");
+ return;
+ }
+ auto callback = self->GetMethodCallback(interface_name);
+ if (callback) {
+ callback(method_name, parameters, invocation);
+ }
+}
+
+static GVariant* OnGetProperty(GDBusConnection* /*connection*/,
+ const gchar* /*sender*/,
+ const gchar* /*object_path*/,
+ const gchar* interface_name,
+ const gchar* property_name,
+ GError** error,
+ gpointer user_data) {
+ DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
+ if (!self) {
+ LoggerE("DBusServer is NULL.");
+ return NULL;
+ }
+
+ auto callback =
+ self->GetPropertyGetter(interface_name);
+
+ GVariant* ret = NULL;
+ if (callback) {
+ ret = callback(property_name);
+ }
+
+ return ret;
+}
+
+static gboolean OnSetProperty(GDBusConnection* /*connection*/,
+ const gchar* /*sender*/,
+ const gchar* /*object_path*/,
+ const gchar* interface_name,
+ const gchar* property_name,
+ GVariant* value,
+ GError** error,
+ gpointer user_data) {
+ DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
+ if (!self) {
+ LoggerE("DBusServer is NULL.");
+ return FALSE;
+ }
+
+ auto callback =
+ self->GetPropertySetter(interface_name);
+
+ gboolean ret = FALSE;
+ if (callback) {
+ if (callback(property_name, value)) {
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+static const GDBusInterfaceVTable kInterfaceVTable = {
+ OnMethodCall,
+ OnGetProperty,
+ OnSetProperty
+};
+
+static void OnClosedConnection(GDBusConnection* connection,
+ gboolean /*remote_peer_vanished*/,
+ GError* /*error*/,
+ gpointer user_data) {
+ g_signal_handlers_disconnect_by_func(connection,
+ (gpointer)OnClosedConnection,
+ user_data);
+ g_object_unref(connection);
+}
+
+static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
+ GDBusConnection* connection,
+ gpointer user_data) {
+ GError* err = NULL;
+ DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
+
+ g_signal_connect(connection, "closed",
+ G_CALLBACK(OnClosedConnection), self);
+
+ if (self) {
+ // Check Peer Credentials
+ DBusServer::PeerCredentialsCallback callback =
+ self->GetPeerCredentialsCallback();
+ if (callback && !callback(
+ g_dbus_connection_get_peer_credentials(connection))) {
+ LoggerW("Invalid peer credentials");
+ g_dbus_connection_close_sync(connection, NULL, NULL);
+ }
+
+ GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
+ if (!node_info) {
+ LoggerE("Introspection is not set.");
+ return TRUE;
+ }
+
+ // TODO(wy80.choi): register multiple interfaces
+ g_object_ref(connection);
+ guint reg_id = g_dbus_connection_register_object(
+ connection,
+ "/",
+ node_info->interfaces[0],
+ &kInterfaceVTable,
+ self,
+ NULL,
+ &err);
+ if (reg_id == 0) {
+ LoggerE("Failed to register object : %s", err->message);
+ g_error_free(err);
+ }
+ }
+ return TRUE;
+}
+
+} // namespace
+
+DBusServer::DBusServer()
+ : server_(NULL),
+ node_info_(NULL) {
+}
+
+DBusServer::~DBusServer() {
+ if (node_info_) {
+ g_dbus_node_info_unref(node_info_);
+ }
+
+ if (server_) {
+ g_object_unref(server_);
+ }
+}
+
+void DBusServer::Start(const std::string& name) {
+ GError* err = NULL;
+
+ std::string address(g_get_user_runtime_dir());
+ address.append("/.");
+ address.append(name);
+
+ // unlink existing bus address
+ unlink(address.c_str());
+ address = "unix:path=" + address;
+
+ // create new bus
+ gchar* guid = g_dbus_generate_guid();
+ server_ = g_dbus_server_new_sync(
+ address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
+ guid, NULL, NULL, &err);
+ g_free(guid);
+ if (!server_) {
+ LoggerE("Failed to create dbus server : %s", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ // start server
+ g_signal_connect(server_, "new-connection",
+ G_CALLBACK(OnClientRequest), this);
+
+ g_dbus_server_start(server_);
+}
+
+std::string DBusServer::GetClientAddress() const {
+ return std::string(g_dbus_server_get_client_address(server_));
+}
+
+void DBusServer::SetIntrospectionXML(const std::string& xml) {
+ GError* err = NULL;
+ node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
+ if (!node_info_) {
+ LoggerE("Failed to create node info from introspection xml : %s",
+ err->message);
+ g_error_free(err);
+ }
+}
+
+void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
+ peer_credentials_callback_ = func;
+}
+
+void DBusServer::SetMethodCallback(
+ const std::string& iface, MethodCallback func) {
+ method_callbacks_[iface] = func;
+}
+
+void DBusServer::SetPropertyGetter(
+ const std::string& iface, PropertyGetter func) {
+ property_getters_[iface] = func;
+}
+
+void DBusServer::SetPropertySetter(
+ const std::string& iface, PropertySetter func) {
+ property_setters_[iface] = func;
+}
+
+DBusServer::PeerCredentialsCallback DBusServer::GetPeerCredentialsCallback() const {
+ return peer_credentials_callback_;
+}
+
+DBusServer::MethodCallback DBusServer::GetMethodCallback(const std::string& iface) {
+ return method_callbacks_[iface];
+}
+
+DBusServer::PropertySetter DBusServer::GetPropertySetter(const std::string& iface) {
+ return property_setters_[iface];
+}
+
+DBusServer::PropertyGetter DBusServer::GetPropertyGetter(const std::string& iface) {
+ return property_getters_[iface];
+}
+
+} // namespace wrt
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WRT_COMMON_DBUS_SERVER_H_
+#define WRT_COMMON_DBUS_SERVER_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <string>
+#include <map>
+#include <functional>
+
+namespace wrt {
+
+class DBusServer {
+ public:
+ typedef std::function<bool(GCredentials* creds)> PeerCredentialsCallback;
+ typedef std::function<void(const std::string& method_name,
+ GVariant* parameters,
+ GDBusMethodInvocation* invocation)> MethodCallback;
+ typedef std::function<GVariant*(const gchar*)> PropertyGetter;
+ typedef std::function<bool(const gchar*, GVariant*)> PropertySetter;
+
+ explicit DBusServer();
+ virtual ~DBusServer();
+
+ void Start(const std::string& name);
+
+ std::string GetClientAddress() const;
+
+ void SetIntrospectionXML(const std::string& xml);
+ GDBusNodeInfo* GetIntrospectionNodeInfo() const { return node_info_; }
+
+ void SetPeerCredentialsCallback(PeerCredentialsCallback func);
+ void SetMethodCallback(const std::string& iface, MethodCallback func);
+ void SetPropertyGetter(const std::string& iface, PropertyGetter func);
+ void SetPropertySetter(const std::string& iface, PropertySetter func);
+ PeerCredentialsCallback GetPeerCredentialsCallback() const;
+ MethodCallback GetMethodCallback(const std::string& iface);
+ PropertySetter GetPropertySetter(const std::string& iface);
+ PropertyGetter GetPropertyGetter(const std::string& iface);
+ private:
+ GDBusServer* server_;
+ GDBusNodeInfo* node_info_;
+
+ PeerCredentialsCallback peer_credentials_callback_;
+ std::map<std::string, MethodCallback> method_callbacks_;
+ std::map<std::string, PropertyGetter> property_getters_;
+ std::map<std::string, PropertySetter> property_setters_;
+};
+
+} // namespace wrt
+
+#endif // WRT_COMMON_DBUS_SERVER_H_