plugins/bluetooth-client: dbus code cleanup.
authorAmarnath Valluri <amarnath.valluri@linux.intel.com>
Fri, 12 Sep 2014 07:22:15 +0000 (10:22 +0300)
committerAmarnath Valluri <amarnath.valluri@linux.intel.com>
Wed, 17 Sep 2014 12:40:01 +0000 (15:40 +0300)
Removed direct dependency to 'libdbus'.

configure.ac
src/Makefile.am
src/plugins/bluetooth-client/bluetooth-plugin.c
src/plugins/bluetooth-client/clients.c
src/plugins/bluetooth-client/dbusif.c
src/plugins/bluetooth-client/pulseif.c

index 0067963..860f34b 100644 (file)
@@ -152,9 +152,7 @@ AC_SUBST(DBUS_LIBS)
 
 # XXX TODO temporarily disable mpris2 and bluetooth plugins
 AM_CONDITIONAL(MPRIS2_ENABLED, [test "xno" = "xyes"])
-AM_CONDITIONAL(BLUETOOTH_ENABLED, [test "xno" = "xyes"])
 AC_SUBST(MPRIS2_ENABLED)
-AC_SUBST(BLUETOOTH_ENABLED)
 
 # Set up common SRS compilation and linking flags.
 SRS_CFLAGS=""
@@ -167,6 +165,13 @@ AC_MSG_CHECKING([libdir])
 AC_MSG_RESULT([$libdir])
 AC_SUBST(LIBDIR, [$libdir])
 
+# Check if bluetooth plugin was enabled
+AC_ARG_ENABLE(bluetooth,
+              [  --enable-bluetooth      enable bluetooth voice recognition support],
+              [enable_bluetooth=$enableval], [enable_bluetooth=auto])
+AM_CONDITIONAL(BLUETOOTH_ENABLED, [test "$enable_bluetooth" = "yes"])
+AC_SUBST(BLUETOOTH_ENABLED)
+
 # Check if sphinx was enabled.
 AC_ARG_ENABLE(sphinx,
               [  --enable-sphinx         enable pocketsphinx support in SRS],
@@ -336,6 +341,7 @@ echo "Sphinx support: $enable_sphinx"
 echo "Festival support: $enable_festival"
 echo "Espeak support: $enable_espeak"
 echo "systemd socket-based activation: $enable_systemd"
+echo "Bluetooth voice recording support: $enable_bluetooth"
 
 if test "$DUMP_LIB_FLAGS" = "yes"; then
     echo "MURPHY_COMMON:"
index fdf45f5..d1ba707 100644 (file)
@@ -10,7 +10,7 @@ pkgconfig_DATA     =
 pkgconfigdir       = ${libdir}/pkgconfig
 
 AM_CPPFLAGS        = -I$(top_builddir)
-AM_CFLAGS          = $(GLIB_CFLAGS)
+AM_CFLAGS          = $(GLIB_CFLAGS) $(WARNING_CFLAGS)
 
 QUIET_GEN          = $(Q:@=@echo '  GEN   '$@;)
 
@@ -267,15 +267,13 @@ plugin_bluetooth_client_la_SOURCES =                              \
 
 plugin_bluetooth_client_la_CFLAGS  =                           \
                $(AM_CFLAGS)                                    \
-               $(MURPHY_DBUS_CFLAGS)                           \
-               $(DBUS_CFLAGS)
+               $(MURPHY_DBUS_CFLAGS)
 
 plugin_bluetooth_client_la_LDFLAGS =                           \
                -module -avoid-version
 
 plugin_bluetooth_client_la_LIBADD  =                           \
-               $(MURPHY_DBUS_LIBS)                             \
-               $(DBUS_LIBS)
+               $(MURPHY_DBUS_LIBS)
 
 endif
 
index 802aa9e..a68efa4 100644 (file)
@@ -49,7 +49,6 @@
 
 static int create_bt_voicerec(srs_plugin_t *plugin)
 {
-    srs_context_t *srs = plugin->srs;
     context_t     *ctx = NULL;
 
     mrp_debug("creating bluetooth voice recognition client plugin");
@@ -57,8 +56,7 @@ static int create_bt_voicerec(srs_plugin_t *plugin)
     if ((ctx = mrp_allocz(sizeof(context_t)))) {
         ctx->plugin = plugin;
 
-        if (dbusif_create(ctx, srs->ml) == 0 &&
-            clients_create(ctx)         == 0  )
+        if (clients_create(ctx) == 0)
         {
             plugin->plugin_data = ctx;
             return TRUE;
@@ -77,29 +75,32 @@ static int create_bt_voicerec(srs_plugin_t *plugin)
 static int config_bt_voicerec(srs_plugin_t *plugin, srs_cfg_t *settings)
 {
     srs_cfg_t *cfgs, *c;
-    const char *key;
+    srs_context_t *srs_ctx = plugin->srs;
+    context_t *ctx = (context_t *)plugin->plugin_data;
     int pfxlen;
     int n, i;
-    int success;
-
-    MRP_UNUSED(plugin);
 
     mrp_debug("configuring bluetooth voice recognition client plugin");
 
-    n = srs_collect_config(settings, BLUETOOTH_PREFIX, &cfgs);
+
+    n = srs_config_collect(settings, BLUETOOTH_PREFIX, &cfgs);
     pfxlen = strlen(BLUETOOTH_PREFIX);
 
     mrp_log_info("Found %d bluetooth voice recognition configuration keys.",n);
 
-    for (i = 0, success = TRUE;   i < n ;   i++) {
+    for (i = 0;   i < n ;   i++) {
+        const char *key = NULL;
+
         c = cfgs + i;
         key = c->key + pfxlen;
 
         c->used = FALSE;
-        success = FALSE;
+        mrp_debug("     '%s=%s'", key, c->value);
     }
 
-    srs_free_config(cfgs);
+    srs_config_free(cfgs);
+
+    dbusif_create(ctx, srs_ctx->ml);
 
     return TRUE;
 }
index 1f9789e..8ddfe19 100644 (file)
@@ -290,7 +290,6 @@ static int notify_command(srs_client_t *srs_client, int idx,
 {
     context_t *ctx;
     clients_t *clients;
-    device_t *device;
     char cmd[2048];
     uint32_t from;
     char *e, *p, *sep;
index b8cca9e..0bfb5d5 100644 (file)
@@ -3,8 +3,10 @@
 #include <string.h>
 
 #include <murphy/common/debug.h>
-#include <murphy/common/dbus.h>
+#include <murphy/common/dbus-libdbus.h>
+#include <murphy/common/hashtbl.h>
 #include <murphy/common/list.h>
+#include <murphy/common/utils.h>
 
 #include "dbusif.h"
 #include "clients.h"
 #define MAKE_DBUS_VERSION(major, minor, patch)  \
     (((major) << 16) | ((minor) << 8) | (patch))
 
-#if DBUS_VERSION < MAKE_DBUS_VERSION(1, 6, 8)
-/* For old versions, we define DBusBasicValue with the member we use... */
-typedef union {
-    char        *str;
-    double       dbl;
-    dbus_bool_t  bool_val;
-} DBusBasicValue;
-#endif
-
 struct dbusif_s {
     const char *bustype;
     mrp_dbus_t *dbus;
     mrp_list_hook_t modems;
 };
 
-
-static modem_t *create_modem(context_t *, const char *, const char *,
-                             const char *);
-static void destroy_modem(modem_t *);
-static modem_t *reference_modem(modem_t *);
-static void unreference_modem(modem_t *);
-static modem_t *find_modem_by_path(context_t *, const char *);
-static void track_modems(context_t *, bool);
-static void query_all_modems(context_t *);
-static void query_modem(modem_t *);
-static void query_handsfree(modem_t *);
-
-static int modem_property_changed_cb(mrp_dbus_t *, DBusMessage *, void *);
-static int handsfree_property_changed_cb(mrp_dbus_t *, DBusMessage *, void *);
-static void modem_query_all_cb(mrp_dbus_t *, DBusMessage *, void *);
-static void modem_query_cb(mrp_dbus_t *, DBusMessage *, void *);
-static void handsfree_query_cb(mrp_dbus_t *, DBusMessage *, void *);
-
-static void set_modem_state(modem_t *, hfp_state_t);
-
-static void parse_modem_properties(context_t *,DBusMessageIter *,const char **,
-                                   const char **, dbus_bool_t *);
-static void parse_handsfree_properties(modem_t *,  DBusMessageIter *,
-                                       hfp_state_t *);
-static void parse_property(DBusMessageIter *, const char **name,
-                           int *type,  DBusBasicValue *);
-static void set_property(DBusMessageIter *, const char *, int, void *);
-
-
-int dbusif_create(context_t *ctx, mrp_mainloop_t *ml)
+static int mrp_dbus_is_basic_type(mrp_dbus_type_t t)
 {
-    dbusif_t *dbusif;
-
-    if (!(dbusif = mrp_allocz(sizeof(dbusif_t))))
-        return -1;
-
-    dbusif->bustype = mrp_strdup("system");
-    dbusif->dbus = mrp_dbus_get(ml, dbusif->bustype, NULL);
-
-    if (!dbusif->dbus) {
-        mrp_log_error("bluetooth voice recognition plugin: "
-                      "failed to obtain DBus");
-        mrp_free(dbusif);
-        return -1;
-    }
-
-    mrp_list_init(&dbusif->modems);
-
-    ctx->dbusif = dbusif;
-
-    return 0;
+    return t != MRP_DBUS_TYPE_ARRAY && t != MRP_DBUS_TYPE_VARIANT &&
+           t != MRP_DBUS_TYPE_STRUCT && t != MRP_DBUS_TYPE_DICT_ENTRY &&
+           t != MRP_DBUS_TYPE_INVALID;
 }
 
-void dbusif_destroy(context_t *ctx)
+static const char * mrp_dbus_type_to_string(mrp_dbus_type_t t)
 {
-    dbusif_t *dbusif;
+    static char type_str[2] = "";
 
-    if (ctx && (dbusif = ctx->dbusif)) {
-        ctx->dbusif = NULL;
+    type_str[0] = t;
 
-        mrp_dbus_unref(dbusif->dbus);
-
-        mrp_free((void *)dbusif->bustype);
-        mrp_free((void *)dbusif);
-    }
+    return type_str;
 }
 
-int dbusif_start(context_t *ctx)
+static modem_t *reference_modem(modem_t *modem)
 {
-    track_modems(ctx, TRUE);
-    query_all_modems(ctx);
-    return 0;
+    if (modem && modem->refcnt >= 0)
+        modem->refcnt++;
+
+    return modem->refcnt < 0 ? NULL : modem;
 }
 
-void dbusif_stop(context_t *ctx)
+static void unreference_modem(modem_t *modem)
 {
-    dbusif_t *dbusif;
-    modem_t *modem;
-    mrp_list_hook_t *entry, *n;
+    device_t *dev = NULL;
 
-    track_modems(ctx, FALSE);
+    if (modem) {
+        if (modem->refcnt > 1)
+            modem->refcnt--;
+        else {
+            mrp_log_info("remove bluetooth modem '%s' @ %s (paths %s)",
+                         modem->name, modem->addr, modem->path);
 
-    if (ctx && (dbusif = ctx->dbusif)) {
-        mrp_list_foreach(&dbusif->modems, entry, n) {
-            modem = mrp_list_entry(entry, modem_t, link);
-            destroy_modem(modem);
+            if ((dev = modem->device)) {
+                modem->device = NULL;
+                clients_remove_device(dev);
+            }
+
+            mrp_list_delete(&modem->link);
+
+            mrp_free((void *)modem->path);
+            mrp_free((void *)modem->name);
+            mrp_free((void *)modem->addr);
+
+            mrp_free((void *)modem);
         }
     }
 }
 
-int dbusif_set_voice_recognition(modem_t *modem, hfp_state_t state)
+static modem_t *find_modem_by_path(context_t *ctx, const char *path)
 {
-    context_t *ctx;
-    dbusif_t *dbusif;
-    DBusMessage *msg;
-    DBusMessageIter mit;
-    dbus_bool_t value;
+    modem_t *modem = NULL;
+    dbusif_t *dbusif = NULL;
+    mrp_list_hook_t *entry, *n;
 
-    if (!modem || !modem->path || !(ctx = modem->ctx) ||
-        !(dbusif = ctx->dbusif))
-        return -1;
+    if (!ctx || !path || !(dbusif = ctx->dbusif))
+        return NULL;
 
-    switch (state) {
-    case VOICE_RECOGNITION_ON:   value = TRUE;    break;
-    case VOICE_RECOGNITION_OFF:  value = FALSE;   break;
-    default:                     /* invalid */    return -1;
+    mrp_list_foreach(&dbusif->modems, entry, n) {
+        modem = mrp_list_entry(entry, modem_t, link);
+        if (!strcmp(path, modem->path))
+            return modem;
     }
 
-    msg = dbus_message_new_method_call("org.ofono",
-                                       modem->path,
-                                       "org.ofono.Handsfree",
-                                       "SetProperty");
-    if (!msg)
-        return -1;
-
-    dbus_message_iter_init_append(msg, &mit);
-    set_property(&mit, "VoiceRecognition", DBUS_TYPE_BOOLEAN, &value);
-
-    mrp_dbus_send_msg(dbusif->dbus, msg);
-
-    dbus_message_unref(msg);
-
-    return 0;
+    return NULL;
 }
 
-
 static modem_t *create_modem(context_t *ctx,
                              const char *path,
                              const char *name,
                              const char *addr)
 {
-    dbusif_t *dbusif;
-    modem_t *modem;
+    modem_t *modem = NULL;
+    dbusif_t *dbusif = NULL;
 
     if (!ctx || !path || !addr || !(dbusif = ctx->dbusif))
         return NULL;
@@ -194,323 +130,203 @@ static void destroy_modem(modem_t *modem)
     }
 }
 
-static modem_t *reference_modem(modem_t *modem)
-{
-    if (modem && modem->refcnt >= 0)
-        modem->refcnt++;
-
-    return modem->refcnt < 0 ? NULL : modem;
-}
+typedef struct {
+  mrp_dbus_type_t type;
+  void *value;
+  size_t n_values; /* for arrays */
+} property_info_t;
 
-static void unreference_modem(modem_t *modem)
+static property_info_t * property_info_new(mrp_dbus_type_t type)
 {
-    device_t *dev;
-
-    if (modem) {
-        if (modem->refcnt > 1)
-            modem->refcnt--;
-        else {
-            mrp_log_info("remove bluetooth modem '%s' @ %s (paths %s)",
-                         modem->name, modem->addr, modem->path);
+  property_info_t *p = NULL;
 
-            if ((dev = modem->device)) {
-                modem->device = NULL;
-                clients_remove_device(dev);
-            }
+  if ((p = mrp_allocz(sizeof(*p)))) {
+    p->type = type;
+    p->value = 0;
+    p->n_values = 0;
+  }
 
-            mrp_list_delete(&modem->link);
-
-            mrp_free((void *)modem->path);
-            mrp_free((void *)modem->name);
-            mrp_free((void *)modem->addr);
-
-            mrp_free((void *)modem);
-        }
-    }
+  return p;
 }
 
-
-static modem_t *find_modem_by_path(context_t *ctx, const char *path)
+static void property_hash_free(void *key, void *object)
 {
-    dbusif_t *dbusif;
-    modem_t *modem;
-    mrp_list_hook_t *entry, *n;
+  property_info_t *p = object;
 
-    if (!ctx || !path || !(dbusif = ctx->dbusif))
-        return NULL;
-
-    mrp_list_foreach(&dbusif->modems, entry, n) {
-        modem = mrp_list_entry(entry, modem_t, link);
-        if (!strcmp(path, modem->path))
-            return modem;
-    }
+  MRP_UNUSED(key);
 
-    return NULL;
+  if (p)
+    mrp_free(p);
 }
 
-static void track_modems(context_t *ctx, bool track)
+static int parse_property_value_basic(mrp_dbus_msg_t *msg,
+                                      const char *name,
+                                      mrp_dbus_type_t type,
+                                      void *value_out)
 {
-    static const char *modem_interface = "org.ofono.Modem";
-    static const char *handsfree_interface = "org.ofono.Handsfree";
-    static const char *member = "PropertyChanged";
+    const char *n = NULL;
 
-    dbusif_t *dbusif;
+    if (!name || !value_out || !mrp_dbus_is_basic_type(type))
+      return FALSE;
 
-    if (ctx && (dbusif = ctx->dbusif)) {
-        if (track) {
-            mrp_dbus_add_signal_handler(dbusif->dbus, NULL, NULL,
-                                        modem_interface, member,
-                                        modem_property_changed_cb, ctx);
-            mrp_dbus_add_signal_handler(dbusif->dbus, NULL, NULL,
-                                        handsfree_interface, member,
-                                        handsfree_property_changed_cb, ctx);
-            mrp_dbus_install_filter(dbusif->dbus, NULL, NULL,
-                                    modem_interface, member, NULL);
-            mrp_dbus_install_filter(dbusif->dbus, NULL, NULL,
-                                    handsfree_interface, member, NULL);
-        }
-        else {
-            mrp_dbus_del_signal_handler(dbusif->dbus, NULL, NULL,
-                                        modem_interface, member,
-                                        modem_property_changed_cb, ctx);
-            mrp_dbus_del_signal_handler(dbusif->dbus, NULL, NULL,
-                                        handsfree_interface, member,
-                                        handsfree_property_changed_cb, ctx);
-            mrp_dbus_remove_filter(dbusif->dbus, NULL, NULL,
-                                   modem_interface, member, NULL);
-            mrp_dbus_remove_filter(dbusif->dbus, NULL, NULL,
-                                   handsfree_interface, member, NULL);
-        }
-    }
-}
+    if (mrp_dbus_msg_arg_type(msg, NULL) != MRP_DBUS_TYPE_STRING)
+        return FALSE;
 
+    mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, &n);
 
-static void query_all_modems(context_t *ctx)
-{
-    dbusif_t *dbusif;
-    DBusMessage *msg;
+    if (strcmp(n, name))
+      return FALSE;
 
-    if (!ctx || !(dbusif = ctx->dbusif))
-        return;
+    if (mrp_dbus_msg_arg_type(msg, NULL) != MRP_DBUS_TYPE_VARIANT)
+        return FALSE;
 
-    msg = dbus_message_new_method_call("org.ofono", "/", "org.ofono.Manager",
-                                       "GetModems");
-    if (msg) {
-        mrp_dbus_send(dbusif->dbus, "org.ofono", "/", "org.ofono.Manager",
-                      "GetModems", 1000, modem_query_all_cb, ctx, msg);
-    }
-}
+    mrp_dbus_msg_enter_container(msg, MRP_DBUS_TYPE_VARIANT,
+                                 mrp_dbus_type_to_string(type));
 
-static void query_modem(modem_t *modem)
-{
-    context_t *ctx;
-    dbusif_t *dbusif;
-    DBusMessage *msg;
-    const char *path;
-    modem_t *ref;
+    mrp_dbus_msg_read_basic(msg, type, value_out);
 
-    if (!modem || !(ctx = modem->ctx) || !(path = modem->path) ||
-        !(dbusif = ctx->dbusif))
-        return;
+    mrp_dbus_msg_exit_container(msg); /* v */
 
-    msg = dbus_message_new_method_call("org.ofono", path, "org.ofono.Modem",
-                                       "GetProperties");
-    if (msg) {
-        if ((ref = reference_modem(modem))) {
-            mrp_dbus_send(dbusif->dbus, "org.ofono", path, "org.ofono.Modem",
-                          "GetProperties", 1000, modem_query_cb, ref, msg);
-        }
-    }
+    return TRUE;
 }
 
-static void query_handsfree(modem_t *modem)
+static void parse_propertites(mrp_dbus_msg_t *msg,
+                              mrp_htbl_t *prop_tbl,
+                              size_t size)
 {
-    context_t *ctx;
-    dbusif_t *dbusif;
-    DBusMessage *msg;
-    const char *path;
-    modem_t *ref;
+    size_t n_found = 0;
 
-    if (!modem || !(ctx = modem->ctx) || !(path = modem->path) ||
-        !(dbusif = ctx->dbusif))
+    if (mrp_dbus_msg_arg_type(msg, NULL) != MRP_DBUS_TYPE_ARRAY)
         return;
 
-    msg = dbus_message_new_method_call("org.ofono",path,"org.ofono.Handsfree",
-                                       "GetProperties");
-    if (msg) {
-        if ((ref = reference_modem(modem))) {
-            mrp_dbus_send(dbusif->dbus, "org.ofono",path,"org.ofono.Handsfree",
-                          "GetProperties", 1000, handsfree_query_cb, ref, msg);
-        }
-    }
-}
-
-static int modem_property_changed_cb(mrp_dbus_t *dbus,
-                                     DBusMessage *msg,
-                                     void *user_data)
-{
-    context_t *ctx = (context_t *)user_data;
-    dbusif_t *dbusif;
-    DBusMessageIter mit;
-    const char *path;
-    modem_t *modem;
-    const char *prop;
-    int type;
-    DBusBasicValue value;
+    if (!mrp_dbus_msg_enter_container(msg, MRP_DBUS_TYPE_ARRAY, "{sv}"))
+        return;
 
-    MRP_UNUSED(dbus);
+    while (mrp_dbus_msg_enter_container(msg,  MRP_DBUS_TYPE_DICT_ENTRY, NULL)) {
+        const char *prop = NULL;
+        property_info_t *p_info = NULL;
 
-    if (ctx && (dbusif = ctx->dbusif) && dbus_message_iter_init(msg, &mit)) {
-        path = dbus_message_get_path(msg);
+        mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, &prop);
 
-        parse_property(&mit, &prop, &type, &value);
+        p_info = (property_info_t *)mrp_htbl_lookup(prop_tbl, (void*)prop);
+        if (p_info) {
+            mrp_dbus_msg_enter_container(msg, MRP_DBUS_TYPE_VARIANT, NULL);
 
-        if (path && prop) {
-            if (!strcmp(prop, "Online")) {
-                modem = find_modem_by_path(ctx, path);
+            /* NOTE: Currently we handle only string arrays, should modify
+             *       based on need
+             */
+            if (p_info->type == MRP_DBUS_TYPE_ARRAY)
+                mrp_dbus_msg_read_array(msg, MRP_DBUS_TYPE_STRING,
+                                        &p_info->value, &p_info->n_values);
+            else if (mrp_dbus_is_basic_type(p_info->type))
+                mrp_dbus_msg_read_basic(msg, p_info->type, &p_info->value);
 
-                if (value.bool_val) {
-                    if (path && !modem) {
-                        if ((modem = create_modem(ctx, path, "", ""))) {
-                            query_modem(modem);
-                            query_handsfree(modem);
-                        }
-                    }
-                }
-                else {
-                    if (modem)
-                        destroy_modem(modem);
-                }
-            }
+            mrp_dbus_msg_exit_container(msg); /* v */
+            n_found++;
         }
-    }
 
-    return FALSE;
-}
+        mrp_dbus_msg_exit_container(msg); /* "{sv}" */
 
-static int handsfree_property_changed_cb(mrp_dbus_t *dbus,
-                                         DBusMessage *msg,
-                                         void *user_data)
-{
-    context_t *ctx = (context_t *)user_data;
-    dbusif_t *dbusif;
-    DBusMessageIter mit;
-    const char *path;
-    modem_t *modem;
-    const char *prop;
-    int type;
-    DBusBasicValue value;
-    hfp_state_t state;
-
-    MRP_UNUSED(dbus);
-
-    if (ctx && (dbusif = ctx->dbusif) && dbus_message_iter_init(msg, &mit)) {
-        path = dbus_message_get_path(msg);
-
-        parse_property(&mit, &prop, &type, &value);
-
-        if (path && prop) {
-            if (!strcmp(prop, "VoiceRecognition")) {
-                if ((modem = find_modem_by_path(ctx, path))) {
-                    if (value.bool_val)
-                        state = VOICE_RECOGNITION_ON;
-                    else
-                        state = VOICE_RECOGNITION_OFF;
-
-                    set_modem_state(modem, state);
-               }
-            }
-        }
+        /* check if found all requested properties */
+        if (n_found == size)
+          break;
     }
 
-    return FALSE;
+    mrp_dbus_msg_exit_container(msg); /* a{sv} */
 }
 
-static void modem_query_all_cb(mrp_dbus_t *dbus,
-                               DBusMessage *msg,
-                               void *user_data)
+static void parse_modem_properties(mrp_dbus_msg_t *msg,
+                                   const char **btaddr,
+                                   const char **btname,
+                                   uint32_t *online)
 {
-    context_t *ctx = (context_t *)user_data;
-    dbusif_t *dbusif;
-    device_t *dev;
-    const char *path;
-    const char *addr;
-    const char *name;
-    dbus_bool_t online;
-    modem_t *modem;
-    DBusMessageIter mit, ait, sit;
-
-    MRP_UNUSED(dbus);
-
-    if (ctx && (dbusif = ctx->dbusif) && dbus_message_iter_init(msg, &mit)) {
-        if (dbus_message_iter_get_arg_type(&mit) != DBUS_TYPE_ARRAY)
-            return;
-
-        dbus_message_iter_recurse(&mit, &ait);
+    bool has_handsfree_interface = FALSE;
 
-        while (dbus_message_iter_get_arg_type(&ait) == DBUS_TYPE_STRUCT) {
-            dbus_message_iter_recurse(&ait, &sit);
+    if (!msg || !btaddr || !btname || !online)
+        return;
 
-            if (dbus_message_iter_get_arg_type(&sit) == DBUS_TYPE_OBJECT_PATH){
-                dbus_message_iter_get_basic(&sit, &path);
-                dbus_message_iter_next(&sit);
-                parse_modem_properties(ctx, &sit, &addr, &name, &online);
+    const char **interfaces = NULL;
+    mrp_htbl_config_t conf = {
+      .nbucket = 0,
+      .nentry = 4,
+      .comp = mrp_string_comp,
+      .hash = mrp_string_hash,
+      .free = property_hash_free
+    };
+    property_info_t *info = NULL;
+    mrp_htbl_t *prop_tbl = mrp_htbl_create(&conf);
+
+    info = property_info_new(MRP_DBUS_TYPE_STRING);
+    mrp_htbl_insert(prop_tbl, "Name", info);
+    info = property_info_new(MRP_DBUS_TYPE_STRING);
+    mrp_htbl_insert(prop_tbl, "Serial", info);
+    info = property_info_new(MRP_DBUS_TYPE_BOOLEAN);
+    mrp_htbl_insert(prop_tbl, "Online", info);
+    info = property_info_new(MRP_DBUS_TYPE_ARRAY);
+    mrp_htbl_insert(prop_tbl, "Interfaces", info);
+
+    parse_propertites(msg, prop_tbl, 4);
+
+    info = (property_info_t *)mrp_htbl_lookup(prop_tbl, (void*)"Name");
+    *btname = (const char *)info->value;
+    info = (property_info_t *)mrp_htbl_lookup(prop_tbl, (void*)"Serial");
+    *btaddr = (const char *)info->value;
+    info = (property_info_t *)mrp_htbl_lookup(prop_tbl, (void*)"Online");
+    *online = *(uint32_t *)info->value;
+    info = (property_info_t *)mrp_htbl_lookup(prop_tbl, (void*)"Interfaces");
+    interfaces = (const char **)info->value;
+    if (interfaces) {
+      size_t i;
+
+      for (i = 0; i < info->n_values; i++) {
+        if (!strcmp(interfaces[i], "org.ofono.Handsfree")) {
+          has_handsfree_interface = TRUE;
+          break;
+        }
+      }
+    }
 
-                if (path && online) {
-                    if ((dev = clients_add_device(ctx, addr)) &&
-                        (modem = create_modem(ctx, path, name, addr)))
-                    {
-                        modem->device = dev;
-                        dev->modem = modem;
+    mrp_htbl_destroy(prop_tbl, TRUE);
 
-                        mrp_log_info("created bluetooth modem '%s' @ %s "
-                                     "(path %s)", modem->name, modem->addr,
-                                     modem->path);
-                        query_handsfree(modem);
-                    }
-                }
-            }
-
-            dbus_message_iter_next(&ait);
-        }
+    if (!has_handsfree_interface) {
+     //   *btname = "<unknown>";
+     //   *btaddr = "<unknown>";
+        *online = FALSE;
     }
 }
 
 static void modem_query_cb(mrp_dbus_t *dbus,
-                           DBusMessage *msg,
+                           mrp_dbus_msg_t *msg,
                            void *user_data)
 {
     modem_t *modem = (modem_t *)user_data;
-    device_t *dev;
-    context_t *ctx;
-    const char *addr;
-    const char *name;
-    dbus_bool_t online;
-    DBusMessageIter mit;
+    context_t *ctx = NULL;
 
     MRP_UNUSED(dbus);
 
     if (modem && (ctx = modem->ctx)) {
+        if (mrp_dbus_msg_type(msg) != MRP_DBUS_MESSAGE_TYPE_ERROR) {
+            const char *addr = NULL;
+            const char *name = NULL;
+            uint32_t online;
+            device_t *dev = NULL;
 
-        if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR) {
-            if (dbus_message_iter_init(msg, &mit)) {
-                parse_modem_properties(ctx, &mit, &addr, &name, &online);
+            parse_modem_properties(msg, &addr, &name, &online);
 
-                if (!online || !name || !(dev = clients_add_device(ctx, addr)))
-                    destroy_modem(modem);
-                else {
-                    mrp_free((void *)modem->addr);
-                    mrp_free((void *)modem->name);
+            if (!online || !name || !(dev = clients_add_device(ctx, addr)))
+                destroy_modem(modem);
+            else {
+                mrp_free((void *)modem->addr);
+                mrp_free((void *)modem->name);
 
-                    modem->addr = mrp_strdup(addr);
-                    modem->name = mrp_strdup(name);
-                    modem->device = dev;
+                modem->addr = mrp_strdup(addr);
+                modem->name = mrp_strdup(name);
+                modem->device = dev;
 
-                    dev->modem = modem;
+                dev->modem = modem;
 
-                    mrp_log_info("created bluetooth modem '%s' @ %s (path %s)",
-                                 modem->name, modem->addr, modem->path);
-                }
+                mrp_log_info("created bluetooth modem '%s' @ %s (path %s)",
+                             modem->name, modem->addr, modem->path);
             }
         }
 
@@ -518,29 +334,58 @@ static void modem_query_cb(mrp_dbus_t *dbus,
     }
 }
 
-static void handsfree_query_cb(mrp_dbus_t *dbus,
-                               DBusMessage *msg,
-                               void *user_data)
+static void query_modem(modem_t *modem)
 {
-    modem_t *modem = (modem_t *)user_data;
-    context_t *ctx;
-    hfp_state_t state;
-    DBusMessageIter mit;
+    context_t *ctx = NULL;
+    dbusif_t *dbusif = NULL;
+    modem_t *ref = NULL;
 
-    MRP_UNUSED(dbus);
+    if (!modem || !modem->path || !(ctx = modem->ctx) ||
+        !(dbusif = ctx->dbusif))
+        return;
 
-    if (modem && (ctx = modem->ctx)) {
+    if ((ref = reference_modem(modem))) {
+        mrp_dbus_msg_t *msg = mrp_dbus_msg_method_call(dbusif->dbus,
+                                                       "org.ofono",
+                                                       modem->path,
+                                                       "org.ofono.Modem",
+                                                       "GetProperties");
+        mrp_dbus_send(dbusif->dbus, "org.ofono", modem->path, "org.ofono.Modem",
+                      "GetProperties", 1000, modem_query_cb, ref, msg);
+        mrp_dbus_msg_unref(msg);
+    }
+}
+
+static void parse_handsfree_properties(modem_t *modem,
+                                       mrp_dbus_msg_t *msg,
+                                       hfp_state_t *state)
+{
+    mrp_htbl_config_t conf = {
+      .nbucket = 0,
+      .nentry = 1,
+      .comp = mrp_string_comp,
+      .hash = mrp_string_hash,
+      .free = property_hash_free
+    };
+    property_info_t *info = NULL;
+    mrp_htbl_t *prop_tbl = NULL;
+
+    if (!modem || !msg || !state)
+        return;
 
-        if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR) {
+    *state = VOICE_RECOGNITION_UNKNOWN;
 
-            if (dbus_message_iter_init(msg, &mit)) {
-                parse_handsfree_properties(modem, &mit, &state);
-                set_modem_state(modem, state);
-            }
+    prop_tbl = mrp_htbl_create(&conf);
+    info = property_info_new(MRP_DBUS_TYPE_BOOLEAN);
+    mrp_htbl_insert(prop_tbl, "VoiceRecognition", info);
 
-            unreference_modem(modem);
-        }
-    }
+    parse_propertites(msg, prop_tbl, 1);
+
+    *state = (uint32_t)(ptrdiff_t)((property_info_t *)mrp_htbl_lookup(
+        prop_tbl, (void*)"VoiceRecognition"))->value ?
+                  VOICE_RECOGNITION_ON : VOICE_RECOGNITION_OFF;
+
+    mrp_htbl_destroy(prop_tbl, TRUE);
 }
 
 static void set_modem_state(modem_t *modem, hfp_state_t state)
@@ -551,13 +396,17 @@ static void set_modem_state(modem_t *modem, hfp_state_t state)
     if (state == modem->state)
         return;
 
+    modem->state = state;
+
+    if (!(device = modem->device))
+        return;
+
     switch (state) {
 
     case VOICE_RECOGNITION_ON:
         mrp_log_info("bluetooth modem: setting voicerecognition on "
                      "for modem %s", modem->addr);
-        modem->state = VOICE_RECOGNITION_ON;
-        if ((device = modem->device) && (card = device->card)) {
+        if ((card = device->card)) {
             pulseif_set_card_profile(card, "hfgw");
         }
         break;
@@ -565,10 +414,7 @@ static void set_modem_state(modem_t *modem, hfp_state_t state)
     case VOICE_RECOGNITION_OFF:
         mrp_log_info("bluetooth modem: setting voicerecognition off "
                      "for modem %s", modem->addr);
-        modem->state = VOICE_RECOGNITION_OFF;
-        if ((device = modem->device)) {
-            clients_stop_recognising_voice(device);
-        }
+        clients_stop_recognising_voice(device);
         break;
 
     default:
@@ -578,173 +424,323 @@ static void set_modem_state(modem_t *modem, hfp_state_t state)
     }
 }
 
-static void parse_modem_properties(context_t *ctx,
-                                   DBusMessageIter *sit,
-                                   const char **btaddr,
-                                   const char **btname,
-                                   dbus_bool_t *online)
+static void handsfree_query_cb(mrp_dbus_t *dbus,
+                               mrp_dbus_msg_t *msg,
+                               void *user_data)
 {
-    const char *prop;
-    int type;
-    DBusBasicValue value;
-    DBusMessageIter ait, dit, vit, iit;
-    dbus_bool_t has_handsfree_interface = FALSE;
+    modem_t *modem = (modem_t *)user_data;
+    hfp_state_t state = VOICE_RECOGNITION_UNKNOWN;
 
-    if (!ctx || !sit || !btaddr || !btname || !online)
-        return;
+    MRP_UNUSED(dbus);
 
-    *btname = "<unknown>";
-    *btaddr = "<unknown>";
-    *online = FALSE;
+    if (!modem) return;
 
-    if (dbus_message_iter_get_arg_type(sit) != DBUS_TYPE_ARRAY)
-        return;
+    if (mrp_dbus_msg_type(msg) != MRP_DBUS_MESSAGE_TYPE_ERROR) {
+        parse_handsfree_properties(modem, msg, &state);
+        set_modem_state(modem, state);
+     }
 
-    dbus_message_iter_recurse(sit, &ait);
-
-    while (dbus_message_iter_get_arg_type(&ait) == DBUS_TYPE_DICT_ENTRY) {
+     unreference_modem(modem);
+}
 
-        dbus_message_iter_recurse(&ait, &dit);
+static void query_handsfree(modem_t *modem)
+{
+    context_t *ctx = NULL;;
+    dbusif_t *dbusif = NULL;
+    modem_t *ref = NULL;
 
-        dbus_message_iter_get_basic(&dit, &prop);
-        dbus_message_iter_next(&dit);
+    if (!modem || !modem->path || !(ctx = modem->ctx) ||
+        !(dbusif = ctx->dbusif))
+        return;
 
-        dbus_message_iter_recurse(&dit, &vit);
-        type = dbus_message_iter_get_arg_type(&vit);
+    if ((ref = reference_modem(modem))) {
+        mrp_dbus_msg_t *msg = mrp_dbus_msg_method_call(dbusif->dbus,
+                                                       "org.ofono",
+                                                       modem->path,
+                                                       "org.ofono.Handsfree",
+                                                       "GetProperties");
+        mrp_dbus_send(dbusif->dbus, "org.ofono", modem->path,
+                      "org.ofono.Handsfree", "GetProperties", 1000,
+                      handsfree_query_cb, ref, msg);
+        mrp_dbus_msg_unref(msg);
+    }
+}
 
-        if (type != DBUS_TYPE_ARRAY) {
-            memset(&value, 0, sizeof(value));
-            dbus_message_iter_get_basic(&vit, &value);
+static int modem_property_changed_cb(mrp_dbus_t *dbus,
+                                     mrp_dbus_msg_t *msg,
+                                     void *user_data)
+{
+    context_t *ctx = (context_t *)user_data;
+    const char *path = NULL;
+    uint32_t is_online = FALSE;
 
-            if (!strcmp(prop, "Online"))
-                *online = value.bool_val;
-            else if(!strcmp(prop, "Name"))
-                *btname = value.str;
-            else if (!strcmp(prop, "Serial"))
-                *btaddr = value.str;
-        }
-        else {
-            if (!strcmp(prop, "Interfaces")) {
-                dbus_message_iter_recurse(&vit, &iit);
+    MRP_UNUSED(dbus);
 
-                while (dbus_message_iter_get_arg_type(&iit)==DBUS_TYPE_STRING){
-                    dbus_message_iter_get_basic(&iit, &value);
+    if (!ctx || !ctx->dbusif ||
+        !(path = mrp_dbus_msg_path(msg)))
+        return FALSE;
 
-                    if (!strcmp(value.str, "org.ofono.Handsfree")) {
-                        has_handsfree_interface = TRUE;
-                        break;
-                    }
+    if (parse_property_value_basic(msg, "Online", MRP_DBUS_TYPE_BOOLEAN,
+                                   &is_online)) {
+        modem_t *modem = find_modem_by_path(ctx, path);
 
-                    dbus_message_iter_next(&iit);
+        if (is_online) {
+            if (!modem) {
+                if ((modem = create_modem(ctx, path, "", ""))) {
+                    query_modem(modem);
+                    query_handsfree(modem);
                 }
             }
+        } else if (modem) {
+            destroy_modem(modem);
         }
-
-        dbus_message_iter_next(&ait);
     }
 
-    if (!has_handsfree_interface) {
-        *btname = "<unknown>";
-        *btaddr = "<unknown>";
-        *online = FALSE;
+    return FALSE;
+}
+
+
+static int handsfree_property_changed_cb(mrp_dbus_t *dbus,
+                                         mrp_dbus_msg_t *msg,
+                                         void *user_data)
+{
+    context_t *ctx = (context_t *)user_data;
+    const char *path = mrp_dbus_msg_path(msg);
+    modem_t *modem = NULL;
+    uint32_t state = FALSE;
+
+    MRP_UNUSED(dbus);
+
+    if (!ctx || !ctx->dbusif || !path)
+        return FALSE;
+
+    if (!(modem = find_modem_by_path(ctx, path)))
+        return FALSE;
+
+    if (parse_property_value_basic(msg, "VoiceRecognition",
+                                   MRP_DBUS_TYPE_BOOLEAN, &state)) {
+        set_modem_state(modem,
+                        state ? VOICE_RECOGNITION_ON : VOICE_RECOGNITION_OFF);
     }
+
+    return FALSE;
 }
 
-static void parse_handsfree_properties(modem_t *modem,
-                                       DBusMessageIter *sit,
-                                       hfp_state_t *state)
+static void modem_query_all_cb(mrp_dbus_t *dbus,
+                               mrp_dbus_msg_t *msg,
+                               void *user_data)
 {
-    const char *prop;
-    int type;
-    DBusBasicValue value;
-    DBusMessageIter ait, dit, vit;
+    context_t *ctx = (context_t *)user_data;
+    modem_t *modem;
 
-    if (!modem || !sit || !state)
-        return;
+    MRP_UNUSED(dbus);
 
-    *state = VOICE_RECOGNITION_UNKNOWN;
+    if (!ctx || !ctx->dbusif)
+        return;
 
-    if (dbus_message_iter_get_arg_type(sit) != DBUS_TYPE_ARRAY)
+    if (mrp_dbus_msg_arg_type(msg, NULL) != MRP_DBUS_TYPE_ARRAY)
         return;
 
-    dbus_message_iter_recurse(sit, &ait);
+    mrp_dbus_msg_enter_container(msg, MRP_DBUS_TYPE_ARRAY, "(oa{sv})");
 
-    while (dbus_message_iter_get_arg_type(&ait) == DBUS_TYPE_DICT_ENTRY) {
+    while (mrp_dbus_msg_enter_container(msg, MRP_DBUS_TYPE_STRUCT, NULL)) {
+        device_t *dev;
+        const char *path = NULL;
+        const char *addr;
+        const char *name;
+        uint32_t online;
 
-        dbus_message_iter_recurse(&ait, &dit);
+        mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_OBJECT_PATH, &path);
 
-        dbus_message_iter_get_basic(&dit, &prop);
-        dbus_message_iter_next(&dit);
+        parse_modem_properties(msg, &addr, &name, &online);
 
-        dbus_message_iter_recurse(&dit, &vit);
-        type = dbus_message_iter_get_arg_type(&vit);
+        mrp_log_info("Modem details: %s %s %s %d", path, addr, name, online);
 
-        if (type != DBUS_TYPE_ARRAY) {
-            memset(&value, 0, sizeof(value));
-            dbus_message_iter_get_basic(&vit, &value);
+        if (path && online) {
+            if ((dev = clients_add_device(ctx, addr)) &&
+                (modem = create_modem(ctx, path, name, addr)))
+            {
+                modem->device = dev;
+                dev->modem = modem;
 
-            if (!strcmp(prop, "VoiceRecognition")) {
-                if (value.bool_val)
-                    *state = VOICE_RECOGNITION_ON;
-                else
-                    *state = VOICE_RECOGNITION_OFF;
+                mrp_log_info("created bluetooth modem '%s' @ %s "
+                             "(path %s)", modem->name, modem->addr,
+                             modem->path);
+                query_handsfree(modem);
             }
         }
 
-        dbus_message_iter_next(&ait);
+        mrp_dbus_msg_exit_container(msg); /* (oa{sv}) */
     }
+
+    mrp_dbus_msg_exit_container(msg); /* a(oa{sv}) */
 }
 
-static void parse_property(DBusMessageIter *it,
-                           const char **name,
-                           int *type,
-                           DBusBasicValue *value)
+static void track_modems(context_t *ctx, bool track)
 {
-    DBusMessageIter vit;
+    static const char *modem_interface = "org.ofono.Modem";
+    static const char *handsfree_interface = "org.ofono.Handsfree";
+    static const char *member = "PropertyChanged";
+    dbusif_t *dbusif = NULL;
+
+    if (!ctx || !(dbusif = ctx->dbusif))
+        return;
+
+    if (track) {
+        mrp_dbus_add_signal_handler(dbusif->dbus, NULL, NULL,
+                                    modem_interface, member,
+                                    modem_property_changed_cb, ctx);
+        mrp_dbus_add_signal_handler(dbusif->dbus, NULL, NULL,
+                                    handsfree_interface, member,
+                                    handsfree_property_changed_cb, ctx);
+        mrp_dbus_install_filter(dbusif->dbus, NULL, NULL,
+                                modem_interface, member, NULL);
+        mrp_dbus_install_filter(dbusif->dbus, NULL, NULL,
+                                handsfree_interface, member, NULL);
+    }
+    else {
+        mrp_dbus_del_signal_handler(dbusif->dbus, NULL, NULL,
+                                    modem_interface, member,
+                                    modem_property_changed_cb, ctx);
+        mrp_dbus_del_signal_handler(dbusif->dbus, NULL, NULL,
+                                    handsfree_interface, member,
+                                    handsfree_property_changed_cb, ctx);
+        mrp_dbus_remove_filter(dbusif->dbus, NULL, NULL,
+                               modem_interface, member, NULL);
+        mrp_dbus_remove_filter(dbusif->dbus, NULL, NULL,
+                               handsfree_interface, member, NULL);
+    }
+}
 
-    if (it && name && type && value) {
-        if (dbus_message_iter_get_arg_type(it) != DBUS_TYPE_STRING)
-            goto failed;
+static void query_all_modems(context_t *ctx)
+{
+    uint32_t query_id;
+    dbusif_t *dbusif = NULL;
 
-        dbus_message_iter_get_basic(it, name);
+    if (!ctx || !(dbusif = ctx->dbusif))
+        return;
 
-        if (!dbus_message_iter_next(it))
-            goto failed;
+    query_id = mrp_dbus_call(dbusif->dbus,
+                             "org.ofono", "/", "org.ofono.Manager",
+                             "GetModems", 1000, modem_query_all_cb, ctx,
+                             MRP_DBUS_TYPE_INVALID);
+    if (query_id == 0) {
+      /* query modems failed */
+    }
+}
 
-        if (dbus_message_iter_get_arg_type(it) != DBUS_TYPE_VARIANT)
-            goto failed;
+static void set_property(mrp_dbus_msg_t *msg,
+                         const char *name,
+                         mrp_dbus_type_t type,
+                         void *value)
+{
+    mrp_dbus_msg_open_container(msg, MRP_DBUS_TYPE_DICT_ENTRY, NULL);
 
-        dbus_message_iter_recurse(it, &vit);
+    mrp_dbus_msg_append_basic(msg, DBUS_TYPE_STRING, (void*)name);
 
-        if ((*type = dbus_message_iter_get_arg_type(&vit)) == DBUS_TYPE_ARRAY)
-            goto failed;
+    mrp_dbus_msg_open_container(msg, MRP_DBUS_TYPE_VARIANT, NULL);
+    mrp_dbus_msg_append_basic(msg, (char)type, value);
+    mrp_dbus_msg_close_container(msg); /* variant */
 
-        dbus_message_iter_get_basic(&vit, value);
+    mrp_dbus_msg_close_container(msg); /* dictionary */
+}
 
-        return;
+int dbusif_create(context_t *ctx, mrp_mainloop_t *ml)
+{
+    dbusif_t *dbusif;
+
+    if (!(dbusif = mrp_allocz(sizeof(dbusif_t))))
+        return -1;
+
+    dbusif->bustype = mrp_strdup("system");
+    dbusif->dbus = mrp_dbus_get(ml, dbusif->bustype, NULL);
+
+    if (!dbusif->dbus) {
+        mrp_log_error("bluetooth voice recognition plugin: "
+                      "failed to obtain DBus");
+        mrp_free(dbusif);
+        return -1;
     }
 
- failed:
-    *name = "<unknown>";
-    *type = 0;
-    memset(value, 0, sizeof(*value));
+    mrp_list_init(&dbusif->modems);
+
+    ctx->dbusif = dbusif;
+
+    return 0;
 }
 
-static void set_property(DBusMessageIter *it,
-                         const char *name,
-                         int type,
-                         void *value)
+void dbusif_destroy(context_t *ctx)
 {
-    char type_str[2] = { type, 0 };
-    DBusMessageIter vit;
+    dbusif_t *dbusif;
+
+    if (ctx && (dbusif = ctx->dbusif)) {
+        ctx->dbusif = NULL;
 
-    dbus_message_iter_append_basic(it, DBUS_TYPE_STRING, &name);
+        mrp_dbus_unref(dbusif->dbus);
 
-    dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, type_str, &vit);
-    dbus_message_iter_append_basic(&vit, type, value);
-    dbus_message_iter_close_container(it, &vit);
+        mrp_free((void *)dbusif->bustype);
+        mrp_free((void *)dbusif);
+    }
+}
+
+int dbusif_start(context_t *ctx)
+{
+    track_modems(ctx, TRUE);
+    query_all_modems(ctx);
+    return 0;
+}
+
+void dbusif_stop(context_t *ctx)
+{
+    dbusif_t *dbusif;
+    modem_t *modem;
+    mrp_list_hook_t *entry, *n;
+
+    track_modems(ctx, FALSE);
+
+    if (ctx && (dbusif = ctx->dbusif)) {
+        mrp_list_foreach(&dbusif->modems, entry, n) {
+            modem = mrp_list_entry(entry, modem_t, link);
+            destroy_modem(modem);
+        }
+    }
 }
 
+int dbusif_set_voice_recognition(modem_t *modem, hfp_state_t state)
+{
+    context_t *ctx = NULL;
+    dbusif_t *dbusif = NULL;;
+    mrp_dbus_msg_t *msg = NULL;
+    uint32_t value;
+
+    if (!modem || !modem->path || !(ctx = modem->ctx) ||
+        !(dbusif = ctx->dbusif))
+        return -1;
+
+    switch (state) {
+    case VOICE_RECOGNITION_ON:   value = TRUE;    break;
+    case VOICE_RECOGNITION_OFF:  value = FALSE;   break;
+    default:                     /* invalid */    return -1;
+    }
+
+    msg = mrp_dbus_msg_method_call(dbusif->dbus, "org.ofono",
+                                   modem->path,
+                                   "org.ofono.Handsfree",
+                                   "SetProperty");
+
+    if (!msg)
+        return -1;
+
+    set_property(msg, "VoiceRecognition", MRP_DBUS_TYPE_BOOLEAN, &value);
+
+    mrp_dbus_send_msg(dbusif->dbus, msg);
+
+    mrp_dbus_msg_unref(msg);
+
+    return 0;
+}
+
+
 /*
  * Local Variables:
  * c-basic-offset: 4
index 6bbd1a0..ac09859 100644 (file)
@@ -28,7 +28,7 @@ static card_t *add_card(context_t *, uint32_t, const char *, const char *,
 static void remove_card(card_t *);
 
 static card_t *find_card_by_index(context_t *, uint32_t);
-static card_t *find_card_by_address(context_t *, const char *);
+//static card_t *find_card_by_address(context_t *, const char *);
 static card_t *find_card_by_sink(context_t *, uint32_t);
 static card_t *find_card_by_source(context_t *, uint32_t);
 
@@ -290,7 +290,7 @@ static card_t *find_card_by_index(context_t *ctx, uint32_t idx)
     return NULL;
 }
 
-
+#if 0
 static card_t *find_card_by_address(context_t *ctx, const char *addr)
 {
     pulseif_t *pulseif;
@@ -308,7 +308,7 @@ static card_t *find_card_by_address(context_t *ctx, const char *addr)
 
     return NULL;
 }
-
+#endif
 
 static card_t *find_card_by_sink(context_t *ctx, uint32_t idx)
 {