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>
37 * DBus::Client class is intended to act as simple DBus client. To call a method
38 * on remote service "Service", on remote object "Object", interface
39 * "Interface",use it like this:
42 * DBus::Client client("Object", "Service", "Interface");
43 * (...) // variables declarations
44 * client.call("Method name", arg1, arg2, arg2, ... argN,
45 * &outArg1, &outArg2, &outArg3, ..., &outArgN);
48 * As You can see, input parameters of the call are passed with reference,
49 * output ones are passed as pointers - parameters MUST be passed this way.
51 * To call a void function (no out params), just pass in arguments to Call().
53 * Currently client supports serialization and deserialization of simple types
54 * (int, char, float, unsigned), strings (std::string and char*) and
55 * some STL containers (std::vector, std::list, std::map, std::set, std::pair).
56 * Structures and classes are not (yet) supported.
66 DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
67 DECLARE_EXCEPTION_TYPE(Base, DBusClientException)
70 Client(std::string serverPath,
71 std::string serviceName,
72 std::string interfaceName) :
73 m_serviceName(serviceName),
74 m_serverPath(serverPath),
75 m_interfaceName(interfaceName)
79 dbus_error_init(&error);
80 m_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
81 if (NULL == m_connection) {
82 LogPedantic("Couldn't get DBUS connection. Error: " <<
84 dbus_error_free(&error);
85 ThrowMsg(Exception::DBusClientException,
86 "Couldn't get DBUS connection." );
90 template<typename ...Args>
91 void call(const char* methodName, const Args&... args)
93 DBusMessage* message = dbus_message_new_method_call(
94 m_serviceName.c_str(),
96 m_interfaceName.c_str(),
98 DBusMessageIter argsIterator;
99 dbus_message_iter_init_append(message, &argsIterator);
100 call(message, &argsIterator, args...);
101 dbus_message_unref(message);
104 template<typename ...Args>
105 void call(std::string methodName, const Args&... args)
107 call(methodName.c_str(), args...);
112 dbus_connection_unref(m_connection);
117 DBusMessage* makeCall(
118 DBusMessage* message)
121 dbus_error_init(&error);
122 DBusMessage* ret = dbus_connection_send_with_reply_and_block(
128 LogPedantic("Error sending DBUS message: " <<
130 dbus_error_free(&error);
131 ThrowMsg(Exception::DBusClientException,
132 "Error sending DBUS message." );
137 void call(DBusMessage* message, DBusMessageIter* /*argsIterator*/)
139 DBusMessage* ret = makeCall(message);
141 dbus_message_unref(ret);
143 LogPedantic("Error getting DBUS response.");
144 ThrowMsg(Exception::DBusClientException,
145 "Error getting DBUS response." );
149 template<typename T, typename ... Args>
151 DBusMessage* message,
152 DBusMessageIter* argsIterator,
156 if (!Serialization::serialize(argsIterator, invalue)){
157 LogPedantic("Error in serialization.");
158 ThrowMsg(Exception::DBusClientException,
159 "Error in serialization." );
161 call(message, argsIterator, args...);
164 template<typename T, typename ... Args>
166 DBusMessage* message,
167 DBusMessageIter* argsIterator,
171 if (!Serialization::serialize(argsIterator, invalue)){
172 LogPedantic("Error in serialization.");
173 ThrowMsg(Exception::DBusClientException,
174 "Error in serialization." );
176 call(message, argsIterator, args...);
179 template<typename T, typename ... Args>
181 DBusMessage* message,
182 DBusMessageIter* argsIterator,
185 if (!Serialization::serialize(argsIterator, invalue)){
186 LogPedantic("Error in serialization.");
187 ThrowMsg(Exception::DBusClientException,
188 "Error in serialization." );
190 call(message, argsIterator);
193 template<typename T, typename ... Args>
195 DBusMessage* message,
196 DBusMessageIter* /*argsIterator*/,
200 DBusMessage* ret = makeCall(message);
202 DBusMessageIter responseIterator;
203 dbus_message_iter_init(ret, &responseIterator);
204 returnFromCall(&responseIterator, out, args...);
205 dbus_message_unref(ret);
209 template<typename T, typename ... Args>
211 DBusMessageIter* responseIterator,
215 if (!Deserialization::deserialize(responseIterator, out)){
216 LogPedantic("Error in deserialization.");
217 ThrowMsg(Exception::DBusClientException,
218 "Error in deserialization." );
220 returnFromCall(responseIterator, args...);
224 void returnFromCall(DBusMessageIter* responseIterator, T* out)
226 if (!Deserialization::deserialize(responseIterator, out)){
227 LogPedantic("Error in deserialization.");
228 ThrowMsg(Exception::DBusClientException,
229 "Error in deserialization." );
233 std::string m_serviceName, m_serverPath, m_interfaceName;
234 DBusConnection* m_connection;
240 #endif // DPL_DBUS_DBUS_CLIENT_H_