dbus-client-interface: use the new Murphy D-Bus API.
authorKrisztian Litkey <kli@iki.fi>
Tue, 1 Oct 2013 16:49:42 +0000 (19:49 +0300)
committerKrisztian Litkey <kli@iki.fi>
Fri, 10 Jan 2014 15:07:29 +0000 (17:07 +0200)
configure.ac
src/Makefile.am
src/client/client.c
src/daemon/client.c
src/daemon/client.h
src/daemon/context.h
src/daemon/daemon.c
src/daemon/resourceif.c
src/plugins/dbus-client-interface/dbus-client.c

index bada291..ae3c43f 100644 (file)
@@ -131,7 +131,7 @@ if test "$enable_dbus" = "yes"; then
     DBUS_SESSION_DIR="`pkg-config --variable session_bus_services_dir dbus-1`"
     AC_SUBST(DBUS_SESSION_DIR)
 
-    PKG_CHECK_MODULES(MURPHY_DBUS, murphy-dbus)
+    PKG_CHECK_MODULES(MURPHY_DBUS, murphy-dbus-libdbus)
 else
     AC_MSG_NOTICE([D-Bus support is disabled.])
 fi
@@ -147,6 +147,12 @@ AC_SUBST(MURPHY_DBUS_LIBS)
 AC_SUBST(DBUS_CFLAGS)
 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=""
 SRS_LIBS=""
index 5b71e65..9c220ff 100644 (file)
@@ -20,6 +20,7 @@ srs_daemon_SOURCES =                          \
                daemon/daemon.c                 \
                daemon/config.c                 \
                daemon/resourceif.c             \
+               daemon/resctl.c                 \
                daemon/client.c                 \
                daemon/plugin.c                 \
                daemon/audiobuf.c               \
@@ -161,7 +162,7 @@ plugin_simple_disambiguator_la_LDFLAGS =                    \
 
 plugin_simple_disambiguator_la_LIBADD  =
 
-if DBUS_ENABLED
+if MPRIS2_ENABLED
 # Mpris2 client plugin
 plugin_LTLIBRARIES += plugin-mpris2-client.la
 
@@ -184,7 +185,7 @@ plugin_mpris2_client_la_LIBADD  =                           \
 endif
 
 
-if DBUS_ENABLED
+if BLUETOOTH_ENABLED
 # Bluetooth client plugin
 plugin_LTLIBRARIES += plugin-bluetooth-client.la
 
index af1f619..f7b9b52 100644 (file)
@@ -37,7 +37,7 @@
 #include <murphy/common/mm.h>
 #include <murphy/common/debug.h>
 #include <murphy/common/mainloop.h>
-#include <murphy/common/dbus.h>
+#include <murphy/common/dbus-libdbus.h>
 #include <murphy/common/pulse-glue.h>
 
 #include <breedline/breedline-murphy.h>
@@ -385,7 +385,7 @@ static client_t *create_client(const char *argv0)
 }
 
 
-static int focus_notify(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data)
+static int focus_notify(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg, void *user_data)
 {
     client_t   *c = (client_t *)user_data;
     const char *focus;
@@ -393,8 +393,7 @@ static int focus_notify(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data)
     MRP_UNUSED(dbus);
 
     hide_prompt(c);
-    if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &focus,
-                              DBUS_TYPE_INVALID))
+    if (mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, &focus))
         print(c, "Voice focus is now: %s", focus);
     else
         print(c, "Failed to parse voice focus notification.");
@@ -404,7 +403,7 @@ static int focus_notify(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data)
 }
 
 
-static int voice_command_notify(mrp_dbus_t *dbus, DBusMessage *msg,
+static int voice_command_notify(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
                                 void *user_data)
 {
     client_t   *c = (client_t *)user_data;
@@ -413,8 +412,7 @@ static int voice_command_notify(mrp_dbus_t *dbus, DBusMessage *msg,
     MRP_UNUSED(dbus);
 
     hide_prompt(c);
-    if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &command,
-                              DBUS_TYPE_INVALID))
+    if (mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, &command))
         print(c, "Received voice command: %s", command);
     else
         print(c, "Failed to parse voice command notification.");
@@ -424,7 +422,7 @@ static int voice_command_notify(mrp_dbus_t *dbus, DBusMessage *msg,
 }
 
 
-static int voice_render_notify(mrp_dbus_t *dbus, DBusMessage *msg,
+static int voice_render_notify(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
                                void *user_data)
 {
     client_t   *c = (client_t *)user_data;
@@ -436,10 +434,8 @@ static int voice_render_notify(mrp_dbus_t *dbus, DBusMessage *msg,
     MRP_UNUSED(dbus);
 
     hide_prompt(c);
-    if (!dbus_message_get_args(msg, NULL,
-                               DBUS_TYPE_UINT32, &id,
-                               DBUS_TYPE_STRING, &event,
-                               DBUS_TYPE_INVALID)) {
+    if (!mrp_dbus_msg_read_basic(msg, DBUS_TYPE_UINT32, &id) ||
+        !mrp_dbus_msg_read_basic(msg, DBUS_TYPE_STRING, &event)) {
         print(c, "Failed to parse voice render event notification.");
         return TRUE;
     }
@@ -447,13 +443,14 @@ static int voice_render_notify(mrp_dbus_t *dbus, DBusMessage *msg,
     if (!strcmp(event, "progress")) {
         pcnt = -1.0;
         msec = (uint32_t)-1;
-        dbus_message_get_args(msg, NULL,
-                              DBUS_TYPE_UINT32, &id,
-                              DBUS_TYPE_STRING, &event,
-                              DBUS_TYPE_DOUBLE, &pcnt,
-                              DBUS_TYPE_UINT32, &msec,
-                              DBUS_TYPE_INVALID);
-        print(c, "Rendering <%u> progress: %f %% (%u msecs)", id, pcnt, msec);
+        if (mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_UINT32, &id) &&
+            mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, &event) &&
+            mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_DOUBLE, &pcnt) &&
+            mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_UINT32, &msec))
+            print(c, "Rendering <%u> progress: %f %% (%u msecs)", id,
+                  pcnt, msec);
+        else
+            print(c, "Rendering <%u> progress: failed to parse message", id);
     }
     else
         print(c, "Rendering <%u>: %s", id, event);
@@ -749,13 +746,14 @@ static void parse_cmdline(client_t *c, int argc, char **argv)
 }
 
 
-static void register_reply(mrp_dbus_t *dbus, DBusMessage *rpl, void *user_data)
+static void register_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl,
+                           void *user_data)
 {
     client_t *c = (client_t *)user_data;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
+    if (mrp_dbus_msg_type(rpl) == MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN) {
         set_prompt(c, c->app_name);
         print(c, "Successfully registered to server.");
         if (c->autofocus)
@@ -785,22 +783,22 @@ static void register_client(client_t *c)
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
                        register_reply, c,
-                       DBUS_TYPE_STRING, &c->app_name,
-                       DBUS_TYPE_STRING, &c->app_class,
-                       DBUS_TYPE_ARRAY , DBUS_TYPE_STRING, &cmds, ncmd,
-                       DBUS_TYPE_INVALID))
+                       MRP_DBUS_TYPE_STRING, c->app_name,
+                       MRP_DBUS_TYPE_STRING, c->app_class,
+                       MRP_DBUS_TYPE_ARRAY , MRP_DBUS_TYPE_STRING, cmds, ncmd,
+                       MRP_DBUS_TYPE_INVALID))
         print(c, "Failed to send register message to server.");
 }
 
 
-static void unregister_reply(mrp_dbus_t *dbus, DBusMessage *rpl,
+static void unregister_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl,
                              void *user_data)
 {
     client_t *c = (client_t *)user_data;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
+    if (mrp_dbus_msg_type(rpl) == MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN) {
         set_prompt(c, "unregistered");
         print(c, "Successfully unregistered from server.");
     }
@@ -822,18 +820,18 @@ static void unregister_client(client_t *c)
     }
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
-                       unregister_reply, c, DBUS_TYPE_INVALID))
+                       unregister_reply, c, MRP_DBUS_TYPE_INVALID))
         print(c, "Failed to send unregister message to server.");
 }
 
 
-static void focus_reply(mrp_dbus_t *dbus, DBusMessage *rpl, void *user_data)
+static void focus_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl, void *user_data)
 {
     client_t *c = (client_t *)user_data;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
+    if (mrp_dbus_msg_type(rpl) == MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN)
         print(c, "Focus request sent to server.");
     else
         print(c, "Focus request failed on server.");
@@ -854,18 +852,18 @@ static void request_focus(client_t *c, const char *focus)
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
                        focus_reply, c,
-                       DBUS_TYPE_STRING, &focus, DBUS_TYPE_INVALID))
+                       MRP_DBUS_TYPE_STRING, focus, DBUS_TYPE_INVALID))
         print(c, "Failed to send focus request to server.");
 }
 
 
-static void render_reply(mrp_dbus_t *dbus, DBusMessage *rpl, void *user_data)
+static void render_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl, void *user_data)
 {
     client_t *c = (client_t *)user_data;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
+    if (mrp_dbus_msg_type(rpl) == MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN)
         print(c, "TTS render request succeeded.");
     else
         print(c, "TTS render request failed on server.");
@@ -902,24 +900,25 @@ static void request_render_voice(client_t *c, const char *msg, const char *vid,
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
                        render_reply, c,
-                       DBUS_TYPE_STRING, &msg,
-                       DBUS_TYPE_STRING, &vid,
-                       DBUS_TYPE_INT32 , &to,
-                       DBUS_TYPE_ARRAY , DBUS_TYPE_STRING, &events, nevent,
-                       DBUS_TYPE_INVALID))
+                       MRP_DBUS_TYPE_STRING, msg,
+                       MRP_DBUS_TYPE_STRING, vid,
+                       MRP_DBUS_TYPE_INT32 , &to,
+                       MRP_DBUS_TYPE_ARRAY ,
+                       MRP_DBUS_TYPE_STRING, events, nevent,
+                       MRP_DBUS_TYPE_INVALID))
         print(c, "Failed to send voice cancel request to server.");
 
     return;
 }
 
 
-static void cancel_reply(mrp_dbus_t *dbus, DBusMessage *rpl, void *user_data)
+static void cancel_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl, void *user_data)
 {
     client_t *c = (client_t *)user_data;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
+    if (mrp_dbus_msg_type(rpl) == MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN)
         print(c, "TTS cancel request succeeded.");
     else
         print(c, "TTS cancel request failed on server.");
@@ -940,63 +939,55 @@ static void request_cancel_voice(client_t *c, uint32_t id)
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
                        cancel_reply, c,
-                       DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID))
+                       MRP_DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID))
         print(c, "Failed to send voice cancel request to server.");
 }
 
 
-static void voice_query_reply(mrp_dbus_t *dbus, DBusMessage *rpl,
+static void voice_query_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *rpl,
                               void *user_data)
 {
-    client_t *c = (client_t *)user_data;
-    uint32_t  nvoice;
-    int       n;
+    client_t  *c = (client_t *)user_data;
+    uint32_t   nvoice;
+    char     **voices, **lang, **dialect, **gender, **description;
+    size_t     dummy;
+    int        i, n;
 
     MRP_UNUSED(dbus);
 
-    if (dbus_message_get_type(rpl) != DBUS_MESSAGE_TYPE_METHOD_RETURN) {
+    if (mrp_dbus_msg_type(rpl) != MRP_DBUS_MESSAGE_TYPE_METHOD_RETURN) {
         print(c, "Voice query failed.");
         return;
     }
 
-    if (!dbus_message_get_args(rpl, NULL,
-                               DBUS_TYPE_UINT32, &nvoice,
-                               DBUS_TYPE_INVALID)) {
+    if (!mrp_dbus_msg_read_basic(rpl, MRP_DBUS_TYPE_UINT32, &nvoice)) {
         print(c, "Failed to parse voice query reply.");
         return;
     }
 
-    n = (int)nvoice;
-    {
-        char **voices, **lang, **dialect, **gender, **description;
-        int    i, dummy;
-
-        if (!dbus_message_get_args(rpl, NULL,
-                                   DBUS_TYPE_UINT32, &nvoice,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                                   &voices, &dummy,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                                   &lang, &dummy,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                                   &dialect, &dummy,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                                   &gender, &dummy,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                                   &description, &dummy,
-                                   DBUS_TYPE_INVALID)) {
-            print(c, "Failed to parse voice query reply.");
-            return;
-        }
+    if (!mrp_dbus_msg_read_basic(rpl, MRP_DBUS_TYPE_UINT32, &nvoice) ||
+        !mrp_dbus_msg_read_array(rpl, MRP_DBUS_TYPE_STRING,
+                                 (void **)&voices, &dummy) ||
+        !mrp_dbus_msg_read_array(rpl, MRP_DBUS_TYPE_STRING,
+                                 (void **)&lang, &dummy) ||
+        !mrp_dbus_msg_read_array(rpl, MRP_DBUS_TYPE_STRING,
+                                 (void **)&dialect, &dummy) ||
+        !mrp_dbus_msg_read_array(rpl, MRP_DBUS_TYPE_STRING,
+                                 (void **)&gender, &dummy) ||
+        !mrp_dbus_msg_read_array(rpl, MRP_DBUS_TYPE_STRING,
+                                 (void **)&description, &dummy)) {
+        print(c, "Failed to parse voice query reply.");
+        return;
+    }
 
-        print(c, "Server has %d voice%s loaded.", nvoice,
-              nvoice == 1 ? "" : "s");
-        for (i = 0; i < nvoice; i++) {
-            print(c, "#%d: %s", i + 1, voices[i]);
-            print(c, "    language: %s", lang[i]);
-            print(c, "    dialect: %s", dialect[i] ? dialect[i] : "<none>");
-            print(c, "    gender: %s", gender[i]);
-            print(c, "    description: %s", description[i]);
-        }
+    print(c, "Server has %d voice%s loaded.", nvoice,
+          nvoice == 1 ? "" : "s");
+    for (i = 0; i < nvoice; i++) {
+        print(c, "#%d: %s", i + 1, voices[i]);
+        print(c, "    language: %s", lang[i]);
+        print(c, "    dialect: %s", dialect[i] ? dialect[i] : "<none>");
+        print(c, "    gender: %s", gender[i]);
+        print(c, "    description: %s", description[i]);
     }
 }
 
@@ -1018,8 +1009,8 @@ static void query_voices(client_t *c, const char *language)
 
     if (!mrp_dbus_call(c->dbus, dest, path, iface, method, -1,
                        voice_query_reply, c,
-                       DBUS_TYPE_STRING, &language,
-                       DBUS_TYPE_INVALID))
+                       MRP_DBUS_TYPE_STRING, language,
+                       MRP_DBUS_TYPE_INVALID))
         print(c, "Failed to send voice query request to server.");
 
     return;
index 42a557d..94006be 100644 (file)
@@ -328,7 +328,7 @@ void client_notify_command(srs_client_t *c, int index,
                            uint32_t *start, uint32_t *end,
                            srs_audiobuf_t *audio)
 {
-    if (c->enabled && /*c->allowed && */ 0 <= index && index < c->ncommand) {
+    if (c->enabled && c->allowed && 0 <= index && index < c->ncommand) {
         c->ops.notify_command(c, index, ntoken, (char **)tokens,
                               start, end, audio);
     }
index 93ae7a0..7b30035 100644 (file)
@@ -145,6 +145,7 @@ struct srs_client_s {
     srs_voice_focus_t       focus;       /* requested voice focus */
     int                     enabled : 1; /* interested in commands */
     int                     allowed : 1; /* has resource granted */
+    int                     shared : 1;  /* */
     mrp_list_hook_t         voices;      /* unfinished voice requests */
     srs_client_ops_t        ops;         /* client ops (notifications)  */
     void                   *user_data;   /* opaque client data */
index e129f06..838989e 100644 (file)
@@ -44,6 +44,7 @@
 typedef struct srs_context_s srs_context_t;
 
 #include "src/daemon/config.h"
+#include "src/daemon/resctl.h"
 
 /*
  * daemon context
@@ -59,6 +60,7 @@ struct srs_context_s {
     mrp_timer_t       *rtmr;             /* resource reconnect timer */
     mrp_res_context_t *rctx;             /* resource context */
     mrp_res_logger_t   rlog;             /* original resource logger */
+    srs_resctx_t      *resctx;           /* resource context */
     mrp_list_hook_t    recognizers;      /* speech recognition backends */
     void              *default_srec;     /* default backend */
     void              *cached_srec;      /* previously looked up backend */
index 8118855..d828833 100644 (file)
 #include "src/daemon/context.h"
 #include "src/daemon/config.h"
 #include "src/daemon/resourceif.h"
+#include "src/daemon/resctl.h"
 #include "src/daemon/plugin.h"
 #include "src/daemon/client.h"
 #include "src/daemon/recognizer.h"
 
 
 static void cleanup_mainloop(srs_context_t *srs);
+static void resctl_state_change(srs_resctl_event_t e, void *user_data);
 
 static void cleanup_context(srs_context_t *srs)
 {
     if (srs != NULL) {
+        srs_resctl_disconnect(srs);
         resource_disconnect(srs);
         cleanup_mainloop(srs);
 
@@ -129,9 +132,11 @@ static void create_mainloop(srs_context_t *srs)
         srs->ml = mrp_mainloop_glib_get(srs->gl);
     }
 
-    if (srs->pa != NULL && srs->ml != NULL)
+    if (srs->pa != NULL && srs->ml != NULL) {
+        srs_resctl_connect(srs, resctl_state_change, srs, TRUE);
         if (resource_connect(srs))
             return;
+    }
 
     cleanup_context(srs);
     exit(1);
@@ -180,6 +185,24 @@ static void cleanup_mainloop(srs_context_t *srs)
 }
 
 
+static void resctl_state_change(srs_resctl_event_t e, void *user_data)
+{
+    srs_context_t *srs = (srs_context_t *)user_data;
+
+    switch (e) {
+    case SRS_RESCTL_UP:
+        mrp_log_info("Resource control connection is up.");
+        client_create_resources(srs);
+        break;
+
+    case SRS_RESCTL_DOWN:
+        mrp_log_info("Resource control connection is down.");
+        client_reset_resources(srs);
+        break;
+    }
+}
+
+
 static void sighandler(mrp_sighandler_t *h, int signum, void *user_data)
 {
     static int rlog = FALSE;
index 70e160e..a3107e2 100644 (file)
@@ -154,7 +154,7 @@ int resource_create(srs_client_t *c)
 
     if (rset != NULL) {
         c->rset = rset;
-        shared  = (c->requested != SRS_VOICE_FOCUS_EXCLUSIVE);
+        shared  = (c->focus != SRS_VOICE_FOCUS_EXCLUSIVE);
 
         if (!mrp_res_create_resource(rctx, rset, RESOURCE, TRUE, shared)) {
             resource_destroy(c);
@@ -163,6 +163,7 @@ int resource_create(srs_client_t *c)
         }
 
         if (c->focus != SRS_VOICE_FOCUS_NONE) {
+            c->shared = !!shared;
             if (!resource_acquire(c)) {
                 resource_destroy(c);
 
@@ -182,7 +183,8 @@ void resource_destroy(srs_client_t *c)
     if (c->srs->rctx != NULL && c->rset != NULL)
         mrp_res_delete_resource_set(c->srs->rctx, c->rset);
 
-    c->rset = NULL;
+    c->rset   = NULL;
+    c->shared =  0;
 }
 
 
@@ -194,6 +196,11 @@ int resource_acquire(srs_client_t *c)
     if (c->rset == NULL && !resource_create(c))
         return FALSE;
 
+    if (c->focus != SRS_VOICE_FOCUS_SHARED && c->shared) {
+        resource_destroy(c);
+        return resource_create(c);
+    }
+
     if (mrp_res_acquire_resource_set(c->srs->rctx, c->rset) >= 0)
         return TRUE;
     else
index b05d0b6..8ae5835 100644 (file)
@@ -33,7 +33,7 @@
 #include <murphy/common/log.h>
 #include <murphy/common/debug.h>
 #include <murphy/common/debug.h>
-#include <murphy/common/dbus.h>
+#include <murphy/common/dbus-libdbus.h>
 
 #include "src/daemon/plugin.h"
 #include "src/daemon/client.h"
 
 #define MAX_COMMANDS 256
 
-static int register_req(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data);
-static int unregister_req(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data);
-static int focus_req(mrp_dbus_t *dbus, DBusMessage *msg, void *user_data);
-static int render_voice_req(mrp_dbus_t *dbus, DBusMessage *msg,void *user_data);
-static int cancel_voice_req(mrp_dbus_t *dbus, DBusMessage *msg,void *user_data);
-static int query_voices_req(mrp_dbus_t *dbus, DBusMessage *msg,void *user_data);
+static int register_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg, void *user_data);
+static int unregister_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
+                          void *user_data);
+static int focus_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg, void *user_data);
+static int render_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
+                            void *user_data);
+static int cancel_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
+                            void *user_data);
+static int query_voices_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *msg,
+                            void *user_data);
 
 static int focus_notify(srs_client_t *c, srs_voice_focus_t focus);
 static int command_notify(srs_client_t *c, int idx, int ntoken, char **tokens,
@@ -82,7 +86,7 @@ static int dbusif_setup(dbusif_t *bus)
 {
     srs_context_t  *srs = bus->self->srs;
     const char     *path, *iface, *method;
-    int           (*cb)(mrp_dbus_t *, DBusMessage *, void *);
+    int           (*cb)(mrp_dbus_t *, mrp_dbus_msg_t *, void *);
 
     mrp_debug("setting up client D-BUS interface (%s)", bus->address);
 
@@ -158,7 +162,7 @@ static void dbusif_cleanup(dbusif_t *bus)
 {
     srs_context_t  *srs = bus->self->srs;
     const char     *path, *iface, *method;
-    int           (*cb)(mrp_dbus_t *, DBusMessage *, void *);
+    int           (*cb)(mrp_dbus_t *, mrp_dbus_msg_t *, void *);
 
     mrp_debug("cleaning up client D-BUS interface");
 
@@ -221,24 +225,26 @@ static void name_change_cb(mrp_dbus_t *dbus, const char *name, int running,
 }
 
 
-static void simple_reply(mrp_dbus_t *dbus, DBusMessage *req, int errcode,
+static void simple_reply(mrp_dbus_t *dbus, mrp_dbus_msg_t *req, int errcode,
                          const char *errmsg)
 {
     int32_t error;
 
     if (!errcode)
-        mrp_dbus_reply(dbus, req, DBUS_TYPE_INVALID);
+        mrp_dbus_reply(dbus, req, MRP_DBUS_TYPE_INVALID);
     else {
         error = errcode;
-        mrp_dbus_reply_error(dbus, req, DBUS_ERROR_FAILED, errmsg,
-                             DBUS_TYPE_INT32, &error, DBUS_TYPE_INVALID);
+        mrp_dbus_reply_error(dbus, req, MRP_DBUS_ERROR_FAILED, errmsg,
+                             MRP_DBUS_TYPE_INT32, &error,
+                             MRP_DBUS_TYPE_INVALID);
     }
 }
 
 
-static void reply_render(mrp_dbus_t *dbus, DBusMessage *req, uint32_t id)
+static void reply_render(mrp_dbus_t *dbus, mrp_dbus_msg_t *req, uint32_t id)
 {
-    mrp_dbus_reply(dbus, req, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID);
+    mrp_dbus_reply(dbus, req, MRP_DBUS_TYPE_UINT32, &id,
+                   MRP_DBUS_TYPE_INVALID);
 }
 
 
@@ -255,7 +261,7 @@ static char *clear_non_us_ascii(char *s)
 }
 
 
-static void reply_voice_query(mrp_dbus_t *dbus, DBusMessage *req, int nactor,
+static void reply_voice_query(mrp_dbus_t *dbus, mrp_dbus_msg_t *req, int nactor,
                               srs_voice_actor_t *actors)
 {
     srs_voice_actor_t *a;
@@ -296,74 +302,59 @@ static void reply_voice_query(mrp_dbus_t *dbus, DBusMessage *req, int nactor,
     g  = gender;
     d  = description;
     mrp_dbus_reply(dbus, req,
-                   DBUS_TYPE_UINT32, &n,
-                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v , n,
-                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &ml, n,
-                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &sl, n,
-                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &g , n,
-                   DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &d , n,
-                   DBUS_TYPE_INVALID);
+                   MRP_DBUS_TYPE_UINT32, &n,
+                   MRP_DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v , n,
+                   MRP_DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &ml, n,
+                   MRP_DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &sl, n,
+                   MRP_DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &g , n,
+                   MRP_DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &d , n,
+                   MRP_DBUS_TYPE_INVALID);
 }
 
 
-static int parse_commands(DBusMessageIter *it, char **commands, int ncommand)
+static int parse_commands(mrp_dbus_msg_t *msg, char **commands, int ncommand)
 {
     int n;
 
     n = 0;
-    while (dbus_message_iter_get_arg_type(it) == DBUS_TYPE_STRING) {
-        if (n >= ncommand)
+    while (n < ncommand - 1) {
+        if (mrp_dbus_msg_read_basic(msg, MRP_DBUS_TYPE_STRING, commands + n))
+            n++;
+        else
             return -1;
-
-        dbus_message_iter_get_basic(it, commands + n);
-        n++;
-
-        dbus_message_iter_next(it);
     }
 
     return n;
 }
 
 
-static int parse_register(DBusMessage *req, const char **id, const char **name,
-                          const char **appclass, char **commands, int *ncommand,
-                          const char **errmsg)
+static int parse_register(mrp_dbus_msg_t *req, const char **id,
+                          const char **name, const char **appclass,
+                          char ***commands, int *ncommand, const char **errmsg)
 {
-    DBusMessageIter it, ia;
+    void   *cmds;
+    size_t  ncmd;
 
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
-    if (*id == NULL || !dbus_message_iter_init(req, &it)) {
+    if (*id == NULL) {
         *errmsg = "failed to parse register message";
         return EINVAL;
     }
 
-    if (dbus_message_iter_get_arg_type(&it) != DBUS_TYPE_STRING)
+    if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, name))
         goto malformed;
-    else
-        dbus_message_iter_get_basic(&it, name);
 
-    dbus_message_iter_next(&it);
-
-    if (dbus_message_iter_get_arg_type(&it) != DBUS_TYPE_STRING)
+    if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, appclass))
         goto malformed;
-    else
-        dbus_message_iter_get_basic(&it, appclass);
 
-    dbus_message_iter_next(&it);
+    if (mrp_dbus_msg_read_array(req, MRP_DBUS_TYPE_STRING, &cmds, &ncmd)) {
+        if (ncmd > 0) {
+            *commands = cmds;
+            *ncommand = (int)ncmd;
 
-    if (dbus_message_iter_get_arg_type(&it) != DBUS_TYPE_ARRAY)
-        goto malformed;
-    else
-        dbus_message_iter_recurse(&it, &ia);
-
-    *ncommand = parse_commands(&ia, commands, *ncommand);
-
-    if (*ncommand > 0)
-        return 0;
-    else {
-        *errmsg = "failed to parse commands";
-        return EINVAL;
+            return 0;
+        }
     }
 
  malformed:
@@ -372,7 +363,7 @@ static int parse_register(DBusMessage *req, const char **id, const char **name,
 }
 
 
-static int register_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int register_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req, void *user_data)
 {
     static srs_client_ops_t ops = {
         .notify_focus   = focus_notify,
@@ -383,12 +374,12 @@ static int register_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
     dbusif_t        *bus = (dbusif_t *)user_data;
     srs_context_t   *srs = bus->self->srs;
     const char      *id, *name, *appcls, *errmsg;
-    char            *cmds[MAX_COMMANDS];
+    char           **cmds;
     int              ncmd, err;
     srs_client_t    *c;
 
     ncmd = MRP_ARRAY_SIZE(cmds);
-    err  = parse_register(req, &id, &name, &appcls, &cmds[0], &ncmd, &errmsg);
+    err  = parse_register(req, &id, &name, &appcls, &cmds, &ncmd, &errmsg);
 
     if (err) {
         reply_register(dbus, req, err, errmsg);
@@ -422,10 +413,10 @@ static int register_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
 }
 
 
-static int parse_unregister(DBusMessage *req, const char **id,
+static int parse_unregister(mrp_dbus_msg_t *req, const char **id,
                             const char **errmsg)
 {
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
     if (*id != NULL)
         return 0;
@@ -436,7 +427,8 @@ static int parse_unregister(DBusMessage *req, const char **id,
 }
 
 
-static int unregister_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int unregister_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
+                          void *user_data)
 {
     dbusif_t      *bus = (dbusif_t *)user_data;
     srs_context_t *srs = bus->self->srs;
@@ -466,16 +458,15 @@ static int unregister_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
 }
 
 
-static int parse_focus(DBusMessage *req, const char **id, int *focus,
+static int parse_focus(mrp_dbus_msg_t *req, const char **id, int *focus,
                        const char **errmsg)
 {
     const char *type;
 
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
     if (*id != NULL) {
-        if (dbus_message_get_args(req, NULL, DBUS_TYPE_STRING, &type,
-                                  DBUS_TYPE_INVALID)) {
+        if (mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, &type)) {
             if (!strcmp(type, "none"))
                 *focus = SRS_VOICE_FOCUS_NONE;
             else if (!strcmp(type, "shared"   ))
@@ -499,7 +490,7 @@ static int parse_focus(DBusMessage *req, const char **id, int *focus,
 }
 
 
-static int focus_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int focus_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req, void *user_data)
 {
     dbusif_t      *bus = (dbusif_t *)user_data;
     srs_context_t *srs = bus->self->srs;
@@ -548,7 +539,7 @@ static int focus_notify(srs_client_t *c, srs_voice_focus_t focus)
     }
 
     return mrp_dbus_signal(bus->dbus, dest, path, iface, sig,
-                           DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID);
+                           MRP_DBUS_TYPE_STRING, state, MRP_DBUS_TYPE_INVALID);
 }
 
 
@@ -586,7 +577,7 @@ static int command_notify(srs_client_t *c, int idx, int ntoken, char **tokens,
     }
 
     return mrp_dbus_signal(bus->dbus, dest, path, iface, sig,
-                           DBUS_TYPE_STRING, &cmd, DBUS_TYPE_INVALID);
+                           MRP_DBUS_TYPE_STRING, cmd, MRP_DBUS_TYPE_INVALID);
 }
 
 
@@ -610,9 +601,9 @@ static int voice_notify(srs_client_t *c, srs_voice_event_t *event)
     case SRS_VOICE_EVENT_ABORTED:   type = "aborted"  ; goto send;
     send:
         return mrp_dbus_signal(bus->dbus, dest, path, iface, sig,
-                               DBUS_TYPE_UINT32, &event->id,
-                               DBUS_TYPE_STRING, &type,
-                               DBUS_TYPE_INVALID);
+                               MRP_DBUS_TYPE_UINT32, &event->id,
+                               MRP_DBUS_TYPE_STRING, type,
+                               MRP_DBUS_TYPE_INVALID);
 
     case SRS_VOICE_EVENT_PROGRESS:
         type = "progress";
@@ -620,11 +611,11 @@ static int voice_notify(srs_client_t *c, srs_voice_event_t *event)
         msec = event->data.progress.msec;
 
         return mrp_dbus_signal(bus->dbus, dest, path, iface, sig,
-                               DBUS_TYPE_UINT32, &event->id,
-                               DBUS_TYPE_STRING, &type,
-                               DBUS_TYPE_DOUBLE, &pcnt,
-                               DBUS_TYPE_UINT32, &msec,
-                               DBUS_TYPE_INVALID);
+                               MRP_DBUS_TYPE_UINT32, &event->id,
+                               MRP_DBUS_TYPE_STRING, type,
+                               MRP_DBUS_TYPE_DOUBLE, &pcnt,
+                               MRP_DBUS_TYPE_UINT32, &msec,
+                               MRP_DBUS_TYPE_INVALID);
 
     default:
         return TRUE;
@@ -632,27 +623,26 @@ static int voice_notify(srs_client_t *c, srs_voice_event_t *event)
 }
 
 
-static int parse_render_voice(DBusMessage *req, const char **id,
+static int parse_render_voice(mrp_dbus_msg_t *req, const char **id,
                               const char **msg, const char **voice,
                               int *timeout, int *notify_events,
                               const char **errmsg)
 {
     char    **events, *e;
-    int       nevent, i;
+    int       i;
+    size_t    nevent;
     int32_t   to;
 
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
     if (*id == NULL)
         return EINVAL;
 
-    if (!dbus_message_get_args(req, NULL,
-                               DBUS_TYPE_STRING, msg,
-                               DBUS_TYPE_STRING, voice,
-                               DBUS_TYPE_INT32 , &to,
-                               DBUS_TYPE_ARRAY,
-                               DBUS_TYPE_STRING, &events, &nevent,
-                               DBUS_TYPE_INVALID)) {
+    if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, msg) ||
+        !mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, voice) ||
+        !mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_INT32 , &to) ||
+        !mrp_dbus_msg_read_array(req, MRP_DBUS_TYPE_STRING,
+                                 (void **)&events, &nevent)) {
         *errmsg = "malformed voice render message";
 
         return EINVAL;
@@ -685,7 +675,8 @@ static int parse_render_voice(DBusMessage *req, const char **id,
 }
 
 
-static int render_voice_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int render_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
+                            void *user_data)
 {
     dbusif_t      *bus = (dbusif_t *)user_data;
     srs_context_t *srs = bus->self->srs;
@@ -722,18 +713,16 @@ static int render_voice_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
 }
 
 
-static int parse_cancel_voice(DBusMessage *req, const char **id,
+static int parse_cancel_voice(mrp_dbus_msg_t *req, const char **id,
                               uint32_t *reqid, const char **errmsg)
 {
 
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
     if (*id == NULL)
         return EINVAL;
 
-    if (!dbus_message_get_args(req, NULL,
-                               DBUS_TYPE_UINT32, reqid,
-                               DBUS_TYPE_INVALID)) {
+    if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_UINT32, &reqid)) {
         *errmsg = "malformed voice render message";
 
         return EINVAL;
@@ -743,7 +732,8 @@ static int parse_cancel_voice(DBusMessage *req, const char **id,
 }
 
 
-static int cancel_voice_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int cancel_voice_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
+                            void *user_data)
 {
     dbusif_t      *bus = (dbusif_t *)user_data;
     srs_context_t *srs = bus->self->srs;
@@ -775,24 +765,23 @@ static int cancel_voice_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
 }
 
 
-static int parse_voice_query(DBusMessage *req, const char **id,
+static int parse_voice_query(mrp_dbus_msg_t *req, const char **id,
                              const char **lang)
 {
-    *id = dbus_message_get_sender(req);
+    *id = mrp_dbus_msg_sender(req);
 
     if (*id == NULL)
         return EINVAL;
 
-    if (!dbus_message_get_args(req, NULL,
-                               DBUS_TYPE_STRING, lang,
-                               DBUS_TYPE_INVALID))
+    if (!mrp_dbus_msg_read_basic(req, MRP_DBUS_TYPE_STRING, lang))
         lang = NULL;
 
     return 0;
 }
 
 
-static int query_voices_req(mrp_dbus_t *dbus, DBusMessage *req, void *user_data)
+static int query_voices_req(mrp_dbus_t *dbus, mrp_dbus_msg_t *req,
+                            void *user_data)
 {
     dbusif_t          *bus = (dbusif_t *)user_data;
     srs_context_t     *srs = bus->self->srs;