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.
27 #include "shared/log.h"
28 #include "dbus-system.h"
31 #define DBUS_REPLY_TIMEOUT (10000)
33 int check_systemd_active(void)
40 _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
42 msg = dbus_handle_method_sync_with_reply_var("org.freedesktop.systemd1",
43 "/org/freedesktop/systemd1/unit/default_2etarget",
44 "org.freedesktop.DBus.Properties",
46 g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"));
50 if (!dh_get_param_from_var(msg, "(v)", &var)) {
51 _E("reply is not variant type");
55 if (!dh_get_param_from_var(var, "(s)", &state)) {
56 _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
61 if (strncmp(state, "active", 6) == 0)
74 static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
75 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
77 void dbus_handle_set_default_bus_type(GBusType bus_type)
79 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
82 pthread_mutex_lock(&g_mutex);
83 g_default_bus_type = bus_type;
84 pthread_mutex_unlock(&g_mutex);
87 GBusType dbus_handle_get_default_bus_type(void)
91 pthread_mutex_lock(&g_mutex);
92 type = g_default_bus_type;
93 pthread_mutex_unlock(&g_mutex);
103 /* basic information */
105 GDBusConnection *conn;
108 GList *list_names; /* dbus_name */
109 GList *list_object; /* dbus_object_handle_s */
110 pthread_mutex_t mutex;
113 /* path + interfaces */
115 dbus_handle_s *dh; /* dbus handle */
116 const char *path; /* object path */
117 GList *list_ifaces; /* dbus_interface_s */
118 } dbus_object_handle_s;
121 dbus_object_handle_s *oh; /* object handle */
122 const char *name; /* interface name */
123 GList *list_methods; /* const dbus_method_s */
128 #define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
130 /* global shared bus : system, session */
131 static dbus_handle_s g_dh[2];
133 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
135 dbus_handle_s * _dbus_handle_get_default_connection(void)
137 return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
140 #define dbus_handle_lock(handle) do {\
142 pthread_mutex_lock(&((handle)->mutex));\
145 #define dbus_handle_unlock(handle) do {\
147 pthread_mutex_unlock(&(handle)->mutex);\
150 #define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
151 #define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
153 _E("dbus handle is null\n");\
157 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
158 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
159 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
160 static GVariant* _append_variant(const char *signature, const char *param[]);
162 dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
164 dbus_interface_s *iface = NULL;
166 if (!iface_u || !iface_u->methods) {
171 iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
173 _E("failed to calloc");
177 iface->name = iface_u->name;
178 iface->modified = TRUE;
180 for (int i = 0 ; i < iface_u->nr_methods; ++i) {
181 //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
182 iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
188 static GDBusConnection * _get_bus(GBusType bus_type)
190 GDBusConnection *conn = NULL;
193 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
194 _E("Wrong bus_type %d", bus_type);
198 conn = g_bus_get_sync(bus_type, NULL, &err);
200 _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
208 static GDBusConnection * _get_bus_private(GBusType bus_type)
211 GDBusConnection *conn = NULL;
212 const char * address;
214 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
215 _E("Wrong bus_type %d", bus_type);
219 address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
220 if (!address || err) {
221 _E("failed to get bus address\n");
226 conn = g_dbus_connection_new_for_address_sync(address,
227 (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
228 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
229 NULL, /* GDBusAuthObserver */
233 _E("failed to get private bus\n");
242 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
244 int ibus = bus_type - 1;
245 dbus_handle_s *dh = NULL;
247 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
248 _E("Unknown bus type %d", bus_type);
253 dbus_handle_lock(dh);
256 dh->conn = _get_bus(bus_type);
258 dh->bus_type = bus_type;
263 dbus_handle_unlock(dh);
269 static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type)
273 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
274 _E("Unknown bus type %d", bus_type);
278 dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
280 _E("failed to allocate memory for dbus handle");
284 dbus_handle_lock(dh);
287 dh->conn = _get_bus_private(bus_type);
288 dh->bus_type = bus_type;
293 dbus_handle_unlock(dh);
298 dbus_handle_unlock(dh);
304 dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv)
306 dbus_handle_s *dh = NULL;
309 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
310 _E("Wrong bus_type %d\n", bus_type);
314 for (i = 0 ; i < 3; ++i) {
317 dh = _dbus_handle_get_connection_private(bus_type);
320 dh = _dbus_handle_get_connection(bus_type);
330 static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
332 dbus_name *dn = NULL;
335 if (!handle || !name || !id)
338 dn = (dbus_name*)calloc(1, sizeof(dbus_name));
340 _E("failed to calloc");
346 // todo : delete lock ?
347 locked = pthread_mutex_trylock(&handle->mutex);
348 if (locked != 0 && locked != EBUSY) {
349 _E("failed to lock %d\n", locked);
353 handle->list_names = g_list_prepend(handle->list_names, dn);
355 // todo : delete lock ?
357 dbus_handle_unlock(handle);
360 static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
362 const char *bus_name = ((dbus_name *)a)->bus_name;
365 return strcmp(bus_name, (const char *)b);
368 dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name)
370 if (!list_name || !bus_name)
373 GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
377 return (dbus_name *)item->data;
380 #define dh_to_ds(x) ((dbus_handle_s*)x)
382 /* remove dbus_name from dbus handle */
383 static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
386 dbus_name *dn = NULL;
389 _E("wrong bus_name %s", bus_name);
393 dh = _dbus_handle_get_default_connection();
395 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
400 dbus_handle_lock(dh);
401 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
403 _E("failed to find dbus name %s", bus_name);
406 dh->list_names = g_list_remove(dh->list_names, dn);
409 dbus_handle_unlock(dh);
412 //extern void booting_done(void);
414 /* default handler */
415 static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
417 dbus_handle_s *dh = (dbus_handle_s *)user_data;
422 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
426 // todo: add bus name?
427 //dh->bus_name = name;
430 /* default handler */
431 static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
433 _E("%s:%d:%s\n", __func__, __LINE__, name);
434 dbus_handle_s *dh = (dbus_handle_s *)user_data;
436 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
439 _dbus_handle_remove_bus_name(dh, name);
442 int dbus_handle_request_bus_name(dbus_handle_h handle,
443 const char *bus_name,
444 GBusNameAcquiredCallback acquired_handler,
445 GBusNameLostCallback lost_handler)
452 _E("bus_name is NULL");
456 /* get shared connection */
458 dh = _dbus_handle_get_default_connection();
460 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
465 dbus_handle_lock(dh);
467 _E("failed to register name: connection is null\n");
471 /* todo : search name on connection */
472 item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
474 id = ((dbus_name*)(item->data))->id;
475 _E("name already exist:%u", id);
479 id = g_bus_own_name_on_connection(dh->conn,
481 G_BUS_NAME_OWNER_FLAGS_NONE,
482 acquired_handler ? acquired_handler : _name_acquired,
483 lost_handler ? lost_handler : _name_lost,
487 _E("failed to own name:%s\n", bus_name);
491 _dbus_handle_add_bus_name(dh, bus_name, id);
494 dbus_handle_unlock(dh);
498 /* !! _name_lost handler callback is disabled by g_bus_unown_name : ubuntu */
499 int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name)
502 dbus_name *dn = NULL;
505 _E("Wrong bus name");
510 dh = _dbus_handle_get_default_connection();
512 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
517 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
519 _E("failed to find bus_name %s on dbus handle", bus_name);
523 _E("unown name %d", dn->id);
524 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
525 g_bus_unown_name(dn->id);
527 dbus_handle_lock(dh);
528 dh->list_names = g_list_remove(dh->list_names, dn);
530 dbus_handle_unlock(dh);
535 int dbus_handle_free_connection(dbus_handle_h handle)
538 dbus_handle_s *pdh = NULL;
543 dh = _dbus_handle_get_default_connection();
545 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
551 _E("connection is NULL");
557 /* disable dbus handler */
558 dbus_handle_lock(dh);
565 /* flush everything */
566 if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
567 _E("failed to flush %s\n", err->message);
572 _D("list_names %u", g_list_length(pdh->list_names));
574 /* unown every well-knwon name */
575 if (pdh->list_names) {
576 dbus_name *dn = NULL;
577 for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
578 dn = (dbus_name *)item->data;
582 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
583 _D("unown name id : %u", dn->id);
584 g_bus_unown_name(dn->id);
587 g_list_free(pdh->list_names);
588 pdh->list_names = NULL;
591 _D("list_object %u", g_list_length(pdh->list_object));
593 /* unregister every object */
594 if (pdh->list_object) {
595 dbus_object_handle_s * oh = NULL;
596 //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
597 for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
598 oh = (dbus_object_handle_s *)item->data;
599 if (!oh || !oh->list_ifaces)
602 _D("delete object path %s", oh->path);
604 /* unregister every interface, method handles */
605 for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
606 dbus_interface_s *ih = (dbus_interface_s *)iface->data;
610 _D("delete object iface %s", ih->name);
613 g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
618 /* close connection */
620 _E("close private connection\n");
622 if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
623 _E("Error closing connection %s\n", err->message);
629 /* _free_func_object callback free the data */
630 //assert(g_list_length(pdh->list_names) == 0);
631 //assert(g_list_length(pdh->list_object) == 0);
633 g_object_unref(pdh->conn);
635 dbus_handle_unlock(dh);
645 #define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
646 #define buf_block_size 8192
648 #define buf_check_space_realloc(buf, nwrite, buf_len) do {\
649 if ((nwrite >= buf_len - 1024)) {\
650 if (buf_len >= buf_block_size * 10) {\
651 _E("buf is too big to allocate. %d", buf_len);\
653 _E("buf_check_space_realloc");\
655 buf_len += buf_block_size;\
656 tmp = (char *)realloc(buf, buf_len);\
658 _E("failed to realloc");\
665 /* cal index of end of brace */
666 static int _check_brace(const char * expr)
677 if (expr[0] != '(' && expr[0] != '{')
680 for (int i = 0 ; i < len; ++i) {
682 if (expr[i] == '(' || expr[i] == '{') {
683 qu[qucnt++] = expr[i];
684 if (qucnt >= sizeof(qu)) {
685 _E("queue is too large. %s", expr);
691 if (expr[i] == ')' || expr[i] == '}') {
699 if (expr[i] == ')') {
704 } else if (expr[i] == '}') {
725 static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
730 const dbus_method_s *pmethod;
731 int buf_len = buf_block_size;
734 _E("interfaces is null");
738 // todo : check dbus naming rule for interface name. ?
739 if (!interfaces->name) {
740 _E("wrong interface name");
743 if (!interfaces->list_methods) {
748 buf = (char *)malloc(buf_len);
750 _E("buf is null. not enough memory\n");
754 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
757 for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
758 pmethod = (const dbus_method_s *)item->data;
762 /* check free space of buf */
763 buf_check_space_realloc(buf, nwrite, buf_len);
765 if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
766 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
770 /* <method name='###'> */
771 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
774 len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
775 for (int m = 0; m < len_args; ++m) {
777 // array a(), as, ay ?
778 if (pmethod->signature_in[m] == 'a') {
780 ei = _check_brace(pmethod->signature_in + m + 1);
782 char tmp[128] = {0,};
783 strncpy(tmp, pmethod->signature_in + m, ei + 1);
784 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='in'/>""\n", tmp, m);
788 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m);
793 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], m);
797 len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
798 for (int m = 0; m < len_args; ++m) {
800 // todo: container type
801 if (pmethod->signature_out[m] == 'a') {
803 ei = _check_brace(pmethod->signature_out + m + 1);
805 char tmp[128] = {0,};
806 strncpy(tmp, pmethod->signature_out + m, ei + 1);
807 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='out'/>""\n", tmp, m);
811 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m);
816 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], m);
820 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
823 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
827 /* todo: delete log */
832 _E("%s", buf + nwrite - 512);
837 static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
839 dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
840 if (!pa->path || !((const char*)b))
842 return strcmp(pa->path, (const char*)b);
845 static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
847 dbus_interface_s * pa = (dbus_interface_s *)a;
848 if (!pa->name || !((const char*)b))
850 return strcmp(pa->name, (const char*)b);
853 static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
855 dbus_interface_s * pa = (dbus_interface_s *)a;
856 if (!pa->reg_id || !((guint*)b))
858 return !(pa->reg_id == *((guint*)b));
861 static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
863 dbus_method_s *pa = (dbus_method_s*)a;
864 if (!pa->member || !((const char*)b))
866 return strcmp(pa->member, (const char*)b);
869 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
871 if (!list_obj || !obj_path)
874 GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
878 return (dbus_object_handle_s *)item->data;
881 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
883 if (!list_iface || !iface_name)
886 GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
890 return (dbus_interface_s *)item->data;
893 dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id)
895 if (!list_iface || !id)
898 GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
902 return (dbus_interface_s *)item->data;
905 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
907 if (!list_methods || !method_name)
910 GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
914 return (dbus_method_s *)item->data;
917 static void _free_func_object(gpointer data)
919 dbus_interface_s *ih = (dbus_interface_s *)data;
920 dbus_object_handle_s *oh = NULL;
923 _E("interface handle is null");
924 assert(0); // something wrong
928 _E("unregister interface %s", ih->name);
930 /* just free list, not data(static dbus_method_s) */
931 g_list_free(ih->list_methods);
935 _E("object handle is null");
936 assert(0); // something wrong
940 /* remove ih from list_ifaces */
941 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
943 /* interface_s is copy of interface_u */
946 /* remove oh from list_object */
947 if (!oh->list_ifaces) {
948 oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
953 static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
955 dbus_object_handle_s *oh = NULL;
957 if (!dh || !obj_path || !iface) {
958 _E("failed to attache object. wrong parameter");
962 /* find object handle */
964 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
967 oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
969 _E("failed to calloc");
976 dh->list_object = g_list_prepend(dh->list_object, oh);
980 /* attach interface */
981 oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
989 libgio verify path and interface of incoming message.
990 --> just check method name.
992 # parameters - member of invocation struct
993 every parameters of this function are member of GDBusMethodInvocation *invocation.
994 There are no reason to using g_dbus_method_invocation_get_* apis to get inforamtion from message.
995 just use params - sender, path, iface, name and param.
998 # user defined handler #
1000 1. synchronous handling
1001 1) with return value
1003 return g_variant_new("(i)", ret);
1006 2) without return value
1008 return dbus_handle_new_g_variant_tuple(); // g_variant_new_tuple(NULL, 0)
1011 2. asynchronous handling
1012 handler MUST call 'g_dbus_method_invocation_return_value' itself. otherwise, LEAK !!
1018 # if handler return NULL, assume asynchronous handling. do nothing.
1023 1) with return value
1024 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret));
1026 2) without return value
1027 g_dbus_method_invocation_return_value(invocation, NULL);
1032 static void _method_call_handler(GDBusConnection *conn,
1033 const gchar *sender,
1038 GDBusMethodInvocation *invocation,
1041 dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
1042 const dbus_method_s *methods;
1043 GVariant *result = NULL;
1046 methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
1048 result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
1050 /* async, maybe they will reply...maybe.. */
1057 g_dbus_method_invocation_return_value(invocation, result);
1060 static GDBusInterfaceVTable path_vtable = {_method_call_handler};
1064 before register object, attach object into dbus handle
1065 _dbus_handle_attach_object()
1067 static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
1073 GDBusNodeInfo * nodeinfo = NULL;
1074 GDBusInterfaceInfo *ifaceinfo = NULL;
1076 if (!obj_path || !iface) {
1077 _E("wrong parameter\n");
1081 dh = _dbus_handle_get_default_connection();
1083 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1088 _E("connection is null\n");
1092 ret = _get_xml_from_interfaces(&buf, iface);
1094 _E("failed to make xml format");
1098 /* todo: delete this */
1100 if (strlen(buf) <= 512) {
1103 _E("%s", buf + strlen(buf) - 512);
1107 nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
1108 if (!nodeinfo || err) {
1109 _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
1114 ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
1116 _E("failed to g_dbus_node_info_lookup_interface");
1122 path own single interface
1123 if interface is already registered, then failed.
1124 g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
1126 ret = g_dbus_connection_register_object(dh->conn,
1134 _E("failed to register object:err:%s:\n", err->message);
1139 iface->reg_id = ret;
1140 iface->modified = FALSE;
1143 /* todo: detach object */
1144 //_dbus_handle_detach_object(dh, obj_path, iface);
1145 /* attach interface before register object */
1146 /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
1148 _E("failed to attach object");
1153 g_dbus_node_info_unref(nodeinfo);
1163 register same interface at once
1165 if interface is constructed by multiple methods,
1166 also it is not possible to make methods struct at once,
1168 use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all().
1172 int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1176 dbus_interface_s *iface = NULL;
1178 if (!obj_path || !iface_u) {
1179 _E("wrong parameter\n");
1183 dh = _dbus_handle_get_default_connection();
1185 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1190 _E("connection is null\n");
1194 /* check registered interface */
1195 if (dh->list_object) {
1196 dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1198 dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1200 _E("path %s, interface %s already registered", obj_path, iface_u->name);
1206 iface = _iface_u_to_s(iface_u);
1208 _E("failed to _iface_u_to_s");
1212 /* attach interface before register object */
1213 ret = _dbus_handle_attach_object(dh, obj_path, iface);
1215 _E("failed to attach object");
1219 ret = _dbus_handle_register_dbus_object(dh, obj_path, iface);
1221 _E("failed to register dbus object%d", ret);
1228 int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
1231 dbus_object_handle_s *oh = NULL;
1238 dh = _dbus_handle_get_default_connection();
1240 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1244 if (!dh->list_object) {
1245 _E("list_object is empty");
1249 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1251 _E("no object with name %s", obj_path);
1255 /* unregister every interface of object*/
1256 for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
1257 dbus_interface_s *ih = item->data;
1259 _E("this is error");
1263 /* remove ih from list_ifaces */
1265 item = g_list_previous(item);
1267 /* remove and free link */
1268 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
1270 /* free list_methods */
1271 g_list_free(ih->list_methods);
1278 /* unregister object by id */
1279 ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
1281 _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
1288 add object temporarily.
1289 dbus_handle_register_dbus_object_all register every objects on connection.
1291 return registered method count
1293 int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1296 dbus_object_handle_s *oh = NULL;
1297 dbus_interface_s *ih = NULL;
1300 if (!obj_path || !iface_u) {
1301 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1304 if (iface_u && (!iface_u->name || !iface_u->methods)) {
1305 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1309 cnt = iface_u->nr_methods;
1312 dh = _dbus_handle_get_default_connection();
1314 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1320 _E("failed to register method. connection is null\n");
1324 /* if there are no object list, just add */
1325 if (!dh->list_object) {
1326 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1327 _E("failed to attach object");
1333 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1334 /* if there are no matched object, just add */
1336 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1337 _E("failed to attach object");
1343 /* this is an error, interface must have one or more item ? */
1344 if (!oh->list_ifaces) {
1345 _E("error. list_ifaces is null\n");
1350 ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1351 /* if there are no matched interface, just add */
1353 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1354 _E("failed to attach object");
1361 1. unregister interface
1362 2. update interface and methods
1363 3. register interface
1366 _E("interface already registered, ignore new interface");
1370 /* attach new methods */
1372 for (int i = 0; i < iface_u->nr_methods; ++i) {
1373 GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
1375 //_D("attached %s", iface_u->methods[i].member);
1376 ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
1382 ih->modified = TRUE;
1385 /*todo: delete debugging log */
1386 //if (dh && dh->list_object)
1387 // _D("obj list len %d", g_list_length(dh->list_object));
1388 //if (oh && oh->list_ifaces)
1389 // _D("iface list len %d", g_list_length(oh->list_ifaces));
1390 //if (ih && ih->list_methods)
1391 // _D("method list len %d", g_list_length(ih->list_methods));
1396 int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
1399 dbus_object_handle_s *oh = NULL;
1400 dbus_interface_s *ih = NULL;
1404 dh = _dbus_handle_get_default_connection();
1406 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1411 _E("connection is null\n");
1415 if (!dh->list_object) {
1416 _E("obj list is empty");
1420 /*if (dh && dh->list_object)
1421 _D("obj list len %d", g_list_length(dh->list_object));*/
1423 for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
1424 oh = (dbus_object_handle_s *)item->data;
1427 _E("something wrong");
1430 if (!oh->list_ifaces) {
1431 _E("path %s: list_ifaces are null", oh->path);
1435 //_D("iface list len %d", g_list_length(oh->list_ifaces));
1437 for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
1438 ih = (dbus_interface_s *)li->data;
1440 /* if there are no modification, goto next */
1444 /* todo: if already registered interface, unregister first */
1446 /*_E("interface %s:", ih->name);
1447 if (ih && ih->list_methods)
1448 _D("method list len %d", g_list_length(ih->list_methods));*/
1450 ret = _dbus_handle_register_dbus_object(dh, oh->path, ih);
1452 _E("failed to register dbus object%d", ret);
1459 // todo: delete all updates
1464 static void _free_func_signal(gpointer data)
1466 //_D("free signal subscribe");
1469 guint subscribe_dbus_signal(dbus_handle_h handle, const char *path,
1470 const char *iface, const char *name,
1471 GDBusSignalCallback cb, void *data,
1472 destroy_notified free_func)
1477 dh = _dbus_handle_get_default_connection();
1479 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1485 _E("connection is null. check bus status");
1488 return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal);
1491 void unsubscribe_dbus_signal(dbus_handle_h handle, guint id)
1495 dh = _dbus_handle_get_default_connection();
1497 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1503 _E("connection is null. check bus status");
1507 g_dbus_connection_signal_unsubscribe(dh->conn, id);
1510 int _check_type_string_is_container(const char *signature)
1515 switch (signature[0]) {
1530 GVariant *dbus_handle_make_simple_array(const char *sig, int *param)
1532 GVariantBuilder *builder = NULL;
1533 GVariant *var = NULL;
1537 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
1539 _E("failed to g_variant_builder_new");
1544 g_variant_builder_add(builder, "i", param[i++]);
1546 snprintf(format, sizeof(format) - 1, "(%s)", sig);
1547 var = g_variant_new(format, builder);
1548 g_variant_builder_unref(builder);
1552 /* todo: looks like garbage... */
1553 static GVariant* _append_variant(const char *signature, const char *param[])
1560 unsigned long long int64_type;
1563 char container[255];// The maximum length of a signature is 255.
1564 const char *sig = signature;
1565 GVariantBuilder *builder = NULL;
1567 if (!signature || !param)
1570 /* workaround for user fault "(i) != i" but we treat this as same signature */
1571 /* G_VARIANT_TYPE("si") return NULL */
1572 /* todo: actually user have to use correct signature */
1573 if (!_check_type_string_is_container(signature)) {
1574 snprintf(container, sizeof(container) - 1, "(%s)", signature);
1577 if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) {
1578 _E("signature (%s) is not container type", signature);
1581 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
1584 for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) {
1590 bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE);
1591 g_variant_builder_add(builder, "b", bool_type);
1594 int_type = atoi(param[pi++]);
1595 g_variant_builder_add(builder, "i", int_type);
1598 int_type = strtoul(param[pi++], NULL, 10);
1599 g_variant_builder_add(builder, "u", int_type);
1602 int64_type = atoll(param[pi++]);
1603 g_variant_builder_add(builder, "t", int64_type);
1606 g_variant_builder_add(builder, "s", param[pi++]);
1612 g_variant_builder_add(builder, "^ay", param[pi++]);
1623 ret = g_variant_builder_end(builder);
1624 g_variant_builder_clear(builder);
1625 g_variant_builder_unref(builder);
1630 int dbus_handle_broadcast_dbus_signal(const char *path,
1633 const char *signature,
1634 const char *param[])
1636 dbus_handle_s *dh = NULL;
1639 GVariant *var = NULL;
1641 dh = _dbus_handle_get_default_connection();
1643 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1647 if (signature && param)
1648 var = _append_variant(signature, param);
1649 ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err);
1651 _E("%d %s\n", ret, err ? err->message : NULL);
1658 int dbus_handle_broadcast_dbus_signal_var(const char *path,
1663 dbus_handle_s *dh = NULL;
1667 dh = _dbus_handle_get_default_connection();
1669 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1673 ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err);
1675 _E("%d %s\n", ret, err ? err->message : NULL);
1682 GVariant *dbus_handle_method_sync_with_reply_var(const char *dest,
1689 GVariant * ret = NULL;
1690 dbus_handle_s *dh = NULL;
1692 if (!dest || !path || !iface || !method) {
1693 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1695 g_variant_unref(var);
1699 dh = _dbus_handle_get_default_connection();
1701 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1703 g_variant_unref(var);
1707 ret = g_dbus_connection_call_sync(dh->conn,
1708 dest, path, iface, method,
1709 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
1712 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1715 _E("failed to g_dbus_connection_call_sync");
1723 GVariant *dbus_handle_method_sync_with_reply_var_timeout(const char *dest, const char *path,
1724 const char *iface, const char *method, GVariant *var, int timeout)
1727 GVariant * ret = NULL;
1728 dbus_handle_s *dh = NULL;
1730 if (!dest || !path || !iface || !method) {
1731 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1733 g_variant_unref(var);
1737 dh = _dbus_handle_get_default_connection();
1739 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1741 g_variant_unref(var);
1745 ret = g_dbus_connection_call_sync(dh->conn,
1746 dest, path, iface, method,
1747 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
1750 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1753 _E("failed to g_dbus_connection_call_sync");
1761 gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
1763 GUnixFDList *fd_list = NULL;
1766 fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
1769 _E("failed to g_unix_fd_list_get_length: fd_list is null");
1773 length = g_unix_fd_list_get_length(fd_list);
1775 _E("failed to g_unix_fd_list_get_length: list size is 0");
1781 return g_unix_fd_list_steal_fds(fd_list, NULL);
1784 GVariant *dbus_handle_method_with_unix_fd_list_sync_with_reply(const char *dest,
1788 const char *signature,
1789 const char *param[],
1796 GVariant * var = NULL;
1797 GVariant * ret = NULL;
1798 dbus_handle_s *dh = NULL;
1799 GDBusProxy *proxy = NULL;
1800 GUnixFDList *g_infdlist = NULL;
1801 GUnixFDList *g_outfdlist = NULL;
1803 if (!dest || !path || !iface || !method) {
1804 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1807 if (in_fdlist && in_size == 0) {
1808 _E("wrong in_fdlist is not null but in_size is 0");
1812 dh = _dbus_handle_get_default_connection();
1814 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1818 if (signature && param)
1819 var = _append_variant(signature, param);
1821 proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
1824 _E("failed to proxy_new_sync(%s)\n", err->message);
1827 _E("failed to proxy_new_sync\n");
1829 g_variant_unref(var);
1835 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
1837 _E("failed to g_unix_fd_list_new_from_array\n");
1840 //g_infdlist = g_unix_fd_list_new();
1841 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
1844 ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1,
1845 g_infdlist, &g_outfdlist, NULL, &err);
1848 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
1851 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
1853 g_variant_unref(var);
1855 g_object_unref(g_infdlist);
1860 /* fds to out array */
1862 *out_size = g_unix_fd_list_get_length(g_outfdlist);
1866 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
1871 g_object_unref(g_outfdlist);
1873 g_object_unref(proxy);
1878 GVariant *dbus_handle_method_with_unix_fd_list_sync_with_reply_var(const char *dest,
1889 GVariant * ret = NULL;
1890 dbus_handle_s *dh = NULL;
1891 GDBusProxy *proxy = NULL;
1892 GUnixFDList *g_infdlist = NULL;
1893 GUnixFDList *g_outfdlist = NULL;
1895 if (!dest || !path || !iface || !method) {
1896 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1899 if (in_fdlist && in_size == 0) {
1900 _E("wrong in_fdlist is not null but in_size is 0");
1904 dh = _dbus_handle_get_default_connection();
1906 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1910 proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
1913 _E("failed to proxy_new_sync(%s)\n", err->message);
1916 _E("failed to proxy_new_sync\n");
1918 g_variant_unref(param);
1925 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
1927 _E("failed to g_unix_fd_list_new_from_array\n");
1930 //g_infdlist = g_unix_fd_list_new();
1931 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
1935 ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1,
1936 g_infdlist, &g_outfdlist, NULL, &err);
1939 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
1942 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
1944 g_variant_unref(param);
1946 g_object_unref(g_infdlist);
1951 /* copy fds to out array */
1953 *out_size = g_unix_fd_list_get_length(g_outfdlist);
1956 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
1960 g_object_unref(g_outfdlist);
1962 g_object_unref(proxy);
1966 int dbus_handle_method_sync(const char *dest,
1970 const char *signature,
1971 const char *param[])
1974 gboolean result_bool;
1975 GVariant *reply = NULL;
1976 GVariant * var = NULL;
1978 dbus_handle_s *dh = NULL;
1980 if (!dest || !path || !iface || !method) {
1981 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1985 dh = _dbus_handle_get_default_connection();
1987 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1991 if (signature && param)
1992 var = _append_variant(signature, param);
1994 reply = g_dbus_connection_call_sync(dh->conn,
1995 dest, path, iface, method,
1996 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
1997 if (!reply || err) {
1999 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2002 _E("failed to g_dbus_connection_call_sync");
2003 g_variant_unref(var);
2008 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
2009 g_variant_get(reply, "(i)", &result);
2010 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
2011 g_variant_get(reply, "(b)", &result_bool);
2012 result = (int)result_bool;
2017 g_variant_unref(reply);
2022 int dbus_handle_method_sync_var(const char *dest,
2029 gboolean result_bool;
2030 GVariant *reply = NULL;
2032 if (!dest || !path || !iface || !method) {
2033 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2037 reply = dbus_handle_method_sync_with_reply_var(dest, path, iface, method, param);
2041 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
2042 g_variant_get(reply, "(i)", &result);
2043 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
2044 g_variant_get(reply, "(b)", &result_bool);
2045 result = (int)result_bool;
2050 g_variant_unref(reply);
2055 int dbus_handle_method_sync_timeout(const char *dest,
2059 const char *signature,
2060 const char *param[],
2063 dbus_handle_s *dh = NULL;
2065 GVariant * var = NULL;
2066 GVariant * reply = NULL;
2069 if (!dest || !path || !iface || !method) {
2070 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2074 dh = _dbus_handle_get_default_connection();
2076 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2080 if (signature && param)
2081 var = _append_variant(signature, param);
2083 reply = g_dbus_connection_call_sync(dh->conn,
2084 dest, path, iface, method,
2085 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
2086 if (!reply || err) {
2087 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2092 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
2093 g_variant_get(reply, "(i)", &result);
2097 g_variant_unref(reply);
2102 int dbus_handle_method_sync_pairs(const char *dest,
2110 GVariant * reply = NULL;
2114 GVariantBuilder *builder;
2115 dbus_handle_s *dh = NULL;
2117 if (!dest || !path || !iface || !method) {
2118 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2122 dh = _dbus_handle_get_default_connection();
2124 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2128 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2130 for (int i = 0 ; i < num ; i = i + 2) {
2131 key = va_arg(args, char *);
2132 value = va_arg(args, char *);
2133 _I("key(%s), value(%s)", key, value);
2134 g_variant_builder_add(builder, "{ss}", key, value);
2137 var = g_variant_new("(a{ss})", builder);
2138 g_variant_builder_unref(builder);
2140 reply = g_dbus_connection_call_sync(dh->conn,
2141 dest, path, iface, method,
2142 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
2143 if (!reply || err) {
2144 _E("failed to g_dbus_connection_call_sync");
2148 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
2149 g_variant_get(reply, "(i)", &ret);
2153 g_variant_unref(reply);
2158 int dbus_handle_method_async_pairs(const char *dest,
2167 GVariantBuilder *builder;
2168 dbus_handle_s *dh = NULL;
2170 if (!dest || !path || !iface || !method) {
2171 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2175 dh = _dbus_handle_get_default_connection();
2177 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2182 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2184 for (int i = 0 ; i < num ; i = i + 2) {
2185 key = va_arg(args, char *);
2186 value = va_arg(args, char *);
2187 _I("key(%s), value(%s)", key, value);
2188 g_variant_builder_add(builder, "{ss}", key, value);
2191 var = g_variant_new("(a{ss})", builder);
2192 g_variant_builder_unref(builder);
2194 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2195 var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2202 int dbus_handle_method_async(const char *dest,
2206 const char *signature,
2207 const char *param[])
2209 GVariant * var = NULL;
2210 dbus_handle_s *dh = NULL;
2212 if (!dest || !path || !iface || !method) {
2213 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2217 dh = _dbus_handle_get_default_connection();
2219 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2223 if (signature && param)
2224 var = _append_variant(signature, param);
2226 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2227 var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2234 int dbus_handle_method_async_var(const char *dest,
2240 dbus_handle_s *dh = NULL;
2242 if (!dest || !path || !iface || !method) {
2243 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2247 dh = _dbus_handle_get_default_connection();
2249 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2253 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2254 param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2261 /* callback should free gvariant */
2262 static void _cb_pending(GDBusConnection *conn,
2266 GVariant *reply = NULL;
2268 pending_call_data *data = (pending_call_data *)user_data;
2270 reply = g_dbus_connection_call_finish(conn, res, &err);
2271 if (!reply || err) {
2273 g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
2274 "Error during g_dbus_connection_call");
2276 if (data && data->func)
2277 data->func(NULL, data->data, err);
2281 if (data && data->func)
2282 data->func(reply, data->data, err);
2290 int dbus_handle_method_async_pairs_with_reply(const char *dest,
2300 dbus_handle_s *dh = NULL;
2301 pending_call_data *pdata = NULL;
2302 GVariantBuilder *builder;
2307 if (!dest || !path || !iface || !method) {
2308 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2312 if (timeout_msec < -1) {
2313 _E("wrong timeout %d", timeout_msec);
2317 dh = _dbus_handle_get_default_connection();
2319 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2324 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2326 for (int i = 0 ; i < num ; i = i + 2) {
2327 key = va_arg(args, char *);
2328 value = va_arg(args, char *);
2329 _I("key(%s), value(%s)", key, value);
2330 g_variant_builder_add(builder, "{ss}", key, value);
2333 param = g_variant_new("(a{ss})", builder);
2334 g_variant_builder_unref(builder);
2337 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2346 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2347 param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
2348 (GAsyncReadyCallback)_cb_pending,
2354 g_variant_unref(param);
2358 int dbus_handle_method_async_with_reply(const char *dest,
2362 const char *signature,
2363 const char *param[],
2368 dbus_handle_s *dh = NULL;
2369 pending_call_data *pdata = NULL;
2370 GVariant * var = NULL;
2373 if (!dest || !path || !iface || !method) {
2374 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2378 if (timeout_msec < -1) {
2379 _E("wrong timeout %d", timeout_msec);
2383 dh = _dbus_handle_get_default_connection();
2385 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2389 if (signature && param)
2390 var = _append_variant(signature, param);
2393 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2402 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2403 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
2404 (GAsyncReadyCallback)_cb_pending,
2410 g_variant_unref(var);
2414 int dbus_handle_method_async_with_reply_var(const char *dest,
2423 dbus_handle_s *dh = NULL;
2424 pending_call_data *pdata = NULL;
2427 if (!dest || !path || !iface || !method) {
2428 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2432 if (timeout_msec < -1) {
2433 _E("wrong timeout %d", timeout_msec);
2437 dh = _dbus_handle_get_default_connection();
2439 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2444 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2453 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2454 param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
2455 (GAsyncReadyCallback)_cb_pending,
2461 g_variant_unref(param);
2465 int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
2468 GVariant *vret = NULL;
2472 _E("connection is null");
2476 _E("sender is null");
2480 vret = g_dbus_connection_call_sync(conn,
2481 "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID",
2482 g_variant_new("(s)", sender),
2484 G_DBUS_CALL_FLAGS_NONE,
2489 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2494 g_variant_get(vret, "(u)", &pid);
2495 g_variant_unref(vret);
2500 int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender)
2505 dh = _dbus_handle_get_default_connection();
2507 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2512 _E("wrong dbus handle. connection is null");
2517 return dbus_connection_get_sender_pid(dh->conn, sender);
2520 int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
2523 GVariant *vret = NULL;
2525 GVariantIter *iter = NULL;
2530 dh = _dbus_handle_get_default_connection();
2532 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2536 vret = g_dbus_connection_call_sync(dh->conn,
2539 DBUS_INTERFACE_NAME,
2540 "GetConnectionCredentials",
2541 g_variant_new("(s)", name),
2543 G_DBUS_CALL_FLAGS_NONE,
2548 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2552 g_variant_get(vret, "(a{sv})", &iter);
2554 while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
2555 if (!g_strcmp0(item, "UnixUserID")) {
2556 g_variant_get(sub, "u", &creds->uid);
2557 //_D("UnixUserID %u", creds->uid);
2558 } else if (!g_strcmp0(item, "ProcessID")) {
2559 g_variant_get(sub, "u", &creds->pid);
2560 //_D("ProcessID %u", creds->pid);
2561 } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
2562 g_variant_get(sub, "^ay", &creds->sec_label);
2563 //_D("%s", creds->sec_label);
2568 g_variant_iter_free(iter);
2570 g_variant_unref(vret);
2575 void _destroy_notify_watch_name(gpointer data)
2581 int dbus_handle_watch_name(const char *name,
2582 GBusNameAppearedCallback name_appeared_handler,
2583 GBusNameVanishedCallback name_vanished_handler,
2585 GDestroyNotify user_data_free_func)
2590 _E("wrong name name %s", name);
2593 if (!name_appeared_handler && !name_vanished_handler) {
2594 _E("both function pointers are null");
2598 id = g_bus_watch_name(dbus_handle_get_default_bus_type(),
2600 G_BUS_NAME_WATCHER_FLAGS_NONE,
2601 name_appeared_handler,
2602 name_vanished_handler,
2604 user_data_free_func ? user_data_free_func : _destroy_notify_watch_name);
2606 _E("failed to g_bus_watch_name");
2613 void dbus_handle_unwatch_name(guint id)
2616 _E("wrong id %d", id);
2619 g_bus_unwatch_name(id);
2622 int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
2625 char buf[PATH_MAX + 1];
2628 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
2629 fd = open(buf, O_RDONLY);
2635 ret = read(fd, buf, PATH_MAX);
2640 buf[PATH_MAX] = '\0';
2642 filename = strrchr(buf, '/');
2643 if (filename == NULL)
2646 filename = filename + 1;
2648 if (cmdline_size < strlen(filename) + 1) {
2653 strncpy(cmdline, filename, cmdline_size - 1);
2654 cmdline[cmdline_size - 1] = '\0';
2659 char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name)
2663 GVariant *vret = NULL;
2664 GVariantIter *iter = NULL;
2665 gchar **strv = NULL;
2670 _E("wrong parameter bus_name(%s)", bus_name);
2675 dh = _dbus_handle_get_default_connection();
2677 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2682 vret = g_dbus_connection_call_sync(dh->conn,
2683 "org.freedesktop.DBus",
2685 "org.freedesktop.DBus",
2687 g_variant_new("(s)", bus_name),
2689 G_DBUS_CALL_FLAGS_NONE,
2694 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2699 g_variant_get(vret, "(as)", &iter);
2700 strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
2703 while (g_variant_iter_loop(iter, "s", &str))
2704 strv[i++] = g_strdup(str);
2707 g_variant_iter_free(iter);
2708 g_variant_unref(vret);
2713 void dbus_handle_check_owner_name(dbus_handle_h handle, const char *owner_name)
2716 char exe_name[PATH_MAX];
2722 dh = _dbus_handle_get_default_connection();
2724 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2729 strv = dbus_handle_get_owner_list(dh, owner_name);
2731 _E("failed to get owner list of %s", owner_name);
2735 for (i = 0; strv[i] != NULL; ++i) {
2736 pid = dbus_handle_get_sender_pid(dh, strv[i]);
2737 if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
2739 _I("%s(%d)", exe_name, pid);