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.
18 * @author Tomasz Swierczek (t.swierczek@samsung.com)
20 * @brief Header file for DBus generic client support
23 #ifndef DPL_DBUS_DBUS_CLIENT_H_
24 #define DPL_DBUS_DBUS_CLIENT_H_
27 #include <dbus/dbus.h>
28 #include <dpl/exception.h>
29 #include <dpl/log/log.h>
30 #include <dpl/dbus/dbus_serialization.h>
31 #include <dpl/dbus/dbus_deserialization.h>
36 * DBus::Client class is intended to act as simple DBus client. To call a method
37 * on remote service "Service", on remote object "Object", interface
38 * "Interface",use it like this:
41 * DBus::Client client("Object", "Service", "Interface");
42 * (...) // variables declarations
43 * client.call("Method name", arg1, arg2, arg2, ... argN,
44 * &outArg1, &outArg2, &outArg3, ..., &outArgN);
47 * As You can see, input parameters of the call are passed with reference,
48 * output ones are passed as pointers - parameters MUST be passed this way.
50 * To call a void function (no out params), just pass in arguments to Call().
52 * Currently client supports serialization and deserialization of simple types
53 * (int, char, float, unsigned), strings (std::string and char*) and
54 * some STL containers (std::vector, std::list, std::map, std::set, std::pair).
55 * Structures and classes are not (yet) supported.
64 DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
65 DECLARE_EXCEPTION_TYPE(Base, DBusClientException)
68 Client(std::string serverPath,
69 std::string serviceName,
70 std::string interfaceName) :
71 m_serviceName(serviceName),
72 m_serverPath(serverPath),
73 m_interfaceName(interfaceName)
77 dbus_error_init(&error);
78 m_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
79 if (NULL == m_connection) {
80 LogPedantic("Couldn't get DBUS connection. Error: " <<
82 dbus_error_free(&error);
83 ThrowMsg(Exception::DBusClientException,
84 "Couldn't get DBUS connection.");
88 template<typename ... Args>
89 void call(const char* methodName, const Args& ... args)
91 DBusMessage* message = dbus_message_new_method_call(
92 m_serviceName.c_str(),
94 m_interfaceName.c_str(),
96 DBusMessageIter argsIterator;
97 dbus_message_iter_init_append(message, &argsIterator);
98 call(message, &argsIterator, args ...);
99 dbus_message_unref(message);
102 template<typename ... Args>
103 void call(std::string methodName, const Args& ... args)
105 call(methodName.c_str(), args ...);
110 dbus_connection_unref(m_connection);
115 DBusMessage* makeCall(
116 DBusMessage* message)
119 dbus_error_init(&error);
120 DBusMessage* ret = dbus_connection_send_with_reply_and_block(
126 LogPedantic("Error sending DBUS message: " <<
128 dbus_error_free(&error);
129 ThrowMsg(Exception::DBusClientException,
130 "Error sending DBUS message.");
135 void call(DBusMessage* message, DBusMessageIter* /*argsIterator*/)
137 DBusMessage* ret = makeCall(message);
139 dbus_message_unref(ret);
141 LogPedantic("Error getting DBUS response.");
142 ThrowMsg(Exception::DBusClientException,
143 "Error getting DBUS response.");
147 template<typename T, typename ... Args>
149 DBusMessage* message,
150 DBusMessageIter* argsIterator,
152 const Args& ... args)
154 if (!Serialization::serialize(argsIterator, invalue)) {
155 LogPedantic("Error in serialization.");
156 ThrowMsg(Exception::DBusClientException,
157 "Error in serialization.");
159 call(message, argsIterator, args ...);
162 template<typename T, typename ... Args>
164 DBusMessage* message,
165 DBusMessageIter* argsIterator,
167 const Args& ... args)
169 if (!Serialization::serialize(argsIterator, invalue)) {
170 LogPedantic("Error in serialization.");
171 ThrowMsg(Exception::DBusClientException,
172 "Error in serialization.");
174 call(message, argsIterator, args ...);
177 template<typename T, typename ... Args>
179 DBusMessage* message,
180 DBusMessageIter* argsIterator,
183 if (!Serialization::serialize(argsIterator, invalue)) {
184 LogPedantic("Error in serialization.");
185 ThrowMsg(Exception::DBusClientException,
186 "Error in serialization.");
188 call(message, argsIterator);
191 template<typename T, typename ... Args>
193 DBusMessage* message,
194 DBusMessageIter* /*argsIterator*/,
196 const Args& ... args)
198 DBusMessage* ret = makeCall(message);
200 DBusMessageIter responseIterator;
201 dbus_message_iter_init(ret, &responseIterator);
202 returnFromCall(&responseIterator, out, args ...);
203 dbus_message_unref(ret);
207 template<typename T, typename ... Args>
209 DBusMessageIter* responseIterator,
211 const Args& ... args)
213 if (!Deserialization::deserialize(responseIterator, out)) {
214 LogPedantic("Error in deserialization.");
215 ThrowMsg(Exception::DBusClientException,
216 "Error in deserialization.");
218 returnFromCall(responseIterator, args ...);
222 void returnFromCall(DBusMessageIter* responseIterator, T* out)
224 if (!Deserialization::deserialize(responseIterator, out)) {
225 LogPedantic("Error in deserialization.");
226 ThrowMsg(Exception::DBusClientException,
227 "Error in deserialization.");
231 std::string m_serviceName, m_serverPath, m_interfaceName;
232 DBusConnection* m_connection;
237 #endif // DPL_DBUS_DBUS_CLIENT_H_