4 * Copyright (c) 2014 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.
22 #include "core/edbus-handler.h"
23 #include "core/common.h"
24 #include "core/list.h"
26 #define EDBUS_INIT_RETRY_COUNT 5
28 /* -1 is a default timeout value, it's converted to 25*1000 internally. */
29 #define DBUS_REPLY_TIMEOUT (-1)
36 E_DBus_Signal_Handler *handler;
39 static struct edbus_object {
41 const char *interface;
43 E_DBus_Interface *iface;
45 { COORD_PATH_ROTATION , COORD_INTERFACE_ROTATION , NULL, NULL },
46 /* Add new object & interface here*/
49 static c_list *edbus_handler_list;
50 static int edbus_init_val;
51 static DBusConnection *conn;
52 static E_DBus_Connection *edbus_conn;
53 static DBusPendingCall *edbus_request_name;
55 static int register_edbus_interface(struct edbus_object *object)
60 _E("object is invalid value!");
64 object->obj = e_dbus_object_add(edbus_conn, object->path, NULL);
66 _E("fail to add edbus obj");
70 object->iface = e_dbus_interface_new(object->interface);
72 _E("fail to add edbus interface");
73 e_dbus_object_free(object->obj);
78 e_dbus_object_interface_attach(object->obj, object->iface);
83 static int unregister_edbus_interface(struct edbus_object *object)
88 _E("object is invalid value!");
93 e_dbus_object_interface_detach(object->obj, object->iface);
94 e_dbus_interface_unref(object->iface);
99 e_dbus_object_free(object->obj);
106 E_DBus_Interface *get_edbus_interface(const char *path)
110 for (i = 0; i < ARRAY_SIZE(edbus_objects); i++)
111 if (!strcmp(path, edbus_objects[i].path))
112 return edbus_objects[i].iface;
117 pid_t get_edbus_sender_pid(DBusMessage *msg)
120 DBusMessage *send_msg;
121 DBusPendingCall *pending;
122 DBusMessageIter iter;
127 _E("invalid argument!");
131 sender = dbus_message_get_sender(msg);
133 _E("invalid sender!");
137 send_msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
140 "GetConnectionUnixProcessID");
142 _E("invalid send msg!");
146 ret = dbus_message_append_args(send_msg, DBUS_TYPE_STRING,
147 &sender, DBUS_TYPE_INVALID);
149 _E("fail to append args!");
150 dbus_message_unref(send_msg);
154 pending = e_dbus_message_send(edbus_conn, send_msg, NULL, -1, NULL);
156 _E("pending is null!");
157 dbus_message_unref(send_msg);
161 dbus_message_unref(send_msg);
163 /* block until reply is received */
164 dbus_pending_call_block(pending);
166 msg = dbus_pending_call_steal_reply(pending);
167 dbus_pending_call_unref(pending);
169 _E("reply msg is null!");
173 dbus_message_iter_init(msg, &iter);
174 dbus_message_iter_get_basic(&iter, &pid);
175 dbus_message_unref(msg);
180 static void unregister_edbus_signal_handle(void)
183 struct edbus_list *entry;
185 C_LIST_FOREACH(edbus_handler_list, tmp, entry) {
187 e_dbus_signal_handler_del(edbus_conn, entry->handler);
188 C_LIST_REMOVE(edbus_handler_list, entry);
189 free(entry->signal_name);
195 int unregister_edbus_signal_handler(const char *interface, const char *name, E_DBus_Signal_Cb cb)
198 struct edbus_list *entry;
199 E_DBus_Signal_Handler *handler;
201 C_LIST_FOREACH(edbus_handler_list, tmp, entry) {
202 if (entry != NULL && strncmp(entry->signal_name, name, strlen(name)) == 0
203 && strncmp(entry->interface_name, interface, strlen(interface)) == 0
204 && entry->cb == cb) {
205 e_dbus_signal_handler_del(edbus_conn, entry->handler);
206 C_LIST_REMOVE(edbus_handler_list, entry);
207 free(entry->signal_name);
208 free(entry->interface_name);
217 int register_edbus_signal_handler(const char *path, const char *interface,
218 const char *name, E_DBus_Signal_Cb cb)
221 struct edbus_list *entry;
222 E_DBus_Signal_Handler *handler;
224 C_LIST_FOREACH(edbus_handler_list, tmp, entry) {
225 if (entry != NULL && strncmp(entry->signal_name, name, strlen(name)) == 0
230 handler = e_dbus_signal_handler_add(edbus_conn, NULL, path,
231 interface, name, cb, NULL);
234 _E("fail to add edbus handler");
238 entry = malloc(sizeof(struct edbus_list));
245 entry->signal_name = strndup(name, strlen(name));
247 if (!entry->signal_name) {
253 entry->interface_name = strndup(interface, strlen(interface));
255 if (!entry->interface_name) {
257 free(entry->signal_name);
262 entry->handler = handler;
264 C_LIST_PREPEND(edbus_handler_list, entry);
265 if (!edbus_handler_list) {
266 _E("eina_list_prepend failed");
267 free(entry->signal_name);
268 free(entry->interface_name);
275 int broadcast_edbus_signal(const char *path, const char *interface,
276 const char *name, const char *sig, char *param[])
279 DBusMessageIter iter;
282 msg = dbus_message_new_signal(path, interface, name);
284 _E("fail to allocate new %s.%s signal", interface, name);
288 dbus_message_iter_init_append(msg, &iter);
289 r = append_variant(&iter, sig, param);
291 _E("append_variant error(%d)", r);
295 e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
297 dbus_message_unref(msg);
301 int send_edbus_message(const char* dest, const char *path, const char *interface,
302 const char *method, const char *sig, char *param[])
305 DBusMessageIter iter;
308 msg = dbus_message_new_method_call(dest, path, interface, method);
310 _E("fail to allocate new %s.%s message", interface, method);
314 dbus_message_iter_init_append(msg, &iter);
315 r = append_variant(&iter, sig, param);
317 _E("append_variant error(%d)", r);
321 e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
323 dbus_message_unref(msg);
327 void register_edbus_method_handler(const char* dest, const char* path, const char* interface,
328 const char* method, E_DBus_Method_Return_Cb cb)
330 DBusMessage *msg = NULL;
332 msg = dbus_message_new_method_call(dest, path, interface, method);
334 _E("Failed: dbus_message_new_method_call()");
337 e_dbus_message_send(edbus_conn, msg, cb, DBUS_REPLY_TIMEOUT, NULL);
339 dbus_message_unref(msg);
342 int register_edbus_method(const char *path, const struct edbus_method *edbus_methods, int size)
344 E_DBus_Interface *iface;
348 iface = get_edbus_interface(path);
351 _E("fail to get edbus interface!");
355 for (i = 0; i < size; i++) {
356 ret = e_dbus_interface_method_add(iface,
357 edbus_methods[i].member,
358 edbus_methods[i].signature,
359 edbus_methods[i].reply_signature,
360 edbus_methods[i].func);
362 _E("fail to add method %s!", edbus_methods[i].member);
370 static void request_name_cb(void *data, DBusMessage *msg, DBusError *error)
377 _D("invalid DBusMessage!");
381 dbus_error_init(&err);
382 r = dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &val, DBUS_TYPE_INVALID);
384 _E("no message : [%s:%s]", err.name, err.message);
385 dbus_error_free(&err);
389 _I("Request Name reply : %d", val);
392 void edbus_init(void *data)
398 dbus_threads_init_default();
399 dbus_error_init(&error);
402 edbus_init_val = e_dbus_init();
405 if (retry == EDBUS_INIT_RETRY_COUNT) {
406 _E("fail to init edbus");
410 } while (retry <= EDBUS_INIT_RETRY_COUNT);
414 edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
417 if (retry == EDBUS_INIT_RETRY_COUNT) {
418 _E("fail to get edbus");
422 } while (retry <= EDBUS_INIT_RETRY_COUNT);
426 edbus_request_name = e_dbus_request_name(edbus_conn, COORD_BUS_NAME,
427 DBUS_NAME_FLAG_REPLACE_EXISTING, request_name_cb, NULL);
428 if (edbus_request_name)
430 if (retry == EDBUS_INIT_RETRY_COUNT) {
431 _E("fail to request edbus name");
435 } while (retry <= EDBUS_INIT_RETRY_COUNT);
437 for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) {
438 ret = register_edbus_interface(&edbus_objects[i]);
440 _E("fail to add obj & interface for %s",
441 edbus_objects[i].interface);
444 _D("add new obj for %s", edbus_objects[i].interface);
449 e_dbus_release_name(edbus_conn, COORD_BUS_NAME, request_name_cb, NULL);
451 e_dbus_connection_close(edbus_conn);
456 void edbus_exit(void *data)
463 unregister_edbus_signal_handle();
465 for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) {
466 ret = unregister_edbus_interface(&edbus_objects[i]);
468 _E("fail to delete obj & interface for %s",
469 edbus_objects[i].interface);
471 _D("add new obj for %s", edbus_objects[i].interface);
474 e_dbus_release_name(edbus_conn, COORD_BUS_NAME, request_name_cb, NULL);
476 e_dbus_connection_close(edbus_conn);