2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "common/dbus_server.h"
19 #include "common/logger.h"
25 static void OnMethodCall(GDBusConnection* connection,
26 const gchar* /*sender*/,
27 const gchar* /*object_path*/,
28 const gchar* interface_name,
29 const gchar* method_name,
31 GDBusMethodInvocation* invocation,
33 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
35 LOGGER(ERROR) << "DBusServer is NULL.";
38 auto callback = self->GetMethodCallback(interface_name);
40 callback(connection, method_name, parameters, invocation);
44 static GVariant* OnGetProperty(GDBusConnection* connection,
45 const gchar* /*sender*/,
46 const gchar* /*object_path*/,
47 const gchar* interface_name,
48 const gchar* property_name,
51 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
53 LOGGER(ERROR) << "DBusServer is NULL.";
58 self->GetPropertyGetter(interface_name);
62 ret = callback(connection, property_name);
68 static gboolean OnSetProperty(GDBusConnection* connection,
69 const gchar* /*sender*/,
70 const gchar* /*object_path*/,
71 const gchar* interface_name,
72 const gchar* property_name,
76 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
78 LOGGER(ERROR) << "DBusServer is NULL.";
83 self->GetPropertySetter(interface_name);
87 if (callback(connection, property_name, value)) {
95 static const GDBusInterfaceVTable kInterfaceVTable = {
101 static void OnClosedConnection(GDBusConnection* connection,
102 gboolean /*remote_peer_vanished*/,
104 gpointer user_data) {
105 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
107 auto callback = self->GetDisconnectedCallback();
109 callback(connection);
113 g_signal_handlers_disconnect_by_func(connection,
114 (gpointer)OnClosedConnection,
116 g_object_unref(connection);
119 static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
120 GDBusConnection* connection,
121 gpointer user_data) {
123 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
125 g_signal_connect(connection, "closed",
126 G_CALLBACK(OnClosedConnection), self);
129 // Check Peer Credentials
130 DBusServer::PeerCredentialsCallback callback =
131 self->GetPeerCredentialsCallback();
132 if (callback && !callback(
133 g_dbus_connection_get_peer_credentials(connection))) {
134 LOGGER(WARN) << "Invalid peer credentials.";
135 g_dbus_connection_close_sync(connection, NULL, NULL);
138 GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
140 LOGGER(ERROR) << "Introspection is not set.";
144 // TODO(wy80.choi): register multiple interfaces
145 g_object_ref(connection);
146 guint reg_id = g_dbus_connection_register_object(
149 node_info->interfaces[0],
155 LOGGER(ERROR) << "Failed to register object : " << err->message;
164 DBusServer::DBusServer()
169 DBusServer::~DBusServer() {
171 g_dbus_node_info_unref(node_info_);
175 g_object_unref(server_);
178 if (!address_path_.empty()) {
179 unlink(address_path_.c_str());
183 void DBusServer::Start(const std::string& name) {
186 address_path_.clear();
187 address_path_.append(g_get_user_runtime_dir());
188 address_path_.append("/.");
189 address_path_.append(name);
190 // unlink existing bus address
191 unlink(address_path_.c_str());
193 std::string address("unix:path=");
194 address.append(address_path_);
196 // create new bus socket
197 // TODO(wy80.choi): bus socket (Address) should be removed gracefully
198 // when application is terminated.
199 gchar* guid = g_dbus_generate_guid();
200 server_ = g_dbus_server_new_sync(
201 address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
202 guid, NULL, NULL, &err);
205 LOGGER(ERROR) << "Failed to create dbus server : " << err->message;
211 g_signal_connect(server_, "new-connection",
212 G_CALLBACK(OnClientRequest), this);
214 g_dbus_server_start(server_);
217 std::string DBusServer::GetClientAddress() const {
218 return std::string(g_dbus_server_get_client_address(server_));
221 void DBusServer::SetIntrospectionXML(const std::string& xml) {
223 node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
225 LOGGER(ERROR) << "Failed to create node info from introspection xml : "
231 void DBusServer::SendSignal(GDBusConnection* connection,
232 const std::string& iface,
233 const std::string& signal_name,
234 GVariant* parameters) {
236 gboolean ret = g_dbus_connection_emit_signal(
237 connection, NULL, "/",
238 iface.c_str(), signal_name.c_str(),
241 LOGGER(ERROR) << "Failed to emit signal : '"
242 << iface << '.' << signal_name << "'";
247 void DBusServer::SetDisconnectedCallback(DisconnectedCallback func) {
248 disconnected_callback_ = func;
251 void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
252 peer_credentials_callback_ = func;
255 void DBusServer::SetMethodCallback(
256 const std::string& iface, MethodCallback func) {
257 method_callbacks_[iface] = func;
260 void DBusServer::SetPropertyGetter(
261 const std::string& iface, PropertyGetter func) {
262 property_getters_[iface] = func;
265 void DBusServer::SetPropertySetter(
266 const std::string& iface, PropertySetter func) {
267 property_setters_[iface] = func;
270 DBusServer::DisconnectedCallback
271 DBusServer::GetDisconnectedCallback() const {
272 return disconnected_callback_;
275 DBusServer::PeerCredentialsCallback
276 DBusServer::GetPeerCredentialsCallback() const {
277 return peer_credentials_callback_;
280 DBusServer::MethodCallback
281 DBusServer::GetMethodCallback(const std::string& iface) {
282 return method_callbacks_[iface];
285 DBusServer::PropertySetter
286 DBusServer::GetPropertySetter(const std::string& iface) {
287 return property_setters_[iface];
290 DBusServer::PropertyGetter
291 DBusServer::GetPropertyGetter(const std::string& iface) {
292 return property_getters_[iface];