2 * Copyright (c) 2011 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 * @file connection.cpp
18 * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
23 #include <dpl/log/wrt_log.h>
24 #include <dpl/dbus/connection.h>
25 #include <dpl/dbus/exception.h>
26 #include <dpl/dbus/object_proxy.h>
30 ConnectionPtr Connection::sessionBus()
32 return connectTo(G_BUS_TYPE_SESSION);
35 ConnectionPtr Connection::systemBus()
37 return connectTo(G_BUS_TYPE_SYSTEM);
40 ConnectionPtr Connection::connectTo(GBusType busType)
44 GDBusConnection* connection = g_bus_get_sync(busType,
47 if (NULL == connection) {
50 message = error->message;
53 ThrowMsg(DBus::Exception,
54 "Couldn't connect to bus: " << message);
57 g_dbus_connection_set_exit_on_close(connection, FALSE);
59 return ConnectionPtr(new Connection(connection));
62 ConnectionPtr Connection::connectTo(const std::string& address)
66 GDBusConnection* connection = g_dbus_connection_new_for_address_sync(
68 G_DBUS_CONNECTION_FLAGS_NONE,
72 if (NULL == connection) {
75 message = error->message;
78 ThrowMsg(DBus::Exception,
79 "Couldn't connect to " << address << ": " << message);
82 return ConnectionPtr(new Connection(connection));
85 Connection::Connection(GDBusConnection* connection) :
86 m_connection(connection)
88 g_signal_connect(m_connection,
90 G_CALLBACK(onConnectionClosed),
94 Connection::~Connection()
96 std::for_each(m_registeredServices.begin(),
97 m_registeredServices.end(),
98 [] (const RegisteredServices::value_type & value)
100 g_bus_unown_name(value.second);
103 std::for_each(m_registeredObjects.begin(),
104 m_registeredObjects.end(),
105 [this] (const RegisteredObjects::value_type & value)
107 g_dbus_connection_unregister_object(
109 value.second.registrationId);
112 if (!g_dbus_connection_is_closed(m_connection)) {
113 GError* error = NULL;
116 g_dbus_connection_flush_sync(m_connection, NULL, &error))
118 WrtLogD("Could not flush the connection <%s>", error->message);
123 g_object_unref(m_connection);
126 void Connection::registerService(const std::string& serviceName)
128 guint regId = g_bus_own_name_on_connection(m_connection,
130 G_BUS_NAME_OWNER_FLAGS_NONE,
131 onServiceNameAcquired,
136 ThrowMsg(DBus::Exception, "Error while registering service.");
139 m_registeredServices.insert(RegisteredServices::value_type(serviceName,
143 void Connection::unregisterService(const std::string& serviceName)
145 auto it = m_registeredServices.find(serviceName);
146 if (m_registeredServices.end() == it) {
147 ThrowMsg(DBus::Exception, "Service not registered.");
150 g_bus_unown_name(it->second);
152 m_registeredServices.erase(it);
155 void Connection::registerObject(const ObjectPtr& object)
157 GError* error = NULL;
159 guint regId = g_dbus_connection_register_object(
161 object->getPath().c_str(),
162 object->getInterface()->getInfo(),
163 object->getInterface()->getVTable(),
164 // TODO This is ugly, fix this!
165 object->getInterface().get(),
171 message = error->message;
172 WrtLogD("%s %i", error->message, error->code);
175 ThrowMsg(DBus::Exception, "Error while registering an object: "
179 m_registeredObjects.insert(RegisteredObjects::value_type(
181 ObjectRegistration(regId, object)));
184 void Connection::unregisterObject(const std::string& objectPath)
186 auto it = m_registeredObjects.find(objectPath);
187 if (m_registeredObjects.end() == it) {
188 ThrowMsg(DBus::Exception, "Object not registered.");
191 gboolean result = g_dbus_connection_unregister_object(
193 it->second.registrationId);
194 if (FALSE == result) {
195 ThrowMsg(DBus::Exception, "Unregistering object failed.");
197 m_registeredObjects.erase(it);
200 ObjectProxyPtr Connection::createObjectProxy(const std::string& serviceName,
201 const std::string& objectPath)
203 if (g_dbus_connection_is_closed(m_connection)) {
204 ThrowMsg(DBus::ConnectionClosedException, "Connection closed.");
207 return ObjectProxyPtr(
208 new ObjectProxy(m_connection, serviceName, objectPath));
211 void Connection::onServiceNameAcquired(GDBusConnection* /*connection*/,
212 const gchar* serviceName,
215 AssertMsg(data, "Connection should not be NULL");
217 Connection* self = static_cast<Connection*>(data);
219 WrtLogD("Emitting service name acquired event: %s", serviceName);
221 ConnectionEvents::ServiceNameAcquiredEvent event(serviceName);
222 self->DPL::Event::EventSupport<ConnectionEvents::ServiceNameAcquiredEvent>
224 EmitEvent(event, DPL::Event::EmitMode::Queued);
227 void Connection::onServiceNameLost(GDBusConnection* /*connection*/,
228 const gchar* serviceName,
231 AssertMsg(data, "Connection should not be NULL");
233 Connection* self = static_cast<Connection*>(data);
235 WrtLogD("Emitting service name lost event: %s", serviceName);
237 ConnectionEvents::ServiceNameLostEvent event(serviceName);
238 self->DPL::Event::EventSupport<ConnectionEvents::ServiceNameLostEvent>::
239 EmitEvent(event, DPL::Event::EmitMode::Queued);
242 void Connection::onConnectionClosed(GDBusConnection* /*connection*/,
243 gboolean peerVanished,
247 AssertMsg(NULL != data, "Connection cannot be NULL");
249 Connection* self = static_cast<Connection*>(data);
251 if ((NULL == error) && (FALSE == peerVanished)) {
252 // Connection closed by this.
253 } else if (NULL != error) {
254 std::string message = error->message;
258 if (TRUE == peerVanished) {
259 // Connection closed by remote host.
260 ConnectionEvents::ConnectionBrokenEvent event(message);
261 self->DPL::Event::EventSupport<ConnectionEvents::
262 ConnectionBrokenEvent>::
263 EmitEvent(event, DPL::Event::EmitMode::Queued);
265 // Invalid or malformed data on connection.
266 ConnectionEvents::ConnectionInvalidEvent event(message);
267 self->DPL::Event::EventSupport<ConnectionEvents::
268 ConnectionInvalidEvent>::
269 EmitEvent(event, DPL::Event::EmitMode::Queued);