1 #include "e_ofono_private.h"
6 * Maximum size for elements hash key.
8 * The elements hash key is contructed by concatenating the object path and the
9 * interface for the element (with a colon separating the two strings). D-Bus
10 * interfaces have a maximum size of 255 but object paths have unlimited size.
11 * We're assuming a maximum key size of 4k here, but this might need to be
12 * increased if oFono object paths grows bigger than that.
14 #define MAX_KEY_SIZE 4096
15 static Eina_Hash *elements = NULL;
17 typedef struct _E_Ofono_Array E_Ofono_Array;
18 typedef struct _E_Ofono_Element_Pending E_Ofono_Element_Pending;
19 typedef struct _E_Ofono_Element_Call_Data E_Ofono_Element_Call_Data;
20 typedef struct _E_Ofono_Element_Property E_Ofono_Element_Property;
21 typedef struct _E_Ofono_Element_Listener E_Ofono_Element_Listener;
22 typedef struct _E_Ofono_Element_Dict_Entry E_Ofono_Element_Dict_Entry;
30 struct _E_Ofono_Element_Pending
33 DBusPendingCall *pending;
35 E_DBus_Method_Return_Cb user_cb;
39 struct _E_Ofono_Element_Call_Data
41 E_Ofono_Element *element;
42 E_DBus_Method_Return_Cb cb;
43 E_Ofono_Element_Pending *pending;
47 struct _E_Ofono_Element_Property
64 struct _E_Ofono_Element_Dict_Entry
78 struct _E_Ofono_Element_Listener
81 void (*cb)(void *data, const E_Ofono_Element *element);
83 void (*free_data)(void *data);
87 _e_ofono_element_event_no_free(void *data __UNUSED__, void *ev)
89 E_Ofono_Element *element = ev;
90 e_ofono_element_unref(element);
94 e_ofono_element_event_add(int event_type, E_Ofono_Element *element)
96 e_ofono_element_ref(element);
98 (event_type, element, _e_ofono_element_event_no_free, element);
102 e_ofono_element_call_dispatch_and_free(void *d, DBusMessage *msg, DBusError *err)
104 E_Ofono_Element_Call_Data *data = d;
105 E_Ofono_Element_Pending *pending;
107 pending = data->pending;
108 pending->pending = NULL;
111 data->cb(data->element, msg, err);
113 if (pending->user_cb)
114 pending->user_cb(pending->user_data, msg, err);
116 pending->data = NULL;
117 *data->p_list = eina_inlist_remove(*data->p_list, EINA_INLIST_GET(pending));
123 e_ofono_element_pending_cancel_and_free(Eina_Inlist **pending)
127 E_Ofono_Element_Pending *p = (E_Ofono_Element_Pending *)*pending;
130 dbus_pending_call_cancel(p->pending);
132 dbus_error_init(&err);
133 dbus_set_error(&err, "Canceled", "Pending method call was canceled.");
134 e_ofono_element_call_dispatch_and_free(p->data, NULL, &err);
135 dbus_error_free(&err);
140 e_ofono_element_listener_add(E_Ofono_Element *element, void (*cb)(void *data, const E_Ofono_Element *element), const void *data, void (*free_data)(void *data))
142 E_Ofono_Element_Listener *l;
146 ERR("safety check failed: element == NULL");
151 ERR("safety check failed: cb == NULL");
155 l = malloc(sizeof(*l));
158 ERR("could not allocate E_Ofono_Element_Listener");
163 l->data = (void *)data;
164 l->free_data = free_data;
166 element->_listeners = eina_inlist_append
167 (element->_listeners, EINA_INLIST_GET(l));
173 free_data((void *)data);
177 e_ofono_element_listener_del(E_Ofono_Element *element, void (*cb)(void *data, const E_Ofono_Element *element), const void *data)
179 E_Ofono_Element_Listener *l;
181 EINA_SAFETY_ON_NULL_RETURN(element);
182 EINA_SAFETY_ON_NULL_RETURN(cb);
184 EINA_INLIST_FOREACH(element->_listeners, l)
185 if ((l->cb == cb) && (l->data == data))
187 element->_listeners = eina_inlist_remove
188 (element->_listeners, EINA_INLIST_GET(l));
189 if (l->free_data) l->free_data(l->data);
196 _e_ofono_element_listeners_call_do(E_Ofono_Element *element)
198 E_Ofono_Element_Listener *l, **shadow;
199 unsigned int i, count;
201 /* NB: iterate on a copy in order to allow listeners to be deleted
202 * from callbacks. number of listeners should be small, so the
203 * following should do fine.
205 count = eina_inlist_count(element->_listeners);
209 shadow = alloca(sizeof(*shadow) * count);
214 EINA_INLIST_FOREACH(element->_listeners, l)
217 for (i = 0; i < count; i++)
218 shadow[i]->cb(shadow[i]->data, element);
221 e_ofono_element_event_add(E_OFONO_EVENT_ELEMENT_UPDATED, element);
225 _e_ofono_element_listeners_call_idler(void *data)
227 E_Ofono_Element *element = data;
228 _e_ofono_element_listeners_call_do(element);
229 element->_idler.changed = NULL;
234 _e_ofono_element_listeners_call(E_Ofono_Element *element)
236 if (element->_idler.changed)
238 element->_idler.changed = ecore_idler_add
239 (_e_ofono_element_listeners_call_idler, element);
242 /***********************************************************************
244 ***********************************************************************/
247 _e_ofono_element_dict_entry_free(E_Ofono_Element_Dict_Entry *entry)
251 case DBUS_TYPE_BOOLEAN:
253 case DBUS_TYPE_UINT16:
254 case DBUS_TYPE_UINT32:
256 case DBUS_TYPE_OBJECT_PATH:
257 eina_stringshare_del(entry->value.path);
259 case DBUS_TYPE_STRING:
260 eina_stringshare_del(entry->value.str);
263 ERR("don't know how to free dict entry '%s' of type %c (%d)",
264 entry->name, entry->type, entry->type);
267 eina_stringshare_del(entry->name);
271 static E_Ofono_Element_Dict_Entry *
272 _e_ofono_element_dict_entry_new(DBusMessageIter *itr)
274 E_Ofono_Element_Dict_Entry *entry;
275 DBusMessageIter e_itr, v_itr;
277 const char *key = NULL;
280 dbus_message_iter_recurse(itr, &e_itr);
282 t = dbus_message_iter_get_arg_type(&e_itr);
283 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
285 ERR("invalid format for dict entry. first type not a string: %c (%d)",
290 dbus_message_iter_get_basic(&e_itr, &key);
293 ERR("invalid format for dict entry. no key.");
297 dbus_message_iter_next(&e_itr);
298 t = dbus_message_iter_get_arg_type(&e_itr);
299 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
301 ERR("invalid format for dict entry '%s'. "
302 "second type not a variant: %c (%d)",
307 dbus_message_iter_recurse(&e_itr, &v_itr);
309 t = dbus_message_iter_get_arg_type(&v_itr);
310 if ((t == DBUS_TYPE_INVALID) || (t == DBUS_TYPE_ARRAY))
312 ERR("invalid type for dict value for entry '%s': %c (%d)",
317 entry = calloc(1, sizeof(*entry));
320 ERR("could not allocate memory for dict entry.");
324 dbus_message_iter_get_basic(&v_itr, &value);
327 case DBUS_TYPE_BOOLEAN:
328 entry->value.boolean = (bool)(long)value;
331 entry->value.byte = (unsigned char)(long)value;
333 case DBUS_TYPE_UINT16:
334 entry->value.u16 = (unsigned short)(long)value;
336 case DBUS_TYPE_UINT32:
337 entry->value.u32 = (unsigned int)(long)value;
339 case DBUS_TYPE_STRING:
340 entry->value.str = eina_stringshare_add(value);
342 case DBUS_TYPE_OBJECT_PATH:
343 entry->value.path = eina_stringshare_add(value);
346 ERR("don't know how to create dict entry '%s' for of type %c (%d)",
352 entry->name = eina_stringshare_add(key);
357 static E_Ofono_Element_Dict_Entry *
358 _e_ofono_element_array_dict_find_stringshared(const E_Ofono_Array *array, const char *key)
360 E_Ofono_Element_Dict_Entry *entry;
361 Eina_Array_Iterator iterator;
364 EINA_ARRAY_ITER_NEXT(array->array, i, entry, iterator)
365 if (entry->name == key)
372 _e_ofono_element_array_free(E_Ofono_Array *array, E_Ofono_Array *new __UNUSED__)
374 Eina_Array_Iterator iterator;
383 case DBUS_TYPE_BOOLEAN:
385 case DBUS_TYPE_UINT16:
386 case DBUS_TYPE_UINT32:
388 case DBUS_TYPE_OBJECT_PATH:
389 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
390 eina_stringshare_del(item);
392 case DBUS_TYPE_STRING:
393 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
394 eina_stringshare_del(item);
396 case DBUS_TYPE_DICT_ENTRY:
397 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
398 _e_ofono_element_dict_entry_free(item);
401 ERR("don't know how to free array of values of type %c (%d)",
402 array->type, array->type);
405 eina_array_free(array->array);
410 _e_ofono_element_property_value_free(E_Ofono_Element_Property *property)
412 switch (property->type)
416 case DBUS_TYPE_BOOLEAN:
418 case DBUS_TYPE_UINT16:
419 case DBUS_TYPE_UINT32:
421 case DBUS_TYPE_STRING:
422 eina_stringshare_del(property->value.str);
424 case DBUS_TYPE_OBJECT_PATH:
425 eina_stringshare_del(property->value.path);
427 case DBUS_TYPE_ARRAY:
428 _e_ofono_element_array_free(property->value.array, NULL);
431 ERR("don't know how to free value of property type %c (%d)",
432 property->type, property->type);
437 _e_ofono_element_get_interface(const char *key)
439 const char *interface = NULL, *tail;
452 ERR("failed to find interface for property \"%s\"", key);
458 _e_ofono_element_item_register(const char *key, const char *item)
460 E_Ofono_Element *element;
461 const char *interface;
463 interface = _e_ofono_element_get_interface(key);
466 element = e_ofono_element_register(item, interface);
467 if ((element) && (!e_ofono_element_properties_sync(element)))
468 WRN("could not get properties of %s", element->path);
471 /* Match 2 arrays to find which are new and which are old elements
472 * For new elements, register them under prop_name property
473 * For old elements, unregister them, sending proper DEL event
476 _e_ofono_element_array_match(E_Ofono_Array *old, E_Ofono_Array *new, const char *prop_name)
478 Eina_List *deleted = NULL;
479 Eina_Array_Iterator iter_old, iter_new;
480 unsigned int i_old = 0, i_new = 0;
481 void *item_old, *item_new;
487 if (old->type != DBUS_TYPE_OBJECT_PATH)
490 if ((!new) || (!new->array) || eina_array_count_get(new->array) == 0)
492 if ((!old) || (!old->array) || eina_array_count_get(old->array) == 0)
496 iter_old = old->array->data;
497 goto out_remove_remaining;
501 iter_new = new->array->data;
502 item_new = *iter_new;
503 EINA_ARRAY_ITER_NEXT(old->array, i_old, item_old, iter_old)
505 if (item_old == item_new)
508 if (i_new >= eina_array_count_get(new->array))
515 item_new = *iter_new;
518 deleted = eina_list_append(deleted, item_old);
521 for(; i_new < eina_array_count_get(new->array); iter_new++, i_new++)
524 item_new = *iter_new;
528 EINA_LIST_FOREACH(deleted, l, data)
530 if (data == item_new)
532 deleted = eina_list_remove_list(deleted, l);
539 _e_ofono_element_item_register(prop_name, item_new);
540 DBG("Add element %s\n", (const char *) item_new);
544 /* everybody after i_old on old->array + everybody from deleted list
547 EINA_LIST_FREE(deleted, data)
549 E_Ofono_Element *e = e_ofono_element_get(data, prop_name);
551 e_ofono_element_unregister(e);
552 DBG("Delete element %s\n", (const char *) data);
555 out_remove_remaining:
556 for(; i_old < eina_array_count_get(old->array); iter_old++, i_old++)
559 item_old = *iter_old;
563 e = e_ofono_element_get(item_old,
564 _e_ofono_element_get_interface(prop_name));
566 e_ofono_element_unregister(e);
567 DBG("Delete element %s\n", (const char *) item_old);
572 _e_ofono_element_property_update(E_Ofono_Element_Property *property, int type, void *data)
576 if ((type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) && data)
577 data = (char *)eina_stringshare_add(data);
579 if (property->type != type)
582 DBG("property type changed from '%c' to '%c'",
583 property->type, type);
584 _e_ofono_element_property_value_free(property);
585 memset(&property->value, 0, sizeof(property->value));
586 property->type = type;
592 case DBUS_TYPE_BOOLEAN:
593 if (changed || property->value.boolean != (bool)(long)data)
595 property->value.boolean = (bool)(long)data;
600 if (changed || property->value.byte != (unsigned char)(long)data)
602 property->value.byte = (unsigned char)(long)data;
606 case DBUS_TYPE_UINT16:
607 if (changed || property->value.u16 != (unsigned short)(long)data)
609 property->value.u16 = (unsigned short)(long)data;
613 case DBUS_TYPE_UINT32:
614 if (changed || property->value.u32 != (unsigned int)(long)data)
616 property->value.u32 = (unsigned int)(long)data;
620 case DBUS_TYPE_STRING:
622 property->value.str = data;
625 if (property->value.str)
626 eina_stringshare_del(property->value.str);
627 if (property->value.str != data)
629 property->value.str = data;
634 case DBUS_TYPE_OBJECT_PATH:
636 property->value.path = data;
639 if (property->value.path)
640 eina_stringshare_del(property->value.path);
641 if (property->value.path != data)
643 property->value.path = data;
648 case DBUS_TYPE_ARRAY:
650 if (property->value.array)
652 _e_ofono_element_array_match(property->value.array, data, property->name);
653 _e_ofono_element_array_free(property->value.array, data);
655 property->value.array = data;
659 ERR("don't know how to update property type %c (%d)", type, type);
665 static E_Ofono_Element_Property *
666 _e_ofono_element_property_new(const char *name, int type, void *data)
668 E_Ofono_Element_Property *property;
670 property = calloc(1, sizeof(*property));
673 eina_stringshare_del(name);
674 ERR("could not allocate property: %s", strerror(errno));
678 property->name = name;
679 _e_ofono_element_property_update(property, type, data);
684 _e_ofono_element_property_free(E_Ofono_Element_Property *property)
686 _e_ofono_element_property_value_free(property);
687 eina_stringshare_del(property->name);
691 /***********************************************************************
693 ***********************************************************************/
695 e_ofono_element_bytes_array_get_stringshared(const E_Ofono_Element *element, const char *property, unsigned int *count)
697 Eina_Array_Iterator iterator;
698 E_Ofono_Array *array;
699 unsigned char *ret, *p;
703 EINA_SAFETY_ON_NULL_RETURN_VAL(element, NULL);
704 EINA_SAFETY_ON_NULL_RETURN_VAL(property, NULL);
705 EINA_SAFETY_ON_NULL_RETURN_VAL(count, NULL);
709 if (!e_ofono_element_property_get_stringshared
710 (element, property, NULL, &array))
713 if ((!array) || (!(array->array)))
716 *count = eina_array_count_get(array->array);
717 ret = malloc(*count * sizeof(unsigned char));
720 ERR("could not allocate return array of %d bytes: %s",
721 *count, strerror(errno));
726 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
728 *p = (unsigned char)(long)item;
735 e_ofono_element_objects_array_get_stringshared(const E_Ofono_Element *element, const char *property, unsigned int *count, E_Ofono_Element ***elements)
737 E_Ofono_Element **ret, **p;
738 Eina_Array_Iterator iterator;
739 E_Ofono_Array *array;
744 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
745 EINA_SAFETY_ON_NULL_RETURN_VAL(property, 0);
746 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
747 EINA_SAFETY_ON_NULL_RETURN_VAL(elements, 0);
752 if (!e_ofono_element_property_get_stringshared
753 (element, property, &type, &array))
756 if (type != DBUS_TYPE_ARRAY)
758 ERR("property %s is not an array!", property);
762 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
765 if (array->type != DBUS_TYPE_OBJECT_PATH)
767 ERR("property %s is not an array of object paths!", property);
771 *count = eina_array_count_get(array->array);
772 ret = malloc(*count * sizeof(E_Ofono_Element *));
775 ERR("could not allocate return array of %d elements: %s",
776 *count, strerror(errno));
782 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
784 E_Ofono_Element *e = e_ofono_element_get(item, property);
795 /* strings are just pointers (references), no strdup or stringshare_add/ref */
797 e_ofono_element_strings_array_get_stringshared(const E_Ofono_Element *element, const char *property, unsigned int *count, const char ***strings)
799 const char **ret, **p;
800 Eina_Array_Iterator iterator;
801 E_Ofono_Array *array;
806 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
807 EINA_SAFETY_ON_NULL_RETURN_VAL(property, 0);
808 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
809 EINA_SAFETY_ON_NULL_RETURN_VAL(strings, 0);
814 if (!e_ofono_element_property_get_stringshared
815 (element, property, &type, &array))
818 if (type != DBUS_TYPE_ARRAY)
820 ERR("property %s is not an array!", property);
824 if ((!array) || (!array->array) || (array->type == DBUS_TYPE_INVALID))
827 if (array->type != DBUS_TYPE_STRING)
829 ERR("property %s is not an array of strings!", property);
833 *count = eina_array_count_get(array->array);
834 ret = malloc(*count * sizeof(char *));
837 ERR("could not allocate return array of %d strings: %s",
838 *count, strerror(errno));
844 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
857 _e_ofono_element_array_print(FILE *fp, E_Ofono_Array *array)
859 Eina_Array_Iterator iterator;
868 case DBUS_TYPE_OBJECT_PATH:
869 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
870 fprintf(fp, "\"%s\", ", (const char *)item);
872 case DBUS_TYPE_STRING:
873 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
874 fprintf(fp, "\"%s\", ", (const char *)item);
877 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
878 fprintf(fp, "%#02hhx (\"%c\"), ", (unsigned char)(long)item,
879 (unsigned char)(long)item);
881 case DBUS_TYPE_UINT16:
882 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
883 fprintf(fp, "%#04hx (%hu), ", (unsigned short)(long)item,
884 (unsigned short)(long)item);
886 case DBUS_TYPE_UINT32:
887 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
888 fprintf(fp, "%#08x (%u), ", (unsigned int)(long)item,
889 (unsigned int)(long)item);
891 case DBUS_TYPE_DICT_ENTRY:
893 EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
895 E_Ofono_Element_Dict_Entry *entry = item;
896 fprintf(fp, "%s: ", entry->name);
899 case DBUS_TYPE_OBJECT_PATH:
900 fprintf(fp, "\"%s\", ", entry->value.path);
902 case DBUS_TYPE_STRING:
903 fprintf(fp, "\"%s\", ", entry->value.str);
906 fprintf(fp, "%#02hhx (\"%c\"), ",
907 entry->value.byte, entry->value.byte);
909 case DBUS_TYPE_UINT16:
910 fprintf(fp, "%#04hx (%hu), ",
911 entry->value.u16, entry->value.u16);
913 case DBUS_TYPE_UINT32:
914 fprintf(fp, "%#08x (%u), ",
915 entry->value.u32, entry->value.u32);
918 fprintf(fp, "<UNKNOWN TYPE '%c'>", entry->type);
924 fprintf(fp, "<UNKNOWN ARRAY TYPE '%c'>", array->type);
929 * Print element to file descriptor.
932 e_ofono_element_print(FILE *fp, const E_Ofono_Element *element)
934 const E_Ofono_Element_Property *p;
936 EINA_SAFETY_ON_NULL_RETURN(fp);
939 fputs("Error: no element to print\n", fp);
944 "Element %p: %s [%s]\n"
946 element, element->path, element->interface);
948 EINA_INLIST_FOREACH(element->props, p)
950 fprintf(fp, "\t\t%s (%c) = ", p->name, p->type);
954 case DBUS_TYPE_STRING:
955 fprintf(fp, "\"%s\"", p->value.str);
957 case DBUS_TYPE_OBJECT_PATH:
958 fprintf(fp, "\"%s\"", p->value.path);
960 case DBUS_TYPE_BOOLEAN:
961 fprintf(fp, "%hhu", p->value.boolean);
964 fprintf(fp, "%#02hhx (%d), ", p->value.byte, p->value.byte);
966 case DBUS_TYPE_UINT16:
967 fprintf(fp, "%hu", p->value.u16);
969 case DBUS_TYPE_UINT32:
970 fprintf(fp, "%u", p->value.u32);
972 case DBUS_TYPE_ARRAY:
973 _e_ofono_element_array_print(fp, p->value.array);
976 fputs("don't know how to print type", fp);
983 static E_Ofono_Element *
984 e_ofono_element_new(const char *path, const char *interface)
986 E_Ofono_Element *element;
988 element = calloc(1, sizeof(*element));
991 ERR("could not allocate element: %s", strerror(errno));
995 element->path = eina_stringshare_add(path);
996 element->interface = eina_stringshare_ref(interface);
997 element->_references = 1;
1003 e_ofono_element_extra_properties_free(E_Ofono_Element *element)
1005 while (element->props)
1007 E_Ofono_Element_Property *prop;
1008 prop = (E_Ofono_Element_Property *)element->props;
1009 element->props = element->props->next;
1010 _e_ofono_element_property_free(prop);
1015 e_ofono_element_free(E_Ofono_Element *element)
1017 if (element->_idler.changed)
1018 ecore_idler_del(element->_idler.changed);
1020 while (element->_listeners)
1022 E_Ofono_Element_Listener *l = (void *)element->_listeners;
1023 element->_listeners = eina_inlist_remove
1024 (element->_listeners, element->_listeners);
1026 if (l->free_data) l->free_data(l->data);
1030 e_ofono_element_pending_cancel_and_free(&element->_pending.properties_get);
1031 e_ofono_element_pending_cancel_and_free(&element->_pending.property_set);
1032 e_ofono_element_pending_cancel_and_free(&element->_pending.agent_register);
1033 e_ofono_element_pending_cancel_and_free(&element->_pending.agent_unregister);
1035 e_ofono_element_extra_properties_free(element);
1036 eina_stringshare_del(element->interface);
1037 eina_stringshare_del(element->path);
1042 * Add reference to element.
1045 e_ofono_element_ref(E_Ofono_Element *element)
1047 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1048 return ++element->_references;
1052 * Remove reference from element.
1054 * If reference count drops to 0 element will be freed.
1057 e_ofono_element_unref(E_Ofono_Element *element)
1060 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1062 i = --element->_references;
1064 e_ofono_element_free(element);
1066 ERR("element %p references %d < 0", element, i);
1071 * Send message with callbacks set to work with ofono elements.
1073 * If this call fails (returns 0), pending callbacks will not be called,
1074 * not even with error messages.
1076 * @return 1 on success, 0 on failure.
1079 e_ofono_element_message_send(E_Ofono_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)
1081 E_Ofono_Element_Call_Data *data;
1082 E_Ofono_Element_Pending *p;
1084 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1085 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1086 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1087 EINA_SAFETY_ON_NULL_RETURN_VAL(msg, 0);
1089 data = malloc(sizeof(*data));
1092 ERR("could not alloc e_ofono_element_call_data: %s",
1094 dbus_message_unref(msg);
1098 p = malloc(sizeof(*p));
1101 ERR("could not alloc E_Ofono_Element_Pending: %s",
1104 dbus_message_unref(msg);
1108 data->element = element;
1111 data->p_list = pending;
1112 p->user_cb = user_cb;
1113 p->user_data = (void *)user_data;
1115 p->pending = e_dbus_message_send
1116 (e_ofono_conn, msg, e_ofono_element_call_dispatch_and_free, -1, data);
1117 dbus_message_unref(msg);
1121 *pending = eina_inlist_append(*pending, EINA_INLIST_GET(p));
1126 ERR("failed to call %s (obj=%s, path=%s, iface=%s)",
1127 method_name, e_ofono_system_bus_name_get(),
1128 element->path, element->interface);
1136 e_ofono_element_call_full(E_Ofono_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)
1140 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1141 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1142 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1144 msg = dbus_message_new_method_call
1145 (e_ofono_system_bus_name_get(), element->path, element->interface,
1148 return e_ofono_element_message_send
1149 (element, method_name, cb, msg, pending, user_cb, user_data);
1153 _e_ofono_element_property_value_add(E_Ofono_Element *element, const char *name, int type, void *value)
1155 E_Ofono_Element_Property *p;
1157 name = eina_stringshare_add(name);
1158 EINA_INLIST_FOREACH(element->props, p)
1160 if (p->name == name)
1162 eina_stringshare_del(name);
1163 return _e_ofono_element_property_update(p, type, value);
1167 p = _e_ofono_element_property_new(name, type, value);
1170 ERR("could not create property %s (%c)", name, type);
1174 element->props = eina_inlist_append(element->props, EINA_INLIST_GET(p));
1178 static E_Ofono_Array *
1179 _e_ofono_element_iter_get_array(DBusMessageIter *itr, const char *key)
1181 E_Ofono_Array *array;
1182 DBusMessageIter e_itr;
1184 array = malloc(sizeof(E_Ofono_Array));
1187 ERR("could not create new e_ofono array.");
1190 array->array = eina_array_new(16);
1191 if (!(array->array))
1193 ERR("could not create new eina array.");
1198 dbus_message_iter_recurse(itr, &e_itr);
1199 array->type = dbus_message_iter_get_arg_type(&e_itr);
1200 if (array->type == DBUS_TYPE_INVALID)
1202 DBG("array %s is of type 'invalid' (empty?)", key);
1203 eina_array_free(array->array);
1210 switch (array->type)
1212 case DBUS_TYPE_OBJECT_PATH:
1216 dbus_message_iter_get_basic(&e_itr, &path);
1217 path = eina_stringshare_add(path);
1218 eina_array_push(array->array, path);
1219 _e_ofono_element_item_register(key, path);
1222 case DBUS_TYPE_STRING:
1226 dbus_message_iter_get_basic(&e_itr, &str);
1227 str = eina_stringshare_add(str);
1228 eina_array_push(array->array, str);
1231 case DBUS_TYPE_BYTE:
1234 dbus_message_iter_get_basic(&e_itr, &byte);
1235 eina_array_push(array->array, (void *)(long)byte);
1238 case DBUS_TYPE_DICT_ENTRY:
1240 E_Ofono_Element_Dict_Entry *entry;
1241 entry = _e_ofono_element_dict_entry_new(&e_itr);
1243 eina_array_push(array->array, entry);
1247 ERR("don't know how to build array '%s' of type %c (%d)",
1248 key, array->type, array->type);
1249 eina_array_free(array->array);
1254 while (dbus_message_iter_next(&e_itr));
1259 _e_ofono_element_get_properties_callback(void *user_data, DBusMessage *msg, DBusError *err)
1261 E_Ofono_Element *element = user_data;
1262 DBusMessageIter itr, s_itr;
1265 DBG("get_properties msg=%p", msg);
1267 if (!_dbus_callback_check_and_init(msg, &itr, err))
1270 t = dbus_message_iter_get_arg_type(&itr);
1271 if (!_dbus_iter_type_check(t, DBUS_TYPE_ARRAY))
1275 dbus_message_iter_recurse(&itr, &s_itr);
1278 DBusMessageIter e_itr, v_itr;
1283 t = dbus_message_iter_get_arg_type(&s_itr);
1284 if (!_dbus_iter_type_check(t, DBUS_TYPE_DICT_ENTRY))
1287 dbus_message_iter_recurse(&s_itr, &e_itr);
1289 t = dbus_message_iter_get_arg_type(&e_itr);
1290 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
1293 dbus_message_iter_get_basic(&e_itr, &key);
1294 dbus_message_iter_next(&e_itr);
1295 t = dbus_message_iter_get_arg_type(&e_itr);
1296 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
1299 dbus_message_iter_recurse(&e_itr, &v_itr);
1300 t = dbus_message_iter_get_arg_type(&v_itr);
1301 if (t == DBUS_TYPE_ARRAY)
1302 value = _e_ofono_element_iter_get_array(&v_itr, key);
1303 else if (t != DBUS_TYPE_INVALID) {
1304 dbus_message_iter_get_basic(&v_itr, &value);
1306 ERR("property has invalid type %s", key);
1310 r = _e_ofono_element_property_value_add(element, key, t, value);
1312 ERR("failed to add property value %s (%c)", key, t);
1315 INF("property value changed %s (%c)", key, t);
1319 while (dbus_message_iter_next(&s_itr));
1322 _e_ofono_element_listeners_call(element);
1326 * Sync element properties with server.
1328 * Call method GetProperties() at the given element on server in order to sync
1331 * @param element to call method on server.
1332 * @param cb function to call when server replies or some error happens.
1333 * @param data data to give to cb when it is called.
1335 * @return 1 on success, 0 otherwise.
1338 e_ofono_element_sync_properties_full(E_Ofono_Element *element, E_DBus_Method_Return_Cb cb, const void *data)
1340 const char name[] = "GetProperties";
1342 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1343 return e_ofono_element_call_full
1344 (element, name, _e_ofono_element_get_properties_callback,
1345 &element->_pending.properties_get, cb, data);
1349 * Sync element properties with server, simple version.
1351 * Call method GetProperties() at the given element on server in order to sync
1352 * them. This is the simple version and there is no check of server reply
1355 * @param element to call method on server.
1357 * @return 1 on success, 0 otherwise.
1360 e_ofono_element_properties_sync(E_Ofono_Element *element)
1362 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1363 return e_ofono_element_sync_properties_full(element, NULL, NULL);
1367 * Call method SetProperty(prop, {key: value}) at the given element on server.
1369 * This is a server call, not local, so it may fail and in that case
1370 * no property is updated locally. If the value was set the event
1371 * E_OFONO_EVENT_ELEMENT_UPDATED will be added to main loop.
1373 * @param element to call method on server.
1374 * @param prop property name.
1375 * @param key dict key name.
1376 * @param type DBus type to use for value.
1377 * @param value pointer to value, just like regular DBus, see
1378 * dbus_message_iter_append_basic().
1379 * @param cb function to call when server replies or some error happens.
1380 * @param data data to give to cb when it is called.
1382 * @return 1 on success, 0 otherwise.
1385 e_ofono_element_property_dict_set_full(E_Ofono_Element *element, const char *prop, const char *key, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
1387 const char name[] = "SetProperty";
1389 DBusMessageIter itr, variant, dict, entry;
1392 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1393 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1395 msg = dbus_message_new_method_call
1396 (e_ofono_system_bus_name_get(), element->path, element->interface, name);
1401 dbus_message_iter_init_append(msg, &itr);
1402 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1404 if ((size_t)snprintf(typestr, sizeof(typestr),
1405 (DBUS_TYPE_ARRAY_AS_STRING
1406 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1407 DBUS_TYPE_STRING_AS_STRING
1409 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1410 type) >= sizeof(typestr))
1412 ERR("sizeof(typestr) is too small!");
1416 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &variant);
1418 snprintf(typestr, sizeof(typestr),
1419 (DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1420 DBUS_TYPE_STRING_AS_STRING
1422 DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
1425 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, typestr, &dict);
1426 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
1428 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1430 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1431 dbus_message_iter_append_basic(&entry, type, &value);
1433 dbus_message_iter_append_basic(&entry, type, value);
1435 dbus_message_iter_close_container(&dict, &entry);
1436 dbus_message_iter_close_container(&variant, &dict);
1437 dbus_message_iter_close_container(&itr, &variant);
1439 return e_ofono_element_message_send
1440 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1444 * Call method SetProperty(prop, value) at the given element on server.
1446 * This is a server call, not local, so it may fail and in that case
1447 * no property is updated locally. If the value was set the event
1448 * E_OFONO_EVENT_ELEMENT_UPDATED will be added to main loop.
1450 * @param element to call method on server.
1451 * @param prop property name.
1452 * @param type DBus type to use for value.
1453 * @param value pointer to value, just like regular DBus, see
1454 * dbus_message_iter_append_basic().
1455 * @param cb function to call when server replies or some error happens.
1456 * @param data data to give to cb when it is called.
1458 * @return 1 on success, 0 otherwise.
1461 e_ofono_element_property_set_full(E_Ofono_Element *element, const char *prop, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
1463 const char name[] = "SetProperty";
1467 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1468 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1470 msg = dbus_message_new_method_call
1471 (e_ofono_system_bus_name_get(), element->path, element->interface, name);
1476 DBusMessageIter itr, v;
1477 dbus_message_iter_init_append(msg, &itr);
1478 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
1482 dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &v);
1483 if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
1484 dbus_message_iter_append_basic(&v, type, &value);
1486 dbus_message_iter_append_basic(&v, type, value);
1487 dbus_message_iter_close_container(&itr, &v);
1489 return e_ofono_element_message_send
1490 (element, name, NULL, msg, &element->_pending.property_set, cb, data);
1494 * Call method SetProperty(prop, value) at the given element on server.
1496 * This is the simple version and there is no check of server reply
1499 * @param element to call method on server.
1500 * @param prop property name.
1501 * @param type DBus type to use for value.
1502 * @param value pointer to value, just like regular DBus, see
1503 * dbus_message_iter_append_basic().
1505 * @return 1 on success, 0 otherwise.
1508 e_ofono_element_property_set(E_Ofono_Element *element, const char *prop, int type, const void *value)
1510 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1511 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
1512 return e_ofono_element_property_set_full
1513 (element, prop, type, value, NULL, NULL);
1517 e_ofono_element_call_with_path(E_Ofono_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)
1519 DBusMessageIter itr;
1522 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1523 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1524 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1525 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1527 msg = dbus_message_new_method_call
1528 (e_ofono_system_bus_name_get(), element->path, element->interface,
1534 dbus_message_iter_init_append(msg, &itr);
1535 dbus_message_iter_append_basic(&itr, DBUS_TYPE_OBJECT_PATH, &string);
1537 return e_ofono_element_message_send
1538 (element, method_name, cb, msg, pending, user_cb, user_data);
1542 e_ofono_element_call_with_string(E_Ofono_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)
1544 DBusMessageIter itr;
1547 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1548 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1549 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1550 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1552 msg = dbus_message_new_method_call
1553 (e_ofono_system_bus_name_get(), element->path, element->interface,
1559 dbus_message_iter_init_append(msg, &itr);
1560 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &string);
1562 return e_ofono_element_message_send
1563 (element, method_name, cb, msg, pending, user_cb, user_data);
1567 e_ofono_element_call_with_path_and_string(E_Ofono_Element *element, const char *method_name, const char *path, const char *string, E_DBus_Method_Return_Cb cb, Eina_Inlist **pending, E_DBus_Method_Return_Cb user_cb, const void *user_data)
1569 DBusMessageIter itr;
1572 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1573 EINA_SAFETY_ON_NULL_RETURN_VAL(method_name, 0);
1574 EINA_SAFETY_ON_NULL_RETURN_VAL(path, 0);
1575 EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1576 EINA_SAFETY_ON_NULL_RETURN_VAL(pending, 0);
1578 msg = dbus_message_new_method_call
1579 (e_ofono_system_bus_name_get(), element->path, element->interface,
1585 dbus_message_iter_init_append(msg, &itr);
1586 dbus_message_iter_append_basic(&itr, DBUS_TYPE_OBJECT_PATH, &path);
1587 dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &string);
1589 return e_ofono_element_message_send
1590 (element, method_name, cb, msg, pending, user_cb, user_data);
1594 * Get property type.
1596 * If zero is returned, then this call failed and parameter-returned
1597 * values shall be considered invalid.
1599 * @param element which element to get the property
1600 * @param name property name, must be previously stringshared
1601 * @param type will contain the value type.
1603 * @return 1 on success, 0 otherwise.
1606 e_ofono_element_property_type_get_stringshared(const E_Ofono_Element *element, const char *name, int *type)
1608 const E_Ofono_Element_Property *p;
1610 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1611 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1612 EINA_SAFETY_ON_NULL_RETURN_VAL(type, 0);
1614 EINA_INLIST_FOREACH(element->props, p)
1616 if (p->name == name)
1623 WRN("element %s (%p) has no property with name \"%s\".",
1624 element->path, element, name);
1629 * Get property type.
1631 * If zero is returned, then this call failed and parameter-returned
1632 * values shall be considered invalid.
1634 * @param element which element to get the property
1635 * @param name property name
1636 * @param type will contain the value type.
1638 * @return 1 on success, 0 otherwise.
1641 e_ofono_element_property_type_get(const E_Ofono_Element *element, const char *name, int *type)
1644 name = eina_stringshare_add(name);
1645 ret = e_ofono_element_property_type_get_stringshared(element, name, type);
1646 eina_stringshare_del(name);
1651 e_ofono_element_list_properties(const E_Ofono_Element *element, bool (*cb)(void *data, const E_Ofono_Element *element, const char *name, int type, const void *value), const void *data)
1653 const E_Ofono_Element_Property *p;
1655 EINA_SAFETY_ON_NULL_RETURN(element);
1656 EINA_SAFETY_ON_NULL_RETURN(cb);
1658 EINA_INLIST_FOREACH(element->props, p)
1660 const void *value = NULL;
1664 case DBUS_TYPE_STRING:
1665 value = &p->value.str;
1667 case DBUS_TYPE_OBJECT_PATH:
1668 value = &p->value.path;
1670 case DBUS_TYPE_BOOLEAN:
1671 value = (void *)p->value.boolean;
1673 case DBUS_TYPE_UINT16:
1674 value = &p->value.u16;
1676 case DBUS_TYPE_UINT32:
1677 value = &p->value.u32;
1680 ERR("unsupported type %c", p->type);
1683 if (!cb((void *)data, element, p->name, p->type, value))
1689 * Get dict value given its key inside a dict property.
1691 * This will look into properties for one of type dict that contains
1692 * the given key, to find the property. If no property is found then
1695 * If zero is returned, then this call failed and parameter-returned
1696 * values shall be considered invalid.
1698 * @param element which element to get the property
1699 * @param dict_name property name, must be previously stringshared
1700 * @param key key inside dict, must be previously stringshared
1701 * @param type if provided it will contain the value type.
1702 * @param value where to store the property value, must be a pointer to the
1703 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1705 * @return 1 on success, 0 otherwise.
1708 e_ofono_element_property_dict_get_stringshared(const E_Ofono_Element *element, const char *dict_name, const char *key, int *type, void *value)
1710 const E_Ofono_Element_Property *p;
1712 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1713 EINA_SAFETY_ON_NULL_RETURN_VAL(dict_name, 0);
1714 EINA_SAFETY_ON_NULL_RETURN_VAL(key, 0);
1715 EINA_SAFETY_ON_NULL_RETURN_VAL(value, 0);
1717 EINA_INLIST_FOREACH(element->props, p)
1719 E_Ofono_Element_Dict_Entry *entry;
1720 E_Ofono_Array *array;
1722 if (p->name != dict_name)
1724 if (p->type != DBUS_TYPE_ARRAY)
1726 WRN("element %s (%p) has property \"%s\" is not an array: %c (%d)",
1727 element->path, element, dict_name, p->type, p->type);
1730 array = p->value.array;
1731 if ((!array) || (array->type != DBUS_TYPE_DICT_ENTRY))
1733 int t = array ? array->type : DBUS_TYPE_INVALID;
1734 WRN("element %s (%p) has property \"%s\" is not a dict: %c (%d)",
1735 element->path, element, dict_name, t, t);
1738 entry = _e_ofono_element_array_dict_find_stringshared(array, key);
1741 WRN("element %s (%p) has no dict property with name \"%s\" with "
1743 element->path, element, dict_name, key);
1747 if (type) *type = entry->type;
1749 switch (entry->type)
1751 case DBUS_TYPE_BOOLEAN:
1752 *(bool *)value = entry->value.boolean;
1754 case DBUS_TYPE_BYTE:
1755 *(unsigned char *)value = entry->value.byte;
1757 case DBUS_TYPE_UINT16:
1758 *(unsigned short *)value = entry->value.u16;
1760 case DBUS_TYPE_UINT32:
1761 *(unsigned int *)value = entry->value.u32;
1763 case DBUS_TYPE_STRING:
1764 *(const char **)value = entry->value.str;
1766 case DBUS_TYPE_OBJECT_PATH:
1767 *(const char **)value = entry->value.path;
1770 ERR("don't know how to get property %s, key %s type %c (%d)",
1771 dict_name, key, entry->type, entry->type);
1776 WRN("element %s (%p) has no property with name \"%s\".",
1777 element->path, element, dict_name);
1782 * Get property value given its name.
1784 * This will look into properties, to find the property.
1785 * If no property is found then 0 is returned.
1787 * If zero is returned, then this call failed and parameter-returned
1788 * values shall be considered invalid.
1790 * @param element which element to get the property
1791 * @param name property name, must be previously stringshared
1792 * @param type if provided it will contain the value type.
1793 * @param value where to store the property value, must be a pointer to the
1794 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1796 * @return 1 on success, 0 otherwise.
1799 e_ofono_element_property_get_stringshared(const E_Ofono_Element *element, const char *name, int *type, void *value)
1801 const E_Ofono_Element_Property *p;
1803 EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
1804 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1805 EINA_SAFETY_ON_NULL_RETURN_VAL(value, 0);
1807 EINA_INLIST_FOREACH(element->props, p)
1809 if (p->name != name)
1812 if (type) *type = p->type;
1816 case DBUS_TYPE_BOOLEAN:
1817 *(bool *)value = p->value.boolean;
1819 case DBUS_TYPE_BYTE:
1820 *(unsigned char *)value = p->value.byte;
1822 case DBUS_TYPE_UINT16:
1823 *(unsigned short *)value = p->value.u16;
1825 case DBUS_TYPE_UINT32:
1826 *(unsigned int *)value = p->value.u32;
1828 case DBUS_TYPE_STRING:
1829 *(const char **)value = p->value.str;
1831 case DBUS_TYPE_OBJECT_PATH:
1832 *(const char **)value = p->value.path;
1834 case DBUS_TYPE_ARRAY:
1835 *(E_Ofono_Array **)value = p->value.array;
1838 ERR("don't know how to get property type %c (%d)",
1844 WRN("element %s (%p) has no property with name \"%s\".",
1845 element->path, element, name);
1850 * Get property value given its name.
1852 * This will look into properties, to find the property.
1853 * If no property is found then 0 is returned.
1855 * If zero is returned, then this call failed and parameter-returned
1856 * values shall be considered invalid.
1858 * @param element which element to get the property
1859 * @param name property name
1860 * @param type if provided it will contain the value type.
1861 * @param value where to store the property value, must be a pointer to the
1862 * exact type, (bool *) for booleans, (char **) for strings, and so on.
1864 * @return 1 on success, 0 otherwise.
1867 e_ofono_element_property_get(const E_Ofono_Element *element, const char *name, int *type, void *value)
1870 name = eina_stringshare_add(name);
1871 ret = e_ofono_element_property_get_stringshared
1872 (element, name, type, value);
1873 eina_stringshare_del(name);
1878 struct e_ofono_elements_for_each_data
1880 Eina_Hash_Foreach cb;
1885 _e_ofono_elements_for_each(Eina_Hash *hash __UNUSED__, const char *key, void *data, void *fdata)
1887 struct e_ofono_elements_for_each_data *each_data = fdata;
1889 each_data->cb(elements, key, data, each_data->data);
1894 * Call the given function for each existing element.
1896 * @param cb function to call for each element. It will get as parameters,
1897 * in order: the element pointer and the given @a user_data.
1898 * @param user_data data to give to @a cb for each element.
1901 e_ofono_elements_for_each(Eina_Hash_Foreach cb, const void *user_data)
1903 struct e_ofono_elements_for_each_data data = {cb, (void *)user_data};
1905 EINA_SAFETY_ON_NULL_RETURN(cb);
1907 eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_ofono_elements_for_each,
1912 _e_ofono_elements_get_allocate(unsigned int *count, E_Ofono_Element ***p_elements)
1914 *count = eina_hash_population(elements);
1921 *p_elements = malloc(*count * sizeof(E_Ofono_Element *));
1924 ERR("could not allocate return array of %d elements: %s",
1925 *count, strerror(errno));
1933 _e_ofono_elements_get_all(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *data, void *fdata)
1935 E_Ofono_Element *element = data;
1936 E_Ofono_Element ***p_ret = fdata;
1944 * Get all known elements.
1946 * No reference is added to these elements, since there are no threads
1947 * in the system, you are free to add references yourself right after
1948 * the return of this call without race condition, elements by the
1949 * system (ie: elementRemoved signal)could only be touched on the next
1950 * main loop iteration.
1952 * @param count return the number of elements in array.
1953 * @param p_elements array with all elements, these are not referenced
1954 * and in no particular order, just set if return is 1.
1956 * @return 1 on success, 0 otherwise.
1959 e_ofono_elements_get_all(unsigned int *count, E_Ofono_Element ***p_elements)
1961 E_Ofono_Element **p;
1963 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
1964 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
1966 if (!_e_ofono_elements_get_allocate(count, p_elements))
1969 eina_hash_foreach(elements, (Eina_Hash_Foreach) _e_ofono_elements_get_all,
1974 struct e_ofono_elements_get_all_str_data
1976 E_Ofono_Element **elements;
1982 _e_ofono_elements_get_all_type(Eina_Hash *hash __UNUSED__, const char *key __UNUSED__, void *e, void *user_data)
1984 struct e_ofono_elements_get_all_str_data *data = user_data;
1985 E_Ofono_Element *element = e;
1987 if ((data->str) && (element->interface != data->str))
1990 data->elements[data->count] = element;
1996 * Get all known elements of type.
1998 * No reference is added to these elements, since there are no threads
1999 * in the system, you are free to add references yourself right after
2000 * the return of this call without race condition, elements by the
2001 * system (ie: ElementRemoved signal) could only be touched on the next
2002 * main loop iteration.
2004 * @param type type to filter, or NULL to get all.
2005 * @param count return the number of elements in array.
2006 * @param p_elements array with all elements, these are not referenced
2007 * and in no particular order, just set if return is 1.
2009 * @return 1 on success, 0 otherwise.
2011 * @see e_ofono_elements_get_all()
2014 e_ofono_elements_get_all_type(const char *type, unsigned int *count, E_Ofono_Element ***p_elements)
2016 struct e_ofono_elements_get_all_str_data data;
2018 EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
2019 EINA_SAFETY_ON_NULL_RETURN_VAL(p_elements, 0);
2021 if (!_e_ofono_elements_get_allocate(count, p_elements))
2024 data.elements = *p_elements;
2026 data.str = eina_stringshare_add(type);
2027 eina_hash_foreach(elements,
2028 (Eina_Hash_Foreach) _e_ofono_elements_get_all_type,
2031 eina_stringshare_del(data.str);
2032 *count = data.count;
2037 * Get the element registered at given path.
2039 * @param path the path to query for registered object.
2041 * @return element pointer if found, NULL otherwise. No references are added.
2044 e_ofono_element_get(const char *path, const char *interface)
2046 E_Ofono_Element *element;
2047 char key[MAX_KEY_SIZE];
2049 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2050 EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
2052 snprintf(key, MAX_KEY_SIZE, "%s:%s", path, interface);
2053 element = eina_hash_find(elements, key);
2059 _e_ofono_element_property_changed_callback(void *data, DBusMessage *msg)
2061 E_Ofono_Element *element = (E_Ofono_Element *)data;
2062 DBusMessageIter itr, v_itr;
2063 int t, r, changed = 0;
2064 const char *name = NULL;
2067 DBG("Property changed in element %s %s", element->path, element->interface);
2069 if (!_dbus_callback_check_and_init(msg, &itr, NULL))
2072 t = dbus_message_iter_get_arg_type(&itr);
2073 if (!_dbus_iter_type_check(t, DBUS_TYPE_STRING))
2075 ERR("missing name in property changed signal");
2078 dbus_message_iter_get_basic(&itr, &name);
2080 dbus_message_iter_next(&itr);
2081 t = dbus_message_iter_get_arg_type(&itr);
2082 if (!_dbus_iter_type_check(t, DBUS_TYPE_VARIANT))
2084 ERR("missing value in property changed signal");
2087 dbus_message_iter_recurse(&itr, &v_itr);
2088 t = dbus_message_iter_get_arg_type(&v_itr);
2090 if (t == DBUS_TYPE_ARRAY)
2091 value = _e_ofono_element_iter_get_array(&v_itr, name);
2092 else if (t != DBUS_TYPE_INVALID)
2093 dbus_message_iter_get_basic(&v_itr, &value);
2096 ERR("property has invalid type %s", name);
2100 r = _e_ofono_element_property_value_add(element, name, t, value);
2102 ERR("failed to add property value %s (%c)", name, t);
2105 INF("property value changed %s (%c)", name, t);
2109 _e_ofono_element_listeners_call(element);
2113 * Register the given pair (path, interface), possibly creating an
2114 * element and return it.
2116 * This will check if (path, interface) is already registered, in
2117 * that case the exiting element is returned. If it was not registered
2118 * yet, a new 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_ofono_element_register(const char *path, const char *interface)
2129 E_Ofono_Element *element;
2130 char key[MAX_KEY_SIZE];
2132 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2133 EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
2135 snprintf(key, MAX_KEY_SIZE, "%s:%s", path, interface);
2136 element = eina_hash_find(elements, key);
2140 element = e_ofono_element_new(path, interface);
2144 if (!eina_hash_add(elements, key, element))
2146 ERR("could not add element %s to hash, delete it.", path);
2147 e_ofono_element_free(element);
2151 element->signal_handler =
2152 e_dbus_signal_handler_add
2153 (e_ofono_conn, e_ofono_system_bus_name_get(),
2154 element->path, element->interface, "PropertyChanged",
2155 _e_ofono_element_property_changed_callback, element);
2157 e_ofono_element_event_add(E_OFONO_EVENT_ELEMENT_ADD, element);
2163 _e_ofono_element_event_unregister_and_free(void *data __UNUSED__, void *ev)
2165 E_Ofono_Element *element = ev;
2166 e_ofono_element_unref(element);
2170 _e_ofono_element_unregister_internal(E_Ofono_Element *element)
2172 if (element->signal_handler)
2174 e_dbus_signal_handler_del(e_ofono_conn, element->signal_handler);
2175 element->signal_handler = NULL;
2178 ecore_event_add(E_OFONO_EVENT_ELEMENT_DEL, element,
2179 _e_ofono_element_event_unregister_and_free, NULL);
2183 * Forget about the given element.
2185 * This will remove the element from the pool of known objects, then
2186 * add an E_OFONO_EVENT_ELEMENT_DEL and after that will unreference it,
2187 * possible freeing it.
2189 * @param element element to forget about. Its reference will be removed.
2192 e_ofono_element_unregister(E_Ofono_Element *element)
2194 char key[MAX_KEY_SIZE];
2199 snprintf(key, MAX_KEY_SIZE, "%s:%s", element->path, element->interface);
2201 eina_hash_del_by_key(elements, key);
2205 * Remove all known elements.
2207 * This will remove all known elements but will NOT add any
2208 * E_OFONO_EVENT_ELEMENT_DEL to main loop.
2210 * This is just useful to make sure next e_ofono_manager_sync_elements()
2211 * will not leave any stale elements. This is unlikely to happen, as
2212 * E_Ofono is supposed to catch all required events to avoid stale elements.
2215 e_ofono_manager_clear_elements(void)
2217 e_ofono_elements_shutdown();
2218 e_ofono_elements_init();
2222 * Creates elements hash.
2224 * This has no init counter since its already guarded by other code.
2228 e_ofono_elements_init(void)
2230 EINA_SAFETY_ON_FALSE_RETURN(elements == NULL);
2232 eina_hash_string_superfast_new(EINA_FREE_CB
2233 (_e_ofono_element_unregister_internal));
2237 e_ofono_elements_shutdown(void)
2239 EINA_SAFETY_ON_FALSE_RETURN(elements != NULL);
2240 eina_hash_free(elements);