4 * Copyright (c) 2019 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.
26 #include "shared/log.h"
30 #define DBUS_REPLY_TIMEOUT (10000)
32 static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
33 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
35 void gdbus_set_default_bus_type(GBusType bus_type)
37 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
40 pthread_mutex_lock(&g_mutex);
41 g_default_bus_type = bus_type;
42 pthread_mutex_unlock(&g_mutex);
45 GBusType gdbus_get_default_bus_type(void)
49 pthread_mutex_lock(&g_mutex);
50 type = g_default_bus_type;
51 pthread_mutex_unlock(&g_mutex);
61 /* basic information */
63 GDBusConnection *conn;
66 GList *list_names; /* dbus_name */
67 GList *list_object; /* dbus_object_handle_s */
68 pthread_mutex_t mutex;
71 /* path + interfaces */
73 dbus_handle_s *dh; /* dbus handle */
74 const char *path; /* object path */
75 GList *list_ifaces; /* dbus_interface_s */
76 } dbus_object_handle_s;
79 dbus_object_handle_s *oh; /* object handle */
80 const char *name; /* interface name */
81 GList *list_methods; /* const dbus_method_s */
86 #define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
88 /* global shared bus : system, session */
89 static dbus_handle_s g_dh[2];
91 static dbus_handle_s *_gdbus_get_connection(GBusType bus_type);
93 dbus_handle_s * _gdbus_get_default_connection(void)
95 return _gdbus_get_connection(gdbus_get_default_bus_type());
98 #define gdbus_lock(handle) do {\
100 pthread_mutex_lock(&((handle)->mutex));\
103 #define gdbus_unlock(handle) do {\
105 pthread_mutex_unlock(&(handle)->mutex);\
108 #define dcl_gdbus() dbus_handle_s *dh = (dbus_handle_s *)handle;
109 #define dcl_gdbus_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
111 _E("dbus handle is null\n");\
115 dbus_object_handle_s * _gdbus_lookup_object(GList *list_obj, const char *obj_path);
116 dbus_interface_s * _gdbus_lookup_interface(GList *list_iface, const char *iface_name);
117 dbus_method_s * _gdbus_lookup_method(GList *list_methods, const char *method_name);
119 dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
121 dbus_interface_s *iface = NULL;
123 if (!iface_u || !iface_u->methods) {
128 iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
130 _E("failed to calloc");
134 iface->name = iface_u->name;
135 iface->modified = TRUE;
137 for (int i = 0 ; i < iface_u->nr_methods; ++i) {
138 //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
139 iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
145 static GDBusConnection * _get_bus(GBusType bus_type)
147 GDBusConnection *conn = NULL;
150 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
151 _E("Wrong bus_type %d", bus_type);
155 conn = g_bus_get_sync(bus_type, NULL, &err);
157 _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
165 static GDBusConnection * _get_bus_private(GBusType bus_type)
168 GDBusConnection *conn = NULL;
169 const char * address;
171 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
172 _E("Wrong bus_type %d", bus_type);
176 address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
177 if (!address || err) {
178 _E("failed to get bus address\n");
183 conn = g_dbus_connection_new_for_address_sync(address,
184 (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
185 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
186 NULL, /* GDBusAuthObserver */
190 _E("failed to get private bus\n");
199 static dbus_handle_s *_gdbus_get_connection(GBusType bus_type)
201 int ibus = bus_type - 1;
202 dbus_handle_s *dh = NULL;
204 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
205 _E("Unknown bus type %d", bus_type);
213 dh->conn = _get_bus(bus_type);
219 dh->bus_type = bus_type;
228 static dbus_handle_s *_gdbus_get_connection_private(GBusType bus_type)
232 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
233 _E("Unknown bus type %d", bus_type);
237 dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
239 _E("failed to allocate memory for dbus handle");
246 dh->conn = _get_bus_private(bus_type);
247 dh->bus_type = bus_type;
263 dbus_handle_h gdbus_get_connection(GBusType bus_type, gboolean priv)
265 dbus_handle_s *dh = NULL;
268 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
269 _E("Wrong bus_type %d\n", bus_type);
273 for (i = 0 ; i < 3; ++i) {
276 dh = _gdbus_get_connection_private(bus_type);
279 dh = _gdbus_get_connection(bus_type);
289 static void _gdbus_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
291 dbus_name *dn = NULL;
294 if (!handle || !name || !id)
297 dn = (dbus_name*)calloc(1, sizeof(dbus_name));
299 _E("failed to calloc");
305 // todo : delete lock ?
306 locked = pthread_mutex_trylock(&handle->mutex);
307 if (locked != 0 && locked != EBUSY) {
308 _E("failed to lock %d\n", locked);
312 handle->list_names = g_list_prepend(handle->list_names, dn);
314 // todo : delete lock ?
316 gdbus_unlock(handle);
319 static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
321 const char *bus_name = ((dbus_name *)a)->bus_name;
324 return strcmp(bus_name, (const char *)b);
327 dbus_name * _gdbus_lookup_dbus_name(GList *list_name, const char *bus_name)
329 if (!list_name || !bus_name)
332 GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
336 return (dbus_name *)item->data;
339 #define dh_to_ds(x) ((dbus_handle_s*)x)
341 /* remove dbus_name from dbus handle */
342 static void _gdbus_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
345 dbus_name *dn = NULL;
348 _E("wrong bus_name is null");
352 dh = _gdbus_get_default_connection();
354 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
360 dn = _gdbus_lookup_dbus_name(dh->list_names, bus_name);
362 _E("failed to find dbus name %s", bus_name);
365 dh->list_names = g_list_remove(dh->list_names, dn);
371 //extern void booting_done(void);
373 /* default handler */
374 static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
376 dbus_handle_s *dh = (dbus_handle_s *)user_data;
381 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
385 // todo: add bus name?
386 //dh->bus_name = name;
389 /* default handler */
390 static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
392 _E("%s:%d:%s\n", __func__, __LINE__, name);
393 dbus_handle_s *dh = (dbus_handle_s *)user_data;
395 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
398 _gdbus_remove_bus_name(dh, name);
401 int gdbus_request_name(dbus_handle_h handle,
402 const char *bus_name,
403 GBusNameAcquiredCallback acquired_handler,
404 GBusNameLostCallback lost_handler)
411 _E("bus_name is NULL");
415 /* get shared connection */
417 dh = _gdbus_get_default_connection();
419 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
426 _E("failed to register name: connection is null\n");
430 /* todo : search name on connection */
431 item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
433 id = ((dbus_name*)(item->data))->id;
434 _E("name already exist:%u", id);
438 id = g_bus_own_name_on_connection(dh->conn,
440 G_BUS_NAME_OWNER_FLAGS_NONE,
441 acquired_handler ? acquired_handler : _name_acquired,
442 lost_handler ? lost_handler : _name_lost,
446 _E("failed to own name:%s\n", bus_name);
450 _gdbus_add_bus_name(dh, bus_name, id);
457 /* !! _name_lost handler callback is disabled by g_bus_unown_name : ubuntu */
458 int gdbus_release_name(dbus_handle_h handle, const char *bus_name)
461 dbus_name *dn = NULL;
464 _E("Wrong bus name");
469 dh = _gdbus_get_default_connection();
471 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
476 dn = _gdbus_lookup_dbus_name(dh->list_names, bus_name);
478 _E("failed to find bus_name %s on dbus handle", bus_name);
482 _E("unown name %d", dn->id);
483 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
484 g_bus_unown_name(dn->id);
487 dh->list_names = g_list_remove(dh->list_names, dn);
494 void gdbus_unwatch_name(guint id)
497 _E("wrong id %d", id);
500 g_bus_unwatch_name(id);
504 char **gdbus_get_owner_list(dbus_handle_h handle, const char *bus_name)
508 GVariant *reply = NULL;
509 GVariantIter *iter = NULL;
515 _E("wrong parameter bus_name is null");
520 dh = _gdbus_get_default_connection();
522 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
527 reply = g_dbus_connection_call_sync(dh->conn,
532 g_variant_new("(s)", bus_name),
534 G_DBUS_CALL_FLAGS_NONE,
539 _E("failed to g_dbus_connection_call_sync:%s", err->message);
544 g_variant_get(reply, "(as)", &iter);
545 strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
548 while (g_variant_iter_loop(iter, "s", &str))
549 strv[i++] = g_strdup(str);
552 g_variant_iter_free(iter);
553 g_variant_unref(reply);
558 int gdbus_free_connection(dbus_handle_h handle)
561 dbus_handle_s *pdh = NULL;
566 dh = _gdbus_get_default_connection();
568 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
574 _E("connection is NULL");
580 /* disable dbus handler */
588 /* flush everything */
589 if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
590 _E("failed to flush %s\n", err->message);
595 _D("list_names %u", g_list_length(pdh->list_names));
597 /* unown every well-knwon name */
598 if (pdh->list_names) {
599 dbus_name *dn = NULL;
600 for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
601 dn = (dbus_name *)item->data;
605 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
606 _D("unown name id : %u", dn->id);
607 g_bus_unown_name(dn->id);
610 g_list_free(pdh->list_names);
611 pdh->list_names = NULL;
614 _D("list_object %u", g_list_length(pdh->list_object));
616 /* unregister every object */
617 if (pdh->list_object) {
618 dbus_object_handle_s * oh = NULL;
619 //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
620 for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
621 oh = (dbus_object_handle_s *)item->data;
622 if (!oh || !oh->list_ifaces)
625 _D("delete object path %s", oh->path);
627 /* unregister every interface, method handles */
628 for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
629 dbus_interface_s *ih = (dbus_interface_s *)iface->data;
633 _D("delete object iface %s", ih->name);
636 g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
641 /* close connection */
643 _E("close private connection\n");
645 if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
646 _E("Error closing connection %s\n", err->message);
652 /* _free_func_object callback free the data */
653 //assert(g_list_length(pdh->list_names) == 0);
654 //assert(g_list_length(pdh->list_object) == 0);
656 g_object_unref(pdh->conn);
668 #define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
669 #define buf_block_size 8192
671 #define buf_check_space_realloc(buf, nwrite, buf_len) do {\
672 if ((nwrite >= buf_len - 1024)) {\
673 if (buf_len >= buf_block_size * 10) {\
674 _E("buf is too big to allocate. %d", buf_len);\
676 _E("buf_check_space_realloc");\
678 buf_len += buf_block_size;\
679 tmp = (char *)realloc(buf, buf_len);\
681 _E("failed to realloc");\
688 /* cal index of end of brace */
689 static int _check_brace(const char * expr)
700 if (expr[0] != '(' && expr[0] != '{')
703 for (int i = 0 ; i < len; ++i) {
705 if (expr[i] == '(' || expr[i] == '{') {
706 qu[qucnt++] = expr[i];
707 if (qucnt >= sizeof(qu)) {
708 _E("queue is too large. %s", expr);
714 if (expr[i] == ')' || expr[i] == '}') {
722 if (expr[i] == ')') {
727 } else if (expr[i] == '}') {
747 static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
752 const dbus_method_s *pmethod;
753 int buf_len = buf_block_size;
756 _E("interfaces is null");
760 // todo : check dbus naming rule for interface name. ?
761 if (!interfaces->name) {
762 _E("wrong interface name");
765 if (!interfaces->list_methods) {
770 buf = (char *)malloc(buf_len);
772 _E("buf is null. not enough memory\n");
776 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
779 for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
780 pmethod = (const dbus_method_s *)item->data;
784 /* check free space of buf */
785 buf_check_space_realloc(buf, nwrite, buf_len);
787 if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
788 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
792 /* <method name='###'> */
793 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
796 len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
797 for (int m = 0; m < len_args; ++m) {
799 // array a(), as, ay ?
800 if (pmethod->signature_in[m] == 'a') {
802 ei = _check_brace(pmethod->signature_in + m + 1);
804 char tmp[128] = {0,};
805 strncpy(tmp, pmethod->signature_in + m, ei + 1);
806 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);
810 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);
815 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);
819 len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
820 for (int m = 0; m < len_args; ++m) {
822 // todo: container type
823 if (pmethod->signature_out[m] == 'a') {
825 ei = _check_brace(pmethod->signature_out + m + 1);
827 char tmp[128] = {0,};
828 strncpy(tmp, pmethod->signature_out + m, ei + 1);
829 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);
833 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);
838 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);
842 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
845 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
849 /* todo: delete log */
854 _E("%s", buf + nwrite - 512);
859 static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
861 dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
862 if (!pa->path || !((const char*)b))
864 return strcmp(pa->path, (const char*)b);
867 static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
869 dbus_interface_s * pa = (dbus_interface_s *)a;
870 if (!pa->name || !((const char*)b))
872 return strcmp(pa->name, (const char*)b);
875 static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
877 dbus_interface_s * pa = (dbus_interface_s *)a;
878 if (!pa->reg_id || !((guint*)b))
880 return !(pa->reg_id == *((guint*)b));
883 static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
885 dbus_method_s *pa = (dbus_method_s*)a;
886 if (!pa->member || !((const char*)b))
888 return strcmp(pa->member, (const char*)b);
891 dbus_object_handle_s * _gdbus_lookup_object(GList *list_obj, const char *obj_path)
893 if (!list_obj || !obj_path)
896 GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
900 return (dbus_object_handle_s *)item->data;
903 dbus_interface_s * _gdbus_lookup_interface(GList *list_iface, const char *iface_name)
905 if (!list_iface || !iface_name)
908 GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
912 return (dbus_interface_s *)item->data;
915 dbus_interface_s * _gdbus_lookup_interface_by_id(GList *list_iface, guint id)
917 if (!list_iface || !id)
920 GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
924 return (dbus_interface_s *)item->data;
927 dbus_method_s * _gdbus_lookup_method(GList *list_methods, const char *method_name)
929 if (!list_methods || !method_name)
932 GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
936 return (dbus_method_s *)item->data;
939 static void _free_func_object(gpointer data)
941 dbus_interface_s *ih = (dbus_interface_s *)data;
942 dbus_object_handle_s *oh = NULL;
945 _E("interface handle is null");
946 assert(0); // something wrong
950 _E("unregister interface %s", ih->name);
952 /* just free list, not data(static dbus_method_s) */
953 g_list_free(ih->list_methods);
957 _E("object handle is null");
958 assert(0); // something wrong
962 /* remove ih from list_ifaces */
963 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
965 /* interface_s is copy of interface_u */
968 /* remove oh from list_object */
969 if (!oh->list_ifaces) {
970 oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
975 static int _gdbus_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
977 dbus_object_handle_s *oh = NULL;
979 if (!dh || !obj_path || !iface) {
980 _E("failed to attache object. wrong parameter");
984 /* find object handle */
986 oh = _gdbus_lookup_object(dh->list_object, obj_path);
989 oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
991 _E("failed to calloc");
998 dh->list_object = g_list_prepend(dh->list_object, oh);
1002 /* attach interface */
1003 oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
1009 _method_call_handler
1011 libgio verify path and interface of incoming message.
1012 --> just check method name.
1014 # parameters - member of invocation struct
1015 every parameters of this function are member of GDBusMethodInvocation *invocation.
1016 There are no reason to using g_dbus_method_invocation_get_* apis to get inforamtion from message.
1017 just use params - sender, path, iface, name and param.
1020 # user defined handler #
1022 1. synchronous handling
1023 1) with return value
1025 return g_variant_new("(i)", ret);
1028 2) without return value
1030 return dbus_handle_new_g_variant_tuple(); // g_variant_new_tuple(NULL, 0)
1033 2. asynchronous handling
1034 handler MUST call 'g_dbus_method_invocation_return_value' itself. otherwise, LEAK !!
1040 # if handler return NULL, assume asynchronous handling. do nothing.
1045 1) with return value
1046 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret));
1048 2) without return value
1049 g_dbus_method_invocation_return_value(invocation, NULL);
1054 static void _method_call_handler(GDBusConnection *conn,
1055 const gchar *sender,
1060 GDBusMethodInvocation *invocation,
1063 dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
1064 const dbus_method_s *methods;
1065 GVariant *reply = NULL;
1068 methods = _gdbus_lookup_method(iface_s->list_methods, name);
1070 reply = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
1072 /* async, maybe they will reply...maybe.. */
1079 g_dbus_method_invocation_return_value(invocation, reply);
1082 static GDBusInterfaceVTable path_vtable = {_method_call_handler};
1086 before register object, attach object into dbus handle
1087 _gdbus_attach_object()
1089 static int _gdbus_register_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
1095 GDBusNodeInfo * nodeinfo = NULL;
1096 GDBusInterfaceInfo *ifaceinfo = NULL;
1098 if (!obj_path || !iface) {
1099 _E("wrong parameter\n");
1103 dh = _gdbus_get_default_connection();
1105 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1110 _E("connection is null\n");
1114 ret = _get_xml_from_interfaces(&buf, iface);
1116 _E("failed to make xml format");
1120 /* todo: delete this */
1122 if (strlen(buf) <= 512) {
1125 _E("%s", buf + strlen(buf) - 512);
1129 nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
1130 if (!nodeinfo || err) {
1131 _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
1136 ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
1138 _E("failed to g_dbus_node_info_lookup_interface");
1144 path own single interface
1145 if interface is already registered, then failed.
1146 g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
1148 ret = g_dbus_connection_register_object(dh->conn,
1156 _E("failed to register object:err:%s:\n", err->message);
1161 iface->reg_id = ret;
1162 iface->modified = FALSE;
1165 /* todo: detach object */
1166 //_dbus_handle_detach_object(dh, obj_path, iface);
1167 /* attach interface before register object */
1168 /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
1170 _E("failed to attach object");
1175 g_dbus_node_info_unref(nodeinfo);
1185 register same interface at once
1187 if interface is constructed by multiple methods,
1188 also it is not possible to make methods struct at once,
1190 use gdbus_add_object(), gdbus_register_object_all().
1194 int gdbus_register_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1198 dbus_interface_s *iface = NULL;
1200 if (!obj_path || !iface_u) {
1201 _E("wrong parameter\n");
1205 dh = _gdbus_get_default_connection();
1207 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1212 _E("connection is null\n");
1216 /* check registered interface */
1217 if (dh->list_object) {
1218 dbus_object_handle_s *oh = _gdbus_lookup_object(dh->list_object, obj_path);
1220 dbus_interface_s *ih = _gdbus_lookup_interface(oh->list_ifaces, iface_u->name);
1222 _E("path %s, interface %s already registered", obj_path, iface_u->name);
1228 iface = _iface_u_to_s(iface_u);
1230 _E("failed to _iface_u_to_s");
1234 /* attach interface before register object */
1235 ret = _gdbus_attach_object(dh, obj_path, iface);
1237 _E("failed to attach object");
1241 ret = _gdbus_register_object(dh, obj_path, iface);
1243 _E("failed to register dbus object%d", ret);
1250 int gdbus_unregister_object(dbus_handle_h handle, const char *obj_path)
1253 dbus_object_handle_s *oh = NULL;
1260 dh = _gdbus_get_default_connection();
1262 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1266 if (!dh->list_object) {
1267 _E("list_object is empty");
1271 oh = _gdbus_lookup_object(dh->list_object, obj_path);
1273 _E("no object with name %s", obj_path);
1277 /* unregister every interface of object*/
1278 for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
1279 dbus_interface_s *ih = item->data;
1281 _E("this is error");
1285 /* remove ih from list_ifaces */
1287 item = g_list_previous(item);
1289 /* remove and free link */
1290 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
1292 /* free list_methods */
1293 g_list_free(ih->list_methods);
1300 /* unregister object by id */
1301 ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
1303 _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
1309 int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
1312 dbus_object_handle_s *oh = NULL;
1319 dh = _gdbus_get_default_connection();
1321 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1325 if (!dh->list_object) {
1326 _E("list_object is empty");
1330 oh = _gdbus_lookup_object(dh->list_object, obj_path);
1332 _E("no object with name %s", obj_path);
1336 /* unregister every interface of object*/
1337 for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
1338 dbus_interface_s *ih = item->data;
1340 _E("this is error");
1344 /* remove ih from list_ifaces */
1346 item = g_list_previous(item);
1348 /* remove and free link */
1349 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
1351 /* free list_methods */
1352 g_list_free(ih->list_methods);
1359 /* unregister object by id */
1360 ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
1362 _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
1369 add object temporarily.
1370 gdbus_register_object_all register every objects on connection.
1372 return registered method count
1374 int gdbus_add_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1377 dbus_object_handle_s *oh = NULL;
1378 dbus_interface_s *ih = NULL;
1381 if (!obj_path || !iface_u) {
1382 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1385 if (iface_u && (!iface_u->name || !iface_u->methods)) {
1386 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1390 cnt = iface_u->nr_methods;
1393 dh = _gdbus_get_default_connection();
1395 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1401 _E("failed to register method. connection is null\n");
1405 /* if there are no object list, just add */
1406 if (!dh->list_object) {
1407 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1408 _E("failed to attach object");
1414 oh = _gdbus_lookup_object(dh->list_object, obj_path);
1415 /* if there are no matched object, just add */
1417 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1418 _E("failed to attach object");
1424 /* this is an error, interface must have one or more item ? */
1425 if (!oh->list_ifaces) {
1426 _E("error. list_ifaces is null\n");
1431 ih = _gdbus_lookup_interface(oh->list_ifaces, iface_u->name);
1432 /* if there are no matched interface, just add */
1434 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1435 _E("failed to attach object");
1442 1. unregister interface
1443 2. update interface and methods
1444 3. register interface
1447 _E("interface already registered, ignore new interface");
1451 /* attach new methods */
1453 for (int i = 0; i < iface_u->nr_methods; ++i) {
1454 GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
1456 //_D("attached %s", iface_u->methods[i].member);
1457 ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
1463 ih->modified = TRUE;
1466 /*todo: delete debugging log */
1467 //if (dh && dh->list_object)
1468 // _D("obj list len %d", g_list_length(dh->list_object));
1469 //if (oh && oh->list_ifaces)
1470 // _D("iface list len %d", g_list_length(oh->list_ifaces));
1471 //if (ih && ih->list_methods)
1472 // _D("method list len %d", g_list_length(ih->list_methods));
1477 int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1480 dbus_object_handle_s *oh = NULL;
1481 dbus_interface_s *ih = NULL;
1484 if (!obj_path || !iface_u) {
1485 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1488 if (iface_u && (!iface_u->name || !iface_u->methods)) {
1489 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1493 cnt = iface_u->nr_methods;
1496 dh = _gdbus_get_default_connection();
1498 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1504 _E("failed to register method. connection is null\n");
1508 /* if there are no object list, just add */
1509 if (!dh->list_object) {
1510 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1511 _E("failed to attach object");
1517 oh = _gdbus_lookup_object(dh->list_object, obj_path);
1518 /* if there are no matched object, just add */
1520 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1521 _E("failed to attach object");
1527 /* this is an error, interface must have one or more item ? */
1528 if (!oh->list_ifaces) {
1529 _E("error. list_ifaces is null\n");
1534 ih = _gdbus_lookup_interface(oh->list_ifaces, iface_u->name);
1535 /* if there are no matched interface, just add */
1537 if (_gdbus_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1538 _E("failed to attach object");
1545 1. unregister interface
1546 2. update interface and methods
1547 3. register interface
1550 _E("interface already registered, ignore new interface");
1554 /* attach new methods */
1556 for (int i = 0; i < iface_u->nr_methods; ++i) {
1557 GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
1559 //_D("attached %s", iface_u->methods[i].member);
1560 ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
1566 ih->modified = TRUE;
1569 /*todo: delete debugging log */
1570 //if (dh && dh->list_object)
1571 // _D("obj list len %d", g_list_length(dh->list_object));
1572 //if (oh && oh->list_ifaces)
1573 // _D("iface list len %d", g_list_length(oh->list_ifaces));
1574 //if (ih && ih->list_methods)
1575 // _D("method list len %d", g_list_length(ih->list_methods));
1580 int gdbus_register_object_all(dbus_handle_h handle)
1583 dbus_object_handle_s *oh = NULL;
1584 dbus_interface_s *ih = NULL;
1588 dh = _gdbus_get_default_connection();
1590 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1595 _E("connection is null\n");
1599 if (!dh->list_object) {
1600 _E("obj list is empty");
1604 /*if (dh && dh->list_object)
1605 _D("obj list len %d", g_list_length(dh->list_object));*/
1607 for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
1608 oh = (dbus_object_handle_s *)item->data;
1611 _E("something wrong");
1614 if (!oh->list_ifaces) {
1615 _E("path %s: list_ifaces are null", oh->path);
1619 //_D("iface list len %d", g_list_length(oh->list_ifaces));
1621 for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
1622 ih = (dbus_interface_s *)li->data;
1624 /* if there are no modification, goto next */
1628 /* todo: if already registered interface, unregister first */
1630 /*_E("interface %s:", ih->name);
1631 if (ih && ih->list_methods)
1632 _D("method list len %d", g_list_length(ih->list_methods));*/
1634 ret_dbus = _gdbus_register_object(dh, oh->path, ih);
1636 _E("failed to register dbus object%d", ret_dbus);
1643 // todo: delete all updates
1648 int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
1651 dbus_object_handle_s *oh = NULL;
1652 dbus_interface_s *ih = NULL;
1656 dh = _gdbus_get_default_connection();
1658 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1663 _E("connection is null\n");
1667 if (!dh->list_object) {
1668 _E("obj list is empty");
1672 /*if (dh && dh->list_object)
1673 _D("obj list len %d", g_list_length(dh->list_object));*/
1675 for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
1676 oh = (dbus_object_handle_s *)item->data;
1679 _E("something wrong");
1682 if (!oh->list_ifaces) {
1683 _E("path %s: list_ifaces are null", oh->path);
1687 //_D("iface list len %d", g_list_length(oh->list_ifaces));
1689 for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
1690 ih = (dbus_interface_s *)li->data;
1692 /* if there are no modification, goto next */
1696 /* todo: if already registered interface, unregister first */
1698 /*_E("interface %s:", ih->name);
1699 if (ih && ih->list_methods)
1700 _D("method list len %d", g_list_length(ih->list_methods));*/
1702 ret_dbus = _gdbus_register_object(dh, oh->path, ih);
1704 _E("failed to register dbus object%d", ret_dbus);
1711 // todo: delete all updates
1716 guint gdbus_signal_subscribe(dbus_handle_h handle, const char *path,
1717 const char *iface, const char *name,
1718 GDBusSignalCallback cb, void *data,
1719 destroy_notified free_func)
1724 dh = _gdbus_get_default_connection();
1726 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1732 _E("connection is null. check bus status");
1735 return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, free_func);
1738 void gdbus_signal_unsubscribe(dbus_handle_h handle, guint id)
1742 dh = _gdbus_get_default_connection();
1744 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1750 _E("connection is null. check bus status");
1754 g_dbus_connection_signal_unsubscribe(dh->conn, id);
1757 static void _signal_reply_sync_cb(GDBusConnection *conn,
1758 const gchar *sender,
1765 sig_ctx *ctx = data;
1767 _E("user data is null");
1771 ctx->param = g_variant_ref(param);
1772 ctx->quit_reason = CTX_QUIT_NORMAL;
1774 if (ctx->timeout_src) {
1775 g_source_destroy(ctx->timeout_src);
1776 ctx->timeout_src = NULL;
1778 g_main_loop_quit(ctx->loop);
1781 sig_ctx *gdbus_signal_ctx_new(void)
1785 ctx = (sig_ctx *)malloc(sizeof(sig_ctx));
1787 _E("failed to alloc mem");
1793 ctx->context = g_main_context_new();
1794 if (!ctx->context) {
1795 _E("failed to alloc context");
1799 ctx->loop = g_main_loop_new(ctx->context, FALSE);
1801 _E("failed to alloc main loop");
1802 g_main_context_unref(ctx->context);
1806 ctx->timeout_src = NULL;
1808 ctx->quit_reason = CTX_QUIT_UNKNOWN;
1809 ctx->user_data = NULL;
1814 void gdbus_signal_ctx_free(sig_ctx *ctx)
1820 g_variant_unref(ctx->param);
1824 gdbus_signal_unsubscribe(NULL, ctx->sig_id);
1827 if (ctx->timeout_src) {
1828 g_source_destroy(ctx->timeout_src);
1829 ctx->timeout_src = NULL;
1832 g_main_context_pop_thread_default(ctx->context);
1833 g_main_context_unref(ctx->context);
1834 ctx->context = NULL;
1837 g_main_loop_unref(ctx->loop);
1843 static gboolean _cb_ctx_timeout(gpointer user_data)
1845 sig_ctx *ctx = user_data;
1848 _E("user_data is null");
1852 ctx->quit_reason = CTX_QUIT_TIMEOUT;
1853 /* if cb return FALSE, source will be destroyed */
1854 ctx->timeout_src = NULL;
1856 gdbus_signal_unsubscribe(NULL, ctx->sig_id);
1859 g_main_loop_quit(ctx->loop);
1864 #define CTX_MAX_TIMEOUT 25000
1866 int gdbus_signal_ctx_add_timeout(sig_ctx *ctx, int timeout_msec)
1868 GSource *src = NULL;
1872 if (timeout_msec < -1)
1875 if (timeout_msec == -1 || timeout_msec >= CTX_MAX_TIMEOUT)
1876 timeout_msec = CTX_MAX_TIMEOUT;
1878 src = g_timeout_source_new(timeout_msec);
1882 g_source_set_callback(src, _cb_ctx_timeout, ctx, NULL);
1883 g_source_attach(src, ctx->context);
1884 g_source_unref(src);
1886 ctx->timeout_src = src;
1891 guint gdbus_signal_ctx_subscribe(dbus_handle_h handle, sig_ctx *ctx,
1892 const char *sender, const char *path,
1893 const char *iface, const char *name,
1894 GDBusSignalCallback _cb)
1899 _E("wrong param ctx is null");
1904 dh = _gdbus_get_default_connection();
1906 _E("failed to get default connection, bustype:%d",
1907 (int)gdbus_get_default_bus_type());
1913 _E("connection is null. check bus status");
1918 _cb = _signal_reply_sync_cb;
1920 /* change context before subscribe */
1921 g_main_context_push_thread_default(ctx->context);
1923 ctx->sig_id = g_dbus_connection_signal_subscribe(dh->conn,
1924 sender, iface, name, path, NULL,
1925 G_DBUS_SIGNAL_FLAGS_NONE, _cb,
1929 _E("failed to subscribe signal");
1934 int gdbus_signal_ctx_wait(sig_ctx *ctx)
1936 if (!ctx || !ctx->loop)
1939 g_main_loop_run(ctx->loop);
1941 _D("quit g_main_loop");
1943 return ctx->quit_reason;
1946 int _check_type_string_is_container(const char *signature)
1951 switch (signature[0]) {
1966 int gdbus_signal_emit(const char *dest,
1972 dbus_handle_s *dh = NULL;
1976 dh = _gdbus_get_default_connection();
1978 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
1982 ret = g_dbus_connection_emit_signal(dh->conn, dest, path, iface, name, param, &err);
1984 _E("%d %s\n", ret, err ? err->message : "NULL");
1991 int gdbus_signal_emit_sync(const char *dest,
1997 dbus_handle_s *dh = NULL;
2001 dh = _gdbus_get_default_connection();
2003 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2007 ret = g_dbus_connection_emit_signal(dh->conn, dest, path, iface, name, param, &err);
2009 _E("%d %s\n", ret, err ? err->message : "NULL");
2013 ret = g_dbus_connection_flush_sync(dh->conn, NULL, &err);
2015 _E("%d %s\n", ret, err ? err->message : "NULL");
2022 int gdbus_flush_sync(dbus_handle_h handle)
2029 dh = _gdbus_get_default_connection();
2031 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2036 ret = g_dbus_connection_flush_sync(dh->conn, NULL, &err);
2038 _E("%d %s\n", ret, err ? err->message : "NULL");
2045 int gdbus_call_sync_with_reply(const char *dest,
2050 GVariant **out_reply)
2053 GVariant *reply = NULL;
2055 dbus_handle_s *dh = NULL;
2057 if (!dest || !path || !iface || !method) {
2058 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2060 g_variant_unref(param);
2064 dh = _gdbus_get_default_connection();
2066 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2068 g_variant_unref(param);
2072 reply = g_dbus_connection_call_sync(dh->conn,
2073 dest, path, iface, method,
2075 G_DBUS_CALL_FLAGS_NONE,
2079 if (!reply || err) {
2081 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2082 if (g_error_matches(err, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED))
2089 _E("failed to g_dbus_connection_call_sync");
2097 g_variant_unref(reply);
2102 int gdbus_call_sync_with_reply_timeout(const char *dest, const char *path,
2103 const char *iface, const char *method, GVariant *param, GVariant **out_reply, int timeout)
2107 dbus_handle_s *dh = NULL;
2109 if (!dest || !path || !iface || !method) {
2110 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2112 g_variant_unref(param);
2116 dh = _gdbus_get_default_connection();
2118 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2120 g_variant_unref(param);
2124 reply = g_dbus_connection_call_sync(dh->conn,
2125 dest, path, iface, method,
2127 G_DBUS_CALL_FLAGS_NONE,
2131 if (!reply || err) {
2133 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2136 _E("failed to g_dbus_connection_call_sync");
2144 g_variant_unref(reply);
2149 int gdbus_call_pairs_sync_with_reply_int(const char *dest,
2157 GVariant *reply = NULL;
2161 GVariantBuilder *builder;
2162 dbus_handle_s *dh = NULL;
2164 if (!dest || !path || !iface || !method) {
2165 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2169 dh = _gdbus_get_default_connection();
2171 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2175 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2177 for (int i = 0 ; i < num ; i = i + 2) {
2178 key = va_arg(args, char *);
2179 value = va_arg(args, char *);
2180 _I("key(%s), value(%s)", key, value);
2181 g_variant_builder_add(builder, "{ss}", key, value);
2184 var = g_variant_new("(a{ss})", builder);
2185 g_variant_builder_unref(builder);
2187 reply = g_dbus_connection_call_sync(dh->conn,
2188 dest, path, iface, method,
2189 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
2190 if (!reply || err) {
2191 _E("failed to g_dbus_connection_call_sync");
2195 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
2196 g_variant_get(reply, "(i)", &ret);
2200 g_variant_unref(reply);
2205 int gdbus_call_pairs_async(const char *dest,
2214 GVariantBuilder *builder;
2215 dbus_handle_s *dh = NULL;
2217 if (!dest || !path || !iface || !method) {
2218 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2222 dh = _gdbus_get_default_connection();
2224 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2229 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2231 for (int i = 0 ; i < num ; i = i + 2) {
2232 key = va_arg(args, char *);
2233 value = va_arg(args, char *);
2234 _I("key(%s), value(%s)", key, value);
2235 g_variant_builder_add(builder, "{ss}", key, value);
2238 var = g_variant_new("(a{ss})", builder);
2239 g_variant_builder_unref(builder);
2241 g_dbus_connection_call(dh->conn,
2242 dest, path, iface, method,
2244 G_DBUS_CALL_FLAGS_NONE,
2253 gint* gdbus_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
2255 GUnixFDList *fd_list = NULL;
2258 fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
2261 _E("failed to g_unix_fd_list_get_length: fd_list is null");
2265 length = g_unix_fd_list_get_length(fd_list);
2267 _E("failed to g_unix_fd_list_get_length: list size is 0");
2273 return g_unix_fd_list_steal_fds(fd_list, NULL);
2276 int gdbus_call_unix_fd_list_sync_with_reply(const char *dest,
2281 GVariant **out_reply,
2288 GVariant *reply = NULL;
2290 dbus_handle_s *dh = NULL;
2291 GUnixFDList *g_infdlist = NULL;
2292 GUnixFDList *g_outfdlist = NULL;
2294 if (!dest || !path || !iface || !method) {
2295 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2298 if (in_fdlist && in_size == 0) {
2299 _E("wrong in_fdlist is not null but in_size is 0");
2303 dh = _gdbus_get_default_connection();
2305 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2311 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
2313 _E("failed to g_unix_fd_list_new_from_array\n");
2317 //g_infdlist = g_unix_fd_list_new();
2318 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
2322 reply = g_dbus_connection_call_with_unix_fd_list_sync(dh->conn,
2323 dest, path, iface, method,
2325 G_DBUS_CALL_FLAGS_NONE,
2327 g_infdlist, &g_outfdlist,
2329 if (!reply || err) {
2331 _E("failed to g_dbus_connection_call_with_unix_fd_list_sync:%s", err->message);
2334 _E("failed to g_dbus_connection_call_with_unix_fd_list_sync:");
2336 g_variant_unref(param);
2338 g_object_unref(g_infdlist);
2347 g_variant_unref(reply);
2349 /* copy fds to out array */
2351 *out_size = g_unix_fd_list_get_length(g_outfdlist);
2354 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
2358 g_object_unref(g_outfdlist);
2362 int gdbus_call_sync_with_reply_int(const char *dest,
2371 gboolean result_bool;
2372 GVariant *reply = NULL;
2374 if (!dest || !path || !iface || !method) {
2375 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2379 ret = gdbus_call_sync_with_reply(dest, path, iface, method, param, &reply);
2386 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
2387 g_variant_get(reply, "(i)", &result);
2390 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
2391 g_variant_get(reply, "(b)", &result_bool);
2393 *output = (int)result_bool;
2398 g_variant_unref(reply);
2403 int gdbus_call_async(const char *dest,
2409 dbus_handle_s *dh = NULL;
2411 if (!dest || !path || !iface || !method) {
2412 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2416 dh = _gdbus_get_default_connection();
2418 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2422 g_dbus_connection_call(dh->conn,
2423 dest, path, iface, method,
2425 G_DBUS_CALL_FLAGS_NONE,
2434 /* callback should free gvariant */
2435 static void _cb_pending(GDBusConnection *conn,
2439 GVariant *reply = NULL;
2441 pending_call_data *data = (pending_call_data *)user_data;
2443 reply = g_dbus_connection_call_finish(conn, res, &err);
2444 if (!reply || err) {
2446 g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
2447 "Error during g_dbus_connection_call");
2449 if (data && data->func)
2450 data->func(NULL, data->data, err);
2454 if (data && data->func)
2455 data->func(reply, data->data, err);
2463 int gdbus_call_async_with_reply(const char *dest,
2472 dbus_handle_s *dh = NULL;
2473 pending_call_data *pdata = NULL;
2476 if (!dest || !path || !iface || !method) {
2477 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2481 if (timeout_msec < -1) {
2482 _E("wrong timeout %d", timeout_msec);
2486 dh = _gdbus_get_default_connection();
2488 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2493 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2502 g_dbus_connection_call(dh->conn,
2503 dest, path, iface, method,
2505 G_DBUS_CALL_FLAGS_NONE,
2508 (GAsyncReadyCallback)_cb_pending,
2514 g_variant_unref(param);
2518 int gdbus_call_pairs_async_with_reply(const char *dest,
2528 dbus_handle_s *dh = NULL;
2529 pending_call_data *pdata = NULL;
2530 GVariantBuilder *builder;
2535 if (!dest || !path || !iface || !method) {
2536 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2540 if (timeout_msec < -1) {
2541 _E("wrong timeout %d", timeout_msec);
2545 dh = _gdbus_get_default_connection();
2547 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2552 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2554 for (int i = 0 ; i < num ; i = i + 2) {
2555 key = va_arg(args, char *);
2556 value = va_arg(args, char *);
2557 _I("key(%s), value(%s)", key, value);
2558 g_variant_builder_add(builder, "{ss}", key, value);
2561 param = g_variant_new("(a{ss})", builder);
2562 g_variant_builder_unref(builder);
2565 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2574 g_dbus_connection_call(dh->conn,
2575 dest, path, iface, method,
2577 G_DBUS_CALL_FLAGS_NONE,
2580 (GAsyncReadyCallback)_cb_pending,
2586 g_variant_unref(param);
2590 int gdbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
2593 GVariant *reply = NULL;
2597 _E("connection is null");
2601 _E("sender is null");
2605 reply = g_dbus_connection_call_sync(conn,
2606 DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME,
2607 "GetConnectionUnixProcessID",
2608 g_variant_new("(s)", sender), NULL,
2609 G_DBUS_CALL_FLAGS_NONE,
2613 if (!reply || err) {
2614 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2619 g_variant_get(reply, "(u)", &pid);
2620 g_variant_unref(reply);
2625 int gdbus_get_sender_pid(dbus_handle_h handle, const char * sender)
2630 dh = _gdbus_get_default_connection();
2632 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2637 _E("wrong dbus handle. connection is null");
2642 return gdbus_connection_get_sender_pid(dh->conn, sender);
2645 int gdbus_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
2648 GVariant *reply = NULL;
2650 GVariantIter *iter = NULL;
2655 dh = _gdbus_get_default_connection();
2657 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2661 reply = g_dbus_connection_call_sync(dh->conn,
2664 DBUS_INTERFACE_NAME,
2665 "GetConnectionCredentials",
2666 g_variant_new("(s)", name),
2668 G_DBUS_CALL_FLAGS_NONE,
2672 if (!reply || err) {
2673 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2677 g_variant_get(reply, "(a{sv})", &iter);
2679 while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
2680 if (!g_strcmp0(item, "UnixUserID")) {
2681 g_variant_get(sub, "u", &creds->uid);
2682 //_D("UnixUserID %u", creds->uid);
2683 } else if (!g_strcmp0(item, "ProcessID")) {
2684 g_variant_get(sub, "u", &creds->pid);
2685 //_D("ProcessID %u", creds->pid);
2686 } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
2687 g_variant_get(sub, "^ay", &creds->sec_label);
2688 //_D("%s", creds->sec_label);
2693 g_variant_iter_free(iter);
2695 g_variant_unref(reply);
2700 void _destroy_notify_watch_name(gpointer data)
2706 int gdbus_watch_name(const char *name,
2707 GBusNameAppearedCallback name_appeared_handler,
2708 GBusNameVanishedCallback name_vanished_handler,
2710 GDestroyNotify user_data_free_func)
2715 _E("wrong name name is null");
2718 if (!name_appeared_handler && !name_vanished_handler) {
2719 _E("both function pointers are null");
2723 id = g_bus_watch_name(gdbus_get_default_bus_type(),
2725 G_BUS_NAME_WATCHER_FLAGS_NONE,
2726 name_appeared_handler,
2727 name_vanished_handler,
2729 user_data_free_func ? user_data_free_func : _destroy_notify_watch_name);
2731 _E("failed to g_bus_watch_name");
2738 int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
2741 char buf[PATH_MAX + 1];
2744 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
2745 fd = open(buf, O_RDONLY);
2751 ret_file = read(fd, buf, PATH_MAX);
2756 buf[PATH_MAX] = '\0';
2758 filename = strrchr(buf, '/');
2759 if (filename == NULL)
2762 filename = filename + 1;
2764 if (cmdline_size < strlen(filename) + 1) {
2769 strncpy(cmdline, filename, cmdline_size - 1);
2770 cmdline[cmdline_size - 1] = '\0';
2774 void gdbus_check_name_owner(dbus_handle_h handle, const char *owner_name)
2777 char exe_name[PATH_MAX];
2783 dh = _gdbus_get_default_connection();
2785 _E("failed to get default connection, bustype:%d", (int)gdbus_get_default_bus_type());
2790 strv = gdbus_get_owner_list(dh, owner_name);
2792 _E("failed to get owner list of %s", owner_name);
2796 for (i = 0; strv[i] != NULL; ++i) {
2797 pid = gdbus_get_sender_pid(dh, strv[i]);
2798 if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
2800 _I("%s(%d)", exe_name, pid);
2806 int check_systemd_active(void)
2809 GVariant *reply = NULL;
2810 GVariant *var = NULL;
2813 _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
2815 ret = gdbus_call_sync_with_reply("org.freedesktop.systemd1",
2816 "/org/freedesktop/systemd1/unit/default_2etarget",
2817 DBUS_INTERFACE_PROPERTIES,
2819 g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"),
2826 if (!g_variant_get_safe(reply, "(v)", &var)) {
2827 _E("reply is not variant type");
2831 if (!g_variant_get_safe(var, "(s)", &state)) {
2832 _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
2837 if (strncmp(state, "active", 6) == 0)
2843 g_variant_unref(var);
2845 g_variant_unref(reply);
2850 GVariant *gdbus_make_simple_array(const char *sig, int *param)
2852 GVariantBuilder *builder = NULL;
2853 GVariant *var = NULL;
2857 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
2859 _E("failed to g_variant_builder_new");
2864 g_variant_builder_add(builder, "i", param[i++]);
2866 snprintf(format, sizeof(format) - 1, "(%s)", sig);
2867 var = g_variant_new(format, builder);
2868 g_variant_builder_unref(builder);