4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include <dbus/dbus-glib-lowlevel.h>
29 #define DBUS_REPLY_TIMEOUT (-1)
31 struct pending_call_data {
36 static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
46 for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
49 int_type = atoi(param[i]);
50 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
53 int_type = strtoul(param[i], NULL, 10);
54 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
57 int64_type = atoll(param[i]);
58 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
61 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]);
71 int dbus_method_sync(const char *dest, const char *path,
72 const char *interface, const char *method,
73 const char *sig, char *param[])
82 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
84 _E("dbus_bus_get error");
88 msg = dbus_message_new_method_call(dest, path, interface, method);
90 _E("dbus_message_new_method_call(%s:%s-%s)",
91 path, interface, method);
95 dbus_message_iter_init_append(msg, &iter);
96 ret = append_variant(&iter, sig, param);
98 _E("append_variant error(%d) %s %s:%s-%s",
99 ret, dest, path, interface, method);
100 dbus_message_unref(msg);
104 dbus_error_init(&err);
106 reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
107 dbus_message_unref(msg);
109 _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
110 err.name, err.message, dest, path, interface, method);
111 dbus_error_free(&err);
115 ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
116 dbus_message_unref(reply);
118 _E("no message : [%s:%s] %s %s:%s-%s",
119 err.name, err.message, dest, path, interface, method);
120 dbus_error_free(&err);
127 static void cb_pending(DBusPendingCall *pending, void *user_data)
131 struct pending_call_data *data = user_data;
134 ret = dbus_pending_call_get_completed(pending);
136 _I("dbus_pending_call_get_completed() fail");
137 dbus_pending_call_unref(pending);
141 dbus_error_init(&err);
142 msg = dbus_pending_call_steal_reply(pending);
144 _E("no message : [%s:%s]", err.name, err.message);
147 dbus_set_error(&err, "org.tizen.system.deviced.NoReply",
148 "There was no reply to this method call");
149 data->func(data->data, NULL, &err);
150 dbus_error_free(&err);
155 ret = dbus_set_error_from_message(&err, msg);
157 _E("error msg : [%s:%s]", err.name, err.message);
160 data->func(data->data, NULL, &err);
161 dbus_error_free(&err);
164 data->func(data->data, msg, &err);
167 dbus_message_unref(msg);
168 dbus_pending_call_unref(pending);
171 int dbus_method_async_with_reply(const char *dest, const char *path,
172 const char *interface, const char *method,
173 const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data)
175 DBusConnection *conn;
177 DBusMessageIter iter;
178 DBusPendingCall *pending = NULL;
179 struct pending_call_data *pdata;
182 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
184 _E("dbus_bus_get error");
188 /* this function should be invoked to receive dbus messages
189 * does nothing if it's already been done */
190 dbus_connection_setup_with_g_main(conn, NULL);
192 msg = dbus_message_new_method_call(dest, path, interface, method);
194 _E("dbus_message_new_method_call(%s:%s-%s)",
195 path, interface, method);
199 dbus_message_iter_init_append(msg, &iter);
200 ret = append_variant(&iter, sig, param);
202 _E("append_variant error(%d)%s %s:%s-%s",
203 ret, dest, path, interface, method);
204 dbus_message_unref(msg);
208 ret = dbus_connection_send_with_reply(conn, msg, &pending, timeout);
210 dbus_message_unref(msg);
211 _E("dbus_connection_send error(%s %s:%s-%s)",
212 dest, path, interface, method);
216 dbus_message_unref(msg);
219 pdata = malloc(sizeof(struct pending_call_data));
226 ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
229 dbus_pending_call_cancel(pending);