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 g_signal_handlers_disconnect_by_func(connection,
106 (gpointer)OnClosedConnection,
108 g_object_unref(connection);
111 static gboolean OnClientRequest(GDBusServer* /*dbus_server*/,
112 GDBusConnection* connection,
113 gpointer user_data) {
115 DBusServer* self = reinterpret_cast<DBusServer*>(user_data);
117 g_signal_connect(connection, "closed",
118 G_CALLBACK(OnClosedConnection), self);
121 // Check Peer Credentials
122 DBusServer::PeerCredentialsCallback callback =
123 self->GetPeerCredentialsCallback();
124 if (callback && !callback(
125 g_dbus_connection_get_peer_credentials(connection))) {
126 LOGGER(WARN) << "Invalid peer credentials.";
127 g_dbus_connection_close_sync(connection, NULL, NULL);
130 GDBusNodeInfo* node_info = self->GetIntrospectionNodeInfo();
132 LOGGER(ERROR) << "Introspection is not set.";
136 // TODO(wy80.choi): register multiple interfaces
137 g_object_ref(connection);
138 guint reg_id = g_dbus_connection_register_object(
141 node_info->interfaces[0],
147 LOGGER(ERROR) << "Failed to register object : " << err->message;
156 DBusServer::DBusServer()
161 DBusServer::~DBusServer() {
163 g_dbus_node_info_unref(node_info_);
167 g_object_unref(server_);
170 if (!address_path_.empty()) {
171 unlink(address_path_.c_str());
175 void DBusServer::Start(const std::string& name) {
178 address_path_.clear();
179 address_path_.append(g_get_user_runtime_dir());
180 address_path_.append("/.");
181 address_path_.append(name);
182 // unlink existing bus address
183 unlink(address_path_.c_str());
185 std::string address("unix:path=");
186 address.append(address_path_);
188 // create new bus socket
189 // TODO(wy80.choi): bus socket (Address) should be removed gracefully
190 // when application is terminated.
191 gchar* guid = g_dbus_generate_guid();
192 server_ = g_dbus_server_new_sync(
193 address.c_str(), G_DBUS_SERVER_FLAGS_NONE,
194 guid, NULL, NULL, &err);
197 LOGGER(ERROR) << "Failed to create dbus server : " << err->message;
203 g_signal_connect(server_, "new-connection",
204 G_CALLBACK(OnClientRequest), this);
206 g_dbus_server_start(server_);
209 std::string DBusServer::GetClientAddress() const {
210 return std::string(g_dbus_server_get_client_address(server_));
213 void DBusServer::SetIntrospectionXML(const std::string& xml) {
215 node_info_ = g_dbus_node_info_new_for_xml(xml.c_str(), &err);
217 LOGGER(ERROR) << "Failed to create node info from introspection xml : "
223 void DBusServer::SendSignal(GDBusConnection* connection,
224 const std::string& iface,
225 const std::string& signal_name,
226 GVariant* parameters) {
228 gboolean ret = g_dbus_connection_emit_signal(
229 connection, NULL, "/",
230 iface.c_str(), signal_name.c_str(),
233 LOGGER(ERROR) << "Failed to emit signal : '"
234 << iface << '.' << signal_name << "'";
239 void DBusServer::SetPeerCredentialsCallback(PeerCredentialsCallback func) {
240 peer_credentials_callback_ = func;
243 void DBusServer::SetMethodCallback(
244 const std::string& iface, MethodCallback func) {
245 method_callbacks_[iface] = func;
248 void DBusServer::SetPropertyGetter(
249 const std::string& iface, PropertyGetter func) {
250 property_getters_[iface] = func;
253 void DBusServer::SetPropertySetter(
254 const std::string& iface, PropertySetter func) {
255 property_setters_[iface] = func;
258 DBusServer::PeerCredentialsCallback
259 DBusServer::GetPeerCredentialsCallback() const {
260 return peer_credentials_callback_;
263 DBusServer::MethodCallback
264 DBusServer::GetMethodCallback(const std::string& iface) {
265 return method_callbacks_[iface];
268 DBusServer::PropertySetter
269 DBusServer::GetPropertySetter(const std::string& iface) {
270 return property_setters_[iface];
273 DBusServer::PropertyGetter
274 DBusServer::GetPropertyGetter(const std::string& iface) {
275 return property_getters_[iface];