1 #include "e_connman_private.h"
5 static Eina_Hash *elements = NULL;
7 typedef struct _E_Connman_Array E_Connman_Array;
8 typedef struct _E_Connman_Element_Pending E_Connman_Element_Pending;
9 typedef struct _E_Connman_Element_Call_Data E_Connman_Element_Call_Data;
10 typedef struct _E_Connman_Element_Property E_Connman_Element_Property;
11 typedef struct _E_Connman_Element_Listener E_Connman_Element_Listener;
12 typedef struct _E_Connman_Element_Dict_Entry E_Connman_Element_Dict_Entry;
14 struct _E_Connman_Array
20 struct _E_Connman_Element_Pending
23 DBusPendingCall *pending;
25 E_DBus_Method_Return_Cb user_cb;
29 struct _E_Connman_Element_Call_Data
31 E_Connman_Element *element;
32 E_DBus_Method_Return_Cb cb;
33 E_Connman_Element_Pending *pending;
37 struct _E_Connman_Element_Property
50 E_Connman_Array *array;
54 struct _E_Connman_Element_Dict_Entry
68 struct _E_Connman_Element_Listener
71 void (*cb)(void *data, const E_Connman_Element *element);
73 void (*free_data)(void *data);
78 _e_connman_element_event_no_free(void *data __UNUSED__, void *ev)
80 E_Connman_Element *element = ev;
81 e_connman_element_unref(element);
85 e_connman_element_event_add(int event_type, E_Connman_Element *element)
87 e_connman_element_ref(element);
89 (event_type, element, _e_connman_element_event_no_free, element);
93 e_connman_element_call_dispatch_and_free(void *d, DBusMessage *msg, DBusError *err)
95 E_Connman_Element_Call_Data *data = d;
96 E_Connman_Element_Pending *pending;
98 pending = data->pending;
99 pending->pending = NULL;
102 data->cb(data->element, msg, err);
104 if (pending->user_cb)
105 pending->user_cb(pending->user_data, msg, err);
107 pending->data = NULL;
108 *data->p_list = eina_inlist_remove(*data->p_list, EINA_INLIST_GET(pending));
114 e_connman_element_pending_cancel_and_free(Eina_Inlist **pending)
118 E_Connman_Element_Pending *p = (E_Connman_Element_Pending *)*pending;
121 dbus_pending_call_cancel(p->pending);
123 dbus_error_init(&err);
124 dbus_set_error(&err, "Canceled", "Pending method call was canceled.");
125 e_connman_element_call_dispatch_and_free(p->data, NULL, &err);
126 dbus_error_free(&err);
131 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))
133 E_Connman_Element_Listener *l;
137 ERR("safety check failed: element == NULL");
142 ERR("safety check failed: cb == NULL");
146 l = malloc(sizeof(*l));
149 ERR("could not allocate E_Connman_Element_Listener");
154 l->data = (void *)data;
155 l->free_data = free_data;
157 element->_listeners = eina_inlist_append
158 (element->_listeners, EINA_INLIST_GET(l));
164 free_data((void *)data);
168 e_connman_element_listener_del(E_Connman_Element *element, void (*cb)(void *data, const E_Connman_Element *element), const void *data)
170 E_Connman_Element_Listener *l;
172 EINA_SAFETY_ON_NULL_RETURN(element);
173 EINA_SAFETY_ON_NULL_RETURN(cb);
175 EINA_INLIST_FOREACH(element->_listeners, l)
176 if ((l->cb == cb) && (l->data == data))
178 element->_listeners = eina_inlist_remove
179 (element->_listeners, EINA_INLIST_GET(l));
180 if (l->free_data) l->free_data(l->data);
187 _e_connman_element_listeners_call_do(E_Connman_Element *element)
189 E_Connman_Element_Listener *l, **shadow;
190 unsigned int i, count;
192 /* NB: iterate on a copy in order to allow listeners to be deleted
193 * from callbacks. number of listeners should be small, so the
194 * following should do fine.
196 count = eina_inlist_count(element->_listeners);
200 shadow = alloca(sizeof(*shadow) * count);
205 EINA_INLIST_FOREACH(element->_listeners, l)
208 for (i = 0; i < count; i++)
209 shadow[i]->cb(shadow[i]->data, element);
212 e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_UPDATED, element);
216 _e_connman_element_listeners_call_idler(void *data)
218 E_Connman_Element *element = data;
219 _e_connman_element_listeners_call_do(element);
220 element->_idler.changed = NULL;
225 _e_connman_element_listeners_call(E_Connman_Element *element)
227 if (element->_idler.changed)
229 element->_idler.changed = ecore_idler_add
230 (_e_connman_element_listeners_call_idler, element);
233 /***********************************************************************
235 ***********************************************************************/
238 _e_connman_element_dict_entry_free(E_Connman_Element_Dict_Entry *entry)
242 case DBUS_TYPE_BOOLEAN:
244 case DBUS_TYPE_UINT16:
245 case DBUS_TYPE_UINT32:
247 case DBUS_TYPE_OBJECT_PATH:
248 eina_stringshare_del(entry->value.path);
250 case DBUS_TYPE_STRING:
251 eina_stringshare_del(entry->value.str);
254 ERR("don't know how to free dict entry '%s' of type %c (%d)",
255 entry->name, entry->type, entry->type);
258 eina_stringshare_del(entry->name);
262 static E_Connman_Element_Dict_Entry *
263 _e_connman_element_dict_entry_new(DBusMessageIter *itr)
265 E_Connman_Element_Dict_Entry *entry;
266 DBusMessageIter e_itr, v_itr;
268 const char *key = NULL;
271 dbus_message_iter_recurse(itr, &e_itr);
273 t = dbus_message_iter_get_arg_type(&e_itr);
274 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
276 ERR("invalid format for dict entry. first type not a string: %c (%d)",
281 dbus_message_iter_get_basic(&e_itr, &key);
284 ERR("invalid format for dict entry. no key.");
288 dbus_message_iter_next(&e_itr);
289 t = dbus_message_iter_get_arg_type(&e_itr);
290 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
292 ERR("invalid format for dict entry '%s'. "
293 "second type not a variant: %c (%d)",
298 dbus_message_iter_recurse(&e_itr, &v_itr);
300 t = dbus_message_iter_get_arg_type(&v_itr);
301 if ((t == DBUS_TYPE_INVALID) || (t == DBUS_TYPE_ARRAY))
303 ERR("invalid type for dict value for entry '%s': %c (%d)",
308 entry = calloc(1, sizeof(*entry));
311 ERR("could not allocate memory for dict entry.");
315 dbus_message_iter_get_basic(&v_itr, &value);
318 case DBUS_TYPE_BOOLEAN:
319 entry->value.boolean = (bool)(long)value;
322 entry->value.byte = (unsigned char)(long)value;
324 case DBUS_TYPE_UINT16:
325 entry->value.u16 = (unsigned short)(long)value;
327 case DBUS_TYPE_UINT32:
328 entry->value.u32 = (unsigned int)(long)value;
330 case DBUS_TYPE_STRING:
331 entry->value.str = eina_stringshare_add(value);
333 case DBUS_TYPE_OBJECT_PATH:
334 entry->value.path = eina_stringshare_add(value);
337 ERR("don't know how to create dict entry '%s' for of type %c (%d)",
343 entry->name = eina_stringshare_add(key);
348 static E_Connman_Element_Dict_Entry *
349 _e_connman_element_array_dict_find_stringshared(const E_Connman_Array *array, const char *key)
351 E_Connman_Element_Dict_Entry *entry;
352 Eina_Array_Iterator iterator;
355 EINA_ARRAY_ITER_NEXT(array->array, i, entry, iterator)
356 if (entry->name == key)
363 _e_connman_element_array_free(E_Connman_Array *array, E_Connman_Array *new __UNUSED__)
365 Eina_Array_Iterator iterator;
374 case DBUS_TYPE_BOOLEAN:
376 case DBUS_TYPE_UINT16:
377 case DBUS_TYPE_UINT32:
379 case DBUS_TYPE_OBJECT_PATH:
380 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
381 eina_stringshare_del(item);
383 case DBUS_TYPE_STRING:
384 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
385 eina_stringshare_del(item);
387 case DBUS_TYPE_DICT_ENTRY:
388 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
389 _e_connman_element_dict_entry_free(item);
392 ERR("don't know how to free array of values of type %c (%d)",
393 array->type, array->type);
396 eina_array_free(array->array);
401 _e_connman_element_property_value_free(E_Connman_Element_Property *property)
403 switch (property->type)
407 case DBUS_TYPE_BOOLEAN:
409 case DBUS_TYPE_UINT16:
410 case DBUS_TYPE_UINT32:
412 case DBUS_TYPE_STRING:
413 eina_stringshare_del(property->value.str);
415 case DBUS_TYPE_OBJECT_PATH:
416 eina_stringshare_del(property->value.path);
418 case DBUS_TYPE_ARRAY:
419 _e_connman_element_array_free(property->value.array, NULL);
422 ERR("don't know how to free value of property type %c (%d)",
423 property->type, property->type);
428 _e_connman_element_get_interface(const char *key)
430 const char *interface = NULL, *tail;
439 if (strcmp(tail, "rofiles") == 0)
440 interface = e_connman_iface_profile;
443 if (strcmp(tail, "evices") == 0)
444 interface = e_connman_iface_device;
447 if (strcmp(tail, "etworks") == 0)
448 interface = e_connman_iface_network;
451 if (strcmp(tail, "ervices") == 0)
452 interface = e_connman_iface_service;
459 ERR("connman reported unknown interface: %s", key);
465 _e_connman_element_item_register(const char *key, const char *item)
467 E_Connman_Element *element;
468 const char *interface;
470 interface = _e_connman_element_get_interface(key);
473 element = e_connman_element_register(item, interface);
474 if ((element) && (!e_connman_element_properties_sync(element)))
475 WRN("could not get properties of %s", element->path);
479 _e_connman_element_objects_array_register(E_Connman_Array *array, const char *name)
481 Eina_Array_Iterator iterator;
487 if (array->type != DBUS_TYPE_OBJECT_PATH)
489 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
490 _e_connman_element_item_register(name, item);
493 /* Match 2 arrays to find which are new and which are old elements
494 * For new elements, register them under prop_name property
495 * For old elements, unregister them, sending proper DEL event
498 _e_connman_element_array_match(E_Connman_Array *old, E_Connman_Array *new, const char *prop_name)
500 Eina_List *deleted = NULL;
501 Eina_Array_Iterator iter_old, iter_new;
502 unsigned int i_old = 0, i_new = 0;
503 void *item_old, *item_new;
509 if (old->type != DBUS_TYPE_OBJECT_PATH)
512 if ((!new) || (!new->array) || eina_array_count_get(new->array) == 0)
514 if ((!old) || (!old->array) || eina_array_count_get(old->array) == 0)
518 iter_old = old->array->data;
519 goto out_remove_remaining;
523 iter_new = new->array->data;
524 item_new = *iter_new;
525 EINA_ARRAY_ITER_NEXT(old->array, i_old, item_old, iter_old)
527 if (item_old == item_new)
530 if (i_new >= eina_array_count_get(new->array))
537 item_new = *iter_new;
540 deleted = eina_list_append(deleted, item_old);
543 for(; i_new < eina_array_count_get(new->array); iter_new++, i_new++)
546 item_new = *iter_new;
550 EINA_LIST_FOREACH(deleted, l, data)
552 if (data == item_new)
554 deleted = eina_list_remove_list(deleted, l);
561 _e_connman_element_item_register(prop_name, item_new);
562 DBG("Add element %s\n", (const char *) item_new);
566 /* everybody after i_old on old->array + everybody from deleted list
569 EINA_LIST_FREE(deleted, data)
571 E_Connman_Element *e = e_connman_element_get(data);
573 e_connman_element_unregister(e);
574 DBG("Delete element %s\n", (const char *) data);
577 out_remove_remaining:
578 for(; i_old < eina_array_count_get(old->array); iter_old++, i_old++)
580 E_Connman_Element *e;
581 item_old = *iter_old;
585 e = e_connman_element_get(item_old);
587 e_connman_element_unregister(e);
588 DBG("Delete element %s\n", (const char *) item_old);
593 _e_connman_element_property_update(E_Connman_Element_Property *property, int type, void *data)
597 if ((type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) && data)
598 data = (char *)eina_stringshare_add(data);
600 if (property->type != type)
603 DBG("property type changed from '%c' to '%c'",
604 property->type, type);
605 _e_connman_element_property_value_free(property);
606 memset(&property->value, 0, sizeof(property->value));
607 property->type = type;
613 case DBUS_TYPE_BOOLEAN:
614 if (changed || property->value.boolean != (bool)(long)data)
616 property->value.boolean = (bool)(long)data;
621 if (changed || property->value.byte != (unsigned char)(long)data)
623 property->value.byte = (unsigned char)(long)data;
627 case DBUS_TYPE_UINT16:
628 if (changed || property->value.u16 != (unsigned short)(long)data)
630 property->value.u16 = (unsigned short)(long)data;
634 case DBUS_TYPE_UINT32:
635 if (changed || property->value.u32 != (unsigned int)(long)data)
637 property->value.u32 = (unsigned int)(long)data;
641 case DBUS_TYPE_STRING:
643 property->value.str = data;
646 if (property->value.str)
647 eina_stringshare_del(property->value.str);
648 if (property->value.str != data)
650 property->value.str = data;
655 case DBUS_TYPE_OBJECT_PATH:
657 property->value.path = data;
660 if (property->value.path)
661 eina_stringshare_del(property->value.path);
662 if (property->value.path != data)
664 property->value.path = data;
669 case DBUS_TYPE_ARRAY:
671 if (property->value.array)
673 _e_connman_element_array_match(property->value.array, data, property->name);
674 _e_connman_element_array_free(property->value.array, data);
676 property->value.array = data;
680 ERR("don't know how to update property type %c (%d)", type, type);
686 static E_Connman_Element_Property *
687 _e_connman_element_property_new(const char *name, int type, void *data)
689 E_Connman_Element_Property *property;
691 property = calloc(1, sizeof(*property));
694 eina_stringshare_del(name);
695 ERR("could not allocate property: %s", strerror(errno));
699 property->name = name;
700 _e_connman_element_property_update(property, type, data);
705 _e_connman_element_property_free(E_Connman_Element_Property *property)
707 _e_connman_element_property_value_free(property);
708 eina_stringshare_del(property->name);
712 /***********************************************************************
714 ***********************************************************************/
716 e_connman_element_bytes_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count)
718 Eina_Array_Iterator iterator;
719 E_Connman_Array *array;
720 unsigned char *ret, *p;
724 EINA_SAFETY_ON_NULL_RETURN_VAL(element, NULL);
725 EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
726 EINA_SAFETY_ON_NULL_RETURN_VAL(count, NULL);
730 if (!e_connman_element_property_get_stringshared
731 (element, property, NULL, &array))
734 if ((!array) || (!(array->array)))
737 *count = eina_array_count_get(array->array);
738 ret = malloc(*count * sizeof(unsigned char));
741 ERR("could not allocate return array of %d bytes: %s",
742 *count, strerror(errno));
747 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
749 *p = (unsigned char)(long)item;
756 e_connman_element_objects_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, E_Connman_Element ***elements)
758 E_Connman_Element **ret, **p;
759 Eina_Array_Iterator iterator;
760 E_Connman_Array *array;
765 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
766 EINA_SAFETY_ON_NULL_RETURN_VAL(property, 0);
767 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
768 EINA_SAFETY_ON_NULL_RETURN_VAL(elements, 0);
773 if (!e_connman_element_property_get_stringshared
774 (element, property, &type, &array))
777 if (type != DBUS_TYPE_ARRAY)
779 ERR("property %s is not an array!", property);
783 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
786 if (array->type != DBUS_TYPE_OBJECT_PATH)
788 ERR("property %s is not an array of object paths!", property);
792 *count = eina_array_count_get(array->array);
793 ret = malloc(*count * sizeof(E_Connman_Element *));
796 ERR("could not allocate return array of %d elements: %s",
797 *count, strerror(errno));
803 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
805 E_Connman_Element *e = e_connman_element_get(item);
816 /* strings are just pointers (references), no strdup or stringshare_add/ref */
818 e_connman_element_strings_array_get_stringshared(const E_Connman_Element *element, const char *property, unsigned int *count, const char ***strings)
820 const char **ret, **p;
821 Eina_Array_Iterator iterator;
822 E_Connman_Array *array;
827 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
828 EINA_SAFETY_ON_NULL_RETURN_VAL(property, 0);
829 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
830 EINA_SAFETY_ON_NULL_RETURN_VAL(strings, 0);
835 if (!e_connman_element_property_get_stringshared
836 (element, property, &type, &array))
839 if (type != DBUS_TYPE_ARRAY)
841 ERR("property %s is not an array!", property);
845 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
848 if (array->type != DBUS_TYPE_STRING)
850 ERR("property %s is not an array of strings!", property);
854 *count = eina_array_count_get(array->array);
855 ret = malloc(*count * sizeof(char *));
858 ERR("could not allocate return array of %d strings: %s",
859 *count, strerror(errno));
865 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
878 _e_connman_element_array_print(FILE *fp, E_Connman_Array *array)
880 Eina_Array_Iterator iterator;
889 case DBUS_TYPE_OBJECT_PATH:
890 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
891 fprintf(fp, "\"%s\", ", (const char *)item);
893 case DBUS_TYPE_STRING:
894 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
895 fprintf(fp, "\"%s\", ", (const char *)item);
898 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
899 fprintf(fp, "%#02hhx (\"%c\"), ", (unsigned char)(long)item,
900 (unsigned char)(long)item);
902 case DBUS_TYPE_UINT16:
903 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
904 fprintf(fp, "%#04hx (%hu), ", (unsigned short)(long)item,
905 (unsigned short)(long)item);
907 case DBUS_TYPE_UINT32:
908 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
909 fprintf(fp, "%#08x (%u), ", (unsigned int)(long)item,
910 (unsigned int)(long)item);
912 case DBUS_TYPE_DICT_ENTRY:
914 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
916 E_Connman_Element_Dict_Entry *entry = item;
917 fprintf(fp, "%s: ", entry->name);
920 case DBUS_TYPE_OBJECT_PATH:
921 fprintf(fp, "\"%s\", ", entry->value.path);
923 case DBUS_TYPE_STRING:
924 fprintf(fp, "\"%s\", ", entry->value.str);
927 fprintf(fp, "%#02hhx (\"%c\"), ",
928 entry->value.byte, entry->value.byte);
930 case DBUS_TYPE_UINT16:
931 fprintf(fp, "%#04hx (%hu), ",
932 entry->value.u16, entry->value.u16);
934 case DBUS_TYPE_UINT32:
935 fprintf(fp, "%#08x (%u), ",
936 entry->value.u32, entry->value.u32);
939 fprintf(fp, "<UNKNOWN TYPE '%c'>", entry->type);
945 fprintf(fp, "<UNKNOWN ARRAY TYPE '%c'>", array->type);
950 * Print element to file descriptor.
953 e_connman_element_print(FILE *fp, const E_Connman_Element *element)
955 const E_Connman_Element_Property *p;
957 EINA_SAFETY_ON_NULL_RETURN(fp);
960 fputs("Error: no element to print\n", fp);
965 "Element %p: %s [%s]\n"
967 element, element->path, element->interface);
969 EINA_INLIST_FOREACH(element->props, p)
971 fprintf(fp, "\t\t%s (%c) = ", p->name, p->type);
975 case DBUS_TYPE_STRING:
976 fprintf(fp, "\"%s\"", p->value.str);
978 case DBUS_TYPE_OBJECT_PATH:
979 fprintf(fp, "\"%s\"", p->value.path);
981 case DBUS_TYPE_BOOLEAN:
982 fprintf(fp, "%hhu", p->value.boolean);
985 fprintf(fp, "%#02hhx (%d), ", p->value.byte, p->value.byte);
987 case DBUS_TYPE_UINT16:
988 fprintf(fp, "%hu", p->value.u16);
990 case DBUS_TYPE_UINT32:
991 fprintf(fp, "%u", p->value.u32);
993 case DBUS_TYPE_ARRAY:
994 _e_connman_element_array_print(fp, p->value.array);
997 fputs("don't know how to print type", fp);
1004 static E_Connman_Element *
1005 e_connman_element_new(const char *path, const char *interface)
1007 E_Connman_Element *element;
1009 element = calloc(1, sizeof(*element));
1012 ERR("could not allocate element: %s", strerror(errno));
1016 element->path = eina_stringshare_add(path);
1017 element->interface = eina_stringshare_ref(interface);
1018 element->_references = 1;
1024 e_connman_element_extra_properties_free(E_Connman_Element *element)
1026 while (element->props)
1028 E_Connman_Element_Property *prop;
1029 prop = (E_Connman_Element_Property *)element->props;
1030 element->props = element->props->next;
1031 _e_connman_element_property_free(prop);
1036 e_connman_element_free(E_Connman_Element *element)
1038 if (element->_idler.changed)
1039 ecore_idler_del(element->_idler.changed);
1041 while (element->_listeners)
1043 E_Connman_Element_Listener *l = (void *)element->_listeners;
1044 element->_listeners = eina_inlist_remove
1045 (element->_listeners, element->_listeners);
1047 if (l->free_data) l->free_data(l->data);
1051 e_connman_element_pending_cancel_and_free(&element->_pending.properties_get);
1052 e_connman_element_pending_cancel_and_free(&element->_pending.property_set);
1053 e_connman_element_pending_cancel_and_free(&element->_pending.agent_register);
1054 e_connman_element_pending_cancel_and_free(&element->_pending.agent_unregister);
1055 e_connman_element_pending_cancel_and_free(&element->_pending.request_scan);
1056 e_connman_element_pending_cancel_and_free(&element->_pending.technology_enable);
1057 e_connman_element_pending_cancel_and_free(&element->_pending.technology_disable);
1058 e_connman_element_pending_cancel_and_free(&element->_pending.profile_remove);
1059 e_connman_element_pending_cancel_and_free(&element->_pending.device_propose_scan);
1060 e_connman_element_pending_cancel_and_free(&element->_pending.service_connect);
1061 e_connman_element_pending_cancel_and_free(&element->_pending.service_disconnect);
1062 e_connman_element_pending_cancel_and_free(&element->_pending.service_remove);
1063 e_connman_element_pending_cancel_and_free(&element->_pending.service_move_before);
1064 e_connman_element_pending_cancel_and_free(&element->_pending.service_move_after);
1065 e_connman_element_pending_cancel_and_free(&element->_pending.service_clear_property);
1067 e_connman_element_extra_properties_free(element);
1068 eina_stringshare_del(element->interface);
1069 eina_stringshare_del(element->path);
1074 * Add reference to element.
1077 e_connman_element_ref(E_Connman_Element *element)
1079 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1080 return ++element->_references;
1084 * Remove reference from element.
1086 * If reference count drops to 0 element will be freed.
1089 e_connman_element_unref(E_Connman_Element *element)
1092 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1094 i = --element->_references;
1096 e_connman_element_free(element);
1098 ERR("element %p references %d < 0", element, i);
1103 * Send message with callbacks set to work with connman elements.
1105 * If this call fails (returns 0), pending callbacks will not be called,
1106 * not even with error messages.
1108 * @return 1 on success, 0 on failure.
1111 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)
1113 E_Connman_Element_Call_Data *data;
1114 E_Connman_Element_Pending *p;
1116 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1117 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1118 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1119 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
1121 data = malloc(sizeof(*data));
1124 ERR("could not alloc e_connman_element_call_data: %s",
1126 dbus_message_unref(msg);
1130 p = malloc(sizeof(*p));
1133 ERR("could not alloc E_Connman_Element_Pending: %s",
1136 dbus_message_unref(msg);
1140 data->element = element;
1143 data->p_list = pending;
1144 p->user_cb = user_cb;
1145 p->user_data = (void *)user_data;
1147 p->pending = e_dbus_message_send
1148 (e_connman_conn, msg, e_connman_element_call_dispatch_and_free, -1, data);
1149 dbus_message_unref(msg);
1153 *pending = eina_inlist_append(*pending, EINA_INLIST_GET(p));
1158 ERR("failed to call %s (obj=%s, path=%s, iface=%s)",
1159 method_name, e_connman_system_bus_name_get(),
1160 element->path, element->interface);
1168 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)
1172 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1173 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1174 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1176 msg = dbus_message_new_method_call
1177 (e_connman_system_bus_name_get(), element->path, element->interface,
1180 return e_connman_element_message_send
1181 (element, method_name, cb, msg, pending, user_cb, user_data);
1185 _e_connman_element_property_value_add(E_Connman_Element *element, const char *name, int type, void *value)
1187 E_Connman_Element_Property *p;
1189 name = eina_stringshare_add(name);
1190 EINA_INLIST_FOREACH(element->props, p)
1192 if (p->name == name)
1194 eina_stringshare_del(name);
1195 return _e_connman_element_property_update(p, type, value);
1199 p = _e_connman_element_property_new(name, type, value);
1202 ERR("could not create property %s (%c)", name, type);
1206 element->props = eina_inlist_append(element->props, EINA_INLIST_GET(p));
1210 static E_Connman_Array *
1211 _e_connman_element_iter_get_array(DBusMessageIter *itr, const char *key)
1213 E_Connman_Array *array;
1214 DBusMessageIter e_itr;
1216 array = malloc(sizeof(E_Connman_Array));
1219 ERR("could not create new e_connman array.");
1222 array->array = eina_array_new(16);
1223 if (!(array->array))
1225 ERR("could not create new eina array.");
1230 dbus_message_iter_recurse(itr, &e_itr);
1231 array->type = dbus_message_iter_get_arg_type(&e_itr);
1232 if (array->type == DBUS_TYPE_INVALID)
1234 DBG("array %s is of type 'invalid' (empty?)", key);
1235 eina_array_free(array->array);
1242 switch (array->type)
1244 case DBUS_TYPE_OBJECT_PATH:
1248 dbus_message_iter_get_basic(&e_itr, &path);
1249 path = eina_stringshare_add(path);
1250 eina_array_push(array->array, path);
1251 _e_connman_element_item_register(key, path);
1254 case DBUS_TYPE_STRING:
1258 dbus_message_iter_get_basic(&e_itr, &str);
1259 str = eina_stringshare_add(str);
1260 eina_array_push(array->array, str);
1263 case DBUS_TYPE_BYTE:
1266 dbus_message_iter_get_basic(&e_itr, &byte);
1267 eina_array_push(array->array, (void *)(long)byte);
1270 case DBUS_TYPE_DICT_ENTRY:
1272 E_Connman_Element_Dict_Entry *entry;
1273 entry = _e_connman_element_dict_entry_new(&e_itr);
1275 eina_array_push(array->array, entry);
1279 ERR("don't know how to build array '%s' of type %c (%d)",
1280 key, array->type, array->type);
1281 eina_array_free(array->array);
1286 while (dbus_message_iter_next(&e_itr));
1291 _e_connman_element_get_properties_callback(void *user_data, DBusMessage *msg, DBusError *err)
1293 E_Connman_Element *element = user_data;
1294 DBusMessageIter itr, s_itr;
1297 DBG("get_properties msg=%p", msg);
1299 if (!_dbus_callback_check_and_init(msg, &itr, err))
1302 t = dbus_message_iter_get_arg_type(&itr);
1303 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
1307 dbus_message_iter_recurse(&itr, &s_itr);
1310 DBusMessageIter e_itr, v_itr;
1315 t = dbus_message_iter_get_arg_type(&s_itr);
1316 if (!_dbus_iter_type_check(t, DBUS_TYPE_DICT_ENTRY))
1319 dbus_message_iter_recurse(&s_itr, &e_itr);
1321 t = dbus_message_iter_get_arg_type(&e_itr);
1322 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
1325 dbus_message_iter_get_basic(&e_itr, &key);
1326 dbus_message_iter_next(&e_itr);
1327 t = dbus_message_iter_get_arg_type(&e_itr);
1328 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
1331 dbus_message_iter_recurse(&e_itr, &v_itr);
1332 t = dbus_message_iter_get_arg_type(&v_itr);
1333 if (t == DBUS_TYPE_ARRAY)
1334 value = _e_connman_element_iter_get_array(&v_itr, key);
1335 else if (t != DBUS_TYPE_INVALID) {
1336 dbus_message_iter_get_basic(&v_itr, &value);
1338 ERR("property has invalid type %s", key);
1342 r = _e_connman_element_property_value_add(element, key, t, value);
1344 ERR("failed to add property value %s (%c)", key, t);
1347 INF("property value changed %s (%c)", key, t);
1351 while (dbus_message_iter_next(&s_itr));
1354 _e_connman_element_listeners_call(element);
1358 * Sync element properties with server.
1360 * Call method GetProperties() at the given element on server in order to sync
1363 * @param element to call method on server.
1364 * @param cb function to call when server replies or some error happens.
1365 * @param data data to give to cb when it is called.
1367 * @return 1 on success, 0 otherwise.
1370 e_connman_element_sync_properties_full(E_Connman_Element *element, E_DBus_Method_Return_Cb cb, const void *data)
1372 const char name[] = "GetProperties";
1374 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1375 return e_connman_element_call_full
1376 (element, name, _e_connman_element_get_properties_callback,
1377 &element->_pending.properties_get, cb, data);
1381 * Sync element properties with server, simple version.
1383 * Call method GetProperties() at the given element on server in order to sync
1384 * them. This is the simple version and there is no check of server reply
1387 * @param element to call method on server.
1389 * @return 1 on success, 0 otherwise.
1392 e_connman_element_properties_sync(E_Connman_Element *element)
1394 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1395 return e_connman_element_sync_properties_full(element, NULL, NULL);
1399 * Call method SetProperty(prop, {key: value}) at the given element on server.
1401 * This is a server call, not local, so it may fail and in that case
1402 * no property is updated locally. If the value was set the event
1403 * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
1405 * @param element to call method on server.
1406 * @param prop property name.
1407 * @param key dict key name.
1408 * @param type DBus type to use for value.
1409 * @param value pointer to value, just like regular DBus, see
1410 * dbus_message_iter_append_basic().
1411 * @param cb function to call when server replies or some error happens.
1412 * @param data data to give to cb when it is called.
1414 * @return 1 on success, 0 otherwise.
1417 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)
1419 const char name[] = "SetProperty";
1421 DBusMessageIter itr, variant, dict, entry;
1424 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1425 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1427 msg = dbus_message_new_method_call
1428 (e_connman_system_bus_name_get(), element->path, element->interface, name);
1433 dbus_message_iter_init_append(msg, &itr);
1434 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1436 if ((size_t)snprintf(typestr, sizeof(typestr),
1437 (DBUS_TYPE_ARRAY_AS_STRING
1438 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1439 DBUS_TYPE_STRING_AS_STRING
1441 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1442 type) >= sizeof(typestr))
1444 ERR("sizeof(typestr) is too small!");
1448 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &variant);
1450 snprintf(typestr, sizeof(typestr),
1451 (DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1452 DBUS_TYPE_STRING_AS_STRING
1454 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1457 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, typestr, &dict);
1458 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
1460 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1462 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1463 dbus_message_iter_append_basic(&entry, type, &value);
1465 dbus_message_iter_append_basic(&entry, type, value);
1467 dbus_message_iter_close_container(&dict, &entry);
1468 dbus_message_iter_close_container(&variant, &dict);
1469 dbus_message_iter_close_container(&itr, &variant);
1471 return e_connman_element_message_send
1472 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1476 * Call method SetProperty(prop, value) at the given element on server.
1478 * This is a server call, not local, so it may fail and in that case
1479 * no property is updated locally. If the value was set the event
1480 * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
1482 * @param element to call method on server.
1483 * @param prop property name.
1484 * @param type DBus type to use for value.
1485 * @param value pointer to value, just like regular DBus, see
1486 * dbus_message_iter_append_basic().
1487 * @param cb function to call when server replies or some error happens.
1488 * @param data data to give to cb when it is called.
1490 * @return 1 on success, 0 otherwise.
1493 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)
1495 const char name[] = "SetProperty";
1499 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1500 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1502 msg = dbus_message_new_method_call
1503 (e_connman_system_bus_name_get(), element->path, element->interface, name);
1508 DBusMessageIter itr, v;
1509 dbus_message_iter_init_append(msg, &itr);
1510 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1514 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &v);
1515 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1516 dbus_message_iter_append_basic(&v, type, &value);
1518 dbus_message_iter_append_basic(&v, type, value);
1519 dbus_message_iter_close_container(&itr, &v);
1521 return e_connman_element_message_send
1522 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1526 * Call method SetProperty(prop, value) at the given element on server.
1528 * This is the simple version and there is no check of server reply
1531 * @param element to call method on server.
1532 * @param prop property name.
1533 * @param type DBus type to use for value.
1534 * @param value pointer to value, just like regular DBus, see
1535 * dbus_message_iter_append_basic().
1537 * @return 1 on success, 0 otherwise.
1540 e_connman_element_property_set(E_Connman_Element *element, const char *prop, int type, const void *value)
1542 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1543 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1544 return e_connman_element_property_set_full
1545 (element, prop, type, value, NULL, NULL);
1549 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)
1551 DBusMessageIter itr;
1554 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1555 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1556 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1557 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1559 msg = dbus_message_new_method_call
1560 (e_connman_system_bus_name_get(), element->path, element->interface,
1566 dbus_message_iter_init_append(msg, &itr);
1567 dbus_message_iter_append_basic(&itr, DBUS_TYPE_OBJECT_PATH, &string);
1569 return e_connman_element_message_send
1570 (element, method_name, cb, msg, pending, user_cb, user_data);
1574 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)
1576 DBusMessageIter itr;
1579 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1580 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1581 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1582 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1584 msg = dbus_message_new_method_call
1585 (e_connman_system_bus_name_get(), element->path, element->interface,
1591 dbus_message_iter_init_append(msg, &itr);
1592 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &string);
1594 return e_connman_element_message_send
1595 (element, method_name, cb, msg, pending, user_cb, user_data);
1599 * Get property type.
1601 * If zero is returned, then this call failed and parameter-returned
1602 * values shall be considered invalid.
1604 * @param element which element to get the property
1605 * @param name property name, must be previously stringshared
1606 * @param type will contain the value type.
1608 * @return 1 on success, 0 otherwise.
1611 e_connman_element_property_type_get_stringshared(const E_Connman_Element *element, const char *name, int *type)
1613 const E_Connman_Element_Property *p;
1615 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1616 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1617 EINA_SAFETY_ON_NULL_RETURN_VAL(type, 0);
1619 EINA_INLIST_FOREACH(element->props, p)
1621 if (p->name == name)
1628 WRN("element %s (%p) has no property with name \"%s\".",
1629 element->path, element, name);
1634 * Get property type.
1636 * If zero is returned, then this call failed and parameter-returned
1637 * values shall be considered invalid.
1639 * @param element which element to get the property
1640 * @param name property name
1641 * @param type will contain the value type.
1643 * @return 1 on success, 0 otherwise.
1646 e_connman_element_property_type_get(const E_Connman_Element *element, const char *name, int *type)
1649 name = eina_stringshare_add(name);
1650 ret = e_connman_element_property_type_get_stringshared(element, name, type);
1651 eina_stringshare_del(name);
1656 e_connman_element_list_properties(const E_Connman_Element *element, bool (*cb)(void *data, const E_Connman_Element *element, const char *name, int type, const void *value), const void *data)
1658 const E_Connman_Element_Property *p;
1660 EINA_SAFETY_ON_NULL_RETURN(element);
1661 EINA_SAFETY_ON_NULL_RETURN(cb);
1663 EINA_INLIST_FOREACH(element->props, p)
1665 const void *value = NULL;
1669 case DBUS_TYPE_STRING:
1670 value = &p->value.str;
1672 case DBUS_TYPE_OBJECT_PATH:
1673 value = &p->value.path;
1675 case DBUS_TYPE_BOOLEAN:
1676 value = (void *)p->value.boolean;
1678 case DBUS_TYPE_UINT16:
1679 value = &p->value.u16;
1681 case DBUS_TYPE_UINT32:
1682 value = &p->value.u32;
1685 ERR("unsupported type %c", p->type);
1688 if (!cb((void *)data, element, p->name, p->type, value))
1694 * Get dict value given its key inside a dict property.
1696 * This will look into properties for one of type dict that contains
1697 * the given key, to find the property. If no property is found then
1700 * If zero is returned, then this call failed and parameter-returned
1701 * values shall be considered invalid.
1703 * @param element which element to get the property
1704 * @param dict_name property name, must be previously stringshared
1705 * @param key key inside dict, must be previously stringshared
1706 * @param type if provided it will contain the value type.
1707 * @param value where to store the property value, must be a pointer to the
1708 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1710 * @return 1 on success, 0 otherwise.
1713 e_connman_element_property_dict_get_stringshared(const E_Connman_Element *element, const char *dict_name, const char *key, int *type, void *value)
1715 const E_Connman_Element_Property *p;
1717 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1718 EINA_SAFETY_ON_NULL_RETURN_VAL(dict_name, 0);
1719 EINA_SAFETY_ON_NULL_RETURN_VAL(key, 0);
1720 EINA_SAFETY_ON_NULL_RETURN_VAL(value, 0);
1722 EINA_INLIST_FOREACH(element->props, p)
1724 E_Connman_Element_Dict_Entry *entry;
1725 E_Connman_Array *array;
1727 if (p->name != dict_name)
1729 if (p->type != DBUS_TYPE_ARRAY)
1731 WRN("element %s (%p) has property \"%s\" is not an array: %c (%d)",
1732 element->path, element, dict_name, p->type, p->type);
1735 array = p->value.array;
1736 if ((!array) || (array->type != DBUS_TYPE_DICT_ENTRY))
1738 int t = array ? array->type : DBUS_TYPE_INVALID;
1739 WRN("element %s (%p) has property \"%s\" is not a dict: %c (%d)",
1740 element->path, element, dict_name, t, t);
1743 entry = _e_connman_element_array_dict_find_stringshared(array, key);
1746 WRN("element %s (%p) has no dict property with name \"%s\" with "
1748 element->path, element, dict_name, key);
1752 if (type) *type = entry->type;
1754 switch (entry->type)
1756 case DBUS_TYPE_BOOLEAN:
1757 *(bool *)value = entry->value.boolean;
1759 case DBUS_TYPE_BYTE:
1760 *(unsigned char *)value = entry->value.byte;
1762 case DBUS_TYPE_UINT16:
1763 *(unsigned short *)value = entry->value.u16;
1765 case DBUS_TYPE_UINT32:
1766 *(unsigned int *)value = entry->value.u32;
1768 case DBUS_TYPE_STRING:
1769 *(const char **)value = entry->value.str;
1771 case DBUS_TYPE_OBJECT_PATH:
1772 *(const char **)value = entry->value.path;
1775 ERR("don't know how to get property %s, key %s type %c (%d)",
1776 dict_name, key, entry->type, entry->type);
1781 WRN("element %s (%p) has no property with name \"%s\".",
1782 element->path, element, dict_name);
1787 * Get property value given its name.
1789 * This will look into properties, to find the property.
1790 * If no property is found then 0 is returned.
1792 * If zero is returned, then this call failed and parameter-returned
1793 * values shall be considered invalid.
1795 * @param element which element to get the property
1796 * @param name property name, must be previously stringshared
1797 * @param type if provided it will contain the value type.
1798 * @param value where to store the property value, must be a pointer to the
1799 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1801 * @return 1 on success, 0 otherwise.
1804 e_connman_element_property_get_stringshared(const E_Connman_Element *element, const char *name, int *type, void *value)
1806 const E_Connman_Element_Property *p;
1808 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1809 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1810 EINA_SAFETY_ON_NULL_RETURN_VAL(value, 0);
1812 EINA_INLIST_FOREACH(element->props, p)
1814 if (p->name != name)
1817 if (type) *type = p->type;
1821 case DBUS_TYPE_BOOLEAN:
1822 *(bool *)value = p->value.boolean;
1824 case DBUS_TYPE_BYTE:
1825 *(unsigned char *)value = p->value.byte;
1827 case DBUS_TYPE_UINT16:
1828 *(unsigned short *)value = p->value.u16;
1830 case DBUS_TYPE_UINT32:
1831 *(unsigned int *)value = p->value.u32;
1833 case DBUS_TYPE_STRING:
1834 *(const char **)value = p->value.str;
1836 case DBUS_TYPE_OBJECT_PATH:
1837 *(const char **)value = p->value.path;
1839 case DBUS_TYPE_ARRAY:
1840 *(E_Connman_Array **)value = p->value.array;
1843 ERR("don't know how to get property type %c (%d)",
1849 WRN("element %s (%p) has no property with name \"%s\".",
1850 element->path, element, name);
1855 * Get property value given its name.
1857 * This will look into properties, to find the property.
1858 * If no property is found then 0 is returned.
1860 * If zero is returned, then this call failed and parameter-returned
1861 * values shall be considered invalid.
1863 * @param element which element to get the property
1864 * @param name property name
1865 * @param type if provided it will contain the value type.
1866 * @param value where to store the property value, must be a pointer to the
1867 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1869 * @return 1 on success, 0 otherwise.
1872 e_connman_element_property_get(const E_Connman_Element *element, const char *name, int *type, void *value)
1875 name = eina_stringshare_add(name);
1876 ret = e_connman_element_property_get_stringshared
1877 (element, name, type, value);
1878 eina_stringshare_del(name);
1883 struct e_connman_elements_for_each_data
1885 Eina_Hash_Foreach cb;
1890 _e_connman_elements_for_each(Eina_Hash *hash __UNUSED__, const char *key, void *data, void *fdata)
1892 struct e_connman_elements_for_each_data *each_data = fdata;
1894 each_data->cb(elements, key, data, each_data->data);
1899 * Call the given function for each existing element.
1901 * @param cb function to call for each element. It will get as parameters,
1902 * in order: the element pointer and the given @a user_data.
1903 * @param user_data data to give to @a cb for each element.
1906 e_connman_elements_for_each(Eina_Hash_Foreach cb, const void *user_data)
1908 struct e_connman_elements_for_each_data data = {cb, (void *)user_data};
1910 EINA_SAFETY_ON_NULL_RETURN(cb);
1912 eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_connman_elements_for_each,
1917 _e_connman_elements_get_allocate(unsigned int *count, E_Connman_Element ***p_elements)
1919 *count = eina_hash_population(elements);
1926 *p_elements = malloc(*count * sizeof(E_Connman_Element *));
1929 ERR("could not allocate return array of %d elements: %s",
1930 *count, strerror(errno));
1938 _e_connman_elements_get_all(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *data, void *fdata)
1940 E_Connman_Element *element = data;
1941 E_Connman_Element ***p_ret = fdata;
1949 * Get all known elements.
1951 * No reference is added to these elements, since there are no threads
1952 * in the system, you are free to add references yourself right after
1953 * the return of this call without race condition, elements by the
1954 * system (ie: elementRemoved signal)could only be touched on the next
1955 * main loop iteration.
1957 * @param count return the number of elements in array.
1958 * @param p_elements array with all elements, these are not referenced
1959 * and in no particular order, just set if return is 1.
1961 * @return 1 on success, 0 otherwise.
1964 e_connman_elements_get_all(unsigned int *count, E_Connman_Element ***p_elements)
1966 E_Connman_Element **p;
1968 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
1969 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
1971 if (!_e_connman_elements_get_allocate(count, p_elements))
1974 eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_connman_elements_get_all,
1979 struct e_connman_elements_get_all_str_data
1981 E_Connman_Element **elements;
1987 _e_connman_elements_get_all_type(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *e, void *user_data)
1989 struct e_connman_elements_get_all_str_data *data = user_data;
1990 E_Connman_Element *element = e;
1992 if ((data->str) && (element->interface != data->str))
1995 data->elements[data->count] = element;
2001 * Get all known elements of type.
2003 * No reference is added to these elements, since there are no threads
2004 * in the system, you are free to add references yourself right after
2005 * the return of this call without race condition, elements by the
2006 * system (ie: ElementRemoved signal) could only be touched on the next
2007 * main loop iteration.
2009 * @param type type to filter, or NULL to get all.
2010 * @param count return the number of elements in array.
2011 * @param p_elements array with all elements, these are not referenced
2012 * and in no particular order, just set if return is 1.
2014 * @return 1 on success, 0 otherwise.
2016 * @see e_connman_elements_get_all()
2019 e_connman_elements_get_all_type(const char *type, unsigned int *count, E_Connman_Element ***p_elements)
2021 struct e_connman_elements_get_all_str_data data;
2023 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
2024 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
2026 if (!_e_connman_elements_get_allocate(count, p_elements))
2029 data.elements = *p_elements;
2031 data.str = eina_stringshare_add(type);
2032 eina_hash_foreach(elements,
2033 (Eina_Hash_Foreach) _e_connman_elements_get_all_type,
2036 eina_stringshare_del(data.str);
2037 *count = data.count;
2042 * Get the element registered at given path.
2044 * @param path the path to query for registered object.
2046 * @return element pointer if found, NULL otherwise. No references are added.
2049 e_connman_element_get(const char *path)
2051 E_Connman_Element *element;
2053 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2054 element = eina_hash_find(elements, path);
2060 _e_connman_element_property_changed_callback(void *data, DBusMessage *msg)
2062 E_Connman_Element *element = (E_Connman_Element *)data;
2063 DBusMessageIter itr, v_itr;
2064 int t, r, changed = 0;
2065 const char *name = NULL;
2068 DBG("Property changed in element %s", element->path);
2070 if (!_dbus_callback_check_and_init(msg, &itr, NULL))
2073 t = dbus_message_iter_get_arg_type(&itr);
2074 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
2076 ERR("missing name in property changed signal");
2079 dbus_message_iter_get_basic(&itr, &name);
2081 dbus_message_iter_next(&itr);
2082 t = dbus_message_iter_get_arg_type(&itr);
2083 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
2085 ERR("missing value in property changed signal");
2088 dbus_message_iter_recurse(&itr, &v_itr);
2089 t = dbus_message_iter_get_arg_type(&v_itr);
2091 if (t == DBUS_TYPE_ARRAY)
2092 value = _e_connman_element_iter_get_array(&v_itr, name);
2093 else if (t != DBUS_TYPE_INVALID)
2094 dbus_message_iter_get_basic(&v_itr, &value);
2097 ERR("property has invalid type %s", name);
2101 r = _e_connman_element_property_value_add(element, name, t, value);
2103 ERR("failed to add property value %s (%c)", name, t);
2106 INF("property value changed %s (%c)", name, t);
2110 _e_connman_element_listeners_call(element);
2114 * Register the given path, possible creating and element and return it.
2116 * This will check if path is already registered, in that case the
2117 * exiting element is returned. If it was not registered yet, a new
2118 * element is created, registered and returned.
2120 * This call will not add extra references to the object.
2122 * @param path the path to register the element
2124 * @return the registered object, no references are added.
2127 e_connman_element_register(const char *path, const char *interface)
2129 E_Connman_Element *element;
2131 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2132 EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
2134 element = eina_hash_find(elements, path);
2138 element = e_connman_element_new(path, interface);
2142 if (!eina_hash_add(elements, element->path, element))
2144 ERR("could not add element %s to hash, delete it.", path);
2145 e_connman_element_free(element);
2149 element->signal_handler =
2150 e_dbus_signal_handler_add
2151 (e_connman_conn, e_connman_system_bus_name_get(),
2152 element->path, element->interface, "PropertyChanged",
2153 _e_connman_element_property_changed_callback, element);
2155 e_connman_element_event_add(E_CONNMAN_EVENT_ELEMENT_ADD, element);
2161 _e_connman_element_event_unregister_and_free(void *data __UNUSED__, void *ev)
2163 E_Connman_Element *element = ev;
2164 e_connman_element_unref(element);
2168 _e_connman_element_unregister_internal(E_Connman_Element *element)
2170 if (element->signal_handler)
2172 e_dbus_signal_handler_del(e_connman_conn, element->signal_handler);
2173 element->signal_handler = NULL;
2176 ecore_event_add(E_CONNMAN_EVENT_ELEMENT_DEL, element,
2177 _e_connman_element_event_unregister_and_free, NULL);
2181 * Forget about the given element.
2183 * This will remove the element from the pool of known objects, then
2184 * add an E_CONNMAN_EVENT_ELEMENT_DEL and after that will unreference it,
2185 * possible freeing it.
2187 * @param element element to forget about. Its reference will be removed.
2190 e_connman_element_unregister(E_Connman_Element *element)
2196 eina_hash_del_by_key(elements, element->path);
2200 * Remove all known elements.
2202 * This will remove all known elements but will NOT add any
2203 * E_CONNMAN_EVENT_ELEMENT_DEL to main loop.
2205 * This is just useful to make sure next e_connman_manager_sync_elements()
2206 * will not leave any stale elements. This is unlikely to happen, as
2207 * E_Connman is supposed to catch all required events to avoid stale elements.
2210 e_connman_manager_clear_elements(void)
2212 e_connman_elements_shutdown();
2213 e_connman_elements_init();
2217 * Creates elements hash.
2219 * This has no init counter since its already guarded by other code.
2223 e_connman_elements_init(void)
2225 EINA_SAFETY_ON_FALSE_RETURN(elements == NULL);
2227 eina_hash_string_superfast_new(EINA_FREE_CB
2228 (_e_connman_element_unregister_internal));
2232 e_connman_elements_shutdown(void)
2234 EINA_SAFETY_ON_FALSE_RETURN(elements != NULL);
2235 eina_hash_free(elements);
2240 _e_connman_element_is(const E_Connman_Element *element, const char *interface)
2242 return element->interface == interface;
2246 e_connman_element_is_manager(const E_Connman_Element *element)
2248 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
2249 return _e_connman_element_is(element, e_connman_iface_manager);
2253 e_connman_element_is_device(const E_Connman_Element *element)
2255 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
2256 return _e_connman_element_is(element, e_connman_iface_device);
2260 e_connman_element_is_profile(const E_Connman_Element *element)
2262 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
2263 return _e_connman_element_is(element, e_connman_iface_profile);
2267 e_connman_element_is_network(const E_Connman_Element *element)
2269 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
2270 return _e_connman_element_is(element, e_connman_iface_network);
2274 e_connman_element_is_service(const E_Connman_Element *element)
2276 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
2277 return _e_connman_element_is(element, e_connman_iface_service);