1 #include "e_connman_private.h"
5 static Eina_Hash *elements = NULL;
7 typedef struct _E_Connman_Element_Pending E_Connman_Element_Pending;
8 typedef struct _E_Connman_Element_Call_Data E_Connman_Element_Call_Data;
9 typedef struct _E_Connman_Element_Property E_Connman_Element_Property;
10 typedef struct _E_Connman_Element_Listener E_Connman_Element_Listener;
11 typedef struct _E_Connman_Element_Dict_Entry E_Connman_Element_Dict_Entry;
13 struct _E_Connman_Element_Pending
16 DBusPendingCall *pending;
18 E_DBus_Method_Return_Cb user_cb;
22 struct _E_Connman_Element_Call_Data
24 E_Connman_Element *element;
25 E_DBus_Method_Return_Cb cb;
26 E_Connman_Element_Pending *pending;
30 struct _E_Connman_Element_Property
43 E_Connman_Array *array;
47 struct _E_Connman_Element_Dict_Entry
58 E_Connman_Array *array;
62 struct _E_Connman_Element_Listener
65 void (*cb)(void *data, const E_Connman_Element *element);
67 void (*free_data)(void *data);
71 _e_connman_element_event_no_free(void *data __UNUSED__, void *ev)
73 E_Connman_Element *element = ev;
74 e_connman_element_unref(element);
78 e_connman_element_event_add(int event_type, E_Connman_Element *element)
80 e_connman_element_ref(element);
82 (event_type, element, _e_connman_element_event_no_free, element);
86 e_connman_element_call_dispatch_and_free(void *d, DBusMessage *msg, DBusError *err)
88 E_Connman_Element_Call_Data *data = d;
89 E_Connman_Element_Pending *pending;
91 pending = data->pending;
92 pending->pending = NULL;
95 data->cb(data->element, msg, err);
98 pending->user_cb(pending->user_data, msg, err);
100 pending->data = NULL;
101 *data->p_list = eina_inlist_remove(*data->p_list, EINA_INLIST_GET(pending));
107 e_connman_element_pending_cancel_and_free(Eina_Inlist **pending)
111 E_Connman_Element_Pending *p = (E_Connman_Element_Pending *)*pending;
114 dbus_pending_call_cancel(p->pending);
116 dbus_error_init(&err);
117 dbus_set_error(&err, "Canceled", "Pending method call was canceled.");
118 e_connman_element_call_dispatch_and_free(p->data, NULL, &err);
119 dbus_error_free(&err);
124 e_connman_element_listener_add(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data, void (*free_data)(void *data))
126 E_Connman_Element_Listener *l;
127 EINA_SAFETY_ON_FALSE_GOTO(element, error);
128 EINA_SAFETY_ON_FALSE_GOTO(cb, error);
130 l = malloc(sizeof(*l));
133 ERR("could not allocate E_Connman_Element_Listener");
138 l->data = (void *)data;
139 l->free_data = free_data;
141 element->_listeners = eina_inlist_append
142 (element->_listeners, EINA_INLIST_GET(l));
148 free_data((void *)data);
152 e_connman_element_listener_del(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data)
154 E_Connman_Element_Listener *l;
156 EINA_SAFETY_ON_NULL_RETURN(element);
157 EINA_SAFETY_ON_NULL_RETURN(cb);
159 EINA_INLIST_FOREACH(element->_listeners, l)
160 if ((l->cb == cb) && (l->data == data))
162 element->_listeners = eina_inlist_remove
163 (element->_listeners, EINA_INLIST_GET(l));
165 l->free_data(l->data);
173 _e_connman_element_listeners_call_do(E_Connman_Element *element)
175 E_Connman_Element_Listener *l;
178 /* NB: iterate on a copy in order to allow listeners to be deleted
179 * from callbacks. number of listeners should be small, so the
180 * following should do fine.
182 if (eina_inlist_count(element->_listeners) < 1) goto end;
184 EINA_INLIST_FOREACH_SAFE(element->_listeners, x, l)
185 l->cb(l->data, element);
188 e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_UPDATED, element);
192 _e_connman_element_listeners_call_idler(void *data)
194 E_Connman_Element *element = data;
195 _e_connman_element_listeners_call_do(element);
196 element->_idler.changed = NULL;
197 return ECORE_CALLBACK_CANCEL;
201 _e_connman_element_listeners_call(E_Connman_Element *element)
203 if (element->_idler.changed)
206 element->_idler.changed = ecore_idler_add
207 (_e_connman_element_listeners_call_idler, element);
210 /***********************************************************************
212 ***********************************************************************/
215 _e_connman_element_dict_entry_free(E_Connman_Element_Dict_Entry *entry)
219 case DBUS_TYPE_BOOLEAN:
221 case DBUS_TYPE_UINT16:
222 case DBUS_TYPE_UINT32:
225 case DBUS_TYPE_OBJECT_PATH:
226 eina_stringshare_del(entry->value.path);
229 case DBUS_TYPE_STRING:
230 eina_stringshare_del(entry->value.str);
234 ERR("don't know how to free dict entry '%s' of type %c (%d)",
235 entry->name, entry->type, entry->type);
238 eina_stringshare_del(entry->name);
242 static E_Connman_Element_Dict_Entry *
243 _e_connman_element_dict_entry_new(DBusMessageIter *itr)
245 E_Connman_Element_Dict_Entry *entry;
246 DBusMessageIter e_itr, v_itr;
248 const char *key = NULL;
251 dbus_message_iter_recurse(itr, &e_itr);
253 t = dbus_message_iter_get_arg_type(&e_itr);
254 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
256 ERR("invalid format for dict entry. first type not a string: %c (%d)",
261 dbus_message_iter_get_basic(&e_itr, &key);
264 ERR("invalid format for dict entry. no key.");
268 dbus_message_iter_next(&e_itr);
269 t = dbus_message_iter_get_arg_type(&e_itr);
270 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
272 ERR("invalid format for dict entry '%s'. "
273 "second type not a variant: %c (%d)",
278 dbus_message_iter_recurse(&e_itr, &v_itr);
280 t = dbus_message_iter_get_arg_type(&v_itr);
281 if ((t == DBUS_TYPE_INVALID) || (t == DBUS_TYPE_ARRAY))
283 ERR("invalid type for dict value for entry '%s': %c (%d)",
288 entry = calloc(1, sizeof(*entry));
291 ERR("could not allocate memory for dict entry.");
295 dbus_message_iter_get_basic(&v_itr, &value);
298 case DBUS_TYPE_BOOLEAN:
299 entry->value.boolean = (Eina_Bool)(long)value;
303 entry->value.byte = (unsigned char)(long)value;
306 case DBUS_TYPE_UINT16:
307 entry->value.u16 = (unsigned short)(long)value;
310 case DBUS_TYPE_UINT32:
311 entry->value.u32 = (unsigned int)(long)value;
314 case DBUS_TYPE_STRING:
315 entry->value.str = eina_stringshare_add(value);
318 case DBUS_TYPE_OBJECT_PATH:
319 entry->value.path = eina_stringshare_add(value);
323 ERR("don't know how to create dict entry '%s' for of type %c (%d)",
329 entry->name = eina_stringshare_add(key);
334 static E_Connman_Element_Dict_Entry *
335 _e_connman_element_array_dict_find_stringshared(const E_Connman_Array *array, const char *key)
337 E_Connman_Element_Dict_Entry *entry;
338 Eina_Array_Iterator iterator;
341 EINA_ARRAY_ITER_NEXT(array->array, i, entry, iterator)
342 if (entry->name == key)
349 _e_connman_element_array_free(E_Connman_Array *array, E_Connman_Array *new __UNUSED__)
351 Eina_Array_Iterator iterator;
360 case DBUS_TYPE_BOOLEAN:
362 case DBUS_TYPE_UINT16:
363 case DBUS_TYPE_UINT32:
366 case DBUS_TYPE_STRING:
367 case DBUS_TYPE_OBJECT_PATH:
368 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
369 eina_stringshare_del(item);
372 case DBUS_TYPE_DICT_ENTRY:
373 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
374 _e_connman_element_dict_entry_free(item);
378 ERR("don't know how to free array of values of type %c (%d)",
379 array->type, array->type);
382 eina_array_free(array->array);
387 _e_connman_element_property_value_free(E_Connman_Element_Property *property)
389 switch (property->type)
394 case DBUS_TYPE_BOOLEAN:
396 case DBUS_TYPE_UINT16:
397 case DBUS_TYPE_UINT32:
400 case DBUS_TYPE_STRING:
401 eina_stringshare_del(property->value.str);
404 case DBUS_TYPE_OBJECT_PATH:
405 eina_stringshare_del(property->value.path);
408 case DBUS_TYPE_ARRAY:
409 _e_connman_element_array_free(property->value.array, NULL);
413 ERR("don't know how to free value of property type %c (%d)",
414 property->type, property->type);
419 _e_connman_element_get_interface(const char *key)
421 const char *interface = NULL, *tail;
430 if (strcmp(tail, "rofiles") == 0)
431 interface = e_connman_iface_profile;
436 if (strcmp(tail, "ervices") == 0)
437 interface = e_connman_iface_service;
442 if (strcmp(tail, "echnologies") == 0)
443 interface = e_connman_iface_technology;
452 ERR("failed to find interface for property \"%s\"", key);
458 _e_connman_element_item_register(const char *key, const char *item)
460 E_Connman_Element *element;
461 const char *interface;
463 interface = _e_connman_element_get_interface(key);
467 element = e_connman_element_register(item, interface);
468 if ((element) && (!e_connman_element_properties_sync(element)))
469 WRN("could not get properties of %s", element->path);
472 /* Match 2 arrays to find which are new and which are old elements
473 * For new elements, register them under prop_name property
474 * For old elements, unregister them, sending proper DEL event
477 _e_connman_element_array_match(E_Connman_Array *old, E_Connman_Array *new, const char *prop_name)
479 Eina_List *deleted = NULL;
480 Eina_Array_Iterator iter_old, iter_new;
481 unsigned int i_old = 0, i_new = 0;
482 void *item_old, *item_new;
489 if (old->type != DBUS_TYPE_OBJECT_PATH)
492 if ((!new) || (!new->array) || eina_array_count_get(new->array) == 0)
494 if ((!old) || (!old->array) || eina_array_count_get(old->array) == 0)
500 iter_old = old->array->data;
501 goto out_remove_remaining;
505 iter_new = new->array->data;
506 item_new = *iter_new;
507 EINA_ARRAY_ITER_NEXT(old->array, i_old, item_old, iter_old)
509 if (item_old == item_new)
512 if (i_new >= eina_array_count_get(new->array))
519 item_new = *iter_new;
523 deleted = eina_list_append(deleted, item_old);
527 for(; i_new < eina_array_count_get(new->array); iter_new++, i_new++)
529 Eina_Bool found = EINA_FALSE;
530 item_new = *iter_new;
534 EINA_LIST_FOREACH(deleted, l, data)
536 if (data == item_new)
538 deleted = eina_list_remove_list(deleted, l);
545 _e_connman_element_item_register(prop_name, item_new);
546 DBG("Add element %s\n", (const char *)item_new);
550 /* everybody after i_old on old->array + everybody from deleted list
553 EINA_LIST_FREE(deleted, data)
555 E_Connman_Element *e = e_connman_element_get(data);
557 e_connman_element_unregister(e);
559 DBG("Delete element %s\n", (const char *)data);
562 out_remove_remaining:
563 for(; i_old < eina_array_count_get(old->array); iter_old++, i_old++)
565 E_Connman_Element *e;
566 item_old = *iter_old;
570 e = e_connman_element_get(item_old);
572 e_connman_element_unregister(e);
574 DBG("Delete element %s\n", (const char *)item_old);
579 _e_connman_element_property_update(E_Connman_Element_Property *property, int type, void *data)
581 Eina_Bool changed = EINA_FALSE;
583 if ((type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) && data)
584 data = (char *)eina_stringshare_add(data);
586 if (property->type != type)
589 DBG("property type changed from '%c' to '%c'",
590 property->type, type);
592 _e_connman_element_property_value_free(property);
593 memset(&property->value, 0, sizeof(property->value));
594 property->type = type;
600 case DBUS_TYPE_BOOLEAN:
601 if (changed || property->value.boolean != (Eina_Bool)(long)data)
603 property->value.boolean = (Eina_Bool)(long)data;
610 if (changed || property->value.byte != (unsigned char)(long)data)
612 property->value.byte = (unsigned char)(long)data;
618 case DBUS_TYPE_UINT16:
619 if (changed || property->value.u16 != (unsigned short)(long)data)
621 property->value.u16 = (unsigned short)(long)data;
627 case DBUS_TYPE_UINT32:
628 if (changed || property->value.u32 != (unsigned int)(long)data)
630 property->value.u32 = (unsigned int)(long)data;
636 case DBUS_TYPE_STRING:
639 property->value.str = data;
643 if (property->value.str)
644 eina_stringshare_del(property->value.str);
646 if (property->value.str != data)
648 property->value.str = data;
655 case DBUS_TYPE_OBJECT_PATH:
658 property->value.path = data;
662 if (property->value.path)
663 eina_stringshare_del(property->value.path);
665 if (property->value.path != data)
667 property->value.path = data;
674 case DBUS_TYPE_ARRAY:
676 if (property->value.array)
678 _e_connman_element_array_match(property->value.array, data, property->name);
679 _e_connman_element_array_free(property->value.array, data);
682 property->value.array = data;
687 ERR("don't know how to update property type %c (%d)", type, type);
693 static E_Connman_Element_Property *
694 _e_connman_element_property_new(const char *name, int type, void *data)
696 E_Connman_Element_Property *property;
698 property = calloc(1, sizeof(*property));
701 eina_stringshare_del(name);
702 ERR("could not allocate property: %s", strerror(errno));
706 property->name = name;
707 _e_connman_element_property_update(property, type, data);
712 _e_connman_element_property_free(E_Connman_Element_Property *property)
714 _e_connman_element_property_value_free(property);
715 eina_stringshare_del(property->name);
719 /***********************************************************************
721 ***********************************************************************/
723 e_connman_element_bytes_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count)
725 Eina_Array_Iterator iterator;
726 E_Connman_Array *array;
727 unsigned char *ret, *p;
731 EINA_SAFETY_ON_NULL_RETURN_VAL(element, NULL);
732 EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
733 EINA_SAFETY_ON_NULL_RETURN_VAL(count, NULL);
737 if (!e_connman_element_property_get_stringshared
738 (element, property, NULL, &array))
741 if ((!array) || (!(array->array)))
744 *count = eina_array_count_get(array->array);
745 ret = malloc(*count * sizeof(unsigned char));
748 ERR("could not allocate return array of %d bytes: %s",
749 *count, strerror(errno));
755 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
757 *p = (unsigned char)(long)item;
764 e_connman_element_objects_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, E_Connman_Element ***p_elements)
766 E_Connman_Element **ret, **p;
767 Eina_Array_Iterator iterator;
768 E_Connman_Array *array;
773 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
774 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE);
775 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
776 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, EINA_FALSE);
781 if (!e_connman_element_property_get_stringshared
782 (element, property, &type, &array))
785 if (type != DBUS_TYPE_ARRAY)
787 ERR("property %s is not an array!", property);
791 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
794 if (array->type != DBUS_TYPE_OBJECT_PATH)
796 ERR("property %s is not an array of object paths!", property);
800 *count = eina_array_count_get(array->array);
801 ret = malloc(*count * sizeof(E_Connman_Element *));
804 ERR("could not allocate return array of %d elements: %s",
805 *count, strerror(errno));
812 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
814 E_Connman_Element *e = e_connman_element_get(item);
826 /* strings are just pointers (references), no strdup or stringshare_add/ref */
828 e_connman_element_strings_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, const char ***strings)
830 const char **ret, **p;
831 Eina_Array_Iterator iterator;
832 E_Connman_Array *array;
837 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
838 EINA_SAFETY_ON_NULL_RETURN_VAL(property, EINA_FALSE);
839 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
840 EINA_SAFETY_ON_NULL_RETURN_VAL(strings, EINA_FALSE);
845 if (!e_connman_element_property_get_stringshared
846 (element, property, &type, &array))
849 if (type != DBUS_TYPE_ARRAY)
851 ERR("property %s is not an array!", property);
855 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
858 if (array->type != DBUS_TYPE_STRING)
860 ERR("property %s is not an array of strings!", property);
864 *count = eina_array_count_get(array->array);
865 ret = malloc(*count * sizeof(char *));
868 ERR("could not allocate return array of %d strings: %s",
869 *count, strerror(errno));
876 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
890 _e_connman_element_array_print(FILE *fp, E_Connman_Array *array)
892 Eina_Array_Iterator iterator;
901 case DBUS_TYPE_OBJECT_PATH:
902 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
903 fprintf(fp, "\"%s\", ", (const char *)item);
906 case DBUS_TYPE_STRING:
907 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
908 fprintf(fp, "\"%s\", ", (const char *)item);
912 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
913 fprintf(fp, "%#02hhx (\"%c\"), ", (unsigned char)(long)item,
914 (unsigned char)(long)item);
917 case DBUS_TYPE_UINT16:
918 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
919 fprintf(fp, "%#04hx (%hu), ", (unsigned short)(long)item,
920 (unsigned short)(long)item);
923 case DBUS_TYPE_UINT32:
924 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
925 fprintf(fp, "%#08x (%u), ", (unsigned int)(long)item,
926 (unsigned int)(long)item);
929 case DBUS_TYPE_DICT_ENTRY:
931 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
933 E_Connman_Element_Dict_Entry *entry = item;
934 fprintf(fp, "%s: ", entry->name);
937 case DBUS_TYPE_OBJECT_PATH:
938 fprintf(fp, "\"%s\", ", entry->value.path);
941 case DBUS_TYPE_STRING:
942 fprintf(fp, "\"%s\", ", entry->value.str);
946 fprintf(fp, "%#02hhx (\"%c\"), ",
947 entry->value.byte, entry->value.byte);
950 case DBUS_TYPE_UINT16:
951 fprintf(fp, "%#04hx (%hu), ",
952 entry->value.u16, entry->value.u16);
955 case DBUS_TYPE_UINT32:
956 fprintf(fp, "%#08x (%u), ",
957 entry->value.u32, entry->value.u32);
961 fprintf(fp, "<UNKNOWN TYPE '%c'>", entry->type);
968 fprintf(fp, "<UNKNOWN ARRAY TYPE '%c'>", array->type);
973 * Print element to file descriptor.
976 e_connman_element_print(FILE *fp, const E_Connman_Element *element)
978 const E_Connman_Element_Property *p;
980 EINA_SAFETY_ON_NULL_RETURN(fp);
983 fputs("Error: no element to print\n", fp);
988 "Element %p: %s [%s]\n"
990 element, element->path, element->interface);
992 EINA_INLIST_FOREACH(element->props, p)
994 fprintf(fp, "\t\t%s (%c) = ", p->name, p->type);
998 case DBUS_TYPE_STRING:
999 fprintf(fp, "\"%s\"", p->value.str);
1002 case DBUS_TYPE_OBJECT_PATH:
1003 fprintf(fp, "\"%s\"", p->value.path);
1006 case DBUS_TYPE_BOOLEAN:
1007 fprintf(fp, "%hhu", p->value.boolean);
1010 case DBUS_TYPE_BYTE:
1011 fprintf(fp, "%#02hhx (%d), ", p->value.byte, p->value.byte);
1014 case DBUS_TYPE_UINT16:
1015 fprintf(fp, "%hu", p->value.u16);
1018 case DBUS_TYPE_UINT32:
1019 fprintf(fp, "%u", p->value.u32);
1022 case DBUS_TYPE_ARRAY:
1023 _e_connman_element_array_print(fp, p->value.array);
1027 fputs("don't know how to print type", fp);
1034 static E_Connman_Element *
1035 e_connman_element_new(const char *path, const char *interface)
1037 E_Connman_Element *element;
1039 element = calloc(1, sizeof(*element));
1042 ERR("could not allocate element: %s", strerror(errno));
1046 element->path = eina_stringshare_add(path);
1047 element->interface = eina_stringshare_ref(interface);
1048 element->_references = 1;
1054 e_connman_element_extra_properties_free(E_Connman_Element *element)
1056 while (element->props)
1058 E_Connman_Element_Property *prop;
1059 prop = (E_Connman_Element_Property *)element->props;
1060 element->props = element->props->next;
1061 _e_connman_element_property_free(prop);
1066 e_connman_element_free(E_Connman_Element *element)
1068 if (element->_idler.changed)
1069 ecore_idler_del(element->_idler.changed);
1071 while (element->_listeners)
1073 E_Connman_Element_Listener *l = (void *)element->_listeners;
1074 element->_listeners = eina_inlist_remove
1075 (element->_listeners, element->_listeners);
1078 l->free_data(l->data);
1083 e_connman_element_pending_cancel_and_free(&element->_pending.properties_get);
1084 e_connman_element_pending_cancel_and_free(&element->_pending.property_set);
1085 e_connman_element_pending_cancel_and_free(&element->_pending.agent_register);
1086 e_connman_element_pending_cancel_and_free(&element->_pending.agent_unregister);
1087 e_connman_element_pending_cancel_and_free(&element->_pending.request_scan);
1088 e_connman_element_pending_cancel_and_free(&element->_pending.technology_enable);
1089 e_connman_element_pending_cancel_and_free(&element->_pending.technology_disable);
1090 e_connman_element_pending_cancel_and_free(&element->_pending.profile_remove);
1091 e_connman_element_pending_cancel_and_free(&element->_pending.service_connect);
1092 e_connman_element_pending_cancel_and_free(&element->_pending.service_disconnect);
1093 e_connman_element_pending_cancel_and_free(&element->_pending.service_remove);
1094 e_connman_element_pending_cancel_and_free(&element->_pending.service_move_before);
1095 e_connman_element_pending_cancel_and_free(&element->_pending.service_move_after);
1096 e_connman_element_pending_cancel_and_free(&element->_pending.service_clear_property);
1098 e_connman_element_extra_properties_free(element);
1099 eina_stringshare_del(element->interface);
1100 eina_stringshare_del(element->path);
1105 * Add reference to element.
1108 e_connman_element_ref(E_Connman_Element *element)
1110 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1111 return ++element->_references;
1115 * Remove reference from element.
1117 * If reference count drops to 0 element will be freed.
1120 e_connman_element_unref(E_Connman_Element *element)
1123 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1125 i = --element->_references;
1127 e_connman_element_free(element);
1129 ERR("element %p references %d < 0", element, i);
1135 * Send message with callbacks set to work with connman elements.
1137 * If this call fails (returns @c EINA_FALSE), pending callbacks will not be called,
1138 * not even with error messages.
1140 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
1143 e_connman_element_message_send(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, DBusMessage *msg, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
1145 E_Connman_Element_Call_Data *data;
1146 E_Connman_Element_Pending *p;
1148 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1149 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, EINA_FALSE);
1150 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, EINA_FALSE);
1151 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, EINA_FALSE);
1153 data = malloc(sizeof(*data));
1156 ERR("could not alloc e_connman_element_call_data: %s",
1158 dbus_message_unref(msg);
1162 p = malloc(sizeof(*p));
1165 ERR("could not alloc E_Connman_Element_Pending: %s",
1168 dbus_message_unref(msg);
1172 data->element = element;
1175 data->p_list = pending;
1176 p->user_cb = user_cb;
1177 p->user_data = (void *)user_data;
1179 p->pending = e_dbus_message_send
1180 (e_connman_conn, msg, e_connman_element_call_dispatch_and_free, -1, data);
1181 dbus_message_unref(msg);
1185 *pending = eina_inlist_append(*pending, EINA_INLIST_GET(p));
1189 ERR("failed to call %s (obj=%s, path=%s, iface=%s)",
1190 method_name, e_connman_system_bus_name_get(),
1191 element->path, element->interface);
1198 e_connman_element_call_full(E_Connman_Element *element, const char *method_name, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
1202 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1203 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, EINA_FALSE);
1204 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, EINA_FALSE);
1206 msg = dbus_message_new_method_call
1207 (e_connman_system_bus_name_get(), element->path, element->interface,
1210 return e_connman_element_message_send
1211 (element, method_name, cb, msg, pending, user_cb, user_data);
1215 _e_connman_element_property_value_add(E_Connman_Element *element, const char *name, int type, void *value)
1217 E_Connman_Element_Property *p;
1219 name = eina_stringshare_add(name);
1220 EINA_INLIST_FOREACH(element->props, p)
1222 if (p->name == name)
1224 eina_stringshare_del(name);
1225 return _e_connman_element_property_update(p, type, value);
1229 p = _e_connman_element_property_new(name, type, value);
1232 ERR("could not create property %s (%c)", name, type);
1236 element->props = eina_inlist_append(element->props, EINA_INLIST_GET(p));
1240 static E_Connman_Array *
1241 _e_connman_element_iter_get_array(DBusMessageIter *itr, const char *key)
1243 E_Connman_Array *array;
1244 DBusMessageIter e_itr;
1246 array = malloc(sizeof(E_Connman_Array));
1249 ERR("could not create new e_connman array.");
1253 array->array = eina_array_new(16);
1254 if (!(array->array))
1256 ERR("could not create new eina array.");
1261 dbus_message_iter_recurse(itr, &e_itr);
1262 array->type = dbus_message_iter_get_arg_type(&e_itr);
1263 if (array->type == DBUS_TYPE_INVALID)
1265 DBG("array %s is of type 'invalid' (empty?)", key);
1266 eina_array_free(array->array);
1273 switch (array->type)
1275 case DBUS_TYPE_OBJECT_PATH:
1279 dbus_message_iter_get_basic(&e_itr, &path);
1280 path = eina_stringshare_add(path);
1281 eina_array_push(array->array, path);
1282 _e_connman_element_item_register(key, path);
1286 case DBUS_TYPE_STRING:
1290 dbus_message_iter_get_basic(&e_itr, &str);
1291 str = eina_stringshare_add(str);
1292 eina_array_push(array->array, str);
1296 case DBUS_TYPE_BYTE:
1299 dbus_message_iter_get_basic(&e_itr, &byte);
1300 eina_array_push(array->array, (void *)(long)byte);
1304 case DBUS_TYPE_DICT_ENTRY:
1306 E_Connman_Element_Dict_Entry *entry;
1307 entry = _e_connman_element_dict_entry_new(&e_itr);
1309 eina_array_push(array->array, entry);
1314 ERR("don't know how to build array '%s' of type %c (%d)",
1315 key, array->type, array->type);
1316 eina_array_free(array->array);
1321 while (dbus_message_iter_next(&e_itr));
1326 _e_connman_element_get_properties_callback(void *user_data, DBusMessage *msg, DBusError *err)
1328 E_Connman_Element *element = user_data;
1329 DBusMessageIter itr, s_itr;
1332 DBG("get_properties msg=%p", msg);
1334 if (!_dbus_callback_check_and_init(msg, &itr, err))
1337 t = dbus_message_iter_get_arg_type(&itr);
1338 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
1342 dbus_message_iter_recurse(&itr, &s_itr);
1345 DBusMessageIter e_itr, v_itr;
1350 t = dbus_message_iter_get_arg_type(&s_itr);
1351 if (!_dbus_iter_type_check(t, DBUS_TYPE_DICT_ENTRY))
1354 dbus_message_iter_recurse(&s_itr, &e_itr);
1356 t = dbus_message_iter_get_arg_type(&e_itr);
1357 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
1360 dbus_message_iter_get_basic(&e_itr, &key);
1361 dbus_message_iter_next(&e_itr);
1362 t = dbus_message_iter_get_arg_type(&e_itr);
1363 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
1366 dbus_message_iter_recurse(&e_itr, &v_itr);
1367 t = dbus_message_iter_get_arg_type(&v_itr);
1368 if (t == DBUS_TYPE_ARRAY)
1370 value = _e_connman_element_iter_get_array(&v_itr, key);
1372 else if (t != DBUS_TYPE_INVALID)
1374 dbus_message_iter_get_basic(&v_itr, &value);
1378 ERR("property has invalid type %s", key);
1382 r = _e_connman_element_property_value_add(element, key, t, value);
1385 ERR("failed to add property value %s (%c)", key, t);
1389 INF("property value changed %s (%c)", key, t);
1393 while (dbus_message_iter_next(&s_itr));
1396 _e_connman_element_listeners_call(element);
1400 * Sync element properties with server.
1402 * Call method GetProperties() at the given element on server in order to sync
1405 * @param element to call method on server.
1406 * @param cb function to call when server replies or some error happens.
1407 * @param data data to give to cb when it is called.
1409 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1412 e_connman_element_sync_properties_full(E_Connman_Element *element, E_DBus_Method_Return_Cb cb, const void *data)
1414 const char name[] = "GetProperties";
1416 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1417 return e_connman_element_call_full
1418 (element, name, _e_connman_element_get_properties_callback,
1419 &element->_pending.properties_get, cb, data);
1423 * Sync element properties with server, simple version.
1425 * Call method GetProperties() at the given element on server in order to sync
1426 * them. This is the simple version and there is no check of server reply
1429 * @param element to call method on server.
1431 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1434 e_connman_element_properties_sync(E_Connman_Element *element)
1436 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1437 return e_connman_element_sync_properties_full(element, NULL, NULL);
1441 * Call method SetProperty(prop, {key: value}) at the given element on server.
1443 * This is a server call, not local, so it may fail and in that case
1444 * no property is updated locally. If the value was set the event
1445 * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
1447 * @param element to call method on server.
1448 * @param prop property name.
1449 * @param key dict key name.
1450 * @param type DBus type to use for value.
1451 * @param value pointer to value, just like regular DBus, see
1452 * dbus_message_iter_append_basic().
1453 * @param cb function to call when server replies or some error happens.
1454 * @param data data to give to cb when it is called.
1456 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1459 e_connman_element_property_dict_set_full(E_Connman_Element *element, const char *prop, const char *key, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
1461 const char name[] = "SetProperty";
1463 DBusMessageIter itr, variant, dict, entry;
1466 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1467 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
1469 msg = dbus_message_new_method_call
1470 (e_connman_system_bus_name_get(), element->path, element->interface, name);
1475 dbus_message_iter_init_append(msg, &itr);
1476 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1478 if ((size_t)snprintf(typestr, sizeof(typestr),
1479 (DBUS_TYPE_ARRAY_AS_STRING
1480 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1481 DBUS_TYPE_STRING_AS_STRING
1483 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1484 type) >= sizeof(typestr))
1486 ERR("sizeof(typestr) is too small!");
1490 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &variant);
1492 snprintf(typestr, sizeof(typestr),
1493 (DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1494 DBUS_TYPE_STRING_AS_STRING
1496 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1499 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, typestr, &dict);
1500 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
1502 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1504 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1505 dbus_message_iter_append_basic(&entry, type, &value);
1507 dbus_message_iter_append_basic(&entry, type, value);
1509 dbus_message_iter_close_container(&dict, &entry);
1510 dbus_message_iter_close_container(&variant, &dict);
1511 dbus_message_iter_close_container(&itr, &variant);
1513 return e_connman_element_message_send
1514 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1518 * Call method SetProperty(prop, value) at the given element on server.
1520 * This is a server call, not local, so it may fail and in that case
1521 * no property is updated locally. If the value was set the event
1522 * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
1524 * @param element to call method on server.
1525 * @param prop property name.
1526 * @param type DBus type to use for value.
1527 * @param value pointer to value, just like regular DBus, see
1528 * dbus_message_iter_append_basic().
1529 * @param cb function to call when server replies or some error happens.
1530 * @param data data to give to cb when it is called.
1532 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1535 e_connman_element_property_set_full(E_Connman_Element *element, const char *prop, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
1537 const char name[] = "SetProperty";
1541 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1542 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
1544 msg = dbus_message_new_method_call
1545 (e_connman_system_bus_name_get(), element->path, element->interface, name);
1550 DBusMessageIter itr, v;
1551 dbus_message_iter_init_append(msg, &itr);
1552 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1556 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &v);
1557 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1559 dbus_message_iter_append_basic(&v, type, &value);
1561 else if (type == DBUS_TYPE_BOOLEAN)
1563 unsigned int b = *(char *)value;
1564 dbus_message_iter_append_basic(&v, type, &b);
1568 dbus_message_iter_append_basic(&v, type, value);
1571 dbus_message_iter_close_container(&itr, &v);
1573 return e_connman_element_message_send
1574 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1578 * Call method SetProperty(prop, value) at the given element on server, when
1579 * value is an array.
1581 * This is a server call, not local, so it may fail and in that case
1582 * no property is updated locally. If the value was set the event
1583 * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
1585 * @param element to call method on server.
1586 * @param prop property name.
1587 * @param type DBus type to use for value.
1588 * @param value pointer to value, just like regular DBus, see
1589 * dbus_message_iter_append_basic().
1590 * @param cb function to call when server replies or some error happens.
1591 * @param data data to give to cb when it is called.
1593 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1596 e_connman_element_property_array_set_full(E_Connman_Element *element, const char *prop, int type, const Eina_List *values, E_DBus_Method_Return_Cb cb, const void *data)
1598 const char name[] = "SetProperty";
1599 char type_sig[2] = { type, '\0'};
1600 char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
1602 DBusMessageIter itr, variant, array;
1606 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1607 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
1609 msg = dbus_message_new_method_call
1610 (e_connman_system_bus_name_get(), element->path, element->interface, name);
1615 dbus_message_iter_init_append(msg, &itr);
1616 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1618 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, array_sig,
1620 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, type_sig,
1623 if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH)
1625 EINA_LIST_FOREACH(values, l, entry)
1626 dbus_message_iter_append_basic(&array, type, &entry);
1630 EINA_LIST_FOREACH(values, l, entry)
1631 dbus_message_iter_append_basic(&array, type, entry);
1634 dbus_message_iter_close_container(&variant, &array);
1635 dbus_message_iter_close_container(&itr, &variant);
1637 return e_connman_element_message_send(element, name, NULL, msg,
1638 &element->_pending.property_set,
1643 * Call method SetProperty(prop, value) at the given element on server.
1645 * This is the simple version and there is no check of server reply
1648 * @param element to call method on server.
1649 * @param prop property name.
1650 * @param type DBus type to use for value.
1651 * @param value pointer to value, just like regular DBus, see
1652 * dbus_message_iter_append_basic().
1654 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1657 e_connman_element_property_set(E_Connman_Element *element, const char *prop, int type, const void *value)
1659 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1660 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
1661 return e_connman_element_property_set_full
1662 (element, prop, type, value, NULL, NULL);
1666 e_connman_element_call_with_path(E_Connman_Element *element, const char *method_name, const char *string, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
1668 DBusMessageIter itr;
1671 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1672 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, EINA_FALSE);
1673 EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
1674 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, EINA_FALSE);
1676 msg = dbus_message_new_method_call
1677 (e_connman_system_bus_name_get(), element->path, element->interface,
1683 dbus_message_iter_init_append(msg, &itr);
1684 dbus_message_iter_append_basic(&itr, DBUS_TYPE_OBJECT_PATH, &string);
1686 return e_connman_element_message_send
1687 (element, method_name, cb, msg, pending, user_cb, user_data);
1691 e_connman_element_call_with_string(E_Connman_Element *element, const char *method_name, const char *string, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
1693 DBusMessageIter itr;
1696 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1697 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, EINA_FALSE);
1698 EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
1699 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, EINA_FALSE);
1701 msg = dbus_message_new_method_call
1702 (e_connman_system_bus_name_get(), element->path, element->interface,
1708 dbus_message_iter_init_append(msg, &itr);
1709 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &string);
1711 return e_connman_element_message_send
1712 (element, method_name, cb, msg, pending, user_cb, user_data);
1716 * Get property type.
1718 * If @c EINA_FALSE is returned, then this call failed and parameter-returned
1719 * values shall be considered invalid.
1721 * @param element which element to get the property
1722 * @param name property name, must be previously stringshared
1723 * @param type will contain the value type.
1725 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1728 e_connman_element_property_type_get_stringshared(const E_Connman_Element *element, const char *name, int *type)
1730 const E_Connman_Element_Property *p;
1732 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1733 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1734 EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE);
1736 EINA_INLIST_FOREACH(element->props, p)
1738 if (p->name == name)
1745 WRN("element %s (%p) has no property with name \"%s\".",
1746 element->path, element, name);
1751 * Get property type.
1753 * If @c EINA_FALSE is returned, then this call failed and parameter-returned
1754 * values shall be considered invalid.
1756 * @param element which element to get the property
1757 * @param name property name
1758 * @param type will contain the value type.
1760 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1763 e_connman_element_property_type_get(const E_Connman_Element *element, const char *name, int *type)
1766 name = eina_stringshare_add(name);
1767 ret = e_connman_element_property_type_get_stringshared(element, name, type);
1768 eina_stringshare_del(name);
1773 e_connman_element_list_properties(const E_Connman_Element *element, Eina_Bool (*cb)(void *data, const E_Connman_Element *element, const char *name, int type, const void *value), const void *data)
1775 const E_Connman_Element_Property *p;
1777 EINA_SAFETY_ON_NULL_RETURN(element);
1778 EINA_SAFETY_ON_NULL_RETURN(cb);
1780 EINA_INLIST_FOREACH(element->props, p)
1782 const void *value = NULL;
1786 case DBUS_TYPE_STRING:
1787 value = &p->value.str;
1790 case DBUS_TYPE_OBJECT_PATH:
1791 value = &p->value.path;
1794 case DBUS_TYPE_BOOLEAN:
1795 value = (void *)&p->value.boolean;
1798 case DBUS_TYPE_UINT16:
1799 value = &p->value.u16;
1802 case DBUS_TYPE_UINT32:
1803 value = &p->value.u32;
1807 ERR("unsupported type %c", p->type);
1810 if (!cb((void *)data, element, p->name, p->type, value))
1816 * Get dict value given its key inside a dict property.
1818 * This will look into properties for one of type dict that contains
1819 * the given key, to find the property. If no property is found then
1820 * @c EINA_FALSE is returned.
1822 * If @c EINA_FALSE is returned, then this call failed and parameter-returned
1823 * values shall be considered invalid.
1825 * @param element which element to get the property
1826 * @param dict_name property name, must be previously stringshared
1827 * @param key key inside dict, must be previously stringshared
1828 * @param type if provided it will contain the value type.
1829 * @param value where to store the property value, must be a pointer to the
1830 * exact type, (Eina_Bool *) for booleans, (char **) for strings, and so on.
1832 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1835 e_connman_element_property_dict_get_stringshared(const E_Connman_Element *element, const char *dict_name, const char *key, int *type, void *value)
1837 const E_Connman_Element_Property *p;
1839 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1840 EINA_SAFETY_ON_NULL_RETURN_VAL(dict_name, EINA_FALSE);
1841 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1842 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
1844 EINA_INLIST_FOREACH(element->props, p)
1846 E_Connman_Element_Dict_Entry *entry;
1847 E_Connman_Array *array;
1849 if (p->name != dict_name)
1852 if (p->type != DBUS_TYPE_ARRAY)
1854 WRN("element %s (%p) has property \"%s\" is not an array: %c (%d)",
1855 element->path, element, dict_name, p->type, p->type);
1859 array = p->value.array;
1860 if ((!array) || (array->type != DBUS_TYPE_DICT_ENTRY))
1862 int t = array ? array->type : DBUS_TYPE_INVALID;
1863 WRN("element %s (%p) has property \"%s\" is not a dict: %c (%d)",
1864 element->path, element, dict_name, t, t);
1868 entry = _e_connman_element_array_dict_find_stringshared(array, key);
1871 WRN("element %s (%p) has no dict property with name \"%s\" with "
1873 element->path, element, dict_name, key);
1878 *type = entry->type;
1880 switch (entry->type)
1882 case DBUS_TYPE_BOOLEAN:
1883 *(Eina_Bool *)value = entry->value.boolean;
1886 case DBUS_TYPE_BYTE:
1887 *(unsigned char *)value = entry->value.byte;
1890 case DBUS_TYPE_UINT16:
1891 *(unsigned short *)value = entry->value.u16;
1894 case DBUS_TYPE_UINT32:
1895 *(unsigned int *)value = entry->value.u32;
1898 case DBUS_TYPE_STRING:
1899 *(const char **)value = entry->value.str;
1902 case DBUS_TYPE_OBJECT_PATH:
1903 *(const char **)value = entry->value.path;
1906 case DBUS_TYPE_ARRAY:
1907 *(E_Connman_Array **)value = entry->value.array;
1911 ERR("don't know how to get property %s, key %s type %c (%d)",
1912 dict_name, key, entry->type, entry->type);
1917 DBG("element %s (%p) has no property with name \"%s\".",
1918 element->path, element, dict_name);
1923 e_connman_element_property_dict_strings_array_get_stringshared(const E_Connman_Element *element, const char *dict_name, const char *key, unsigned int *count, const char ***strings)
1925 const char **ret, **p;
1926 Eina_Array_Iterator iterator;
1927 E_Connman_Array *array;
1932 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
1933 EINA_SAFETY_ON_NULL_RETURN_VAL(dict_name, EINA_FALSE);
1934 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1935 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
1936 EINA_SAFETY_ON_NULL_RETURN_VAL(strings, EINA_FALSE);
1941 if (!e_connman_element_property_dict_get_stringshared(element, dict_name,
1942 key, &type, &array))
1945 if (type != DBUS_TYPE_ARRAY)
1947 ERR("property %s.%s is not an array!", dict_name, key);
1951 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
1954 if (array->type != DBUS_TYPE_STRING)
1956 ERR("property %s.%s is not an array of strings!", dict_name, key);
1960 *count = eina_array_count_get(array->array);
1961 ret = malloc(*count * sizeof(char *));
1964 ERR("could not allocate return array of %d strings: %s",
1965 *count, strerror(errno));
1972 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
1986 * Get property value given its name.
1988 * This will look into properties, to find the property.
1989 * If no property is found then @c EINA_FALSE is returned.
1991 * If @c EINA_FALSE is returned, then this call failed and parameter-returned
1992 * values shall be considered invalid.
1994 * @param element which element to get the property
1995 * @param name property name, must be previously stringshared
1996 * @param type if provided it will contain the value type.
1997 * @param value where to store the property value, must be a pointer to the
1998 * exact type, (Eina_Bool *) for booleans, (char **) for strings, and so on.
2000 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2003 e_connman_element_property_get_stringshared(const E_Connman_Element *element, const char *name, int *type, void *value)
2005 const E_Connman_Element_Property *p;
2007 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
2008 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
2009 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
2011 EINA_INLIST_FOREACH(element->props, p)
2013 if (p->name != name)
2021 case DBUS_TYPE_BOOLEAN:
2022 *(Eina_Bool *)value = p->value.boolean;
2025 case DBUS_TYPE_BYTE:
2026 *(unsigned char *)value = p->value.byte;
2029 case DBUS_TYPE_UINT16:
2030 *(unsigned short *)value = p->value.u16;
2033 case DBUS_TYPE_UINT32:
2034 *(unsigned int *)value = p->value.u32;
2037 case DBUS_TYPE_STRING:
2038 *(const char **)value = p->value.str;
2041 case DBUS_TYPE_OBJECT_PATH:
2042 *(const char **)value = p->value.path;
2045 case DBUS_TYPE_ARRAY:
2046 *(E_Connman_Array **)value = p->value.array;
2050 ERR("don't know how to get property type %c (%d)",
2056 WRN("element %s (%p) has no property with name \"%s\".",
2057 element->path, element, name);
2062 * Get property value given its name.
2064 * This will look into properties, to find the property.
2065 * If no property is found then @c EINA_FALSE is returned.
2067 * If @c EINA_FALSE is returned, then this call failed and parameter-returned
2068 * values shall be considered invalid.
2070 * @param element which element to get the property
2071 * @param name property name
2072 * @param type if provided it will contain the value type.
2073 * @param value where to store the property value, must be a pointer to the
2074 * exact type, (Eina_Bool *) for booleans, (char **) for strings, and so on.
2076 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2079 e_connman_element_property_get(const E_Connman_Element *element, const char *name, int *type, void *value)
2082 name = eina_stringshare_add(name);
2083 ret = e_connman_element_property_get_stringshared
2084 (element, name, type, value);
2085 eina_stringshare_del(name);
2089 struct e_connman_elements_for_each_data
2091 Eina_Hash_Foreach cb;
2096 _e_connman_elements_for_each(Eina_Hash *hash __UNUSED__, const char *key, void *data, void *fdata)
2098 struct e_connman_elements_for_each_data *each_data = fdata;
2100 each_data->cb(elements, key, data, each_data->data);
2105 * Call the given function for each existing element.
2107 * @param cb function to call for each element. It will get as parameters,
2108 * in order: the element pointer and the given @a user_data.
2109 * @param user_data data to give to @a cb for each element.
2112 e_connman_elements_for_each(Eina_Hash_Foreach cb, const void *user_data)
2114 struct e_connman_elements_for_each_data data = {cb, (void *)user_data};
2116 EINA_SAFETY_ON_NULL_RETURN(cb);
2118 eina_hash_foreach(elements, (Eina_Hash_Foreach)_e_connman_elements_for_each,
2123 _e_connman_elements_get_allocate(unsigned int *count, E_Connman_Element ***p_elements)
2125 *count = eina_hash_population(elements);
2132 *p_elements = malloc(*count * sizeof(E_Connman_Element *));
2135 ERR("could not allocate return array of %d elements: %s",
2136 *count, strerror(errno));
2145 _e_connman_elements_get_all(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *data, void *fdata)
2147 E_Connman_Element *element = data;
2148 E_Connman_Element ***p_ret = fdata;
2156 * Get all known elements.
2158 * No reference is added to these elements, since there are no threads
2159 * in the system, you are free to add references yourself right after
2160 * the return of this call without race condition, elements by the
2161 * system (ie: elementRemoved signal)could only be touched on the next
2162 * main loop iteration.
2164 * @param count return the number of elements in array.
2165 * @param p_elements array with all elements, these are not referenced
2166 * and in no particular order, just set if return is @c EINA_TRUE.
2168 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2171 e_connman_elements_get_all(unsigned int *count, E_Connman_Element ***p_elements)
2173 E_Connman_Element **p;
2175 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
2176 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, EINA_FALSE);
2178 if (!_e_connman_elements_get_allocate(count, p_elements))
2182 eina_hash_foreach(elements, (Eina_Hash_Foreach)_e_connman_elements_get_all,
2187 struct e_connman_elements_get_all_str_data
2189 E_Connman_Element **elements;
2195 _e_connman_elements_get_all_type(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *e, void *user_data)
2197 struct e_connman_elements_get_all_str_data *data = user_data;
2198 E_Connman_Element *element = e;
2200 if ((data->str) && (element->interface != data->str))
2203 data->elements[data->count] = element;
2209 * Get all known elements of type.
2211 * No reference is added to these elements, since there are no threads
2212 * in the system, you are free to add references yourself right after
2213 * the return of this call without race condition, elements by the
2214 * system (ie: ElementRemoved signal) could only be touched on the next
2215 * main loop iteration.
2217 * @param type type to filter, or NULL to get all.
2218 * @param count return the number of elements in array.
2219 * @param p_elements array with all elements, these are not referenced
2220 * and in no particular order, just set if return is @c EINA_TRUE.
2222 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2224 * @see e_connman_elements_get_all()
2227 e_connman_elements_get_all_type(const char *type, unsigned int *count, E_Connman_Element ***p_elements)
2229 struct e_connman_elements_get_all_str_data data;
2231 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
2232 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, EINA_FALSE);
2234 if (!_e_connman_elements_get_allocate(count, p_elements))
2237 data.elements = *p_elements;
2239 data.str = eina_stringshare_add(type);
2240 eina_hash_foreach(elements,
2241 (Eina_Hash_Foreach)_e_connman_elements_get_all_type,
2244 eina_stringshare_del(data.str);
2245 *count = data.count;
2250 * Get the element registered at given path.
2252 * @param path the path to query for registered object.
2254 * @return element pointer if found, NULL otherwise. No references are added.
2257 e_connman_element_get(const char *path)
2259 E_Connman_Element *element;
2261 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2262 element = eina_hash_find(elements, path);
2268 _e_connman_element_property_changed_callback(void *data, DBusMessage *msg)
2270 E_Connman_Element *element = (E_Connman_Element *)data;
2271 DBusMessageIter itr, v_itr;
2272 int t, r, changed = 0;
2273 const char *name = NULL;
2276 DBG("Property changed in element %s", element->path);
2278 if (!_dbus_callback_check_and_init(msg, &itr, NULL))
2281 t = dbus_message_iter_get_arg_type(&itr);
2282 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
2284 ERR("missing name in property changed signal");
2288 dbus_message_iter_get_basic(&itr, &name);
2290 dbus_message_iter_next(&itr);
2291 t = dbus_message_iter_get_arg_type(&itr);
2292 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
2294 ERR("missing value in property changed signal");
2298 dbus_message_iter_recurse(&itr, &v_itr);
2299 t = dbus_message_iter_get_arg_type(&v_itr);
2301 if (t == DBUS_TYPE_ARRAY)
2303 value = _e_connman_element_iter_get_array(&v_itr, name);
2305 else if (t != DBUS_TYPE_INVALID)
2307 dbus_message_iter_get_basic(&v_itr, &value);
2311 ERR("property has invalid type %s", name);
2315 r = _e_connman_element_property_value_add(element, name, t, value);
2318 ERR("failed to add property value %s (%c)", name, t);
2322 INF("property value changed %s (%c)", name, t);
2327 _e_connman_element_listeners_call(element);
2331 * Register the given path, possible creating and element and return it.
2333 * This will check if path is already registered, in that case the
2334 * exiting element is returned. If it was not registered yet, a new
2335 * element is created, registered and returned.
2337 * This call will not add extra references to the object.
2339 * @param path the path to register the element
2341 * @return the registered object, no references are added.
2344 e_connman_element_register(const char *path, const char *interface)
2346 E_Connman_Element *element;
2348 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2349 EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
2351 element = eina_hash_find(elements, path);
2355 element = e_connman_element_new(path, interface);
2359 if (!eina_hash_add(elements, element->path, element))
2361 ERR("could not add element %s to hash, delete it.", path);
2362 e_connman_element_free(element);
2366 element->signal_handler =
2367 e_dbus_signal_handler_add
2368 (e_connman_conn, e_connman_system_bus_name_get(),
2369 element->path, element->interface, "PropertyChanged",
2370 _e_connman_element_property_changed_callback, element);
2372 e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_ADD, element);
2378 _e_connman_element_event_unregister_and_free(void *data __UNUSED__, void *ev)
2380 E_Connman_Element *element = ev;
2381 e_connman_element_unref(element);
2385 _e_connman_element_unregister_internal(E_Connman_Element *element)
2387 if (element->signal_handler)
2389 e_dbus_signal_handler_del(e_connman_conn, element->signal_handler);
2390 element->signal_handler = NULL;
2393 ecore_event_add(E_CONNMAN_EVENT_ELEMENT_DEL, element,
2394 _e_connman_element_event_unregister_and_free, NULL);
2398 * Forget about the given element.
2400 * This will remove the element from the pool of known objects, then
2401 * add an E_CONNMAN_EVENT_ELEMENT_DEL and after that will unreference it,
2402 * possible freeing it.
2404 * @param element element to forget about. Its reference will be removed.
2407 e_connman_element_unregister(E_Connman_Element *element)
2413 eina_hash_del_by_key(elements, element->path);
2417 * Remove all known elements.
2419 * This will remove all known elements but will NOT add any
2420 * E_CONNMAN_EVENT_ELEMENT_DEL to main loop.
2422 * This is just useful to make sure next e_connman_manager_sync_elements()
2423 * will not leave any stale elements. This is unlikely to happen, as
2424 * E_Connman is supposed to catch all required events to avoid stale elements.
2427 e_connman_manager_clear_elements(void)
2429 e_connman_elements_shutdown();
2430 e_connman_elements_init();
2434 * Creates elements hash.
2436 * This has no init counter since its already guarded by other code.
2440 e_connman_elements_init(void)
2442 EINA_SAFETY_ON_FALSE_RETURN(!elements);
2444 eina_hash_string_superfast_new(EINA_FREE_CB
2445 (_e_connman_element_unregister_internal));
2449 e_connman_elements_shutdown(void)
2451 EINA_SAFETY_ON_FALSE_RETURN(!!elements);
2452 eina_hash_free(elements);
2456 static inline Eina_Bool
2457 _e_connman_element_is(const E_Connman_Element *element, const char *interface)
2459 return element->interface == interface;
2463 e_connman_element_is_manager(const E_Connman_Element *element)
2465 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
2466 return _e_connman_element_is(element, e_connman_iface_manager);
2470 e_connman_element_is_profile(const E_Connman_Element *element)
2472 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
2473 return _e_connman_element_is(element, e_connman_iface_profile);
2477 e_connman_element_is_service(const E_Connman_Element *element)
2479 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
2480 return _e_connman_element_is(element, e_connman_iface_service);
2484 e_connman_element_is_technology(const E_Connman_Element *element)
2486 EINA_SAFETY_ON_NULL_RETURN_VAL(element, EINA_FALSE);
2487 return _e_connman_element_is(element, e_connman_iface_technology);