From: Vinicius Costa Gomes <[email protected]>

With the move of BlueZ to DBus ObjectManager and the ProfileManager1
interface, the case that ofono receives a message with a properties
dictionary should be more common, so we add a function to help deal
with it.
---
 include/dbus.h |  6 ++++
 src/dbus.c     | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/include/dbus.h b/include/dbus.h
index 44faa7f..3901a96 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -100,6 +100,12 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection 
*conn,
                                                const char *name, int type,
                                                void *value);
 
+typedef void (*property_handler_cb)(DBusMessageIter *iter, void *user_data);
+
+void ofono_dbus_iter_parse_properties(DBusMessageIter *array,
+                               const char *property, property_handler_cb cb,
+                               void *user_data, ...);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/dbus.c b/src/dbus.c
index 1558a51..1afbb44 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -30,6 +30,14 @@
 
 #define OFONO_ERROR_INTERFACE "org.ofono.Error"
 
+typedef void (*property_handler_cb)(DBusMessageIter *iter, void *user_data);
+
+struct property_handler {
+       const char *property;
+       property_handler_cb callback;
+       void *user_data;
+};
+
 static DBusConnection *g_connection;
 
 struct error_mapping_entry {
@@ -273,6 +281,88 @@ int ofono_dbus_signal_dict_property_changed(DBusConnection 
*conn,
        return g_dbus_send_message(conn, signal);
 }
 
+static gint property_handler_compare(gconstpointer a, gconstpointer b)
+{
+       const struct property_handler *handler = a;
+       const char *property = b;
+
+       return g_strcmp0(handler->property, property);
+}
+
+void ofono_dbus_iter_parse_properties(DBusMessageIter *array,
+                               const char *property, property_handler_cb cb,
+                               void *user_data, ...)
+{
+       va_list args;
+       GSList *prop_handlers = NULL;
+       DBusMessageIter dict;
+
+       if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
+               goto done;
+
+       va_start(args, user_data);
+
+       if (property == NULL)
+               return;
+
+       while (1) {
+               struct property_handler *handler =
+                                       g_new0(struct property_handler, 1);
+
+               handler->property = property;
+               handler->callback = cb;
+               handler->user_data = user_data;
+
+               prop_handlers = g_slist_prepend(prop_handlers, handler);
+
+               property = va_arg(args, const char *);
+               if (property == NULL)
+                       break;
+
+               cb = va_arg(args, property_handler_cb);
+               user_data = va_arg(args, void *);
+       }
+
+       va_end(args);
+
+       dbus_message_iter_recurse(array, &dict);
+
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value;
+               const char *key;
+               GSList *l;
+
+               dbus_message_iter_recurse(&dict, &entry);
+
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+                       goto done;
+
+               dbus_message_iter_get_basic(&entry, &key);
+
+               dbus_message_iter_next(&entry);
+
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+                       goto done;
+
+               dbus_message_iter_recurse(&entry, &value);
+
+               l = g_slist_find_custom(prop_handlers, key,
+                                       property_handler_compare);
+
+               if (l) {
+                       struct property_handler *handler = l->data;
+
+                       handler->callback(&value, handler->user_data);
+               }
+
+               dbus_message_iter_next(&dict);
+       }
+
+done:
+       g_slist_foreach(prop_handlers, (GFunc) g_free, NULL);
+       g_slist_free(prop_handlers);
+}
+
 DBusMessage *__ofono_error_invalid_args(DBusMessage *msg)
 {
        return g_dbus_create_error(msg, OFONO_ERROR_INTERFACE
-- 
1.7.11.7

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to