1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "common/dbus_server.h"
7 #include "common/logger.h"
13 static void OnMethodCall(GDBusConnection* connection,
14 const gchar* /*sender*/,
15 const gchar* /*object_path*/,
16 const gchar* interface_name,
17 const gchar* method_name,
19 GDBusMethodInvocation* invocation,
21 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
23 LOGGER(ERROR) << "DBusServer is NULL.";
26 auto callback = self->GetMethodCallback(interface_name);
28 callback(connection, method_name, parameters, invocation);
32 static GVariant* OnGetProperty(GDBusConnection* connection,
33 const gchar* /*sender*/,
34 const gchar* /*object_path*/,
35 const gchar* interface_name,
36 const gchar* property_name,
39 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
41 LOGGER(ERROR) << "DBusServer is NULL.";
46 self->GetPropertyGetter(interface_name);
50 ret = callback(connection, property_name);
56 static gboolean OnSetProperty(GDBusConnection* connection,
57 const gchar* /*sender*/,
58 const gchar* /*object_path*/,
59 const gchar* interface_name,
60 const gchar* property_name,
64 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
66 LOGGER(ERROR) << "DBusServer is NULL.";
71 self->GetPropertySetter(interface_name);
75 if (callback(connection, property_name, value)) {
83 static const GDBusInterfaceVTable kInterfaceVTable = {
89 static void OnClosedConnection(GDBusConnection* connection,
90 gboolean /*remote_peer_vanished*/,
93 g_signal_handlers_disconnect_by_func(connection,
94 (gpointer)OnClosedConnection,
96 g_object_unref(connection);
99 static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
100 GDBusConnection* connection,
101 gpointer user_data) {
103 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
105 g_signal_connect(connection, "closed",
106 G_CALLBACK(OnClosedConnection), self);
109 // Check Peer Credentials
110 DBusServer::PeerCredentialsCallback callback =
111 self->GetPeerCredentialsCallback();
112 if (callback && !callback(
113 g_dbus_connection_get_peer_credentials(connection))) {
114 LOGGER(WARN) << "Invalid peer credentials.";
115 g_dbus_connection_close_sync(connection, NULL, NULL);
118 GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
120 LOGGER(ERROR) << "Introspection is not set.";
124 // TODO(wy80.choi): register multiple interfaces
125 g_object_ref(connection);
126 guint reg_id = g_dbus_connection_register_object(
129 node_info->interfaces[0],
135 LOGGER(ERROR) << "Failed to register object : " << err->message;
144 DBusServer::DBusServer()
149 DBusServer::~DBusServer() {
151 g_dbus_node_info_unref(node_info_);
155 g_object_unref(server_);
158 if (!address_path_.empty()) {
159 unlink(address_path_.c_str());
163 void DBusServer::Start(const std::string& name) {
166 address_path_.clear();
167 address_path_.append(g_get_user_runtime_dir());
168 address_path_.append("/.");
169 address_path_.append(name);
170 // unlink existing bus address
171 unlink(address_path_.c_str());
173 std::string address("unix:path=");
174 address.append(address_path_);
176 // create new bus socket
177 // TODO(wy80.choi): bus socket (Address) should be removed gracefully
178 // when application is terminated.
179 gchar* guid = g_dbus_generate_guid();
180 server_ = g_dbus_server_new_sync(
181 address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
182 guid, NULL, NULL, &err);
185 LOGGER(ERROR) << "Failed to create dbus server : " << err->message;
191 g_signal_connect(server_, "new-connection",
192 G_CALLBACK(OnClientRequest), this);
194 g_dbus_server_start(server_);
197 std::string DBusServer::GetClientAddress() const {
198 return std::string(g_dbus_server_get_client_address(server_));
201 void DBusServer::SetIntrospectionXML(const std::string& xml) {
203 node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
205 LOGGER(ERROR) << "Failed to create node info from introspection xml : "
211 void DBusServer::SendSignal(GDBusConnection* connection,
212 const std::string& iface,
213 const std::string& signal_name,
214 GVariant* parameters) {
216 gboolean ret = g_dbus_connection_emit_signal(
217 connection, NULL, "/",
218 iface.c_str(), signal_name.c_str(),
221 LOGGER(ERROR) << "Failed to emit signal : '"
222 << iface << '.' << signal_name << "'";
227 void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
228 peer_credentials_callback_ = func;
231 void DBusServer::SetMethodCallback(
232 const std::string& iface, MethodCallback func) {
233 method_callbacks_[iface] = func;
236 void DBusServer::SetPropertyGetter(
237 const std::string& iface, PropertyGetter func) {
238 property_getters_[iface] = func;
241 void DBusServer::SetPropertySetter(
242 const std::string& iface, PropertySetter func) {
243 property_setters_[iface] = func;
246 DBusServer::PeerCredentialsCallback
247 DBusServer::GetPeerCredentialsCallback() const {
248 return peer_credentials_callback_;
251 DBusServer::MethodCallback
252 DBusServer::GetMethodCallback(const std::string& iface) {
253 return method_callbacks_[iface];
256 DBusServer::PropertySetter
257 DBusServer::GetPropertySetter(const std::string& iface) {
258 return property_setters_[iface];
261 DBusServer::PropertyGetter
262 DBusServer::GetPropertyGetter(const std::string& iface) {
263 return property_getters_[iface];