3 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
5 * Licensed under the Apache License, Version 2.0 (the "License"),
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
25 #include "storaged_common.h"
30 #define DBUS_REPLY_TIMEOUT (10000)
32 int check_systemd_active(void)
39 _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
41 msg = dbus_method_sync_with_reply_var("org.freedesktop.systemd1",
42 "/org/freedesktop/systemd1/unit/default_2etarget",
43 "org.freedesktop.DBus.Properties",
44 "Get", g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"));
48 if (!dh_get_param_from_var(msg, "(v)", &var)) {
49 _E("reply is not variant type");
53 if (!dh_get_param_from_var(var, "(s)", &state)) {
54 _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
59 if (strncmp(state, "active", 6) == 0)
72 static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
73 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
75 void dbus_handle_set_default_bus_type(GBusType bus_type)
77 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
80 pthread_mutex_lock(&g_mutex);
81 g_default_bus_type = bus_type;
82 pthread_mutex_unlock(&g_mutex);
85 GBusType dbus_handle_get_default_bus_type(void)
89 pthread_mutex_lock(&g_mutex);
90 type = g_default_bus_type;
91 pthread_mutex_unlock(&g_mutex);
101 /* basic information */
103 GDBusConnection *conn;
106 GList *list_names; // dbus_name
107 GList *list_object; /* dbus_object_handle_s */
108 pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
111 /* path + interfaces */
113 dbus_handle_s *dh; /* dbus handle */
115 GList *list_ifaces; /* dbus_interface_s */
116 } dbus_object_handle_s;
119 dbus_object_handle_s *oh;
121 GList *list_methods; // const dbus_method_s;
126 #define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
128 static dbus_handle_s g_dh[2];
130 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
132 dbus_handle_s * _dbus_handle_get_default_connection(void)
134 return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
137 #define dbus_handle_lock(handle) do {\
139 pthread_mutex_lock(&((handle)->mutex));\
142 #define dbus_handle_unlock(handle) do {\
144 pthread_mutex_unlock(&(handle)->mutex);\
147 #define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
148 #define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
150 _E("dbus handle is null\n");\
154 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
155 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
156 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
157 static GVariant* _append_variant(const char *signature, const char *param[]);
159 dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
161 dbus_interface_s *iface = NULL;
163 if (!iface_u || !iface_u->methods) {
168 iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
170 _E("failed to calloc");
174 iface->name = iface_u->name;
175 iface->modified = TRUE;
177 for (int i = 0 ; i < iface_u->nr_methods; ++i) {
178 //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
179 iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
185 static GDBusConnection * _get_bus(GBusType bus_type)
187 GDBusConnection *conn = NULL;
190 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
191 _E("Wrong bus_type %d", bus_type);
195 conn = g_bus_get_sync(bus_type, NULL, &err);
197 _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
205 static GDBusConnection * _get_bus_private(GBusType bus_type)
208 GDBusConnection *conn = NULL;
209 const char * address;
211 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
212 _E("Wrong bus_type %d", bus_type);
216 address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
217 if (!address || err) {
218 _E("failed to get bus address\n");
223 conn = g_dbus_connection_new_for_address_sync(address,
224 (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
225 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
226 NULL, /* GDBusAuthObserver */
230 _E("failed to get private bus\n");
239 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
241 int ibus = bus_type - 1;
242 dbus_handle_s *dh = NULL;
244 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
245 _E("Unknown bus type %d", bus_type);
250 dbus_handle_lock(dh);
253 dh->conn = _get_bus(bus_type);
255 dh->bus_type = bus_type;
260 dbus_handle_unlock(dh);
266 static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type)
270 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
271 _E("Unknown bus type %d", bus_type);
275 dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
277 _E("failed to allocate memory for dbus handle");
281 dbus_handle_lock(dh);
284 dh->conn = _get_bus_private(bus_type);
285 dh->bus_type = bus_type;
290 dbus_handle_unlock(dh);
295 dbus_handle_unlock(dh);
301 dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv)
303 dbus_handle_s *dh = NULL;
305 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
306 _E("Wrong bus_type %d\n", bus_type);
312 dh = _dbus_handle_get_connection_private(bus_type);
315 dh = _dbus_handle_get_connection(bus_type);
320 static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
322 dbus_name *dn = NULL;
325 if (!handle || !name || !id)
328 dn = (dbus_name*)calloc(1, sizeof(dbus_name));
330 _E("failed to calloc");
336 // todo : delete lock ?
337 locked = pthread_mutex_trylock(&handle->mutex);
338 if (locked != 0 && locked != EBUSY) {
339 _E("failed to lock %d\n", locked);
343 handle->list_names = g_list_prepend(handle->list_names, dn);
345 // todo : delete lock ?
347 dbus_handle_unlock(handle);
350 static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
352 const char *bus_name = ((dbus_name *)a)->bus_name;
355 return strcmp(bus_name, (const char *)b);
358 dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name)
360 if (!list_name || !bus_name)
363 GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
367 return (dbus_name *)item->data;
370 #define dh_to_ds(x) ((dbus_handle_s*)x)
372 /* remove dbus_name from dbus handle */
373 static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
376 dbus_name *dn = NULL;
379 _E("wrong bus_name %s", bus_name);
383 dh = _dbus_handle_get_default_connection();
385 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
390 dbus_handle_lock(dh);
391 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
393 _E("failed to find dbus name %s", bus_name);
396 dh->list_names = g_list_remove(dh->list_names, dn);
399 dbus_handle_unlock(dh);
402 static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
404 dbus_handle_s *dh = (dbus_handle_s *)user_data;
409 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
412 // todo: add bus name?
413 //dh->bus_name = name;
416 static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
418 _E("%s:%d:%s\n", __func__, __LINE__, name);
419 dbus_handle_s *dh = (dbus_handle_s *)user_data;
421 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
424 _dbus_handle_remove_bus_name(dh, name);
427 int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name)
434 _E("bus_name is NULL");
438 /* get shared connection */
440 dh = _dbus_handle_get_default_connection();
442 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
447 dbus_handle_lock(dh);
449 _E("failed to register name: connection is null\n");
453 /* todo : search name on connection */
454 item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
456 id = ((dbus_name*)(item->data))->id;
457 _E("name already exist:%u", id);
461 id = g_bus_own_name_on_connection(dh->conn, bus_name, G_BUS_NAME_OWNER_FLAGS_NONE, _name_acquired, _name_lost, dh, NULL);
463 _E("failed to own name:%s\n", bus_name);
467 _dbus_handle_add_bus_name(dh, bus_name, id);
470 dbus_handle_unlock(dh);
474 int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name)
477 dbus_name *dn = NULL;
480 _E("Wrong bus name");
485 dh = _dbus_handle_get_default_connection();
487 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
492 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
494 _E("failed to find bus_name %s on dbus handle", bus_name);
498 _E("unown name %d", dn->id);
499 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
500 g_bus_unown_name(dn->id);
502 dbus_handle_lock(dh);
503 dh->list_names = g_list_remove(dh->list_names, dn);
505 dbus_handle_unlock(dh);
510 int dbus_handle_free_connection(dbus_handle_h handle)
513 dbus_handle_s *pdh = NULL;
518 dh = _dbus_handle_get_default_connection();
520 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
526 _E("connection is NULL");
532 /* disable dbus handler */
533 dbus_handle_lock(dh);
540 /* flush everything */
541 if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
542 _E("failed to flush %s\n", err->message);
547 _D("list_names %u", g_list_length(pdh->list_names));
549 /* unown every well-knwon name */
550 if (pdh->list_names) {
551 dbus_name *dn = NULL;
552 for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
553 dn = (dbus_name *)item->data;
557 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
558 _D("unown name id : %u", dn->id);
559 g_bus_unown_name(dn->id);
562 g_list_free(pdh->list_names);
563 pdh->list_names = NULL;
566 _D("list_object %u", g_list_length(pdh->list_object));
568 /* unregister every object */
569 if (pdh->list_object) {
570 dbus_object_handle_s * oh = NULL;
571 //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
572 for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
573 oh = (dbus_object_handle_s *)item->data;
574 if (!oh || !oh->list_ifaces)
577 _D("delete object path %s", oh->path);
579 /* unregister every interface, method handles */
580 for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
581 dbus_interface_s *ih = (dbus_interface_s *)iface->data;
585 _D("delete object iface %s", ih->name);
588 g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
593 /* close connection */
595 _E("close private connection\n");
597 if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
598 _E("Error closing connection %s\n", err->message);
604 /* _free_func_object callback free the data */
605 //assert(g_list_length(pdh->list_names) == 0);
606 //assert(g_list_length(pdh->list_object) == 0);
608 g_object_unref(pdh->conn);
610 dbus_handle_unlock(dh);
620 #define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
621 #define buf_block_size 8192
623 #define buf_check_space_realloc(buf, nwrite, buf_len) do {\
624 if ((nwrite >= buf_len - 1024)) {\
625 if (buf_len >= buf_block_size * 10) {\
626 _E("buf is too big to allocate. %d", buf_len);\
628 _E("buf_check_space_realloc");\
630 buf_len += buf_block_size;\
631 tmp = (char *)realloc(buf, buf_len);\
633 _E("failed to realloc");\
640 static int _check_brace(const char * expr)
651 if (expr[0] != '(' && expr[0] != '{')
654 for (int i = 0 ; i < len; ++i) {
656 if (expr[i] == '(' || expr[i] == '{') {
657 qu[qucnt++] = expr[i];
658 if (qucnt >= sizeof(qu)) {
659 _E("queue is too large. %s", expr);
665 if (expr[i] == ')' || expr[i] == '}') {
673 if (expr[i] == ')') {
678 } else if (expr[i] == '}') {
695 static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
700 const dbus_method_s *pmethod;
701 int buf_len = buf_block_size;
704 _E("interfaces is null");
708 // todo : check dbus naming rule for interface name. ?
709 if (!interfaces->name) {
710 _E("wrong interface name");
713 if (!interfaces->list_methods) {
718 buf = (char *)malloc(buf_len);
720 _E("buf is null. not enough memory\n");
724 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
727 for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
728 pmethod = (const dbus_method_s *)item->data;
732 /* check free space of buf */
733 buf_check_space_realloc(buf, nwrite, buf_len);
735 if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
736 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
740 /* <method name='###'> */
741 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
744 len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
745 for (int m = 0; m < len_args; ++m) {
747 // array a(), as, ay ?
748 if (pmethod->signature_in[m] == 'a') {
750 ei = _check_brace(pmethod->signature_in + m + 1);
752 char tmp[128] = {0,};
753 strncpy(tmp, pmethod->signature_in + m, ei + 1);
754 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);
758 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);
763 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);
767 len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
768 for (int m = 0; m < len_args; ++m) {
770 // todo: container type
771 if (pmethod->signature_out[m] == 'a') {
773 ei = _check_brace(pmethod->signature_out + m + 1);
775 char tmp[128] = {0,};
776 strncpy(tmp, pmethod->signature_out + m, ei + 1);
777 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);
781 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);
786 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);
790 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
793 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
797 /* todo: delete log */
802 _E("%s", buf + nwrite - 512);
807 static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
809 dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
810 if (!pa->path || !((const char*)b))
812 return strcmp(pa->path, (const char*)b);
815 static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
817 dbus_interface_s * pa = (dbus_interface_s *)a;
818 if (!pa->name || !((const char*)b))
820 return strcmp(pa->name, (const char*)b);
823 static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
825 dbus_interface_s * pa = (dbus_interface_s *)a;
826 if (!pa->reg_id || !((guint*)b))
828 return !(pa->reg_id == *((guint*)b));
831 static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
833 dbus_method_s *pa = (dbus_method_s*)a;
834 if (!pa->member || !((const char*)b))
836 return strcmp(pa->member, (const char*)b);
839 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
841 if (!list_obj || !obj_path)
844 GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
848 return (dbus_object_handle_s *)item->data;
851 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
853 if (!list_iface || !iface_name)
856 GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
860 return (dbus_interface_s *)item->data;
863 dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id)
865 if (!list_iface || !id)
868 GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
872 return (dbus_interface_s *)item->data;
875 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
877 if (!list_methods || !method_name)
880 GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
884 return (dbus_method_s *)item->data;
887 static void _free_func_object(gpointer data)
889 dbus_interface_s *ih = (dbus_interface_s *)data;
890 dbus_object_handle_s *oh = NULL;
893 _E("interface handle is null");
894 assert(0); // something wrong
898 _E("unregister interface %s", ih->name);
900 /* just free list, not data(static dbus_method_s) */
901 g_list_free(ih->list_methods);
905 _E("object handle is null");
906 assert(0); // something wrong
910 /* remove ih from list_ifaces */
911 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
913 /* interface_s is copy of interface_u */
916 /* remove oh from list_object */
917 if (!oh->list_ifaces) {
918 oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
923 static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
925 dbus_object_handle_s *oh = NULL;
927 if (!dh || !obj_path || !iface) {
928 _E("failed to attache object. wrong parameter");
932 /* find object handle */
934 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
937 oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
939 _E("failed to calloc");
946 dh->list_object = g_list_prepend(dh->list_object, oh);
950 /* attach interface */
951 oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
956 /* libgio verify path and interface */
957 static void _method_call_handler(GDBusConnection *conn,
958 const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
959 GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
961 dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
962 const dbus_method_s *methods;
963 GVariant *result = NULL;
966 methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
968 result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
970 /* async, maybe they will reply...maybe.. */
972 _E("finish method handle : NULL");
979 g_dbus_method_invocation_return_value(invocation, result);
980 //if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) {
981 // //_E("TUPLE %s", g_variant_get_type_string(result));
982 // g_dbus_method_invocation_return_value(invocation, result);
984 //else if (g_variant_is_container(result)) {
985 // /* todo: we don't have any plan to using variant type for reply */
986 // _E("CONTAINER %s", g_variant_get_type_string(result));
987 // g_dbus_method_invocation_return_value(invocation, result);
988 // //g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result));
990 // _E("Type is not Container : %s", g_variant_get_type_string(result));
994 static GDBusInterfaceVTable path_vtable = {_method_call_handler};
998 before register object, attach object into dbus handle
999 _dbus_handle_attach_object()
1001 static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
1007 GDBusNodeInfo * nodeinfo = NULL;
1008 GDBusInterfaceInfo *ifaceinfo = NULL;
1010 if (!obj_path || !iface) {
1011 _E("wrong parameter\n");
1015 dh = _dbus_handle_get_default_connection();
1017 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1022 _E("connection is null\n");
1026 ret = _get_xml_from_interfaces(&buf, iface);
1028 _E("failed to make xml format");
1032 /* todo: delete this */
1034 if (strlen(buf) <= 512) {
1037 _E("%s", buf + strlen(buf) - 512);
1041 nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
1042 if (!nodeinfo || err) {
1043 _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
1048 ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
1050 _E("failed to g_dbus_node_info_lookup_interface");
1056 path own single interface
1057 if interface is already registered, then failed.
1058 g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
1060 ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface,
1064 _E("failed to register object:err:%s:\n", err->message);
1069 iface->reg_id = ret;
1070 iface->modified = FALSE;
1073 /* todo: detach object */
1074 //_dbus_handle_detach_object(dh, obj_path, iface);
1075 /* attach interface before register object */
1076 /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
1078 _E("failed to attach object");
1083 g_dbus_node_info_unref(nodeinfo);
1093 register same interface at once
1095 if interface is constructed by multiple methods,
1096 also it is not possible to make methods struct at once,
1098 use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all().
1102 int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1106 dbus_interface_s *iface = NULL;
1108 if (!obj_path || !iface_u) {
1109 _E("wrong parameter\n");
1113 dh = _dbus_handle_get_default_connection();
1115 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1120 _E("connection is null\n");
1124 /* check registered interface */
1125 if (dh->list_object) {
1126 dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1128 dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1130 _E("path %s, interface %s already registered", obj_path, iface_u->name);
1136 iface = _iface_u_to_s(iface_u);
1138 _E("failed to _iface_u_to_s");
1142 /* attach interface before register object */
1143 ret = _dbus_handle_attach_object(dh, obj_path, iface);
1145 _E("failed to attach object");
1149 ret = _dbus_handle_register_dbus_object(dh, obj_path, iface);
1151 _E("failed to register dbus object%d", ret);
1158 int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
1161 dbus_object_handle_s *oh = NULL;
1168 dh = _dbus_handle_get_default_connection();
1170 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1174 if (!dh->list_object) {
1175 _E("list_object is empty");
1179 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1181 _E("no object with name %s", obj_path);
1185 /* unregister every interface of object*/
1186 for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
1187 dbus_interface_s *ih = item->data;
1189 _E("this is error");
1193 /* remove ih from list_ifaces */
1195 item = g_list_previous(item);
1197 /* remove and free link */
1198 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
1200 /* free list_methods */
1201 g_list_free(ih->list_methods);
1208 /* unregister object by id */
1209 ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
1211 _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
1218 add object temporarily.
1219 dbus_handle_register_dbus_object_all will register every objects on connection.
1221 return registered method count
1223 int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1226 dbus_object_handle_s *oh = NULL;
1227 dbus_interface_s *ih = NULL;
1230 if (!obj_path || !iface_u) {
1231 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1234 if (iface_u && (!iface_u->name || !iface_u->methods)) {
1235 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1239 cnt = iface_u->nr_methods;
1242 dh = _dbus_handle_get_default_connection();
1244 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1250 _E("failed to register method. connection is null\n");
1254 /* if there are no object list, just add */
1255 if (!dh->list_object) {
1256 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1257 _E("failed to attach object");
1263 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1264 /* if there are no matched object, just add */
1266 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1267 _E("failed to attach object");
1273 /* this is an error, interface must have one or more item ? */
1274 if (!oh->list_ifaces) {
1275 _E("error. list_ifaces is null\n");
1280 ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1281 /* if there are no matched interface, just add */
1283 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1284 _E("failed to attach object");
1291 1. unregister interface
1292 2. update interface and methods
1293 3. register interface
1296 _E("interface already registered, ignore new interface");
1300 /* attach new methods */
1302 for (int i = 0; i < iface_u->nr_methods; ++i) {
1303 GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
1305 //_D("attached %s", iface_u->methods[i].member);
1306 ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
1312 ih->modified = TRUE;
1315 /*todo: delete debugging log */
1316 //if (dh && dh->list_object)
1317 // _D("obj list len %d", g_list_length(dh->list_object));
1318 //if (oh && oh->list_ifaces)
1319 // _D("iface list len %d", g_list_length(oh->list_ifaces));
1320 //if (ih && ih->list_methods)
1321 // _D("method list len %d", g_list_length(ih->list_methods));
1326 int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
1329 dbus_object_handle_s *oh = NULL;
1330 dbus_interface_s *ih = NULL;
1334 dh = _dbus_handle_get_default_connection();
1336 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1341 _E("connection is null\n");
1345 if (!dh->list_object) {
1346 _E("obj list is empty");
1350 /*if (dh && dh->list_object)
1351 _D("obj list len %d", g_list_length(dh->list_object));*/
1353 for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
1354 oh = (dbus_object_handle_s *)item->data;
1357 _E("something wrong");
1360 if (!oh->list_ifaces) {
1361 _E("path %s: list_ifaces are null", oh->path);
1365 //_D("iface list len %d", g_list_length(oh->list_ifaces));
1367 for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
1368 ih = (dbus_interface_s *)li->data;
1370 /* if there are no modification, goto next */
1374 /* todo: if already registered interface, unregister first */
1376 /*_E("interface %s:", ih->name);
1377 if (ih && ih->list_methods)
1378 _D("method list len %d", g_list_length(ih->list_methods));*/
1380 ret = _dbus_handle_register_dbus_object(dh, oh->path, ih);
1382 _E("failed to register dbus object%d", ret);
1389 // todo: delete all updates
1394 static void _free_func_signal(gpointer data)
1396 //_D("free signal subscribe");
1399 guint subscribe_dbus_signal(dbus_handle_h handle, const char *path,
1400 const char *iface, const char *name,
1401 GDBusSignalCallback cb, void *data,
1402 destroy_notified free_func)
1407 dh = _dbus_handle_get_default_connection();
1409 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1415 _E("connection is null. check bus status");
1418 return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal);
1421 void unsubscribe_dbus_signal(dbus_handle_h handle, guint id)
1425 dh = _dbus_handle_get_default_connection();
1427 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1433 _E("connection is null. check bus status");
1437 g_dbus_connection_signal_unsubscribe(dh->conn, id);
1440 int _check_type_string_is_container(const char *signature)
1445 switch (signature[0]) {
1460 GVariant *dbus_handle_make_simple_array(const char *sig, int *param)
1462 GVariantBuilder *builder = NULL;
1463 GVariant *var = NULL;
1467 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
1469 _E("failed to g_variant_builder_new");
1474 g_variant_builder_add(builder, "i", param[i++]);
1476 snprintf(format, sizeof(format) - 1, "(%s)", sig);
1477 var = g_variant_new(format, builder);
1478 g_variant_builder_unref(builder);
1482 /* todo: looks like garbage... */
1483 static GVariant* _append_variant(const char *signature, const char *param[])
1490 unsigned long long int64_type;
1493 char container[255];// The maximum length of a signature is 255.
1494 const char *sig = signature;
1495 GVariantBuilder *builder = NULL;
1497 if (!signature || !param)
1500 /* workaround for user fault "(i) != i" but we treat this as same signature */
1501 /* G_VARIANT_TYPE("si") return NULL */
1502 /* todo: actually user have to use correct signature */
1503 if (!_check_type_string_is_container(signature)) {
1504 snprintf(container, sizeof(container) - 1, "(%s)", signature);
1507 if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) {
1508 _E("signature (%s) is not container type", signature);
1511 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
1514 for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) {
1520 bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE);
1521 g_variant_builder_add(builder, "b", bool_type);
1524 int_type = atoi(param[pi++]);
1525 g_variant_builder_add(builder, "i", int_type);
1528 int_type = strtoul(param[pi++], NULL, 10);
1529 g_variant_builder_add(builder, "u", int_type);
1532 int64_type = atoll(param[pi++]);
1533 g_variant_builder_add(builder, "t", int64_type);
1536 g_variant_builder_add(builder, "s", param[pi++]);
1542 g_variant_builder_add(builder, "^ay", param[pi++]);
1553 ret = g_variant_builder_end(builder);
1554 g_variant_builder_clear(builder);
1555 g_variant_builder_unref(builder);
1560 int dbus_handle_broadcast_dbus_signal(const char *path,
1561 const char *iface, const char *name,
1562 const char *signature, const char *param[])
1564 dbus_handle_s *dh = NULL;
1567 GVariant *var = NULL;
1569 dh = _dbus_handle_get_default_connection();
1571 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1575 if (signature && param)
1576 var = _append_variant(signature, param);
1577 ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err);
1579 _E("%d %s\n", ret, err ? err->message : NULL);
1586 int dbus_handle_broadcast_dbus_signal_var(const char *path,
1587 const char *iface, const char *name,
1590 dbus_handle_s *dh = NULL;
1594 dh = _dbus_handle_get_default_connection();
1596 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1600 ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err);
1602 _E("%d %s\n", ret, err ? err->message : NULL);
1609 GVariant *dbus_method_sync_with_reply(const char *dest, const char *path,
1610 const char *iface, const char *method,
1611 const char *signature, const char *param[])
1614 GVariant * var = NULL;
1615 GVariant * ret = NULL;
1616 dbus_handle_s *dh = NULL;
1618 if (!dest || !path || !iface || !method) {
1619 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1623 dh = _dbus_handle_get_default_connection();
1625 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1629 if (signature && param)
1630 var = _append_variant(signature, param);
1632 ret = g_dbus_connection_call_sync(dh->conn,
1633 dest, path, iface, method,
1634 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
1637 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1640 _E("failed to g_dbus_connection_call_sync");
1641 g_variant_unref(var);
1649 GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path,
1650 const char *iface, const char *method, GVariant *var)
1653 GVariant * ret = NULL;
1654 dbus_handle_s *dh = NULL;
1656 if (!dest || !path || !iface || !method) {
1657 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1659 g_variant_unref(var);
1663 dh = _dbus_handle_get_default_connection();
1665 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1667 g_variant_unref(var);
1671 ret = g_dbus_connection_call_sync(dh->conn,
1672 dest, path, iface, method,
1673 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
1676 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1679 _E("failed to g_dbus_connection_call_sync");
1687 GVariant *dbus_method_sync_with_reply_var_timeout(const char *dest, const char *path,
1688 const char *iface, const char *method, GVariant *var, int timeout)
1691 GVariant * ret = NULL;
1692 dbus_handle_s *dh = NULL;
1694 if (!dest || !path || !iface || !method) {
1695 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1697 g_variant_unref(var);
1701 dh = _dbus_handle_get_default_connection();
1703 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1705 g_variant_unref(var);
1709 ret = g_dbus_connection_call_sync(dh->conn,
1710 dest, path, iface, method,
1711 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
1714 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1717 _E("failed to g_dbus_connection_call_sync");
1725 gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
1727 GUnixFDList *fd_list = NULL;
1730 fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
1733 _E("failed to g_unix_fd_list_get_length: fd_list is null");
1737 length = g_unix_fd_list_get_length(fd_list);
1739 _E("failed to g_unix_fd_list_get_length: list size is 0");
1745 return g_unix_fd_list_steal_fds(fd_list, NULL);
1748 GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path,
1749 const char *iface, const char *method,
1750 const char *signature, const char *param[],
1751 int *in_fdlist, int in_size,
1752 int **out_fdlist, int *out_size)
1755 GVariant * var = NULL;
1756 GVariant * ret = NULL;
1757 dbus_handle_s *dh = NULL;
1758 GDBusProxy *proxy = NULL;
1759 GUnixFDList *g_infdlist = NULL;
1760 GUnixFDList *g_outfdlist = NULL;
1762 if (!dest || !path || !iface || !method) {
1763 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1766 if (in_fdlist && in_size == 0) {
1767 _E("wrong in_fdlist is not null but in_size is 0");
1771 dh = _dbus_handle_get_default_connection();
1773 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1777 if (signature && param)
1778 var = _append_variant(signature, param);
1780 proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
1783 _E("failed to proxy_new_sync(%s)\n", err->message);
1786 _E("failed to proxy_new_sync\n");
1788 g_variant_unref(var);
1794 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
1796 _E("failed to g_unix_fd_list_new_from_array\n");
1799 //g_infdlist = g_unix_fd_list_new();
1800 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
1803 ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1,
1804 g_infdlist, &g_outfdlist, NULL, &err);
1807 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
1810 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
1812 g_variant_unref(var);
1814 g_object_unref(g_infdlist);
1819 /* fds to out array */
1821 *out_size = g_unix_fd_list_get_length(g_outfdlist);
1825 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
1830 g_object_unref(g_outfdlist);
1832 g_object_unref(proxy);
1837 GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path,
1838 const char *iface, const char *method,
1840 int *in_fdlist, int in_size,
1841 int **out_fdlist, int *out_size)
1844 GVariant * ret = NULL;
1845 dbus_handle_s *dh = NULL;
1846 GDBusProxy *proxy = NULL;
1847 GUnixFDList *g_infdlist = NULL;
1848 GUnixFDList *g_outfdlist = NULL;
1850 if (!dest || !path || !iface || !method) {
1851 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1854 if (in_fdlist && in_size == 0) {
1855 _E("wrong in_fdlist is not null but in_size is 0");
1859 dh = _dbus_handle_get_default_connection();
1861 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1865 proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err);
1868 _E("failed to proxy_new_sync(%s)\n", err->message);
1871 _E("failed to proxy_new_sync\n");
1873 g_variant_unref(param);
1880 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
1882 _E("failed to g_unix_fd_list_new_from_array\n");
1885 //g_infdlist = g_unix_fd_list_new();
1886 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
1890 ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1,
1891 g_infdlist, &g_outfdlist, NULL, &err);
1894 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message);
1897 _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:");
1899 g_variant_unref(param);
1901 g_object_unref(g_infdlist);
1906 /* copy fds to out array */
1908 *out_size = g_unix_fd_list_get_length(g_outfdlist);
1911 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
1915 g_object_unref(g_outfdlist);
1917 g_object_unref(proxy);
1921 int dbus_method_sync(const char *dest, const char *path,
1922 const char *iface, const char *method,
1923 const char *signature, const char *param[])
1926 gboolean result_bool;
1927 GVariant *reply = NULL;
1929 if (!dest || !path || !iface || !method) {
1930 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1934 reply = dbus_method_sync_with_reply(dest, path, iface, method, signature, param);
1938 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
1939 g_variant_get(reply, "(i)", &result);
1940 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
1941 g_variant_get(reply, "(b)", &result_bool);
1942 result = (int)result_bool;
1947 g_variant_unref(reply);
1952 int dbus_method_sync_var(const char *dest, const char *path,
1953 const char *iface, const char *method, GVariant *param)
1956 gboolean result_bool;
1957 GVariant *reply = NULL;
1959 if (!dest || !path || !iface || !method) {
1960 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1964 reply = dbus_method_sync_with_reply_var(dest, path, iface, method, param);
1968 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
1969 g_variant_get(reply, "(i)", &result);
1970 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
1971 g_variant_get(reply, "(b)", &result_bool);
1972 result = (int)result_bool;
1977 g_variant_unref(reply);
1982 int dbus_method_sync_timeout(const char *dest, const char *path,
1983 const char *iface, const char *method,
1984 const char *signature, const char *param[], int timeout)
1986 dbus_handle_s *dh = NULL;
1988 GVariant * var = NULL;
1989 GVariant * reply = NULL;
1992 if (!dest || !path || !iface || !method) {
1993 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1997 dh = _dbus_handle_get_default_connection();
1999 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2003 if (signature && param)
2004 var = _append_variant(signature, param);
2006 reply = g_dbus_connection_call_sync(dh->conn,
2007 dest, path, iface, method,
2008 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err);
2009 if (!reply || err) {
2010 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2015 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
2016 g_variant_get(reply, "(i)", &result);
2020 g_variant_unref(reply);
2025 int dbus_method_sync_pairs(const char *dest, const char *path,
2026 const char *iface, const char *method,
2027 int num, va_list args)
2030 GVariant * reply = NULL;
2034 GVariantBuilder *builder;
2035 dbus_handle_s *dh = NULL;
2037 if (!dest || !path || !iface || !method) {
2038 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2042 dh = _dbus_handle_get_default_connection();
2044 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2048 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2050 for (int i = 0 ; i < num ; i = i + 2) {
2051 key = va_arg(args, char *);
2052 value = va_arg(args, char *);
2053 _I("key(%s), value(%s)", key, value);
2054 g_variant_builder_add(builder, "{ss}", key, value);
2057 var = g_variant_new("(a{ss})", builder);
2058 g_variant_builder_unref(builder);
2060 reply = g_dbus_connection_call_sync(dh->conn,
2061 dest, path, iface, method,
2062 var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
2063 if (!reply || err) {
2064 _E("failed to g_dbus_connection_call_sync");
2068 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0)
2069 g_variant_get(reply, "(i)", &ret);
2073 g_variant_unref(reply);
2078 int dbus_method_async_pairs(const char *dest, const char *path,
2079 const char *iface, const char *method,
2080 int num, va_list args)
2084 GVariantBuilder *builder;
2085 dbus_handle_s *dh = NULL;
2087 if (!dest || !path || !iface || !method) {
2088 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2092 dh = _dbus_handle_get_default_connection();
2094 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2099 builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}"));
2101 for (int i = 0 ; i < num ; i = i + 2) {
2102 key = va_arg(args, char *);
2103 value = va_arg(args, char *);
2104 _I("key(%s), value(%s)", key, value);
2105 g_variant_builder_add(builder, "{ss}", key, value);
2108 var = g_variant_new("(a{ss})", builder);
2109 g_variant_builder_unref(builder);
2111 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2112 var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2119 int dbus_method_async(const char *dest, const char *path,
2120 const char *iface, const char *method,
2121 const char *signature, const char *param[])
2123 GVariant * var = NULL;
2124 dbus_handle_s *dh = NULL;
2126 if (!dest || !path || !iface || !method) {
2127 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2131 dh = _dbus_handle_get_default_connection();
2133 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2137 if (signature && param)
2138 var = _append_variant(signature, param);
2140 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2141 var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2148 int dbus_method_async_var(const char *dest, const char *path,
2149 const char *iface, const char *method, GVariant *param)
2151 dbus_handle_s *dh = NULL;
2153 if (!dest || !path || !iface || !method) {
2154 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2158 dh = _dbus_handle_get_default_connection();
2160 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2164 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2165 param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
2172 /* callback should free gvariant */
2173 static void _cb_pending(GDBusConnection *conn,
2177 GVariant *reply = NULL;
2179 pending_call_data *data = (pending_call_data *)user_data;
2181 reply = g_dbus_connection_call_finish(conn, res, &err);
2182 if (!reply || err) {
2184 _E("no message : [%s]", err->message);
2190 if (data && data->func)
2191 data->func(NULL, data->data, err);
2195 if (data && data->func)
2196 data->func(reply, data->data, err);
2202 int dbus_method_async_with_reply(const char *dest,
2206 const char *signature,
2207 const char *param[],
2212 dbus_handle_s *dh = NULL;
2213 pending_call_data *pdata = NULL;
2214 GVariant * var = NULL;
2217 if (!dest || !path || !iface || !method) {
2218 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2222 if (timeout_msec < -1) {
2223 _E("wrong timeout %d", timeout_msec);
2227 dh = _dbus_handle_get_default_connection();
2229 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2233 if (signature && param)
2234 var = _append_variant(signature, param);
2237 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2246 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2247 var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
2248 (GAsyncReadyCallback)_cb_pending,
2254 g_variant_unref(var);
2258 int dbus_method_async_with_reply_var(const char *dest,
2267 dbus_handle_s *dh = NULL;
2268 pending_call_data *pdata = NULL;
2271 if (!dest || !path || !iface || !method) {
2272 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2276 if (timeout_msec < -1) {
2277 _E("wrong timeout %d", timeout_msec);
2281 dh = _dbus_handle_get_default_connection();
2283 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2288 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2297 g_dbus_connection_call(dh->conn, dest, path, iface, method,
2298 param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL,
2299 (GAsyncReadyCallback)_cb_pending,
2305 g_variant_unref(param);
2309 int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
2312 GVariant *vret = NULL;
2316 _E("connection is null");
2320 _E("sender is null");
2324 vret = g_dbus_connection_call_sync(conn,
2325 "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID",
2326 g_variant_new("(s)", sender),
2328 G_DBUS_CALL_FLAGS_NONE,
2333 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2338 g_variant_get(vret, "(u)", &pid);
2339 g_variant_unref(vret);
2344 int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender)
2349 dh = _dbus_handle_get_default_connection();
2351 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2356 _E("wrong dbus handle. connection is null");
2361 return dbus_connection_get_sender_pid(dh->conn, sender);
2364 int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
2367 GVariant *vret = NULL;
2369 GVariantIter *iter = NULL;
2374 dh = _dbus_handle_get_default_connection();
2376 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2380 vret = g_dbus_connection_call_sync(dh->conn, DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME,
2381 "GetConnectionCredentials", g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err);
2383 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2387 g_variant_get(vret, "(a{sv})", &iter);
2389 while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
2390 if (!g_strcmp0(item, "UnixUserID")) {
2391 g_variant_get(sub, "u", &creds->uid);
2392 _D("UnixUserID %u", creds->uid);
2393 } else if (!g_strcmp0(item, "ProcessID")) {
2394 g_variant_get(sub, "u", &creds->pid);
2395 _D("ProcessID %u", creds->pid);
2396 } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
2397 g_variant_get(sub, "^ay", &creds->sec_label);
2398 _D("%s", creds->sec_label);
2403 g_variant_iter_free(iter);
2405 g_variant_unref(vret);
2410 void _destroy_notify_watch_name(gpointer data)
2416 int dbus_handle_watch_name(const char *name,
2417 GBusNameAppearedCallback name_appeared_handler,
2418 GBusNameVanishedCallback name_vanished_handler,
2424 _E("wrong name name %s", name);
2427 if (!name_appeared_handler && !name_vanished_handler) {
2428 _E("both function pointers are null");
2432 id = g_bus_watch_name(dbus_handle_get_default_bus_type(), name, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_handler, name_vanished_handler, user_data, _destroy_notify_watch_name);
2434 _E("failed to g_bus_watch_name");
2441 void dbus_handle_unwatch_name(guint id)
2444 _E("wrong id %d", id);
2447 g_bus_unwatch_name(id);
2450 int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
2453 char buf[PATH_MAX + 1];
2456 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
2457 fd = open(buf, O_RDONLY);
2463 ret = read(fd, buf, PATH_MAX);
2468 buf[PATH_MAX] = '\0';
2470 filename = strrchr(buf, '/');
2471 if (filename == NULL)
2474 filename = filename + 1;
2476 if (cmdline_size < strlen(filename) + 1) {
2481 strncpy(cmdline, filename, cmdline_size - 1);
2482 cmdline[cmdline_size - 1] = '\0';
2487 char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name)
2491 GVariant *vret = NULL;
2492 GVariantIter *iter = NULL;
2493 gchar **strv = NULL;
2498 _E("wrong parameter bus_name(%s)", bus_name);
2503 dh = _dbus_handle_get_default_connection();
2505 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2510 vret = g_dbus_connection_call_sync(dh->conn,
2511 "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners",
2512 g_variant_new("(s)", bus_name),
2514 G_DBUS_CALL_FLAGS_NONE,
2519 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2524 g_variant_get(vret, "(as)", &iter);
2525 strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
2528 while (g_variant_iter_loop(iter, "s", &str))
2529 strv[i++] = g_strdup(str);
2532 g_variant_iter_free(iter);
2533 g_variant_unref(vret);
2538 void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name)
2541 char exe_name[PATH_MAX];
2547 dh = _dbus_handle_get_default_connection();
2549 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2554 strv = dbus_handle_get_owner_list(dh, owner_name);
2556 _E("failed to get owner list of %s", owner_name);
2560 for (i = 0; strv[i] != NULL; ++i) {
2561 pid = dbus_handle_get_sender_pid(dh, strv[i]);
2562 if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
2564 _I("%s(%d)", exe_name, pid);
2570 dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name)
2572 dbus_handle_h handle = NULL;
2576 _E("Wrong bus name, %s", bus_name);
2580 // todo: do we need retry ? - booting time
2581 for (i = 0 ; i < 3; ++i) {
2582 handle = dbus_handle_get_connection(type, FALSE);
2587 ret = dbus_handle_request_bus_name(handle, bus_name);
2591 dbush_handle_check_owner_name(NULL, bus_name);