upgrade obexd to 0.47
[profile/ivi/obexd.git] / client / pbap.c
index fc19ac8..48dbac1 100644 (file)
@@ -45,8 +45,6 @@
        "\x79\x61\x35\xF0\xF0\xC5\x11\xD8\x09\x66\x08\x00\x20\x0C\x9A\x66"
 #define OBEX_PBAP_UUID_LEN 16
 
-#define ERROR_INF PBAP_INTERFACE ".Error"
-
 #define FORMAT_VCARD21 0x0
 #define FORMAT_VCARD30 0x1
 
@@ -122,18 +120,23 @@ static const char *filter_list[] = {
 #define FILTER_BIT_MAX 63
 #define FILTER_ALL     0xFFFFFFFFFFFFFFFFULL
 
-#define PBAP_INTERFACE  "org.openobex.PhonebookAccess"
+#define PBAP_INTERFACE "org.bluez.obex.PhonebookAccess"
+#define ERROR_INTERFACE "org.bluez.obex.Error"
 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
 
 struct pbap_data {
        struct obc_session *session;
        char *path;
-       DBusMessage *msg;
        guint8 format;
        guint8 order;
        uint64_t filter;
 };
 
+struct pending_request {
+       struct pbap_data *pbap;
+       DBusMessage *msg;
+};
+
 struct pullphonebook_apparam {
        uint8_t     filter_tag;
        uint8_t     filter_len;
@@ -168,6 +171,24 @@ struct apparam_hdr {
 
 static DBusConnection *conn = NULL;
 
+static struct pending_request *pending_request_new(struct pbap_data *pbap,
+                                                       DBusMessage *message)
+{
+       struct pending_request *p;
+
+       p = g_new0(struct pending_request, 1);
+       p->pbap = pbap;
+       p->msg = dbus_message_ref(message);
+
+       return p;
+}
+
+static void pending_request_free(struct pending_request *p)
+{
+       dbus_message_unref(p->msg);
+       g_free(p);
+}
+
 static void listing_element(GMarkupParseContext *ctxt,
                                const gchar *element,
                                const gchar **names,
@@ -241,144 +262,53 @@ static gchar *build_phonebook_path(const char *location, const char *item)
        return path;
 }
 
-typedef void (*setpath_cb_t) (GError *err, gpointer user_data);
-
-struct setpath_data {
-       char **remaining;
-       int index;
-       setpath_cb_t func;
-       gpointer user_data;
-};
-
-static void setpath_complete(GError *err, struct setpath_data *data)
-{
-       if (data->func)
-               data->func(err, data->user_data);
-       g_strfreev(data->remaining);
-       g_free(data);
-}
-
-static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
-                                                       gpointer user_data)
-{
-       struct setpath_data *data = user_data;
-       char *next;
-
-       if (err != NULL) {
-               setpath_complete(err, data);
-               return;
-       }
-
-       next = data->remaining[data->index];
-       if (next == NULL) {
-               setpath_complete(NULL, data);
-               return;
-       }
-
-       data->index++;
-
-       g_obex_setpath(obex, next, setpath_cb, data, &err);
-       if (err != NULL) {
-               setpath_complete(err, data);
-               g_error_free(err);
-       }
-}
-
-static gboolean setpath(GObex *obex, const char *path, size_t max_elem,
-                                       setpath_cb_t func, gpointer user_data)
-{
-       GError *err = NULL;
-       struct setpath_data *data;
-
-       data = g_new0(struct setpath_data, 1);
-
-       g_obex_setpath(obex, "", setpath_cb, data, &err);
-       if (err != NULL) {
-               error("set_path: %s", err->message);
-               g_error_free(err);
-               g_free(data);
-               return FALSE;
-       }
-
-       data->func = func;
-       data->user_data = user_data;
-       data->remaining = g_strsplit(path, "/", max_elem);
-
-       return TRUE;
-}
-
 /* should only be called inside pbap_set_path */
 static void pbap_reset_path(struct pbap_data *pbap)
 {
-       GObex *obex = obc_session_get_obex(pbap->session);
-
        if (!pbap->path)
                return;
 
-       setpath(obex, pbap->path, 3, NULL, NULL);
+       obc_session_setpath(pbap->session, pbap->path, NULL, NULL, NULL);
 }
 
-static void pbap_setpath_cb(GError *err, gpointer user_data)
+static void pbap_setpath_cb(struct obc_session *session,
+                                               struct obc_transfer *transfer,
+                                               GError *err, void *user_data)
 {
-       struct pbap_data *pbap = user_data;
+       struct pending_request *request = user_data;
+       struct pbap_data *pbap = request->pbap;
 
        if (err != NULL)
-               pbap_reset_path(user_data);
-
-       if (pbap->msg == NULL)
-               return;
+               pbap_reset_path(pbap);
 
        if (err) {
-               DBusMessage *reply= g_dbus_create_error(pbap->msg,
-                                                       ERROR_INF ".Failed",
-                                                       "%s", err->message);
+               DBusMessage *reply = g_dbus_create_error(request->msg,
+                                               ERROR_INTERFACE ".Failed",
+                                               "%s", err->message);
                g_dbus_send_message(conn, reply);
        } else
-               g_dbus_send_reply(conn, pbap->msg, DBUS_TYPE_INVALID);
+               g_dbus_send_reply(conn, request->msg, DBUS_TYPE_INVALID);
 
-       dbus_message_unref(pbap->msg);
-       pbap->msg = NULL;
+       pending_request_free(request);
 }
 
-static int pbap_set_path(struct pbap_data *pbap, const char *path)
-{
-       GObex *obex = obc_session_get_obex(pbap->session);
-
-       if (!path)
-               return G_OBEX_RSP_BAD_REQUEST;
-
-       if (pbap->path != NULL && g_str_equal(pbap->path, path))
-               return 0;
-
-       if (!setpath(obex, path, 3, pbap_setpath_cb, pbap))
-               return G_OBEX_RSP_INTERNAL_SERVER_ERROR;
-
-       g_free(pbap->path);
-       pbap->path = g_strdup(path);
-
-       return G_OBEX_RSP_SUCCESS;
-}
-
-static void read_return_apparam(struct obc_session *session,
+static void read_return_apparam(struct obc_transfer *transfer,
                                guint16 *phone_book_size, guint8 *new_missed_calls)
 {
-       struct obc_transfer *transfer = obc_session_get_transfer(session);
-       struct obc_transfer_params params;
-       unsigned char *buf;
-       size_t size = 0;
+       const struct apparam_hdr *hdr;
+       size_t size;
 
        *phone_book_size = 0;
        *new_missed_calls = 0;
 
-       if (obc_transfer_get_params(transfer, &params) < 0)
+       hdr = obc_transfer_get_params(transfer, &size);
+       if (hdr == NULL)
                return;
 
-       if (params.size < APPARAM_HDR_SIZE)
+       if (size < APPARAM_HDR_SIZE)
                return;
 
        while (size > APPARAM_HDR_SIZE) {
-               struct apparam_hdr *hdr = (struct apparam_hdr *) params.data;
-
                if (hdr->len > size - APPARAM_HDR_SIZE) {
                        error("Unexpected PBAP pullphonebook app"
                                        " length, tag %d, len %d",
@@ -404,115 +334,69 @@ static void read_return_apparam(struct obc_session *session,
                                        hdr->tag, hdr->len);
                }
 
-               buf += APPARAM_HDR_SIZE + hdr->len;
                size -= APPARAM_HDR_SIZE + hdr->len;
+               hdr += APPARAM_HDR_SIZE + hdr->len;
        }
 }
 
-static void pull_phonebook_callback(struct obc_session *session,
-                                       GError *err, void *user_data)
-{
-       struct obc_transfer *transfer = obc_session_get_transfer(session);
-       struct pbap_data *pbap = user_data;
-       DBusMessage *reply;
-       const char *buf;
-       int size;
-
-       if (pbap->msg == NULL)
-               goto done;
-
-       if (err) {
-               reply = g_dbus_create_error(pbap->msg,
-                                               "org.openobex.Error.Failed",
-                                               "%s", err->message);
-               goto send;
-       }
-
-       reply = dbus_message_new_method_return(pbap->msg);
-
-       buf = obc_transfer_get_buffer(transfer, &size);
-       if (size == 0)
-               buf = "";
-
-       dbus_message_append_args(reply,
-                       DBUS_TYPE_STRING, &buf,
-                       DBUS_TYPE_INVALID);
-
-       obc_transfer_clear_buffer(transfer);
-
-send:
-       g_dbus_send_message(conn, reply);
-       dbus_message_unref(pbap->msg);
-       pbap->msg = NULL;
-
-done:
-       obc_transfer_unregister(transfer);
-}
-
 static void phonebook_size_callback(struct obc_session *session,
-                                       GError *err, void *user_data)
+                                               struct obc_transfer *transfer,
+                                               GError *err, void *user_data)
 {
-       struct obc_transfer *transfer = obc_session_get_transfer(session);
-       struct pbap_data *pbap = user_data;
+       struct pending_request *request = user_data;
        DBusMessage *reply;
        guint16 phone_book_size;
        guint8 new_missed_calls;
 
-       if (pbap->msg == NULL)
-               goto done;
-
        if (err) {
-               reply = g_dbus_create_error(pbap->msg,
-                                               "org.openobex.Error.Failed",
+               reply = g_dbus_create_error(request->msg,
+                                               ERROR_INTERFACE ".Failed",
                                                "%s", err->message);
                goto send;
        }
 
-       reply = dbus_message_new_method_return(pbap->msg);
+       reply = dbus_message_new_method_return(request->msg);
 
-       read_return_apparam(session, &phone_book_size, &new_missed_calls);
+       read_return_apparam(transfer, &phone_book_size, &new_missed_calls);
 
        dbus_message_append_args(reply,
                        DBUS_TYPE_UINT16, &phone_book_size,
                        DBUS_TYPE_INVALID);
 
-       obc_transfer_clear_buffer(transfer);
-
 send:
        g_dbus_send_message(conn, reply);
-       dbus_message_unref(pbap->msg);
-       pbap->msg = NULL;
-
-done:
-       obc_transfer_unregister(transfer);
+       pending_request_free(request);
 }
 
 static void pull_vcard_listing_callback(struct obc_session *session,
-                                       GError *err, void *user_data)
+                                               struct obc_transfer *transfer,
+                                               GError *err, void *user_data)
 {
-       struct obc_transfer *transfer = obc_session_get_transfer(session);
-       struct pbap_data *pbap = user_data;
+       struct pending_request *request = user_data;
        GMarkupParseContext *ctxt;
        DBusMessage *reply;
        DBusMessageIter iter, array;
-       const char *buf;
-       int size;
-
-       if (pbap->msg == NULL)
-               goto complete;
+       char *contents;
+       size_t size;
+       int perr;
 
        if (err) {
-               reply = g_dbus_create_error(pbap->msg,
-                                               "org.openobex.Error.Failed",
+               reply = g_dbus_create_error(request->msg,
+                                               ERROR_INTERFACE ".Failed",
                                                "%s", err->message);
                goto send;
        }
 
-       reply = dbus_message_new_method_return(pbap->msg);
+       perr = obc_transfer_get_contents(transfer, &contents, &size);
+       if (perr < 0) {
+               reply = g_dbus_create_error(request->msg,
+                                               ERROR_INTERFACE ".Failed",
+                                               "Error reading contents: %s",
+                                               strerror(-perr));
+               goto send;
+       }
 
-       buf = obc_transfer_get_buffer(transfer, &size);
-       if (size == 0)
-               buf = "";
+       reply = dbus_message_new_method_return(request->msg);
 
        dbus_message_iter_init_append(reply, &iter);
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -520,33 +404,33 @@ static void pull_vcard_listing_callback(struct obc_session *session,
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
                        DBUS_STRUCT_END_CHAR_AS_STRING, &array);
        ctxt = g_markup_parse_context_new(&listing_parser, 0, &array, NULL);
-       g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
+       g_markup_parse_context_parse(ctxt, contents, size, NULL);
        g_markup_parse_context_free(ctxt);
        dbus_message_iter_close_container(&iter, &array);
-
-       obc_transfer_clear_buffer(transfer);
+       g_free(contents);
 
 send:
        g_dbus_send_message(conn, reply);
-       dbus_message_unref(pbap->msg);
-       pbap->msg = NULL;
-complete:
-       obc_transfer_unregister(transfer);
+       pending_request_free(request);
 }
 
-static DBusMessage *pull_phonebook(struct pbap_data *pbap,
-                                       DBusMessage *message, guint8 type,
-                                       const char *name, uint64_t filter,
-                                       guint8 format, guint16 maxlistcount,
-                                       guint16 liststartoffset)
+static struct obc_transfer *pull_phonebook(struct pbap_data *pbap,
+                                               DBusMessage *message,
+                                               guint8 type, const char *name,
+                                               const char *targetfile,
+                                               uint64_t filter, guint8 format,
+                                               guint16 maxlistcount,
+                                               guint16 liststartoffset,
+                                               GError **err)
 {
+       struct pending_request *request;
+       struct obc_transfer *transfer;
        struct pullphonebook_apparam apparam;
        session_callback_t func;
 
-       if (pbap->msg)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.InProgress",
-                               "Transfer in progress");
+       transfer = obc_transfer_get("x-bt/phonebook", name, targetfile, err);
+       if (transfer == NULL)
+               return NULL;
 
        apparam.filter_tag = FILTER_TAG;
        apparam.filter_len = FILTER_LEN;
@@ -563,26 +447,29 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
 
        switch (type) {
        case PULLPHONEBOOK:
-               func = pull_phonebook_callback;
+               func = NULL;
+               request = NULL;
                break;
        case GETPHONEBOOKSIZE:
                func = phonebook_size_callback;
+               request = pending_request_new(pbap, message);
                break;
        default:
                error("Unexpected type : 0x%2x", type);
                return NULL;
        }
 
-       if (obc_session_get(pbap->session, "x-bt/phonebook", name, NULL,
-                               (guint8 *) &apparam, sizeof(apparam),
-                               func, pbap) < 0)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.Failed",
-                               "Failed");
+       obc_transfer_set_params(transfer, &apparam, sizeof(apparam));
 
-       pbap->msg = dbus_message_ref(message);
+       if (!obc_session_queue(pbap->session, transfer, func, request, err)) {
+               if (request != NULL)
+                       pending_request_free(request);
 
-       return NULL;
+               return NULL;
+       }
+
+
+       return transfer;
 }
 
 static guint8 *fill_apparam(guint8 *dest, void *buf, guint8 tag, guint8 len)
@@ -602,14 +489,16 @@ static DBusMessage *pull_vcard_listing(struct pbap_data *pbap,
                                        guint8 order, char *searchval, guint8 attrib,
                                        guint16 count, guint16 offset)
 {
-       guint8 *p, *apparam = NULL;
+       struct pending_request *request;
+       struct obc_transfer *transfer;
+       guint8 *p, apparam[272];
        gint apparam_size;
-       int err;
+       GError *err = NULL;
+       DBusMessage *reply;
 
-       if (pbap->msg)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.InProgress",
-                               "Transfer in progress");
+       transfer = obc_transfer_get("x-bt/vcard-listing", name, NULL, &err);
+       if (transfer == NULL)
+               goto fail;
 
        /* trunc the searchval string if it's length exceed the max value of guint8 */
        if (strlen(searchval) > 254)
@@ -620,10 +509,6 @@ static DBusMessage *pull_vcard_listing(struct pbap_data *pbap,
                        (APPARAM_HDR_SIZE + SEARCHATTRIB_LEN) +
                        (APPARAM_HDR_SIZE + MAXLISTCOUNT_LEN) +
                        (APPARAM_HDR_SIZE + LISTSTARTOFFSET_LEN);
-       apparam = g_try_malloc0(apparam_size);
-       if (!apparam)
-               return g_dbus_create_error(message,
-                               ERROR_INF ".Failed", "No Memory");
 
        p = apparam;
 
@@ -635,20 +520,23 @@ static DBusMessage *pull_vcard_listing(struct pbap_data *pbap,
        p = fill_apparam(p, &count, MAXLISTCOUNT_TAG, MAXLISTCOUNT_LEN);
 
        offset = GUINT16_TO_BE(offset);
-       p = fill_apparam(p, &offset, LISTSTARTOFFSET_TAG, LISTSTARTOFFSET_LEN);
+       fill_apparam(p, &offset, LISTSTARTOFFSET_TAG, LISTSTARTOFFSET_LEN);
 
-       err = obc_session_get(pbap->session, "x-bt/vcard-listing", name, NULL,
-                               apparam, apparam_size,
-                               pull_vcard_listing_callback, pbap);
-       g_free(apparam);
-       if (err < 0)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.Failed",
-                               "Failed");
+       request = pending_request_new(pbap, message);
 
-       pbap->msg = dbus_message_ref(message);
+       obc_transfer_set_params(transfer, apparam, apparam_size);
 
-       return NULL;
+       if (obc_session_queue(pbap->session, transfer,
+                               pull_vcard_listing_callback, request, &err))
+               return NULL;
+
+       pending_request_free(request);
+
+fail:
+       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+                                                               err->message);
+       g_error_free(err);
+       return reply;
 }
 
 static int set_format(struct pbap_data *pbap, const char *formatstr)
@@ -744,10 +632,7 @@ static gchar **get_filter_strs(uint64_t filter, gint *size)
        gint i;
        gint filter_list_size = sizeof(filter_list) / sizeof(filter_list[0]) - 1;
 
-       list = g_try_malloc0(sizeof(gchar **) * (FILTER_BIT_MAX + 2));
-
-       if (!list)
-               return NULL;
+       list = g_malloc0(sizeof(gchar **) * (FILTER_BIT_MAX + 2));
 
        item = list;
 
@@ -769,29 +654,44 @@ static DBusMessage *pbap_select(DBusConnection *connection,
 {
        struct pbap_data *pbap = user_data;
        const char *item, *location;
-       char *path = NULL;
-       int err = 0;
+       char *path;
+       struct pending_request *request;
+       GError *err = NULL;
 
        if (dbus_message_get_args(message, NULL,
                        DBUS_TYPE_STRING, &location,
                        DBUS_TYPE_STRING, &item,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        path = build_phonebook_path(location, item);
-       if (!path)
+       if (path == NULL)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", "InvalidPhonebook");
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "Invalid path");
 
-       err = pbap_set_path(pbap, path);
-       g_free(path);
-       if (err != G_OBEX_RSP_SUCCESS)
-               return g_dbus_create_error(message,
-                               ERROR_INF ".Failed",
-                               "0x%02x", err);
+       if (pbap->path != NULL && g_str_equal(pbap->path, path)) {
+               g_free(path);
+               return dbus_message_new_method_return(message);
+       }
+
+       request = pending_request_new(pbap, message);
+
+       obc_session_setpath(pbap->session, path, pbap_setpath_cb, request,
+                                                                       &err);
+       if (err != NULL) {
+               DBusMessage *reply;
+               reply =  g_dbus_create_error(message, ERROR_INTERFACE ".Failed",
+                                                       "%s", err->message);
+               g_error_free(err);
+               g_free(path);
+               pending_request_free(request);
+               return reply;
+       }
 
-       pbap->msg = dbus_message_ref(message);
+       g_free(pbap->path);
+       pbap->path = path;
 
        return NULL;
 }
@@ -800,44 +700,65 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
                                        DBusMessage *message, void *user_data)
 {
        struct pbap_data *pbap = user_data;
-       DBusMessage * err;
+       struct obc_transfer *transfer;
+       const char *targetfile;
        char *name;
+       GError *err = NULL;
 
        if (!pbap->path)
                return g_dbus_create_error(message,
-                               ERROR_INF ".Forbidden", "Call Select first of all");
+                                       ERROR_INTERFACE ".Forbidden",
+                                       "Call Select first of all");
+
+       if (dbus_message_get_args(message, NULL,
+                       DBUS_TYPE_STRING, &targetfile,
+                       DBUS_TYPE_INVALID) == FALSE)
+               return g_dbus_create_error(message,
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        name = g_strconcat(pbap->path, ".vcf", NULL);
 
-       err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
-                               pbap->filter, pbap->format,
-                               DEFAULT_COUNT, DEFAULT_OFFSET);
+       transfer = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
+                               targetfile, pbap->filter, pbap->format,
+                               DEFAULT_COUNT, DEFAULT_OFFSET, &err);
        g_free(name);
-       return err;
+
+       if (transfer == NULL) {
+               DBusMessage *reply = g_dbus_create_error(message,
+                                       ERROR_INTERFACE ".Failed", "%s",
+                                       err->message);
+               g_error_free(err);
+               return reply;
+       }
+
+       return obc_transfer_create_dbus_reply(transfer, message);
 }
 
 static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
                                        DBusMessage *message, void *user_data)
 {
        struct pbap_data *pbap = user_data;
+       struct obc_transfer *transfer;
        struct pullvcardentry_apparam apparam;
-       const char *name;
+       const char *name, *targetfile;
+       DBusMessage *reply;
+       GError *err = NULL;
 
        if (!pbap->path)
                return g_dbus_create_error(message,
-                               ERROR_INF ".Forbidden",
+                               ERROR_INTERFACE ".Forbidden",
                                "Call Select first of all");
 
        if (dbus_message_get_args(message, NULL,
                        DBUS_TYPE_STRING, &name,
+                       DBUS_TYPE_STRING, &targetfile,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
-       if (pbap->msg)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.InProgress",
-                               "Transfer in progress");
+       transfer = obc_transfer_get("x-bt/vcard", name, targetfile, &err);
+       if (transfer == NULL)
+               goto fail;
 
        apparam.filter_tag = FILTER_TAG;
        apparam.filter_len = FILTER_LEN;
@@ -846,16 +767,18 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
        apparam.format_len = FORMAT_LEN;
        apparam.format = pbap->format;
 
-       if (obc_session_get(pbap->session, "x-bt/vcard", name, NULL,
-                       (guint8 *)&apparam, sizeof(apparam),
-                       pull_phonebook_callback, pbap) < 0)
-               return g_dbus_create_error(message,
-                               "org.openobex.Error.Failed",
-                               "Failed");
+       obc_transfer_set_params(transfer, &apparam, sizeof(apparam));
 
-       pbap->msg = dbus_message_ref(message);
+       if (!obc_session_queue(pbap->session, transfer, NULL, NULL, &err))
+               goto fail;
 
-       return NULL;
+       return obc_transfer_create_dbus_reply(transfer, message);
+
+fail:
+       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+                                                               err->message);
+       g_error_free(err);
+       return reply;
 }
 
 static DBusMessage *pbap_list(DBusConnection *connection,
@@ -865,7 +788,8 @@ static DBusMessage *pbap_list(DBusConnection *connection,
 
        if (!pbap->path)
                return g_dbus_create_error(message,
-                               ERROR_INF ".Forbidden", "Call Select first of all");
+                                       ERROR_INTERFACE ".Forbidden",
+                                       "Call Select first of all");
 
        return pull_vcard_listing(pbap, message, "", pbap->order, "",
                                ATTRIB_NAME, DEFAULT_COUNT, DEFAULT_OFFSET);
@@ -883,11 +807,12 @@ static DBusMessage *pbap_search(DBusConnection *connection,
                        DBUS_TYPE_STRING, &value,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        if (!pbap->path)
                return g_dbus_create_error(message,
-                               ERROR_INF ".Forbidden", "Call Select first of all");
+                                       ERROR_INTERFACE ".Forbidden",
+                                       "Call Select first of all");
 
        if (!field || g_str_equal(field, ""))
                attrib = ATTRIB_NAME;
@@ -899,7 +824,7 @@ static DBusMessage *pbap_search(DBusConnection *connection,
                attrib = ATTRIB_SOUND;
        else
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        return pull_vcard_listing(pbap, message, "", pbap->order, value,
                                        attrib, DEFAULT_COUNT, DEFAULT_OFFSET);
@@ -909,20 +834,31 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,
                                        DBusMessage *message, void *user_data)
 {
        struct pbap_data *pbap = user_data;
-       DBusMessage * err;
+       DBusMessage *reply;
+       struct obc_transfer *transfer;
        char *name;
+       GError *err = NULL;
 
        if (!pbap->path)
                return g_dbus_create_error(message,
-                               ERROR_INF ".Forbidden", "Call Select first of all");
+                                       ERROR_INTERFACE ".Forbidden",
+                                       "Call Select first of all");
 
        name = g_strconcat(pbap->path, ".vcf", NULL);
 
-       err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
+       transfer = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name, NULL,
                                pbap->filter, pbap->format, 0,
-                               DEFAULT_OFFSET);
+                               DEFAULT_OFFSET, &err);
+
        g_free(name);
-       return err;
+
+       if (transfer != NULL)
+               return NULL;
+
+       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+                                                               err->message);
+       g_error_free(err);
+       return reply;
 }
 
 static DBusMessage *pbap_set_format(DBusConnection *connection,
@@ -935,11 +871,12 @@ static DBusMessage *pbap_set_format(DBusConnection *connection,
                        DBUS_TYPE_STRING, &format,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        if (set_format(pbap, format) < 0)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", "InvalidFormat");
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "InvalidFormat");
 
        return dbus_message_new_method_return(message);
 }
@@ -954,11 +891,12 @@ static DBusMessage *pbap_set_order(DBusConnection *connection,
                        DBUS_TYPE_STRING, &order,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        if (set_order(pbap, order) < 0)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", "InvalidFilter");
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "InvalidFilter");
 
        return dbus_message_new_method_return(message);
 }
@@ -975,7 +913,7 @@ static DBusMessage *pbap_set_filter(DBusConnection *connection,
                        DBUS_TYPE_STRING, &filters, &size,
                        DBUS_TYPE_INVALID) == FALSE)
                return g_dbus_create_error(message,
-                               ERROR_INF ".InvalidArguments", NULL);
+                               ERROR_INTERFACE ".InvalidArguments", NULL);
 
        remove_filter(pbap, "ALL");
        if (size == 0)
@@ -986,7 +924,8 @@ static DBusMessage *pbap_set_filter(DBusConnection *connection,
                        pbap->filter = oldfilter;
                        g_strfreev(filters);
                        return g_dbus_create_error(message,
-                                       ERROR_INF ".InvalidArguments", "InvalidFilters");
+                                       ERROR_INTERFACE ".InvalidArguments",
+                                       "InvalidFilters");
                }
        }
 
@@ -1030,24 +969,45 @@ static DBusMessage *pbap_list_filter_fields(DBusConnection *connection,
        return reply;
 }
 
-static GDBusMethodTable pbap_methods[] = {
-       { "Select",     "ss",   "",     pbap_select,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "PullAll",    "",     "s",    pbap_pull_all,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "Pull",       "s",    "s",    pbap_pull_vcard,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "List",       "",     "a(ss)",        pbap_list,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "Search",     "ss",   "a(ss)",        pbap_search,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "GetSize",    "",     "q",    pbap_get_size,
-                                       G_DBUS_METHOD_FLAG_ASYNC },
-       { "SetFormat",  "s",    "",     pbap_set_format },
-       { "SetOrder",   "s",    "",     pbap_set_order },
-       { "SetFilter",  "as",   "",     pbap_set_filter },
-       { "GetFilter",  "",     "as",   pbap_get_filter },
-       { "ListFilterFields", "",       "as",   pbap_list_filter_fields },
+static const GDBusMethodTable pbap_methods[] = {
+       { GDBUS_ASYNC_METHOD("Select",
+                       GDBUS_ARGS({ "location", "s" }, { "phonebook", "s" }),
+                       NULL, pbap_select) },
+       { GDBUS_METHOD("PullAll",
+                       GDBUS_ARGS({ "targetfile", "s" }),
+                       GDBUS_ARGS({ "transfer", "o" },
+                                       { "properties", "a{sv}" }),
+                       pbap_pull_all) },
+       { GDBUS_METHOD("Pull",
+                       GDBUS_ARGS({ "vcard", "s" }, { "targetfile", "s" }),
+                       GDBUS_ARGS({ "transfer", "o" },
+                                       { "properties", "a{sv}" }),
+                       pbap_pull_vcard) },
+       { GDBUS_ASYNC_METHOD("List",
+                               NULL, GDBUS_ARGS({ "vcard_listing", "a(ss)" }),
+                               pbap_list) },
+       { GDBUS_ASYNC_METHOD("Search",
+                               GDBUS_ARGS({ "field", "s" }, { "value", "s" }),
+                               GDBUS_ARGS({ "vcard_listing", "a(ss)" }),
+                               pbap_search) },
+       { GDBUS_ASYNC_METHOD("GetSize",
+                               NULL, GDBUS_ARGS({ "size", "q" }),
+                               pbap_get_size) },
+       { GDBUS_METHOD("SetFormat",
+                               GDBUS_ARGS({ "format", "s" }), NULL,
+                               pbap_set_format) },
+       { GDBUS_METHOD("SetOrder",
+                               GDBUS_ARGS({ "order", "s" }), NULL,
+                               pbap_set_order) },
+       { GDBUS_METHOD("SetFilter",
+                               GDBUS_ARGS({ "fields", "as" }), NULL,
+                               pbap_set_filter) },
+       { GDBUS_METHOD("GetFilter",
+                               NULL, GDBUS_ARGS({ "fields", "as" }),
+                               pbap_get_filter) },
+       { GDBUS_METHOD("ListFilterFields",
+                               NULL, GDBUS_ARGS({ "fields", "as" }),
+                               pbap_list_filter_fields) },
        { }
 };
 
@@ -1056,6 +1016,7 @@ static void pbap_free(void *data)
        struct pbap_data *pbap = data;
 
        obc_session_unref(pbap->session);
+       g_free(pbap->path);
        g_free(pbap);
 }
 
@@ -1106,6 +1067,7 @@ int pbap_init(void)
        int err;
 
        DBG("");
+
        conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
        if (!conn)
                return -EIO;