2011-12-08 15:27:34

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 00/21] Major API changes in obex-client

This patch series proposes an implementation of the previously discussed D-Bus API changes in obex-client.

As a consequence of these changes some internal interfaces have also been simplified or modified (patch 11/21). The new approach tries to be easier to use and safer.

The resulting code seems functional but has had limited testing only, so it will probably introduce several new bugs. However, most of the test scripts have been updated so the result (first impression) can be evaluated without much effort.

Some of the patches have been squashed in order to have a shorter series. Particularly the changes in the test scripts have been merged into the implementation patches.

In addition, there is one more change discussed in the IRC but not included in this series: the D-Bus API should return transfer properties along with the transfer path for each method initiating a transfer. This has been left out, to be discussed later.

I hope you like the general approach.

Mikel Astiz (21):
client-doc: minor formatting changes
client-doc: wrap OPP into specific session type
client: wrap OPP into specific session type
client-doc: replace SendFiles with SendFile
client: replace SendFiles with SendFile
client-doc: GetCapabilities moved to session API
client: GetCapabilities moved to session API
client-doc: replace parameter dict with conventional ones
client: replace parameter dict with conventional ones
client-doc: remove agent in favour of transfer signals
client: remove agent in favour of transfer signals
client-doc: ObjectPush sessions return transports
client: ObjectPush sessions return transports
client-doc: FileTransfer sessions return transports
client: FileTransfer sessions return transports
client-doc: Synchronization sessions return transports
client: Synchronization sessions return transports
client-doc: PhonebookAccess sessions return transports
client: PhonebookAccess sessions return transports
client: report size in GET operations
client: update copyright statement

Makefile.am | 3 +-
client/agent.c | 252 --------
client/agent.h | 43 --
client/dbus.c | 255 ++++++++
client/dbus.h | 66 ++
client/ftp.c | 188 ++++--
client/manager.c | 401 ++-----------
client/opp.c | 157 +++++-
client/pbap.c | 196 +++---
client/session.c | 1390 +++++++++++++++++++-----------------------
client/session.h | 75 ++--
client/sync.c | 74 ++-
client/transfer.c | 839 ++++++++++++++------------
client/transfer.h | 68 ++-
client/transferqueue.c | 230 +++++++
client/transferqueue.h | 47 ++
doc/client-api.txt | 274 +++++----
gobex/gobex-defs.h | 1 +
gobex/gobex-transfer.c | 28 +-
gobex/gobex.h | 1 +
test/exchange-business-cards | 9 +-
test/ftp-client | 191 +++---
test/get-capabilities | 15 +-
test/list-folders | 2 +-
test/pbap-client | 192 +++++--
test/pull-business-card | 8 +-
test/send-files | 88 +---
27 files changed, 2706 insertions(+), 2387 deletions(-)
delete mode 100644 client/agent.c
delete mode 100644 client/agent.h
create mode 100644 client/dbus.c
create mode 100644 client/dbus.h
create mode 100644 client/transferqueue.c
create mode 100644 client/transferqueue.h

--
1.7.6.4



2011-12-09 12:43:19

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 19/21] client: PhonebookAccess sessions return transports

Hi Mikel,

On Thu, Dec 8, 2011 at 5:27 PM, Mikel Astiz <[email protected]> wrote:
> ---
> ?client/pbap.c ? ?| ?119 ++++++++++++++++++---------------
> ?test/pbap-client | ?192 ++++++++++++++++++++++++++++++++++++++++++++----------
> ?2 files changed, 221 insertions(+), 90 deletions(-)
>
> diff --git a/client/pbap.c b/client/pbap.c
> index 8e21cb5..da2c22d 100644
> --- a/client/pbap.c
> +++ b/client/pbap.c
> @@ -411,39 +411,6 @@ static void read_return_apparam(const struct obc_transfer *transfer,
> ? ? ? ?}
> ?}
>
> -static void pull_phonebook_callback(struct obc_session *session,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct obc_transfer *transfer,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *user_data)
> -{
> - ? ? ? struct pbap_data *pbap = user_data;
> - ? ? ? DBusMessage *reply;
> - ? ? ? const void *buf;
> -
> - ? ? ? if (pbap->msg == NULL)
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? 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);
> -
> - ? ? ? dbus_message_append_args(reply,
> - ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_STRING, &buf,
> - ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> -
> -send:
> - ? ? ? g_dbus_send_message(conn, reply);
> - ? ? ? dbus_message_unref(pbap->msg);
> - ? ? ? pbap->msg = NULL;
> -}
> -
> ?static void phonebook_size_callback(struct obc_session *session,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?GError *err,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const struct obc_transfer *transfer,
> @@ -521,12 +488,16 @@ send:
>
> ?static DBusMessage *pull_phonebook(struct pbap_data *pbap,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DBusMessage *message, guint8 type,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *name, uint64_t filter,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *name,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const char *targetname,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t filter,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?guint8 format, guint16 maxlistcount,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? guint16 liststartoffset)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? guint16 liststartoffset,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct obc_transfer **transfer)
> ?{
> ? ? ? ?struct pullphonebook_apparam apparam;
> ? ? ? ?session_transfer_callback_t func;
> + ? ? ? int ret;
>
> ? ? ? ?if (pbap->msg)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> @@ -548,7 +519,7 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
>
> ? ? ? ?switch (type) {
> ? ? ? ?case PULLPHONEBOOK:
> - ? ? ? ? ? ? ? func = pull_phonebook_callback;
> + ? ? ? ? ? ? ? func = NULL;
> ? ? ? ? ? ? ? ?break;
> ? ? ? ?case GETPHONEBOOKSIZE:
> ? ? ? ? ? ? ? ?func = phonebook_size_callback;
> @@ -558,14 +529,23 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
> ? ? ? ? ? ? ? ?return NULL;
> ? ? ? ?}
>
> - ? ? ? if (obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
> + ? ? ? if (targetname != NULL)
> + ? ? ? ? ? ? ? ret = obc_session_get(pbap->session, "x-bt/phonebook", name,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? targetname,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (guint8 *) &apparam, sizeof(apparam),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? func, pbap, transfer);

How about making obc_session_get get a void * so we don't have to cast
to guint8 *?

> + ? ? ? else
> + ? ? ? ? ? ? ? ret = obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(guint8 *) &apparam, sizeof(apparam),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? func, pbap, NULL) < 0)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? func, pbap, transfer);
> +
> + ? ? ? if (ret < 0)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.Failed",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Failed");
>
> - ? ? ? pbap->msg = dbus_message_ref(message);
> + ? ? ? if (func != NULL)
> + ? ? ? ? ? ? ? pbap->msg = dbus_message_ref(message);
>
> ? ? ? ?return NULL;
> ?}
> @@ -795,18 +775,40 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
> ? ? ? ?struct pbap_data *pbap = user_data;
> ? ? ? ?DBusMessage * err;
> ? ? ? ?char *name;
> + ? ? ? const char *target_file;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
> +
> + ? ? ? if (dbus_message_get_args(message, NULL,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_STRING, &target_file,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID) == FALSE)
> + ? ? ? ? ? ? ? return g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
>
> ? ? ? ?if (!pbap->path)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Forbidden", "Call Select first of all");
> + ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Forbidden", "Call Select first of all");
>
> ? ? ? ?name = g_strconcat(pbap->path, ".vcf", NULL);
>
> - ? ? ? err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
> + ? ? ? err = pull_phonebook(pbap, message, PULLPHONEBOOK, name, target_file,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pbap->filter, pbap->format,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DEFAULT_COUNT, DEFAULT_OFFSET);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DEFAULT_COUNT, DEFAULT_OFFSET, &transfer);

Same suggestion as the others, return the transfer and take err as parameter.

> ? ? ? ?g_free(name);
> - ? ? ? return err;
> +
> + ? ? ? if (err != NULL)
> + ? ? ? ? ? ? ? return err;
> +
> + ? ? ? path = obc_transfer_get_path(transfer);
> +
> + ? ? ? reply = dbus_message_new_method_return(message);
> +
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> +
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
> @@ -814,7 +816,10 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
> ?{
> ? ? ? ?struct pbap_data *pbap = user_data;
> ? ? ? ?struct pullvcardentry_apparam apparam;
> - ? ? ? const char *name;
> + ? ? ? const char *name, *target_file;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
>
> ? ? ? ?if (!pbap->path)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> @@ -823,6 +828,7 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
>
> ? ? ? ?if (dbus_message_get_args(message, NULL,
> ? ? ? ? ? ? ? ? ? ? ? ?DBUS_TYPE_STRING, &name,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_STRING, &target_file,
> ? ? ? ? ? ? ? ? ? ? ? ?DBUS_TYPE_INVALID) == FALSE)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ERROR_INF ".InvalidArguments", NULL);
> @@ -839,15 +845,22 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
> ? ? ? ?apparam.format_len = FORMAT_LEN;
> ? ? ? ?apparam.format = pbap->format;
>
> - ? ? ? if (obc_session_get_mem(pbap->session, "x-bt/vcard", name,
> + ? ? ? if (obc_session_get(pbap->session, "x-bt/vcard", name, target_file,
> ? ? ? ? ? ? ? ? ? ? ? ?(guint8 *) &apparam, sizeof(apparam),
> - ? ? ? ? ? ? ? ? ? ? ? pull_phonebook_callback, pbap, NULL) < 0)
> + ? ? ? ? ? ? ? ? ? ? ? NULL, NULL, &transfer) < 0)

Here too.

> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.Failed",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Failed");
>
> - ? ? ? pbap->msg = dbus_message_ref(message);
> - ? ? ? return NULL;
> + ? ? ? path = obc_transfer_get_path(transfer);
> +
> + ? ? ? reply = dbus_message_new_method_return(message);
> +
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> +
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *pbap_list(DBusConnection *connection,
> @@ -910,9 +923,9 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,
>
> ? ? ? ?name = g_strconcat(pbap->path, ".vcf", NULL);
>
> - ? ? ? err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
> + ? ? ? err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name, NULL,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pbap->filter, pbap->format, 0,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DEFAULT_OFFSET);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DEFAULT_OFFSET, NULL);

Same here.

> ? ? ? ?g_free(name);
> ? ? ? ?return err;
> ?}
> @@ -1025,10 +1038,8 @@ static DBusMessage *pbap_list_filter_fields(DBusConnection *connection,
> ?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 },
> + ? ? ? { "PullAll", ? ?"s", ? ?"o", ? ?pbap_pull_all },
> + ? ? ? { "Pull", ? ? ? "ss", ? "o", ? ?pbap_pull_vcard },
> ? ? ? ?{ "List", ? ? ? "", ? ? "a(ss)", ? ? ? ?pbap_list,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> ? ? ? ?{ "Search", ? ? "ss", ? "a(ss)", ? ? ? ?pbap_search,
> diff --git a/test/pbap-client b/test/pbap-client
> index f87f33c..7eb528c 100755
> --- a/test/pbap-client
> +++ b/test/pbap-client
> @@ -1,41 +1,161 @@
> ?#!/usr/bin/python
>
> +import gobject
> +
> ?import sys
> ?import dbus
> +import dbus.service
> +import dbus.mainloop.glib
> +
> +class Transfer:
> + ? ?def __init__(self, callback_func):
> + ? ? ? ?self.callback_func = callback_func
> + ? ? ? ?self.path = None
> + ? ? ? ?self.filename = None
> +
> +class PbapClient:
> + ? ?def __init__(self, session_path):
> + ? ? ? ?self.pending_transfers = 0
> + ? ? ? ?self.transfer_dict = dict()
> + ? ? ? ?self.flush_func = None
> + ? ? ? ?bus = dbus.SessionBus()
> + ? ? ? ?self.session = dbus.Interface(bus.get_object("org.openobex.client",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? session_path),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Session")
> + ? ? ? ?self.pbap = dbus.Interface(bus.get_object("org.openobex.client",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?session_path),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.PhonebookAccess")
> + ? ? ? ?bus.add_signal_receiver(
> + ? ? ? ? ? ?self.transfer_added,
> + ? ? ? ? ? ?dbus_interface="org.openobex.Session",
> + ? ? ? ? ? ?signal_name="TransferAdded")
> + ? ? ? ?bus.add_signal_receiver(
> + ? ? ? ? ? ?self.transfer_complete,
> + ? ? ? ? ? ?dbus_interface="org.openobex.Transfer",
> + ? ? ? ? ? ?signal_name="Complete",
> + ? ? ? ? ? ?path_keyword="path")
> + ? ? ? ?bus.add_signal_receiver(
> + ? ? ? ? ? ?self.transfer_error,
> + ? ? ? ? ? ?dbus_interface="org.openobex.Transfer",
> + ? ? ? ? ? ?signal_name="Error",
> + ? ? ? ? ? ?path_keyword="path")
> +
> + ? ?def register(self, path, transfer):
> + ? ? ? ?print "Transfer created: %s" % path
> + ? ? ? ?transfer.path = path
> + ? ? ? ?self.transfer_dict[path] = transfer
> +
> + ? ?def error(self, err):
> + ? ? ? ?print err
> + ? ? ? ?mainloop.quit()
> +
> + ? ?def transfer_added(self, path, properties):
> + ? ? ? ?req = self.transfer_dict.get(path)
> + ? ? ? ?if req == None:
> + ? ? ? ? ? ?return
> + ? ? ? ?req.filename = properties.get("Location")
> +
> + ? ?def transfer_complete(self, path):
> + ? ? ? ?req = self.transfer_dict.get(path)
> + ? ? ? ?if req == None:
> + ? ? ? ? ? ?return
> + ? ? ? ?self.pending_transfers -= 1
> + ? ? ? ?print "Transfer %s finished an stored in %s" % (path, req.filename)
> + ? ? ? ?f = open(req.filename, "r")
> + ? ? ? ?lines = f.readlines()
> + ? ? ? ?del self.transfer_dict[path]
> + ? ? ? ?req.callback_func(lines)
> +
> + ? ? ? ?if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
> + ? ? ? ? ? ?if self.flush_func != None:
> + ? ? ? ? ? ? ? ?f = self.flush_func
> + ? ? ? ? ? ? ? ?self.flush_func = None
> + ? ? ? ? ? ? ? ?f()
> +
> + ? ?def transfer_error(self, error, path):
> + ? ? ? ?req = self.transfer_dict.get(path)
> + ? ? ? ?if req == None:
> + ? ? ? ? ? ?return
> + ? ? ? ?print "Transfer %s finished with an error: %s" % (path, error)
> + ? ? ? ?mainloop.quit()
> +
> + ? ?def pull(self, vcard, func):
> + ? ? ? ?req = Transfer(func)
> + ? ? ? ?self.pbap.Pull(vcard, "",
> + ? ? ? ? ? ? ? ? ? ? ? reply_handler=lambda p: self.register(p, req),
> + ? ? ? ? ? ? ? ? ? ? ? error_handler=self.error)
> + ? ? ? ?self.pending_transfers += 1
> +
> + ? ?def pull_all(self, func):
> + ? ? ? ?req = Transfer(func)
> + ? ? ? ?self.pbap.PullAll("",
> + ? ? ? ? ? ? ? ? ? ? ? ? ?reply_handler=lambda p: self.register(p, req),
> + ? ? ? ? ? ? ? ? ? ? ? ? ?error_handler=self.error)
> + ? ? ? ?self.pending_transfers += 1
> +
> + ? ?def flush_transfers(self, func):
> + ? ? ? ?if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
> + ? ? ? ? ? ?return
> + ? ? ? ?self.flush_func = func
> +
> + ? ?def interface(self):
> + ? ? ? ?return self.pbap
> +
> +if ?__name__ == '__main__':
> +
> + ? ?dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
> +
> + ? ?bus = dbus.SessionBus()
> + ? ?mainloop = gobject.MainLoop()
> +
> + ? ?client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Client")
> +
> + ? ?if (len(sys.argv) < 2):
> + ? ? ? print "Usage: %s <device>" % (sys.argv[0])
> + ? ? ? sys.exit(1)
> +
> + ? ?print "Creating Session"
> + ? ?session_path = client.CreateSession("", sys.argv[1], "pbap", dict())
> +
> + ? ?pbap_client = PbapClient(session_path)
> +
> + ? ?def process_result(lines, header):
> + ? ? ? ?print header,
> + ? ? ? ?for line in lines:
> + ? ? ? ? ? ?print line,
> + ? ? ? ?print
> +
> + ? ?def test_paths(paths):
> + ? ? ? ?if len(paths) == 0:
> + ? ? ? ? ? ?print
> + ? ? ? ? ? ?print "FINISHED"
> + ? ? ? ? ? ?mainloop.quit()
> + ? ? ? ? ? ?return
> +
> + ? ? ? ?path = paths[0]
> +
> + ? ? ? ?print "\n--- Select Phonebook %s ---\n" % (path)
> + ? ? ? ?pbap_client.interface().Select("int", path)
> +
> + ? ? ? ?print "\n--- GetSize ---\n"
> + ? ? ? ?ret = pbap_client.interface().GetSize()
> + ? ? ? ?print "Size = %d\n" % (ret)
> +
> + ? ? ? ?print "\n--- List vCard ---\n"
> + ? ? ? ?ret = pbap_client.interface().List()
> + ? ? ? ?for item in ret:
> + ? ? ? ? ? ? ? ?print "%s : %s" % (item[0], item[1])
> + ? ? ? ? ? ? ? ?pbap_client.interface().SetFormat("vcard30")
> + ? ? ? ? ? ? ? ?pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
> + ? ? ? ? ? ? ? ?pbap_client.pull(item[0], lambda x: process_result(x, ""))
> +
> + ? ? ? ?pbap_client.interface().SetFormat("vcard30")
> + ? ? ? ?pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
> + ? ? ? ?pbap_client.pull_all(lambda x: process_result(x, "\n--- PullAll ---\n"))
> +
> + ? ? ? ?pbap_client.flush_transfers(lambda: test_paths(paths[1:]))
> +
> + ? ?test_paths(["PB", "ICH", "OCH", "MCH", "CCH"])
>
> -bus = dbus.SessionBus()
> -
> -client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Client")
> -
> -print "Creating Session"
> -session_path = client.CreateSession("", sys.argv[1], "PBAP", dict())
> -pbap = dbus.Interface(bus.get_object("org.openobex.client", session_path),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.PhonebookAccess")
> -session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Session")
> -
> -paths = ["PB", "ICH", "OCH", "MCH", "CCH"]
> -
> -for path in paths:
> - ? ? ? print "\n--- Select Phonebook %s ---\n" % (path)
> - ? ? ? pbap.Select("int", path)
> -
> - ? ? ? print "\n--- GetSize ---\n"
> - ? ? ? ret = pbap.GetSize()
> - ? ? ? print "Size = %d\n" % (ret)
> -
> - ? ? ? print "\n--- List vCard ---\n"
> - ? ? ? ret = pbap.List()
> - ? ? ? for item in ret:
> - ? ? ? ? ? ? ? print "%s : %s" % (item[0], item[1])
> - ? ? ? ? ? ? ? pbap.SetFormat("vcard30")
> - ? ? ? ? ? ? ? pbap.SetFilter(["VERSION", "FN", "TEL"]);
> - ? ? ? ? ? ? ? ret = pbap.Pull(item[0])
> - ? ? ? ? ? ? ? print "%s" % (ret)
> -
> - ? ? ? print "\n--- PullAll ---\n"
> - ? ? ? pbap.SetFormat("vcard30")
> - ? ? ? pbap.SetFilter(["VERSION", "FN", "TEL"]);
> - ? ? ? ret = pbap.PullAll()
> - ? ? ? print "%s" % (ret)
> + ? ?mainloop.run()
> --
> 1.7.6.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2011-12-09 12:35:11

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 15/21] client: FileTransfer sessions return transports

Hi Mikel,

On Thu, Dec 8, 2011 at 5:27 PM, Mikel Astiz <[email protected]> wrote:
> ---
> ?client/ftp.c ? ?| ? 61 ++++++++----------
> ?test/ftp-client | ?188 ++++++++++++++++++++++++++-----------------------------
> ?2 files changed, 117 insertions(+), 132 deletions(-)
>
> diff --git a/client/ftp.c b/client/ftp.c
> index 6630cc9..15b2b48 100644
> --- a/client/ftp.c
> +++ b/client/ftp.c
> @@ -192,29 +192,6 @@ static const GMarkupParser parser = {
> ? ? ? ?NULL
> ?};
>
> -static void get_file_callback(struct obc_session *session, GError *err,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct obc_transfer *transfer,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *user_data)
> -{
> - ? ? ? struct ftp_data *ftp = user_data;
> - ? ? ? DBusMessage *reply;
> -
> - ? ? ? if (!ftp->msg)
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? if (err)
> - ? ? ? ? ? ? ? reply = g_dbus_create_error(ftp->msg,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.Failed",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
> - ? ? ? else
> - ? ? ? ? ? ? ? reply = dbus_message_new_method_return(ftp->msg);
> -
> - ? ? ? g_dbus_send_message(conn, reply);
> -
> - ? ? ? dbus_message_unref(ftp->msg);
> - ? ? ? ftp->msg = NULL;
> -}
> -
> ?static void list_folder_callback(struct obc_session *session,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?GError *err,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const struct obc_transfer *transfer,
> @@ -325,6 +302,9 @@ static DBusMessage *get_file(DBusConnection *connection,
> ? ? ? ?struct ftp_data *ftp = user_data;
> ? ? ? ?struct obc_session *session = ftp->session;
> ? ? ? ?const char *target_file, *source_file;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
>
> ? ? ? ?if (dbus_message_get_args(message, NULL,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DBUS_TYPE_STRING, &target_file,
> @@ -334,15 +314,21 @@ static DBusMessage *get_file(DBusConnection *connection,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.InvalidArguments", NULL);
>
> ? ? ? ?if (obc_session_get(session, NULL, source_file,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? target_file, NULL, 0, get_file_callback,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ftp, NULL) < 0)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? target_file, NULL, 0, NULL,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL, &transfer) < 0)

Make obc_session_get to return the transfer and get an int *err as parameter.

> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.Failed",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Failed");
>
> - ? ? ? ftp->msg = dbus_message_ref(message);
> + ? ? ? path = obc_transfer_get_path(transfer);
>
> - ? ? ? return NULL;
> + ? ? ? reply = dbus_message_new_method_return(message);
> +
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> +
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *put_file(DBusConnection *connection,
> @@ -351,6 +337,9 @@ static DBusMessage *put_file(DBusConnection *connection,
> ? ? ? ?struct ftp_data *ftp = user_data;
> ? ? ? ?struct obc_session *session = ftp->session;
> ? ? ? ?gchar *sourcefile, *targetfile;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
>
> ? ? ? ?if (dbus_message_get_args(message, NULL,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DBUS_TYPE_STRING, &sourcefile,
> @@ -360,12 +349,20 @@ static DBusMessage *put_file(DBusConnection *connection,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.InvalidArguments",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Invalid arguments in method call");
>
> - ? ? ? if (obc_session_put(session, targetfile, sourcefile, NULL) < 0)
> + ? ? ? if (obc_session_put(session, targetfile, sourcefile, &transfer) < 0)
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.Failed",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"Failed");

Same here.

> - ? ? ? return dbus_message_new_method_return(message);
> + ? ? ? path = obc_transfer_get_path(transfer);
> +
> + ? ? ? reply = dbus_message_new_method_return(message);
> +
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> +
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *copy_file(DBusConnection *connection,
> @@ -503,10 +500,8 @@ static GDBusMethodTable ftp_methods[] = {
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> ? ? ? ?{ "ListFolder", ? ? ? ? "", "aa{sv}", ? list_folder,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> - ? ? ? { "GetFile", ? ? ? ? ? ?"ss", "", ? ? ? get_file,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> - ? ? ? { "PutFile", ? ? ? ? ? ?"ss", "", ? ? ? put_file,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> + ? ? ? { "GetFile", ? ? ? ? ? ?"ss", "o", ? ? ?get_file },
> + ? ? ? { "PutFile", ? ? ? ? ? ?"ss", "o", ? ? ?put_file },
> ? ? ? ?{ "CopyFile", ? ? ? ? ? "ss", "", ? ? ? copy_file,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> ? ? ? ?{ "MoveFile", ? ? ? ? ? "ss", "", ? ? ? move_file,
> diff --git a/test/ftp-client b/test/ftp-client
> index 05f16ad..d48b44e 100755
> --- a/test/ftp-client
> +++ b/test/ftp-client
> @@ -9,42 +9,6 @@ import dbus.mainloop.glib
> ?import os.path
> ?from optparse import OptionParser
>
> -class Agent(dbus.service.Object):
> - ? ?def __init__(self, conn=None, obj_path=None, verbose=False):
> - ? ? ? ?dbus.service.Object.__init__(self, conn, obj_path)
> - ? ? ? ?self.verbose = verbose
> -
> - ? [email protected]("org.openobex.Agent",
> - ? ? ? ? ? ? ? ? ? ?in_signature="o", out_signature="s")
> - ? ?def Request(self, path):
> - ? ? ? ?return ""
> -
> - ? [email protected]("org.openobex.Agent",
> - ? ? ? ? ? ? ? ? ? ?in_signature="ot", out_signature="")
> - ? ?def Progress(self, path, transferred):
> - ? ? ? ?if self.verbose:
> - ? ? ? ? ? ?print "Transfer progress (%d bytes)" % (transferred)
> - ? ? ? ?return
> -
> - ? [email protected]("org.openobex.Agent",
> - ? ? ? ? ? ? ? ? ? ?in_signature="o", out_signature="")
> - ? ?def Complete(self, path):
> - ? ? ? ?if self.verbose:
> - ? ? ? ? ? ?print "Transfer finished"
> - ? ? ? ?mainloop.quit()
> -
> - ? [email protected]("org.openobex.Agent",
> - ? ? ? ? ? ? ? ? ? ?in_signature="os", out_signature="")
> - ? ?def Error(self, path, error):
> - ? ? ? ?print "Transfer finished with an error: %s" % (error)
> - ? ? ? ?mainloop.quit()
> -
> - ? [email protected]("org.openobex.Agent",
> - ? ? ? ? ? ? ? ? ? ?in_signature="", out_signature="")
> - ? ?def Release(self):
> - ? ? ? ?mainloop.quit()
> -
> -
> ?def parse_options():
> ? ? parser.add_option("-d", "--device", dest="device",
> ? ? ? ? ? ? ? ? ? ? ? help="Device to connect", metavar="DEVICE")
> @@ -64,55 +28,89 @@ def parse_options():
> ? ? ? ? ? ? ? ? ? ? ? help="Destination FILE", metavar="FILE")
> ? ? parser.add_option("-r", "--remove", dest="remove_file",
> ? ? ? ? ? ? ? ? ? ? ? help="Remove FILE", metavar="FILE")
> - ? ?parser.add_option("-v", "--verbose", action="store_true", dest="verbose")
>
> ? ? return parser.parse_args()
>
> -def error(err):
> - ? ?print err
> -
> -def void_reply():
> - ? ?pass
> -
> -def change_folder(session, new_dir):
> - ? ?for node in new_dir.split("/"):
> - ? ? ? ?session.ChangeFolder(node)
> -
> -def list_folder(session):
> - ? ?for i in session.ListFolder():
> - ? ? ? ?if i["Type"] == "folder":
> - ? ? ? ? ? ?print "%s/" % (i["Name"])
> - ? ? ? ?else:
> - ? ? ? ? ? ?print "%s" % (i["Name"])
> -
> -def put_file(session, filename):
> - ? ?session.PutFile(os.path.abspath(filename),
> - ? ? ? ? ? ? ? ? ? ?os.path.basename(filename),
> - ? ? ? ? ? ? ? ? ? ?reply_handler=void_reply,
> - ? ? ? ? ? ? ? ? ? ?error_handler=error)
> -
> -def get_file(session, filename):
> - ? ?session.GetFile(os.path.abspath(filename),
> - ? ? ? ? ? ? ? ? ? ?os.path.basename(filename),
> - ? ? ? ? ? ? ? ? ? ?reply_handler=void_reply,
> - ? ? ? ? ? ? ? ? ? ?error_handler=error)
> -
> -def remove_file(session, filename):
> - ? ?session.Delete(filename,
> - ? ? ? ? ? ? ? ? ? ?reply_handler=void_reply,
> - ? ? ? ? ? ? ? ? ? ?error_handler=error)
> -
> -def move_file(session, filename, destname):
> - ? ?session.MoveFile(filename,
> - ? ? ? ? ? ? ? ? ? ?destname,
> - ? ? ? ? ? ? ? ? ? ?reply_handler=void_reply,
> - ? ? ? ? ? ? ? ? ? ?error_handler=error)
> -
> -def copy_file(session, filename, destname):
> - ? ?session.CopyFile(filename,
> - ? ? ? ? ? ? ? ? ? ?destname,
> - ? ? ? ? ? ? ? ? ? ?reply_handler=void_reply,
> - ? ? ? ? ? ? ? ? ? ?error_handler=error)
> +class FtpClient:
> + ? ?def __init__(self, session_path):
> + ? ? ? ?self.transfer_path = None
> + ? ? ? ?bus = dbus.SessionBus()
> + ? ? ? ?self.session = dbus.Interface(bus.get_object("org.openobex.client",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? session_path),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Session")
> + ? ? ? ?self.ftp = dbus.Interface(bus.get_object("org.openobex.client",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? session_path),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.FileTransfer")
> + ? ? ? ?bus.add_signal_receiver(
> + ? ? ? ? ? ?self.transfer_complete,
> + ? ? ? ? ? ?dbus_interface="org.openobex.Transfer",
> + ? ? ? ? ? ?signal_name="Complete",
> + ? ? ? ? ? ?path_keyword="path")
> + ? ? ? ?bus.add_signal_receiver(
> + ? ? ? ? ? ?self.transfer_error,
> + ? ? ? ? ? ?dbus_interface="org.openobex.Transfer",
> + ? ? ? ? ? ?signal_name="Error",
> + ? ? ? ? ? ?path_keyword="path")
> +
> + ? ?def create_transfer_reply(self, path):
> + ? ? ? ?self.transfer_path = path
> + ? ? ? ?print "Transfer created: %s" % path
> +
> + ? ?def error(self, err):
> + ? ? ? ?print err
> + ? ? ? ?mainloop.quit()
> +
> + ? ?def transfer_complete(self, path):
> + ? ? ? ?if path != self.transfer_path:
> + ? ? ? ? ? ?return
> + ? ? ? ?print "Transfer finished"
> + ? ? ? ?mainloop.quit()
> +
> + ? ?def transfer_error(self, error, path):
> + ? ? ? ?if path != self.transfer_path:
> + ? ? ? ? ? ?return
> + ? ? ? ?print "Transfer finished with an error: %s" % (error)
> + ? ? ? ?mainloop.quit()
> +
> + ? ?def change_folder(self, new_dir):
> + ? ? ? ?for node in new_dir.split("/"):
> + ? ? ? ? ? ?self.ftp.ChangeFolder(node)
> +
> + ? ?def list_folder(self):
> + ? ? ? ?for i in self.ftp.ListFolder():
> + ? ? ? ? ? ?if i["Type"] == "folder":
> + ? ? ? ? ? ? ? ?print "%s/" % (i["Name"])
> + ? ? ? ? ? ?else:
> + ? ? ? ? ? ? ? ?print "%s" % (i["Name"])
> +
> + ? ?def put_file(self, filename):
> + ? ? ? ?self.ftp.PutFile(os.path.abspath(filename),
> + ? ? ? ? ? ? ? ? ? ? ? ? os.path.basename(filename),
> + ? ? ? ? ? ? ? ? ? ? ? ? reply_handler=self.create_transfer_reply,
> + ? ? ? ? ? ? ? ? ? ? ? ? error_handler=self.error)
> +
> + ? ?def get_file(self, filename):
> + ? ? ? ?self.ftp.GetFile(os.path.abspath(filename),
> + ? ? ? ? ? ? ? ? ? ? ? ? os.path.basename(filename),
> + ? ? ? ? ? ? ? ? ? ? ? ? reply_handler=self.create_transfer_reply,
> + ? ? ? ? ? ? ? ? ? ? ? ? error_handler=self.error)
> +
> + ? ?def remove_file(self, filename):
> + ? ? ? ?self.ftp.Delete(filename,
> + ? ? ? ? ? ? ? ? ? ? ? ?reply_handler=self.create_transfer_reply,
> + ? ? ? ? ? ? ? ? ? ? ? ?error_handler=self.error)
> +
> + ? ?def move_file(self, filename, destname):
> + ? ? ? ?self.ftp.MoveFile(filename,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?destname,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?reply_handler=self.create_transfer_reply,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?error_handler=self.error)
> +
> + ? ?def copy_file(self, filename, destname):
> + ? ? ? ?self.ftp.CopyFile(filename,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?destname,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?reply_handler=self.create_transfer_reply,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?error_handler=self.error)
>
> ?if ?__name__ == '__main__':
>
> @@ -129,41 +127,33 @@ if ?__name__ == '__main__':
> ? ? bus = dbus.SessionBus()
> ? ? mainloop = gobject.MainLoop()
>
> - ? ?path = "/test/agent"
> - ? ?agent = Agent(bus, path, options.verbose)
> -
> ? ? client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Client")
>
> + ? ?print "Creating Session"
> ? ? session_path = client.CreateSession("", options.device, "ftp", dict())
>
> - ? ?session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
> - ? ? ? ? ? ? ? ? "org.openobex.Session")
> -
> - ? ?session.AssignAgent(path)
> -
> - ? ?ftp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
> - ? ? ? ? ? ? ? ? "org.openobex.FileTransfer")
> + ? ?ftp_client = FtpClient(session_path)
>
> ? ? if options.new_dir:
> - ? ? ? ?change_folder(ftp, options.new_dir)
> + ? ? ? ?ftp_client.change_folder(options.new_dir)
>
> ? ? if options.list_dir:
> - ? ? ? ?list_folder(ftp)
> + ? ? ? ?ftp_client.list_folder()
>
> ? ? if options.get_file:
> - ? ? ? ?get_file(ftp, options.get_file)
> + ? ? ? ?ftp_client.get_file(options.get_file)
>
> ? ? if options.put_file:
> - ? ? ? ?put_file(ftp, options.put_file)
> + ? ? ? ?ftp_client.put_file(options.put_file)
>
> ? ? if options.move_file:
> - ? ? ? ?move_file(ftp, options.move_file, options.dest_file)
> + ? ? ? ?ftp_client.move_file(options.move_file, options.dest_file)
>
> ? ? if options.copy_file:
> - ? ? ? ?copy_file(ftp, options.copy_file, options.dest_file)
> + ? ? ? ?ftp_client.copy_file(options.copy_file, options.dest_file)
>
> ? ? if options.remove_file:
> - ? ? ? remove_file(ftp, options.remove_file)
> + ? ? ? ftp_client.remove_file(options.remove_file)
>
> ? ? mainloop.run()
> --
> 1.7.6.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2011-12-09 12:31:34

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 13/21] client: ObjectPush sessions return transports

Hi Mikel,

On Fri, Dec 9, 2011 at 2:29 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
>
> hmm, I think transfer should be the return of obc_session_put and the
> err the parameter.
>
>> ? ? ? ? ? ? ? ?g_free(basename);
>> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ERROR_INF ".Failed", NULL);
>> ? ? ? ?}
>>
>> - ? ? ? return dbus_message_new_method_return(message);
>> -}
>> + ? ? ? path = obc_transfer_get_path(transfer);
>>
>> -static void pull_complete_callback(struct obc_session *session,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct obc_transfer *transfer,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *user_data)
>> -{
>> - ? ? ? struct pull_data *data = user_data;
>> -
>> - ? ? ? if (err != NULL) {
>> - ? ? ? ? ? ? ? DBusMessage *error = g_dbus_create_error(data->message,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Failed",
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
>> - ? ? ? ? ? ? ? g_dbus_send_message(data->connection, error);
>> - ? ? ? ? ? ? ? goto done;
>> - ? ? ? }
>> + ? ? ? reply = dbus_message_new_method_return(message);
>>
>> - ? ? ? g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
>> + ? ? ? dbus_message_append_args(reply,
>> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
>> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
>>
>> -done:
>> - ? ? ? dbus_message_unref(data->message);
>> - ? ? ? dbus_connection_unref(data->connection);
>> + ? ? ? return reply;
>> ?}
>>
>> ?static DBusMessage *opp_pull_business_card(DBusConnection *connection,
>> @@ -102,9 +86,11 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void *user_data)
>> ?{
>> ? ? ? ?struct opp_data *opp = user_data;
>> - ? ? ? struct pull_data *data;
>> ? ? ? ?DBusMessageIter iter;
>> ? ? ? ?const char *filename = NULL;
>> + ? ? ? DBusMessage *reply;
>> + ? ? ? struct obc_transfer *transfer;
>> + ? ? ? const char *path;
>>
>> ? ? ? ?dbus_message_iter_init(message, &iter);
>>
>> @@ -114,20 +100,19 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
>>
>> ? ? ? ?dbus_message_iter_get_basic(&iter, &filename);
>>
>> - ? ? ? data = g_try_malloc0(sizeof(*data));
>> - ? ? ? if (!data)
>> - ? ? ? ? ? ? ? return g_dbus_create_error(message,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Failed", "No Memory");
>> + ? ? ? obc_session_get_mem(opp->session, "text/x-vcard", filename,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL, 0, NULL, NULL,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &transfer);
>
> I thought we gonna store vcards in files too so we don't have to store
> everything in memory and then copy again to the application over
> D-Bus.

Forgot to tell you that there is a typo in the commit message, it
should be transfers instead of transports.

--
Luiz Augusto von Dentz

2011-12-09 12:29:03

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 13/21] client: ObjectPush sessions return transports

Hi Mikel,

On Thu, Dec 8, 2011 at 5:27 PM, Mikel Astiz <[email protected]> wrote:
> ---
> ?client/opp.c | ? 72 +++++++++++++++++++++------------------------------------
> ?1 files changed, 27 insertions(+), 45 deletions(-)
>
> diff --git a/client/opp.c b/client/opp.c
> index a1b1f75..5379222 100644
> --- a/client/opp.c
> +++ b/client/opp.c
> @@ -30,6 +30,7 @@
> ?#include "log.h"
>
> ?#include "session.h"
> +#include "transfer.h"
> ?#include "driver.h"
> ?#include "opp.h"
>
> @@ -37,16 +38,10 @@
> ?#define OPP_INTERFACE "org.openobex.ObjectPush"
> ?#define ERROR_INF OPP_INTERFACE ".Error"
>
> -
> ?struct opp_data {
> ? ? ? ?struct obc_session *session;
> ?};
>
> -struct pull_data {
> - ? ? ? DBusConnection *connection;
> - ? ? ? DBusMessage *message;
> -};
> -
> ?static DBusConnection *conn = NULL;
>
> ?static DBusMessage *opp_send_file(DBusConnection *connection,
> @@ -56,6 +51,9 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
> ? ? ? ?DBusMessageIter iter;
> ? ? ? ?char *filename;
> ? ? ? ?char *basename;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
>
> ? ? ? ?dbus_message_iter_init(message, &iter);
>
> @@ -66,35 +64,21 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
> ? ? ? ?dbus_message_iter_get_basic(&iter, &filename);
> ? ? ? ?basename = g_path_get_basename(filename);
>
> - ? ? ? if (obc_session_put(opp->session, basename, filename, NULL) < 0) {
> + ? ? ? if (obc_session_put(opp->session, basename, filename, &transfer) < 0) {

hmm, I think transfer should be the return of obc_session_put and the
err the parameter.

> ? ? ? ? ? ? ? ?g_free(basename);
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ERROR_INF ".Failed", NULL);
> ? ? ? ?}
>
> - ? ? ? return dbus_message_new_method_return(message);
> -}
> + ? ? ? path = obc_transfer_get_path(transfer);
>
> -static void pull_complete_callback(struct obc_session *session,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const struct obc_transfer *transfer,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void *user_data)
> -{
> - ? ? ? struct pull_data *data = user_data;
> -
> - ? ? ? if (err != NULL) {
> - ? ? ? ? ? ? ? DBusMessage *error = g_dbus_create_error(data->message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Failed",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
> - ? ? ? ? ? ? ? g_dbus_send_message(data->connection, error);
> - ? ? ? ? ? ? ? goto done;
> - ? ? ? }
> + ? ? ? reply = dbus_message_new_method_return(message);
>
> - ? ? ? g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
>
> -done:
> - ? ? ? dbus_message_unref(data->message);
> - ? ? ? dbus_connection_unref(data->connection);
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *opp_pull_business_card(DBusConnection *connection,
> @@ -102,9 +86,11 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void *user_data)
> ?{
> ? ? ? ?struct opp_data *opp = user_data;
> - ? ? ? struct pull_data *data;
> ? ? ? ?DBusMessageIter iter;
> ? ? ? ?const char *filename = NULL;
> + ? ? ? DBusMessage *reply;
> + ? ? ? struct obc_transfer *transfer;
> + ? ? ? const char *path;
>
> ? ? ? ?dbus_message_iter_init(message, &iter);
>
> @@ -114,20 +100,19 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
>
> ? ? ? ?dbus_message_iter_get_basic(&iter, &filename);
>
> - ? ? ? data = g_try_malloc0(sizeof(*data));
> - ? ? ? if (!data)
> - ? ? ? ? ? ? ? return g_dbus_create_error(message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ERROR_INF ".Failed", "No Memory");
> + ? ? ? obc_session_get_mem(opp->session, "text/x-vcard", filename,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL, 0, NULL, NULL,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &transfer);

I thought we gonna store vcards in files too so we don't have to store
everything in memory and then copy again to the application over
D-Bus.

> + ? ? ? path = obc_transfer_get_path(transfer);
>
> - ? ? ? data->connection = connection;
> - ? ? ? data->message = dbus_message_ref(message);
> + ? ? ? reply = dbus_message_new_method_return(message);
>
> - ? ? ? obc_session_get(opp->session, "text/x-vcard", filename, NULL,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL, 0,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pull_complete_callback, data,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL);
> + ? ? ? dbus_message_append_args(reply,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_OBJECT_PATH, &path,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
>
> - ? ? ? return NULL;
> + ? ? ? return reply;
> ?}
>
> ?static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
> @@ -137,12 +122,9 @@ static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
> ?}
>
> ?static GDBusMethodTable opp_methods[] = {
> - ? ? ? { "SendFile", ? ? ? ? ? "s", ? ?"", ? ? opp_send_file,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> - ? ? ? { "PullBusinessCard", ? "s", ? ?"", ? ? opp_pull_business_card,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> - ? ? ? { "ExchangeBusinessCards", "ss", "", ? ?opp_exchange_business_cards,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> + ? ? ? { "SendFile", ? ? ? ? ? "s", ? ?"o", ? ?opp_send_file },
> + ? ? ? { "PullBusinessCard", ? "s", ? ?"o", ? ?opp_pull_business_card },
> + ? ? ? { "ExchangeBusinessCards", "ss", "o", ? opp_exchange_business_cards },
> ? ? ? ?{ }
> ?};
>
> --
> 1.7.6.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2011-12-09 12:17:43

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 09/21] client: replace parameter dict with conventional ones

Hi Mikel,

On Thu, Dec 8, 2011 at 5:27 PM, Mikel Astiz <[email protected]> wrote:
> ---
> ?client/manager.c ? ? ? ? ? ? | ? 47 +++++++++++++++++++++++++++++------------
> ?test/exchange-business-cards | ? ?3 +-
> ?test/ftp-client ? ? ? ? ? ? ?| ? ?3 +-
> ?test/list-folders ? ? ? ? ? ?| ? ?2 +-
> ?test/pbap-client ? ? ? ? ? ? | ? ?2 +-
> ?test/pull-business-card ? ? ?| ? ?3 +-
> ?test/send-files ? ? ? ? ? ? ?| ? ?3 +-
> ?7 files changed, 39 insertions(+), 24 deletions(-)
>
> diff --git a/client/manager.c b/client/manager.c
> index 99c495a..ce3aa91 100644
> --- a/client/manager.c
> +++ b/client/manager.c
> @@ -101,9 +101,7 @@ done:
> ? ? ? ?g_free(data);
> ?}
>
> -static int parse_device_dict(DBusMessageIter *iter,
> - ? ? ? ? ? ? ? const char **source, const char **dest, const char **target,
> - ? ? ? ? ? ? ? uint8_t *channel)
> +static int parse_device_dict(DBusMessageIter *iter, uint8_t *channel)
> ?{
> ? ? ? ?while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
> ? ? ? ? ? ? ? ?DBusMessageIter entry, value;
> @@ -116,14 +114,6 @@ static int parse_device_dict(DBusMessageIter *iter,
> ? ? ? ? ? ? ? ?dbus_message_iter_recurse(&entry, &value);
>
> ? ? ? ? ? ? ? ?switch (dbus_message_iter_get_arg_type(&value)) {
> - ? ? ? ? ? ? ? case DBUS_TYPE_STRING:
> - ? ? ? ? ? ? ? ? ? ? ? if (g_str_equal(key, "Source") == TRUE)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_iter_get_basic(&value, source);
> - ? ? ? ? ? ? ? ? ? ? ? else if (g_str_equal(key, "Destination") == TRUE)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_iter_get_basic(&value, dest);
> - ? ? ? ? ? ? ? ? ? ? ? else if (g_str_equal(key, "Target") == TRUE)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_iter_get_basic(&value, target);
> - ? ? ? ? ? ? ? ? ? ? ? break;
> ? ? ? ? ? ? ? ?case DBUS_TYPE_BYTE:
> ? ? ? ? ? ? ? ? ? ? ? ?if (g_str_equal(key, "Channel") == TRUE)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?dbus_message_iter_get_basic(&value, channel);
> @@ -160,10 +150,36 @@ static DBusMessage *create_session(DBusConnection *connection,
> ? ? ? ?uint8_t channel = 0;
>
> ? ? ? ?dbus_message_iter_init(message, &iter);
> + ? ? ? if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
> + ? ? ? ? ? ? ? return g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
> +
> + ? ? ? dbus_message_iter_get_basic(&iter, &source);
> + ? ? ? dbus_message_iter_next(&iter);
> +
> + ? ? ? if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
> + ? ? ? ? ? ? ? return g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
> +
> + ? ? ? dbus_message_iter_get_basic(&iter, &dest);
> + ? ? ? dbus_message_iter_next(&iter);
> +
> + ? ? ? if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
> + ? ? ? ? ? ? ? return g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
> +
> + ? ? ? dbus_message_iter_get_basic(&iter, &target);
> + ? ? ? dbus_message_iter_next(&iter);
> +
> + ? ? ? if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
> + ? ? ? ? ? ? ? return g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
> +
> ? ? ? ?dbus_message_iter_recurse(&iter, &dict);
>
> - ? ? ? parse_device_dict(&dict, &source, &dest, &target, &channel);
> - ? ? ? if (dest == NULL || target == NULL)
> + ? ? ? parse_device_dict(&dict, &channel);
> +
> + ? ? ? if (*dest == '\0' || *target == '\0')
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.InvalidArguments", NULL);
>
> @@ -172,6 +188,9 @@ static DBusMessage *create_session(DBusConnection *connection,
> ? ? ? ? ? ? ? ?return g_dbus_create_error(message,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.openobex.Error.NoMemory", NULL);
>
> + ? ? ? if (*source == '\0')
> + ? ? ? ? ? ? ? source = NULL;
> +
> ? ? ? ?data->connection = dbus_connection_ref(connection);
> ? ? ? ?data->message = dbus_message_ref(message);
>
> @@ -219,7 +238,7 @@ static DBusMessage *remove_session(DBusConnection *connection,
> ?}
>
> ?static GDBusMethodTable client_methods[] = {
> - ? ? ? { "CreateSession", "a{sv}", "o", create_session,
> + ? ? ? { "CreateSession", "sssa{sv}", "o", create_session,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },

Only destination should be mandatory, the rest leave in the dictionary
as they are optional.

--
Luiz Augusto von Dentz

2011-12-09 12:11:22

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 07/21] client: GetCapabilities moved to session API

Hi Again,

On Fri, Dec 9, 2011 at 2:07 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
>> +static DBusMessage *get_capabilities(DBusConnection *connection,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DBusMessage *message, void *user_data)
>> +{
>> + ? ? ? struct obc_session *session = user_data;
>> +
>> + ? ? ? obc_session_pull(session, "x-obex/capability", NULL,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capabilities_complete_callback,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_ref(message));
>
> I guess you should probably mark this method as async, this way you
> don't need to reference the message. Actually I don't think this works
> without it having G_DBUS_METHOD_FLAG_ASYNC, if you return NULL as you
> did bellow gdbus will return DBUS_HANDLER_RESULT_NEED_MEMORY to
> libdbus.
>

Btw we should probably add a watch to the application so we are able
to cancel the request if the application disconnects before we reply.

--
Luiz Augusto von Dentz

2011-12-09 12:07:56

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC obexd v2 07/21] client: GetCapabilities moved to session API

Hi Mikel,

On Thu, Dec 8, 2011 at 5:27 PM, Mikel Astiz <[email protected]> wrote:
> ---
> ?client/manager.c | ? 99 ------------------------------------------------------
> ?client/session.c | ? 75 +++++++++++++++++++++++++++++++++++-----
> ?2 files changed, 65 insertions(+), 109 deletions(-)
>
> diff --git a/client/manager.c b/client/manager.c
> index efc6745..99c495a 100644
> --- a/client/manager.c
> +++ b/client/manager.c
> @@ -218,110 +218,11 @@ static DBusMessage *remove_session(DBusConnection *connection,
> ? ? ? ?return dbus_message_new_method_return(message);
> ?}
>
> -static void capabilities_complete_callback(struct obc_session *session,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err, void *user_data)
> -{
> - ? ? ? struct obc_transfer *transfer = obc_session_get_transfer(session);
> - ? ? ? struct send_data *data = user_data;
> - ? ? ? const char *capabilities;
> - ? ? ? int size;
> -
> - ? ? ? if (err != NULL) {
> - ? ? ? ? ? ? ? DBusMessage *error = g_dbus_create_error(data->message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.Failed",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
> - ? ? ? ? ? ? ? g_dbus_send_message(data->connection, error);
> - ? ? ? ? ? ? ? goto done;
> - ? ? ? }
> -
> - ? ? ? capabilities = obc_transfer_get_buffer(transfer, &size);
> - ? ? ? if (size == 0)
> - ? ? ? ? ? ? ? capabilities = "";
> -
> - ? ? ? g_dbus_send_reply(data->connection, data->message,
> - ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_STRING, &capabilities,
> - ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> -
> -done:
> -
> - ? ? ? shutdown_session(session);
> - ? ? ? dbus_message_unref(data->message);
> - ? ? ? dbus_connection_unref(data->connection);
> - ? ? ? g_free(data);
> -}
> -
> -static void capability_obc_session_callback(struct obc_session *session,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err, void *user_data)
> -{
> - ? ? ? struct send_data *data = user_data;
> -
> - ? ? ? if (err != NULL) {
> - ? ? ? ? ? ? ? DBusMessage *error = g_dbus_create_error(data->message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.Failed",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
> - ? ? ? ? ? ? ? g_dbus_send_message(data->connection, error);
> - ? ? ? ? ? ? ? shutdown_session(session);
> - ? ? ? ? ? ? ? goto done;
> - ? ? ? }
> -
> - ? ? ? obc_session_pull(session, "x-obex/capability", NULL,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capabilities_complete_callback, data);
> -
> - ? ? ? return;
> -
> -done:
> - ? ? ? dbus_message_unref(data->message);
> - ? ? ? dbus_connection_unref(data->connection);
> - ? ? ? g_free(data);
> -}
> -
> -static DBusMessage *get_capabilities(DBusConnection *connection,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DBusMessage *message, void *user_data)
> -{
> - ? ? ? DBusMessageIter iter, dict;
> - ? ? ? struct obc_session *session;
> - ? ? ? struct send_data *data;
> - ? ? ? const char *source = NULL, *dest = NULL, *target = NULL;
> - ? ? ? uint8_t channel = 0;
> -
> - ? ? ? dbus_message_iter_init(message, &iter);
> - ? ? ? dbus_message_iter_recurse(&iter, &dict);
> -
> - ? ? ? parse_device_dict(&dict, &source, &dest, &target, &channel);
> - ? ? ? if ((dest == NULL) || (target == NULL))
> - ? ? ? ? ? ? ? return g_dbus_create_error(message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.InvalidArguments", NULL);
> -
> - ? ? ? data = g_try_malloc0(sizeof(*data));
> - ? ? ? if (data == NULL)
> - ? ? ? ? ? ? ? return g_dbus_create_error(message,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.NoMemory", NULL);
> -
> - ? ? ? data->connection = dbus_connection_ref(connection);
> - ? ? ? data->message = dbus_message_ref(message);
> -
> - ? ? ? session = obc_session_create(source, dest, target, channel,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_get_sender(message),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capability_obc_session_callback, data);
> - ? ? ? if (session != NULL) {
> - ? ? ? ? ? ? ? sessions = g_slist_append(sessions, session);
> - ? ? ? ? ? ? ? return NULL;
> - ? ? ? }
> -
> - ? ? ? dbus_message_unref(data->message);
> - ? ? ? dbus_connection_unref(data->connection);
> - ? ? ? g_free(data);
> -
> - ? ? ? return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
> -}
> -
> ?static GDBusMethodTable client_methods[] = {
> ? ? ? ?{ "CreateSession", "a{sv}", "o", create_session,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> ? ? ? ?{ "RemoveSession", "o", "", remove_session,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?G_DBUS_METHOD_FLAG_ASYNC },
> - ? ? ? { "GetCapabilities", "a{sv}", "s", get_capabilities,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? G_DBUS_METHOD_FLAG_ASYNC },
> ? ? ? ?{ }
> ?};
>
> diff --git a/client/session.c b/client/session.c
> index 9f02512..0d56a1c 100644
> --- a/client/session.c
> +++ b/client/session.c
> @@ -91,7 +91,6 @@ struct obc_session {
> ? ? ? ?gchar *path; ? ? ? ? ? ?/* Session path */
> ? ? ? ?DBusConnection *conn;
> ? ? ? ?DBusConnection *conn_system; /* system bus connection */
> - ? ? ? DBusMessage *msg;
> ? ? ? ?GObex *obex;
> ? ? ? ?GIOChannel *io;
> ? ? ? ?struct obc_agent *agent;
> @@ -100,7 +99,6 @@ struct obc_session {
> ? ? ? ?guint watch;
> ? ? ? ?GSList *pending;
> ? ? ? ?GSList *pending_calls;
> - ? ? ? void *priv;
> ? ? ? ?char *adapter;
> ?};
>
> @@ -694,6 +692,7 @@ static void adapter_reply(DBusPendingCall *call, void *user_data)
> ? ? ? ?struct callback_data *callback = user_data;
> ? ? ? ?struct obc_session *session = callback->session;
> ? ? ? ?struct pending_req *req = find_session_request(session, call);
> + ? ? ? GError *gerr = NULL;
>
> ? ? ? ?reply = dbus_pending_call_steal_reply(call);
>
> @@ -702,19 +701,26 @@ static void adapter_reply(DBusPendingCall *call, void *user_data)
>
> ? ? ? ?dbus_error_init(&err);
> ? ? ? ?if (dbus_set_error_from_message(&err, reply)) {
> - ? ? ? ? ? ? ? error("manager replied with an error: %s, %s",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? err.name, err.message);
> + ? ? ? ? ? ? ? gerr = g_error_new(OBEX_IO_ERROR, -EIO,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "adapter replied with an error: %s, %s",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? err.name, err.message);
> + ? ? ? ? ? ? ? error(gerr->message);
> ? ? ? ? ? ? ? ?dbus_error_free(&err);
> -
> ? ? ? ? ? ? ? ?goto failed;
> ? ? ? ?}
>
> - ? ? ? if (session_connect(session, callback) < 0)
> + ? ? ? if (session_connect(session, callback) < 0) {
> + ? ? ? ? ? ? ? gerr = g_error_new(OBEX_IO_ERROR, -EIO,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "session connect error");
> ? ? ? ? ? ? ? ?goto failed;
> + ? ? ? }
>
> ? ? ? ?goto proceed;
>
> ?failed:
> + ? ? ? callback->func(session, gerr, callback->data);
> + ? ? ? g_clear_error(&gerr);
> +
> ? ? ? ?obc_session_unref(session);
> ? ? ? ?g_free(callback);
>
> @@ -730,6 +736,7 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
> ? ? ? ?struct callback_data *callback = user_data;
> ? ? ? ?struct obc_session *session = callback->session;
> ? ? ? ?struct pending_req *req = find_session_request(session, call);
> + ? ? ? GError *gerr = NULL;
>
> ? ? ? ?reply = dbus_pending_call_steal_reply(call);
>
> @@ -738,10 +745,11 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
>
> ? ? ? ?dbus_error_init(&err);
> ? ? ? ?if (dbus_set_error_from_message(&err, reply)) {
> - ? ? ? ? ? ? ? error("manager replied with an error: %s, %s",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? err.name, err.message);
> + ? ? ? ? ? ? ? gerr = g_error_new(OBEX_IO_ERROR, -EIO,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "manager replied with an error: %s, %s",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? err.name, err.message);
> + ? ? ? ? ? ? ? error(gerr->message);
> ? ? ? ? ? ? ? ?dbus_error_free(&err);
> -
> ? ? ? ? ? ? ? ?goto failed;
> ? ? ? ?}
>
> @@ -756,8 +764,11 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?BT_ADAPTER_IFACE, "RequestSession",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?adapter_reply, callback,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DBUS_TYPE_INVALID);
> - ? ? ? ? ? ? ? if (!req)
> + ? ? ? ? ? ? ? if (!req) {
> + ? ? ? ? ? ? ? ? ? ? ? gerr = g_error_new(OBEX_IO_ERROR, -EIO,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "RequestSession failed");
> ? ? ? ? ? ? ? ? ? ? ? ?goto failed;
> + ? ? ? ? ? ? ? }
>
> ? ? ? ? ? ? ? ?session->pending_calls = g_slist_prepend(session->pending_calls,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?req);
> @@ -767,6 +778,9 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
> ? ? ? ?goto proceed;
>
> ?failed:
> + ? ? ? callback->func(session, gerr, callback->data);
> + ? ? ? g_clear_error(&gerr);
> +
> ? ? ? ?obc_session_unref(session);
> ? ? ? ?g_free(callback);
>
> @@ -1013,10 +1027,51 @@ static DBusMessage *session_get_properties(DBusConnection *connection,
> ? ? ? ?return reply;
> ?}
>
> +static void capabilities_complete_callback(struct obc_session *session,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GError *err, void *user_data)
> +{
> + ? ? ? struct obc_transfer *transfer = obc_session_get_transfer(session);
> + ? ? ? DBusMessage *message = user_data;
> + ? ? ? const char *capabilities;
> + ? ? ? int size;
> +
> + ? ? ? if (err != NULL) {
> + ? ? ? ? ? ? ? DBusMessage *error = g_dbus_create_error(message,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.openobex.Error.Failed",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "%s", err->message);
> + ? ? ? ? ? ? ? g_dbus_send_message(session->conn, error);
> + ? ? ? ? ? ? ? goto done;
> + ? ? ? }
> +
> + ? ? ? capabilities = obc_transfer_get_buffer(transfer, &size);
> + ? ? ? if (size == 0)
> + ? ? ? ? ? ? ? capabilities = "";
> +
> + ? ? ? g_dbus_send_reply(session->conn, message,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_STRING, &capabilities,
> + ? ? ? ? ? ? ? ? ? ? ? DBUS_TYPE_INVALID);
> +
> +done:
> + ? ? ? dbus_message_unref(message);
> +}
> +
> +static DBusMessage *get_capabilities(DBusConnection *connection,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DBusMessage *message, void *user_data)
> +{
> + ? ? ? struct obc_session *session = user_data;
> +
> + ? ? ? obc_session_pull(session, "x-obex/capability", NULL,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capabilities_complete_callback,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dbus_message_ref(message));

I guess you should probably mark this method as async, this way you
don't need to reference the message. Actually I don't think this works
without it having G_DBUS_METHOD_FLAG_ASYNC, if you return NULL as you
did bellow gdbus will return DBUS_HANDLER_RESULT_NEED_MEMORY to
libdbus.

> + ? ? ? return NULL;
> +}
> +
> ?static GDBusMethodTable session_methods[] = {
> ? ? ? ?{ "GetProperties", ? ? ?"", "a{sv}", ? ?session_get_properties ?},
> ? ? ? ?{ "AssignAgent", ? ? ? ?"o", "", ? ? ? ?assign_agent ? ?},
> ? ? ? ?{ "ReleaseAgent", ? ? ? "o", "", ? ? ? ?release_agent ? },
> + ? ? ? { "GetCapabilities", ? ?"", "s", ? ? ? ?get_capabilities },
> ? ? ? ?{ }
> ?};
>
> --
> 1.7.6.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2011-12-08 15:27:44

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 10/21] client-doc: remove agent in favour of transfer signals

Assuming that the request confirmation from the agent is not necessary,
the rest of the reports can be achieved using signals in the transfer
object itself.

The main benefit of this is that the API is simpler and the client apps
do not have to register the agent, and can just listen to the relevant
signals.
---
doc/client-api.txt | 74 ++++++++++++++++++++-------------------------------
1 files changed, 29 insertions(+), 45 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index ad92869..0c30312 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -40,25 +40,26 @@ Methods dict GetProperties()

Returns all properties for the session.

- void AssignAgent(object agent)
-
- Assign an OBEX agent to this session. This allows
- detailed progress reports about the transactions.
-
- void ReleaseAgent(object agent)
-
- Release a previously assigned OBEX agent.
-
string GetCapabilities()

Get remote device capabilities.

+ array{object,dict} GetTransfers()
+
+ Get existing (queued) transfers in this session. This
+ method should only be called once, and further changes
+ should be monitored using the appropriate signals.
+
Properties string Source [readonly]

string Destination [readonly]

byte Channel [readonly]

+Signals void TransferAdded(object path, dict properties)
+
+ Informs that a new transfer has been created (queued).
+
Object Push hierarchy
=====================

@@ -286,54 +287,37 @@ Properties string Name [readonly]

Name of the transferred object.

- uint64 Size [readonly]
+ string Location [readonly, optional]

- Size of the transferred object. If the size is
- unknown, then this property will not be present.
-
- string Filename [readonly]
-
- Complete name of the file being received or sent.
-
-Agent hierarchy
-===============
+ Complete name of the local file being received or sent.
+ For operations from or to memory, this property will not
+ be present.

-Service unique name
-Interface org.openobex.Agent
-Object path freely definable
+ uint64 Size [readonly, optional]

-Methods void Release()
-
- This method gets called when the service daemon
- unregisters the agent. An agent can use it to do
- cleanup tasks. There is no need to unregister the
- agent, because when this method gets called it has
- already been unregistered.
-
- string Request(object transfer)
+ Size of the transferred object(s). If the size is
+ unknown, then this property will not be present.

- Accept or reject a new transfer (client and server)
- and provide the filename for it.
+ uint64 Progress [readonly, optional]

- In case of incoming transfers it is the filename
- where to store the file and for outgoing transfers
- it is the filename to show the remote device. If left
- empty it will be calculated automatically.
+ Number of bytes transferred. For queued transfers, this
+ value will not be present. When a queued transfer
+ begins, this property will take an initial value of 0.

- Possible errors: org.openobex.Error.Rejected
- org.openobex.Error.Canceled
+Signals PropertyChanged(string name, variant value)

- void Progress(object transfer, uint64 transferred)
+ This signal indicates a changed value of the given
+ property.

- Progress within the transfer has been made. The
- number of transferred bytes is given as second
- argument for convenience.
+ Upon creation, a transfer object will emit a signal of
+ type PropertyChanged("Progress", 0). This can be used
+ to monitor existing transfers.

- void Complete(object transfer)
+ void Complete()

Informs that the transfer has completed successfully.

- void Error(object transfer, string message)
+ void Error(string message)

Informs that the transfer has been terminated because
of some error.
--
1.7.6.4


2011-12-08 15:27:37

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 03/21] client: wrap OPP into specific session type

---
client/manager.c | 249 ++----------------------------------------
client/opp.c | 172 +++++++++++++++++++++++++++++-
test/exchange-business-cards | 10 ++-
test/get-capabilities | 15 +--
test/pull-business-card | 9 ++-
test/send-files | 86 ++------------
6 files changed, 216 insertions(+), 325 deletions(-)

diff --git a/client/manager.c b/client/manager.c
index dfb282b..efc6745 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -51,10 +51,6 @@
struct send_data {
DBusConnection *connection;
DBusMessage *message;
- gchar *sender;
- gchar *agent;
- char *filename;
- GPtrArray *files;
};

static GSList *sessions = NULL;
@@ -81,7 +77,7 @@ static void create_callback(struct obc_session *session, GError *err,
void *user_data)
{
struct send_data *data = user_data;
- unsigned int i;
+ const char *path;

if (err != NULL) {
DBusMessage *error = g_dbus_create_error(data->message,
@@ -92,44 +88,16 @@ static void create_callback(struct obc_session *session, GError *err,
goto done;
}

- if (obc_session_get_target(session) != NULL) {
- const char *path;

- path = obc_session_register(session, unregister_session);
+ path = obc_session_register(session, unregister_session);

- g_dbus_send_reply(data->connection, data->message,
+ g_dbus_send_reply(data->connection, data->message,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- goto done;
- }
-
- g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
-
- obc_session_set_agent(session, data->sender, data->agent);
-
- for (i = 0; i < data->files->len; i++) {
- const gchar *filename = g_ptr_array_index(data->files, i);
- gchar *basename = g_path_get_basename(filename);
-
- if (obc_session_send(session, filename, basename) < 0) {
- g_free(basename);
- break;
- }
-
- g_free(basename);
- }
-
- /* No need to keep a reference for SendFiles */
- sessions = g_slist_remove(sessions, session);
- obc_session_unref(session);

done:
- if (data->files)
- g_ptr_array_free(data->files, TRUE);
dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->agent);
g_free(data);
}

@@ -168,192 +136,6 @@ static int parse_device_dict(DBusMessageIter *iter,
return 0;
}

-static DBusMessage *send_files(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, array;
- struct obc_session *session;
- GPtrArray *files;
- struct send_data *data;
- const char *agent, *source = NULL, *dest = NULL, *target = NULL;
- const char *sender;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- parse_device_dict(&array, &source, &dest, &target, &channel);
- if (dest == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &array);
-
- files = g_ptr_array_new();
- if (files == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.NoMemory", NULL);
-
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
- char *value;
-
- dbus_message_iter_get_basic(&array, &value);
- g_ptr_array_add(files, value);
-
- dbus_message_iter_next(&array);
- }
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_get_basic(&iter, &agent);
-
- if (files->len == 0) {
- g_ptr_array_free(files, TRUE);
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
- }
-
- sender = dbus_message_get_sender(message);
-
- data = g_try_malloc0(sizeof(*data));
- if (data == NULL) {
- g_ptr_array_free(files, TRUE);
- return g_dbus_create_error(message,
- "org.openobex.Error.NoMemory", NULL);
- }
-
- data->connection = dbus_connection_ref(connection);
- data->message = dbus_message_ref(message);
- data->sender = g_strdup(sender);
- data->agent = g_strdup(agent);
- data->files = files;
-
- session = obc_session_create(source, dest, "OPP", channel, sender,
- create_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- return NULL;
- }
-
- g_ptr_array_free(data->files, TRUE);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->agent);
- g_free(data);
-
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
-static void pull_complete_callback(struct obc_session *session,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- goto done;
- }
-
- g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
-
-done:
- shutdown_session(session);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->filename);
- g_free(data->sender);
- g_free(data);
-}
-
-static void pull_obc_session_callback(struct obc_session *session,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- shutdown_session(session);
- goto done;
- }
-
- obc_session_pull(session, "text/x-vcard", data->filename,
- pull_complete_callback, data);
-
- return;
-
-done:
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->filename);
- g_free(data->sender);
- g_free(data);
-}
-
-static DBusMessage *pull_business_card(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, dict;
- struct obc_session *session;
- struct send_data *data;
- const char *source = NULL, *dest = NULL, *target = NULL;
- const char *name = NULL;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &dict);
-
- parse_device_dict(&dict, &source, &dest, &target, &channel);
- if (dest == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- dbus_message_iter_get_basic(&iter, &name);
-
- data = g_try_malloc0(sizeof(*data));
- if (data == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.NoMemory", NULL);
-
- data->connection = dbus_connection_ref(connection);
- data->message = dbus_message_ref(message);
- data->sender = g_strdup(dbus_message_get_sender(message));
- data->filename = g_strdup(name);
-
- session = obc_session_create(source, dest, "OPP", channel, data->sender,
- pull_obc_session_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- return NULL;
- }
-
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data->sender);
- g_free(data->filename);
- g_free(data);
-
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
-static DBusMessage *exchange_business_cards(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
static struct obc_session *find_session(const char *path)
{
GSList *l;
@@ -392,10 +174,10 @@ static DBusMessage *create_session(DBusConnection *connection,

data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);
- data->sender = g_strdup(dbus_message_get_sender(message));

- session = obc_session_create(source, dest, target, channel, data->sender,
- create_callback, data);
+ session = obc_session_create(source, dest, target, channel,
+ dbus_message_get_sender(message),
+ create_callback, data);
if (session != NULL) {
sessions = g_slist_append(sessions, session);
return NULL;
@@ -403,7 +185,6 @@ static DBusMessage *create_session(DBusConnection *connection,

dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
g_free(data);

return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
@@ -466,7 +247,6 @@ done:
shutdown_session(session);
dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
g_free(data);
}

@@ -492,7 +272,6 @@ static void capability_obc_session_callback(struct obc_session *session,
done:
dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
g_free(data);
}

@@ -509,7 +288,7 @@ static DBusMessage *get_capabilities(DBusConnection *connection,
dbus_message_iter_recurse(&iter, &dict);

parse_device_dict(&dict, &source, &dest, &target, &channel);
- if (dest == NULL)
+ if ((dest == NULL) || (target == NULL))
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

@@ -520,12 +299,9 @@ static DBusMessage *get_capabilities(DBusConnection *connection,

data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);
- data->sender = g_strdup(dbus_message_get_sender(message));

- if (!target)
- target = "OPP";
-
- session = obc_session_create(source, dest, target, channel, data->sender,
+ session = obc_session_create(source, dest, target, channel,
+ dbus_message_get_sender(message),
capability_obc_session_callback, data);
if (session != NULL) {
sessions = g_slist_append(sessions, session);
@@ -534,19 +310,12 @@ static DBusMessage *get_capabilities(DBusConnection *connection,

dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
g_free(data);

return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
}

static GDBusMethodTable client_methods[] = {
- { "SendFiles", "a{sv}aso", "", send_files,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "PullBusinessCard", "a{sv}s", "", pull_business_card,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "ExchangeBusinessCards", "a{sv}ss", "", exchange_business_cards,
- G_DBUS_METHOD_FLAG_ASYNC },
{ "CreateSession", "a{sv}", "o", create_session,
G_DBUS_METHOD_FLAG_ASYNC },
{ "RemoveSession", "o", "", remove_session,
diff --git a/client/opp.c b/client/opp.c
index be382ef..5af18b5 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -25,6 +25,8 @@
#include <config.h>
#endif

+#include <errno.h>
+
#include "log.h"

#include "session.h"
@@ -32,22 +34,190 @@
#include "opp.h"

#define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
+#define OPP_INTERFACE "org.openobex.ObjectPush"
+#define ERROR_INF OPP_INTERFACE ".Error"
+
+
+struct opp_data {
+ struct obc_session *session;
+};
+
+struct pull_data {
+ DBusConnection *connection;
+ DBusMessage *message;
+};
+
+static DBusConnection *conn = NULL;
+
+static DBusMessage *opp_send_files(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct opp_data *opp = user_data;
+ DBusMessageIter iter, array;
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ char *filename;
+ char *basename;
+
+ dbus_message_iter_get_basic(&array, &filename);
+ basename = g_path_get_basename(filename);
+
+ if (obc_session_send(opp->session, filename, basename) < 0) {
+ g_free(basename);
+ break;
+ }
+
+ g_free(basename);
+ dbus_message_iter_next(&array);
+ }
+
+ return dbus_message_new_method_return(message);
+}
+
+static void pull_complete_callback(struct obc_session *session,
+ GError *err, void *user_data)
+{
+ struct pull_data *data = user_data;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(data->message,
+ ERROR_INF ".Failed",
+ "%s", err->message);
+ g_dbus_send_message(data->connection, error);
+ goto done;
+ }
+
+ g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+
+done:
+ dbus_message_unref(data->message);
+ dbus_connection_unref(data->connection);
+}
+
+static DBusMessage *opp_pull_business_card(DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ struct opp_data *opp = user_data;
+ struct pull_data *data;
+ DBusMessageIter iter;
+ const char *filename = NULL;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ ERROR_INF ".InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&iter, &filename);
+
+ data = g_try_malloc0(sizeof(*data));
+ if (!data)
+ return g_dbus_create_error(message,
+ ERROR_INF ".Failed", "No Memory");
+
+ data->connection = connection;
+ data->message = dbus_message_ref(message);
+
+ obc_session_pull(opp->session, "text/x-vcard", filename,
+ pull_complete_callback, data);
+
+ return NULL;
+}
+
+static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ return g_dbus_create_error(message, ERROR_INF ".Failed", NULL);
+}
+
+static GDBusMethodTable opp_methods[] = {
+ { "SendFiles", "as", "", opp_send_files,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "PullBusinessCard", "s", "", opp_pull_business_card,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "ExchangeBusinessCards", "ss", "", opp_exchange_business_cards,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { }
+};
+
+static void opp_free(void *data)
+{
+ struct opp_data *opp = data;
+
+ obc_session_unref(opp->session);
+ g_free(opp);
+}
+
+static int opp_probe(struct obc_session *session)
+{
+ struct opp_data *opp;
+ const char *path;
+
+ path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ opp = g_try_new0(struct opp_data, 1);
+ if (!opp)
+ return -ENOMEM;
+
+ opp->session = obc_session_ref(session);
+
+ if (!g_dbus_register_interface(conn, path, OPP_INTERFACE, opp_methods,
+ NULL, NULL, opp, opp_free)) {
+ opp_free(opp);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void opp_remove(struct obc_session *session)
+{
+ const char *path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ g_dbus_unregister_interface(conn, path, OPP_INTERFACE);
+}

static struct obc_driver opp = {
.service = "OPP",
.uuid = OPP_UUID,
+ .probe = opp_probe,
+ .remove = opp_remove
};

int opp_init(void)
{
+ int err;
+
DBG("");

- return obc_driver_register(&opp);
+ conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!conn)
+ return -EIO;
+
+ err = obc_driver_register(&opp);
+ if (err < 0) {
+ dbus_connection_unref(conn);
+ conn = NULL;
+ return err;
+ }
+
+ return 0;
}

void opp_exit(void)
{
DBG("");

+ dbus_connection_unref(conn);
+ conn = NULL;
+
obc_driver_unregister(&opp);
}
diff --git a/test/exchange-business-cards b/test/exchange-business-cards
index 4b0c7ed..548ad2d 100755
--- a/test/exchange-business-cards
+++ b/test/exchange-business-cards
@@ -11,5 +11,11 @@ if (len(sys.argv) < 4):
print "Usage: %s <device> <clientfile> <file>" % (sys.argv[0])
sys.exit(1)

-client.ExchangeBusinessCards({ "Destination": sys.argv[1] },
- sys.argv[2], sys.argv[3])
+print "Creating Session"
+session_path = client.CreateSession({"Destination": sys.argv[1],
+ "Target": "OPP"})
+opp = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.ObjectPush")
+
+opp.ExchangeBusinessCards(sys.argv[2], sys.argv[3])
diff --git a/test/get-capabilities b/test/get-capabilities
index c835bd9..1bbc274 100755
--- a/test/get-capabilities
+++ b/test/get-capabilities
@@ -7,14 +7,13 @@ bus = dbus.SessionBus()
client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
"org.openobex.Client")

-if (len(sys.argv) < 2):
- print "Usage: %s <device> [target]" % (sys.argv[0])
+if (len(sys.argv) < 3):
+ print "Usage: %s <device> <target>" % (sys.argv[0])
sys.exit(1)

-if (len(sys.argv) == 3):
- dict = {"Destination": sys.argv[1],
- "Target": sys.argv[2]}
-else:
- dict = {"Destination": sys.argv[1]}
+print "Creating Session"
+session_path = client.CreateSession("", sys.argv[1], sys.argv[2], dict())
+session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
+ "org.openobex.Session")

-print client.GetCapabilities(dict)
+print session.GetCapabilities()
diff --git a/test/pull-business-card b/test/pull-business-card
index b13968d..5912155 100755
--- a/test/pull-business-card
+++ b/test/pull-business-card
@@ -28,7 +28,14 @@ if __name__ == '__main__':
print "Usage: %s <device> <file>" % (sys.argv[0])
sys.exit(1)

- client.PullBusinessCard({ "Destination": sys.argv[1] }, sys.argv[2],
+ print "Creating Session"
+ session_path = client.CreateSession({"Destination": sys.argv[1],
+ "Target": "OPP"})
+ opp = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.ObjectPush")
+
+ opp.PullBusinessCard(sys.argv[2],
reply_handler=success, error_handler=failure)

mainloop.run()
diff --git a/test/send-files b/test/send-files
index 52f9c04..6d634f5 100755
--- a/test/send-files
+++ b/test/send-files
@@ -1,82 +1,22 @@
#!/usr/bin/python

-import gobject
-
-import os
import sys
-import time
import dbus
-import dbus.service
-import dbus.mainloop.glib
-
-class Agent(dbus.service.Object):
- def __init__(self, conn=None, obj_path=None):
- dbus.service.Object.__init__(self, conn, obj_path)
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="o", out_signature="s")
- def Request(self, path):
- print "Transfer Request"
- self.transfer = dbus.Interface(bus.get_object("org.openobex.client",
- path), "org.openobex.Transfer")
- properties = self.transfer.GetProperties()
- for key in properties.keys():
- print " %s = %s" % (key, properties[key])
- self.start = True
- return ""
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="ot", out_signature="")
- def Progress(self, path, transferred):
- if (self.start):
- print "Transfer Started"
- properties = self.transfer.GetProperties()
- self.transfer_size = properties['Size']
- self.start_time = time.time()
- self.start = False
- else:
- speed = transferred / abs((time.time() - self.start_time) * 1000)
- progress = "(" + str(transferred) + "/" + str(self.transfer_size) + " bytes) @ " + str(int(speed)) + " kB/s"
- out = "\rTransfer progress " + progress
- sys.stdout.write(out)
- sys.stdout.flush()
- return
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="o", out_signature="")
- def Complete(self, path):
- print "\nTransfer finished"
- return
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="os", out_signature="")
- def Error(self, path, error):
- print "\nTransfer finished with an error: %s" % (error)
- return
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="", out_signature="")
- def Release(self):
- mainloop.quit()
- return
-
-if __name__ == '__main__':
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
- bus = dbus.SessionBus()
- client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
- "org.openobex.Client")

- if (len(sys.argv) < 3):
- print "Usage: %s <device> <file> [file*]" % (sys.argv[0])
- sys.exit(1)
+bus = dbus.SessionBus()
+client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
+ "org.openobex.Client")

- path = "/test/agent"
- agent = Agent(bus, path)
+if (len(sys.argv) < 3):
+ print "Usage: %s <device> <file> [file*]" % (sys.argv[0])
+ sys.exit(1)

- mainloop = gobject.MainLoop()
- files = [os.path.realpath(f) for f in sys.argv[2:]]
+files = [os.path.realpath(f) for f in sys.argv[2:]]

- client.SendFiles({ "Destination": sys.argv[1] }, files, path)
+print "Creating Session"
+session_path = client.CreateSession({"Destination": sys.argv[1],
+ "Target": "OPP"})
+opp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
+ "org.openobex.ObjectPush")

- mainloop.run()
+opp.SendFiles(files)
--
1.7.6.4


2011-12-08 15:27:40

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 06/21] client-doc: GetCapabilities moved to session API

---
doc/client-api.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 43521ff..65de1f1 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -20,10 +20,6 @@ Methods object CreateSession(dict device)

Unregister session and abort pending transfers.

- string GetCapabilities(dict device)
-
- Get remote device capabilities.
-
Properties string Target

string Source
@@ -52,6 +48,10 @@ Methods dict GetProperties()

Release a previously assigned OBEX agent.

+ string GetCapabilities()
+
+ Get remote device capabilities.
+
Properties string Source [readonly]

string Destination [readonly]
--
1.7.6.4


2011-12-08 15:27:42

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 08/21] client-doc: replace parameter dict with conventional ones

Common arguments are required as formal parameters in the D-Bus API, and
an additional dictionary is used to pass target-specific parameters.
This will allow future extensions without breaking the method signature.
---
doc/client-api.txt | 23 ++++++++++++-----------
1 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 65de1f1..ad92869 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -11,23 +11,24 @@ Service org.openobex.client
Interface org.openobex.Client
Object path /

-Methods object CreateSession(dict device)
+Methods object CreateSession(string source, string destination,
+ string target, dict args)

- Create a new OBEX session. The device is configured
- via properties like in SendFiles.
+ Create a new OBEX session for the given source (local)
+ address, destination (remote) address and target. The
+ supported target values are:
+ - "OPP"
+ - "FTP"
+ - "SYNC"
+ - "PBAP"
+
+ The fourth argument is used to pass target-specific
+ parameters.

void RemoveSession(object session)

Unregister session and abort pending transfers.

-Properties string Target
-
- string Source
-
- string Destination
-
- byte Channel
-
Session hierarchy
=================

--
1.7.6.4


2011-12-08 15:27:47

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 13/21] client: ObjectPush sessions return transports

---
client/opp.c | 72 +++++++++++++++++++++------------------------------------
1 files changed, 27 insertions(+), 45 deletions(-)

diff --git a/client/opp.c b/client/opp.c
index a1b1f75..5379222 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -30,6 +30,7 @@
#include "log.h"

#include "session.h"
+#include "transfer.h"
#include "driver.h"
#include "opp.h"

@@ -37,16 +38,10 @@
#define OPP_INTERFACE "org.openobex.ObjectPush"
#define ERROR_INF OPP_INTERFACE ".Error"

-
struct opp_data {
struct obc_session *session;
};

-struct pull_data {
- DBusConnection *connection;
- DBusMessage *message;
-};
-
static DBusConnection *conn = NULL;

static DBusMessage *opp_send_file(DBusConnection *connection,
@@ -56,6 +51,9 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
DBusMessageIter iter;
char *filename;
char *basename;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

dbus_message_iter_init(message, &iter);

@@ -66,35 +64,21 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
dbus_message_iter_get_basic(&iter, &filename);
basename = g_path_get_basename(filename);

- if (obc_session_put(opp->session, basename, filename, NULL) < 0) {
+ if (obc_session_put(opp->session, basename, filename, &transfer) < 0) {
g_free(basename);
return g_dbus_create_error(message,
ERROR_INF ".Failed", NULL);
}

- return dbus_message_new_method_return(message);
-}
+ path = obc_transfer_get_path(transfer);

-static void pull_complete_callback(struct obc_session *session,
- GError *err,
- const struct obc_transfer *transfer,
- void *user_data)
-{
- struct pull_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- ERROR_INF ".Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- goto done;
- }
+ reply = dbus_message_new_method_return(message);

- g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);

-done:
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
+ return reply;
}

static DBusMessage *opp_pull_business_card(DBusConnection *connection,
@@ -102,9 +86,11 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
void *user_data)
{
struct opp_data *opp = user_data;
- struct pull_data *data;
DBusMessageIter iter;
const char *filename = NULL;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

dbus_message_iter_init(message, &iter);

@@ -114,20 +100,19 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,

dbus_message_iter_get_basic(&iter, &filename);

- data = g_try_malloc0(sizeof(*data));
- if (!data)
- return g_dbus_create_error(message,
- ERROR_INF ".Failed", "No Memory");
+ obc_session_get_mem(opp->session, "text/x-vcard", filename,
+ NULL, 0, NULL, NULL,
+ &transfer);
+
+ path = obc_transfer_get_path(transfer);

- data->connection = connection;
- data->message = dbus_message_ref(message);
+ reply = dbus_message_new_method_return(message);

- obc_session_get(opp->session, "text/x-vcard", filename, NULL,
- NULL, 0,
- pull_complete_callback, data,
- NULL);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);

- return NULL;
+ return reply;
}

static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
@@ -137,12 +122,9 @@ static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
}

static GDBusMethodTable opp_methods[] = {
- { "SendFile", "s", "", opp_send_file,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "PullBusinessCard", "s", "", opp_pull_business_card,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "ExchangeBusinessCards", "ss", "", opp_exchange_business_cards,
- G_DBUS_METHOD_FLAG_ASYNC },
+ { "SendFile", "s", "o", opp_send_file },
+ { "PullBusinessCard", "s", "o", opp_pull_business_card },
+ { "ExchangeBusinessCards", "ss", "o", opp_exchange_business_cards },
{ }
};

--
1.7.6.4


2011-12-08 15:27:43

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 09/21] client: replace parameter dict with conventional ones

---
client/manager.c | 47 +++++++++++++++++++++++++++++------------
test/exchange-business-cards | 3 +-
test/ftp-client | 3 +-
test/list-folders | 2 +-
test/pbap-client | 2 +-
test/pull-business-card | 3 +-
test/send-files | 3 +-
7 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/client/manager.c b/client/manager.c
index 99c495a..ce3aa91 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -101,9 +101,7 @@ done:
g_free(data);
}

-static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **dest, const char **target,
- uint8_t *channel)
+static int parse_device_dict(DBusMessageIter *iter, uint8_t *channel)
{
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry, value;
@@ -116,14 +114,6 @@ static int parse_device_dict(DBusMessageIter *iter,
dbus_message_iter_recurse(&entry, &value);

switch (dbus_message_iter_get_arg_type(&value)) {
- case DBUS_TYPE_STRING:
- if (g_str_equal(key, "Source") == TRUE)
- dbus_message_iter_get_basic(&value, source);
- else if (g_str_equal(key, "Destination") == TRUE)
- dbus_message_iter_get_basic(&value, dest);
- else if (g_str_equal(key, "Target") == TRUE)
- dbus_message_iter_get_basic(&value, target);
- break;
case DBUS_TYPE_BYTE:
if (g_str_equal(key, "Channel") == TRUE)
dbus_message_iter_get_basic(&value, channel);
@@ -160,10 +150,36 @@ static DBusMessage *create_session(DBusConnection *connection,
uint8_t channel = 0;

dbus_message_iter_init(message, &iter);
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&iter, &source);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&iter, &dest);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&iter, &target);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
dbus_message_iter_recurse(&iter, &dict);

- parse_device_dict(&dict, &source, &dest, &target, &channel);
- if (dest == NULL || target == NULL)
+ parse_device_dict(&dict, &channel);
+
+ if (*dest == '\0' || *target == '\0')
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

@@ -172,6 +188,9 @@ static DBusMessage *create_session(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.NoMemory", NULL);

+ if (*source == '\0')
+ source = NULL;
+
data->connection = dbus_connection_ref(connection);
data->message = dbus_message_ref(message);

@@ -219,7 +238,7 @@ static DBusMessage *remove_session(DBusConnection *connection,
}

static GDBusMethodTable client_methods[] = {
- { "CreateSession", "a{sv}", "o", create_session,
+ { "CreateSession", "sssa{sv}", "o", create_session,
G_DBUS_METHOD_FLAG_ASYNC },
{ "RemoveSession", "o", "", remove_session,
G_DBUS_METHOD_FLAG_ASYNC },
diff --git a/test/exchange-business-cards b/test/exchange-business-cards
index 548ad2d..78c8294 100755
--- a/test/exchange-business-cards
+++ b/test/exchange-business-cards
@@ -12,8 +12,7 @@ if (len(sys.argv) < 4):
sys.exit(1)

print "Creating Session"
-session_path = client.CreateSession({"Destination": sys.argv[1],
- "Target": "OPP"})
+session_path = client.CreateSession("", sys.argv[1], "OPP", dict())
opp = dbus.Interface(bus.get_object("org.openobex.client",
session_path),
"org.openobex.ObjectPush")
diff --git a/test/ftp-client b/test/ftp-client
index 9bc038d..05f16ad 100755
--- a/test/ftp-client
+++ b/test/ftp-client
@@ -135,8 +135,7 @@ if __name__ == '__main__':
client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
"org.openobex.Client")

- session_path = client.CreateSession({ "Destination": options.device,
- "Target": "ftp"})
+ session_path = client.CreateSession("", options.device, "ftp", dict())

session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.Session")
diff --git a/test/list-folders b/test/list-folders
index c7eec10..3e185be 100755
--- a/test/list-folders
+++ b/test/list-folders
@@ -9,7 +9,7 @@ def list_folder(folder):
client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
"org.openobex.Client")

- session_path = client.CreateSession({ "Destination": sys.argv[1], "Target": "ftp"})
+ session_path = client.CreateSession("", sys.argv[1], "ftp", dict())

ftp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.FileTransfer")
diff --git a/test/pbap-client b/test/pbap-client
index 7456c01..f87f33c 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -9,7 +9,7 @@ client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
"org.openobex.Client")

print "Creating Session"
-session_path = client.CreateSession({"Destination": sys.argv[1], "Target": "PBAP"})
+session_path = client.CreateSession("", sys.argv[1], "PBAP", dict())
pbap = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.PhonebookAccess")
session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
diff --git a/test/pull-business-card b/test/pull-business-card
index 5912155..20e42b7 100755
--- a/test/pull-business-card
+++ b/test/pull-business-card
@@ -29,8 +29,7 @@ if __name__ == '__main__':
sys.exit(1)

print "Creating Session"
- session_path = client.CreateSession({"Destination": sys.argv[1],
- "Target": "OPP"})
+ session_path = client.CreateSession("", sys.argv[1], "OPP", dict())
opp = dbus.Interface(bus.get_object("org.openobex.client",
session_path),
"org.openobex.ObjectPush")
diff --git a/test/send-files b/test/send-files
index e84d10f..da12382 100755
--- a/test/send-files
+++ b/test/send-files
@@ -14,8 +14,7 @@ if (len(sys.argv) < 3):
files = [os.path.realpath(f) for f in sys.argv[2:]]

print "Creating Session"
-session_path = client.CreateSession({"Destination": sys.argv[1],
- "Target": "OPP"})
+session_path = client.CreateSession("", sys.argv[1], "OPP", dict())
opp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.ObjectPush")
for f in files:
--
1.7.6.4


2011-12-08 15:27:50

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 16/21] client-doc: Synchronization sessions return transports

---
doc/client-api.txt | 19 +++++++++++++++----
1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3736982..b17eee9 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -285,14 +285,25 @@ Methods void SetLocation(string location)
"SIM2"
......

- string GetPhonebook()
+ object GetPhonebook(string targetfile)

Retrieve an entire Phonebook Object store from remote
- device
+ device, and stores it in a local file.

- void PutPhonebook(string obj)
+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.

- Send an entire Phonebook Object store to remote device
+ object PutPhonebook(string obj)
+
+ Send an entire Phonebook Object store to remote device.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.

Transfer hierarchy
==================
--
1.7.6.4


2011-12-08 15:27:53

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 19/21] client: PhonebookAccess sessions return transports

---
client/pbap.c | 119 ++++++++++++++++++---------------
test/pbap-client | 192 ++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 221 insertions(+), 90 deletions(-)

diff --git a/client/pbap.c b/client/pbap.c
index 8e21cb5..da2c22d 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -411,39 +411,6 @@ static void read_return_apparam(const struct obc_transfer *transfer,
}
}

-static void pull_phonebook_callback(struct obc_session *session,
- GError *err,
- const struct obc_transfer *transfer,
- void *user_data)
-{
- struct pbap_data *pbap = user_data;
- DBusMessage *reply;
- const void *buf;
-
- if (pbap->msg == NULL)
- return;
-
- 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);
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &buf,
- DBUS_TYPE_INVALID);
-
-send:
- g_dbus_send_message(conn, reply);
- dbus_message_unref(pbap->msg);
- pbap->msg = NULL;
-}
-
static void phonebook_size_callback(struct obc_session *session,
GError *err,
const struct obc_transfer *transfer,
@@ -521,12 +488,16 @@ send:

static DBusMessage *pull_phonebook(struct pbap_data *pbap,
DBusMessage *message, guint8 type,
- const char *name, uint64_t filter,
+ const char *name,
+ const char *targetname,
+ uint64_t filter,
guint8 format, guint16 maxlistcount,
- guint16 liststartoffset)
+ guint16 liststartoffset,
+ struct obc_transfer **transfer)
{
struct pullphonebook_apparam apparam;
session_transfer_callback_t func;
+ int ret;

if (pbap->msg)
return g_dbus_create_error(message,
@@ -548,7 +519,7 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,

switch (type) {
case PULLPHONEBOOK:
- func = pull_phonebook_callback;
+ func = NULL;
break;
case GETPHONEBOOKSIZE:
func = phonebook_size_callback;
@@ -558,14 +529,23 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
return NULL;
}

- if (obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
+ if (targetname != NULL)
+ ret = obc_session_get(pbap->session, "x-bt/phonebook", name,
+ targetname,
+ (guint8 *) &apparam, sizeof(apparam),
+ func, pbap, transfer);
+ else
+ ret = obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
(guint8 *) &apparam, sizeof(apparam),
- func, pbap, NULL) < 0)
+ func, pbap, transfer);
+
+ if (ret < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");

- pbap->msg = dbus_message_ref(message);
+ if (func != NULL)
+ pbap->msg = dbus_message_ref(message);

return NULL;
}
@@ -795,18 +775,40 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
struct pbap_data *pbap = user_data;
DBusMessage * err;
char *name;
+ const char *target_file;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &target_file,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);

if (!pbap->path)
return g_dbus_create_error(message,
- ERROR_INF ".Forbidden", "Call Select first of all");
+ ERROR_INF ".Forbidden", "Call Select first of all");

name = g_strconcat(pbap->path, ".vcf", NULL);

- err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
+ err = pull_phonebook(pbap, message, PULLPHONEBOOK, name, target_file,
pbap->filter, pbap->format,
- DEFAULT_COUNT, DEFAULT_OFFSET);
+ DEFAULT_COUNT, DEFAULT_OFFSET, &transfer);
g_free(name);
- return err;
+
+ if (err != NULL)
+ return err;
+
+ path = obc_transfer_get_path(transfer);
+
+ reply = dbus_message_new_method_return(message);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
@@ -814,7 +816,10 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
{
struct pbap_data *pbap = user_data;
struct pullvcardentry_apparam apparam;
- const char *name;
+ const char *name, *target_file;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

if (!pbap->path)
return g_dbus_create_error(message,
@@ -823,6 +828,7 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &target_file,
DBUS_TYPE_INVALID) == FALSE)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
@@ -839,15 +845,22 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
apparam.format_len = FORMAT_LEN;
apparam.format = pbap->format;

- if (obc_session_get_mem(pbap->session, "x-bt/vcard", name,
+ if (obc_session_get(pbap->session, "x-bt/vcard", name, target_file,
(guint8 *) &apparam, sizeof(apparam),
- pull_phonebook_callback, pbap, NULL) < 0)
+ NULL, NULL, &transfer) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");

- pbap->msg = dbus_message_ref(message);
- return NULL;
+ path = obc_transfer_get_path(transfer);
+
+ reply = dbus_message_new_method_return(message);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static DBusMessage *pbap_list(DBusConnection *connection,
@@ -910,9 +923,9 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,

name = g_strconcat(pbap->path, ".vcf", NULL);

- err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
+ err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name, NULL,
pbap->filter, pbap->format, 0,
- DEFAULT_OFFSET);
+ DEFAULT_OFFSET, NULL);
g_free(name);
return err;
}
@@ -1025,10 +1038,8 @@ static DBusMessage *pbap_list_filter_fields(DBusConnection *connection,
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 },
+ { "PullAll", "s", "o", pbap_pull_all },
+ { "Pull", "ss", "o", pbap_pull_vcard },
{ "List", "", "a(ss)", pbap_list,
G_DBUS_METHOD_FLAG_ASYNC },
{ "Search", "ss", "a(ss)", pbap_search,
diff --git a/test/pbap-client b/test/pbap-client
index f87f33c..7eb528c 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -1,41 +1,161 @@
#!/usr/bin/python

+import gobject
+
import sys
import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+class Transfer:
+ def __init__(self, callback_func):
+ self.callback_func = callback_func
+ self.path = None
+ self.filename = None
+
+class PbapClient:
+ def __init__(self, session_path):
+ self.pending_transfers = 0
+ self.transfer_dict = dict()
+ self.flush_func = None
+ bus = dbus.SessionBus()
+ self.session = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.Session")
+ self.pbap = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.PhonebookAccess")
+ bus.add_signal_receiver(
+ self.transfer_added,
+ dbus_interface="org.openobex.Session",
+ signal_name="TransferAdded")
+ bus.add_signal_receiver(
+ self.transfer_complete,
+ dbus_interface="org.openobex.Transfer",
+ signal_name="Complete",
+ path_keyword="path")
+ bus.add_signal_receiver(
+ self.transfer_error,
+ dbus_interface="org.openobex.Transfer",
+ signal_name="Error",
+ path_keyword="path")
+
+ def register(self, path, transfer):
+ print "Transfer created: %s" % path
+ transfer.path = path
+ self.transfer_dict[path] = transfer
+
+ def error(self, err):
+ print err
+ mainloop.quit()
+
+ def transfer_added(self, path, properties):
+ req = self.transfer_dict.get(path)
+ if req == None:
+ return
+ req.filename = properties.get("Location")
+
+ def transfer_complete(self, path):
+ req = self.transfer_dict.get(path)
+ if req == None:
+ return
+ self.pending_transfers -= 1
+ print "Transfer %s finished an stored in %s" % (path, req.filename)
+ f = open(req.filename, "r")
+ lines = f.readlines()
+ del self.transfer_dict[path]
+ req.callback_func(lines)
+
+ if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
+ if self.flush_func != None:
+ f = self.flush_func
+ self.flush_func = None
+ f()
+
+ def transfer_error(self, error, path):
+ req = self.transfer_dict.get(path)
+ if req == None:
+ return
+ print "Transfer %s finished with an error: %s" % (path, error)
+ mainloop.quit()
+
+ def pull(self, vcard, func):
+ req = Transfer(func)
+ self.pbap.Pull(vcard, "",
+ reply_handler=lambda p: self.register(p, req),
+ error_handler=self.error)
+ self.pending_transfers += 1
+
+ def pull_all(self, func):
+ req = Transfer(func)
+ self.pbap.PullAll("",
+ reply_handler=lambda p: self.register(p, req),
+ error_handler=self.error)
+ self.pending_transfers += 1
+
+ def flush_transfers(self, func):
+ if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
+ return
+ self.flush_func = func
+
+ def interface(self):
+ return self.pbap
+
+if __name__ == '__main__':
+
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ bus = dbus.SessionBus()
+ mainloop = gobject.MainLoop()
+
+ client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
+ "org.openobex.Client")
+
+ if (len(sys.argv) < 2):
+ print "Usage: %s <device>" % (sys.argv[0])
+ sys.exit(1)
+
+ print "Creating Session"
+ session_path = client.CreateSession("", sys.argv[1], "pbap", dict())
+
+ pbap_client = PbapClient(session_path)
+
+ def process_result(lines, header):
+ print header,
+ for line in lines:
+ print line,
+ print
+
+ def test_paths(paths):
+ if len(paths) == 0:
+ print
+ print "FINISHED"
+ mainloop.quit()
+ return
+
+ path = paths[0]
+
+ print "\n--- Select Phonebook %s ---\n" % (path)
+ pbap_client.interface().Select("int", path)
+
+ print "\n--- GetSize ---\n"
+ ret = pbap_client.interface().GetSize()
+ print "Size = %d\n" % (ret)
+
+ print "\n--- List vCard ---\n"
+ ret = pbap_client.interface().List()
+ for item in ret:
+ print "%s : %s" % (item[0], item[1])
+ pbap_client.interface().SetFormat("vcard30")
+ pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
+ pbap_client.pull(item[0], lambda x: process_result(x, ""))
+
+ pbap_client.interface().SetFormat("vcard30")
+ pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
+ pbap_client.pull_all(lambda x: process_result(x, "\n--- PullAll ---\n"))
+
+ pbap_client.flush_transfers(lambda: test_paths(paths[1:]))
+
+ test_paths(["PB", "ICH", "OCH", "MCH", "CCH"])

-bus = dbus.SessionBus()
-
-client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
- "org.openobex.Client")
-
-print "Creating Session"
-session_path = client.CreateSession("", sys.argv[1], "PBAP", dict())
-pbap = dbus.Interface(bus.get_object("org.openobex.client", session_path),
- "org.openobex.PhonebookAccess")
-session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
- "org.openobex.Session")
-
-paths = ["PB", "ICH", "OCH", "MCH", "CCH"]
-
-for path in paths:
- print "\n--- Select Phonebook %s ---\n" % (path)
- pbap.Select("int", path)
-
- print "\n--- GetSize ---\n"
- ret = pbap.GetSize()
- print "Size = %d\n" % (ret)
-
- print "\n--- List vCard ---\n"
- ret = pbap.List()
- for item in ret:
- print "%s : %s" % (item[0], item[1])
- pbap.SetFormat("vcard30")
- pbap.SetFilter(["VERSION", "FN", "TEL"]);
- ret = pbap.Pull(item[0])
- print "%s" % (ret)
-
- print "\n--- PullAll ---\n"
- pbap.SetFormat("vcard30")
- pbap.SetFilter(["VERSION", "FN", "TEL"]);
- ret = pbap.PullAll()
- print "%s" % (ret)
+ mainloop.run()
--
1.7.6.4


2011-12-08 15:27:49

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 15/21] client: FileTransfer sessions return transports

---
client/ftp.c | 61 ++++++++----------
test/ftp-client | 188 ++++++++++++++++++++++++++-----------------------------
2 files changed, 117 insertions(+), 132 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 6630cc9..15b2b48 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -192,29 +192,6 @@ static const GMarkupParser parser = {
NULL
};

-static void get_file_callback(struct obc_session *session, GError *err,
- const struct obc_transfer *transfer,
- void *user_data)
-{
- struct ftp_data *ftp = user_data;
- DBusMessage *reply;
-
- if (!ftp->msg)
- return;
-
- if (err)
- reply = g_dbus_create_error(ftp->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- else
- reply = dbus_message_new_method_return(ftp->msg);
-
- g_dbus_send_message(conn, reply);
-
- dbus_message_unref(ftp->msg);
- ftp->msg = NULL;
-}
-
static void list_folder_callback(struct obc_session *session,
GError *err,
const struct obc_transfer *transfer,
@@ -325,6 +302,9 @@ static DBusMessage *get_file(DBusConnection *connection,
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
const char *target_file, *source_file;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &target_file,
@@ -334,15 +314,21 @@ static DBusMessage *get_file(DBusConnection *connection,
"org.openobex.Error.InvalidArguments", NULL);

if (obc_session_get(session, NULL, source_file,
- target_file, NULL, 0, get_file_callback,
- ftp, NULL) < 0)
+ target_file, NULL, 0, NULL,
+ NULL, &transfer) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");

- ftp->msg = dbus_message_ref(message);
+ path = obc_transfer_get_path(transfer);

- return NULL;
+ reply = dbus_message_new_method_return(message);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static DBusMessage *put_file(DBusConnection *connection,
@@ -351,6 +337,9 @@ static DBusMessage *put_file(DBusConnection *connection,
struct ftp_data *ftp = user_data;
struct obc_session *session = ftp->session;
gchar *sourcefile, *targetfile;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &sourcefile,
@@ -360,12 +349,20 @@ static DBusMessage *put_file(DBusConnection *connection,
"org.openobex.Error.InvalidArguments",
"Invalid arguments in method call");

- if (obc_session_put(session, targetfile, sourcefile, NULL) < 0)
+ if (obc_session_put(session, targetfile, sourcefile, &transfer) < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"Failed");

- return dbus_message_new_method_return(message);
+ path = obc_transfer_get_path(transfer);
+
+ reply = dbus_message_new_method_return(message);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static DBusMessage *copy_file(DBusConnection *connection,
@@ -503,10 +500,8 @@ static GDBusMethodTable ftp_methods[] = {
G_DBUS_METHOD_FLAG_ASYNC },
{ "ListFolder", "", "aa{sv}", list_folder,
G_DBUS_METHOD_FLAG_ASYNC },
- { "GetFile", "ss", "", get_file,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "PutFile", "ss", "", put_file,
- G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetFile", "ss", "o", get_file },
+ { "PutFile", "ss", "o", put_file },
{ "CopyFile", "ss", "", copy_file,
G_DBUS_METHOD_FLAG_ASYNC },
{ "MoveFile", "ss", "", move_file,
diff --git a/test/ftp-client b/test/ftp-client
index 05f16ad..d48b44e 100755
--- a/test/ftp-client
+++ b/test/ftp-client
@@ -9,42 +9,6 @@ import dbus.mainloop.glib
import os.path
from optparse import OptionParser

-class Agent(dbus.service.Object):
- def __init__(self, conn=None, obj_path=None, verbose=False):
- dbus.service.Object.__init__(self, conn, obj_path)
- self.verbose = verbose
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="o", out_signature="s")
- def Request(self, path):
- return ""
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="ot", out_signature="")
- def Progress(self, path, transferred):
- if self.verbose:
- print "Transfer progress (%d bytes)" % (transferred)
- return
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="o", out_signature="")
- def Complete(self, path):
- if self.verbose:
- print "Transfer finished"
- mainloop.quit()
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="os", out_signature="")
- def Error(self, path, error):
- print "Transfer finished with an error: %s" % (error)
- mainloop.quit()
-
- @dbus.service.method("org.openobex.Agent",
- in_signature="", out_signature="")
- def Release(self):
- mainloop.quit()
-
-
def parse_options():
parser.add_option("-d", "--device", dest="device",
help="Device to connect", metavar="DEVICE")
@@ -64,55 +28,89 @@ def parse_options():
help="Destination FILE", metavar="FILE")
parser.add_option("-r", "--remove", dest="remove_file",
help="Remove FILE", metavar="FILE")
- parser.add_option("-v", "--verbose", action="store_true", dest="verbose")

return parser.parse_args()

-def error(err):
- print err
-
-def void_reply():
- pass
-
-def change_folder(session, new_dir):
- for node in new_dir.split("/"):
- session.ChangeFolder(node)
-
-def list_folder(session):
- for i in session.ListFolder():
- if i["Type"] == "folder":
- print "%s/" % (i["Name"])
- else:
- print "%s" % (i["Name"])
-
-def put_file(session, filename):
- session.PutFile(os.path.abspath(filename),
- os.path.basename(filename),
- reply_handler=void_reply,
- error_handler=error)
-
-def get_file(session, filename):
- session.GetFile(os.path.abspath(filename),
- os.path.basename(filename),
- reply_handler=void_reply,
- error_handler=error)
-
-def remove_file(session, filename):
- session.Delete(filename,
- reply_handler=void_reply,
- error_handler=error)
-
-def move_file(session, filename, destname):
- session.MoveFile(filename,
- destname,
- reply_handler=void_reply,
- error_handler=error)
-
-def copy_file(session, filename, destname):
- session.CopyFile(filename,
- destname,
- reply_handler=void_reply,
- error_handler=error)
+class FtpClient:
+ def __init__(self, session_path):
+ self.transfer_path = None
+ bus = dbus.SessionBus()
+ self.session = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.Session")
+ self.ftp = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.FileTransfer")
+ bus.add_signal_receiver(
+ self.transfer_complete,
+ dbus_interface="org.openobex.Transfer",
+ signal_name="Complete",
+ path_keyword="path")
+ bus.add_signal_receiver(
+ self.transfer_error,
+ dbus_interface="org.openobex.Transfer",
+ signal_name="Error",
+ path_keyword="path")
+
+ def create_transfer_reply(self, path):
+ self.transfer_path = path
+ print "Transfer created: %s" % path
+
+ def error(self, err):
+ print err
+ mainloop.quit()
+
+ def transfer_complete(self, path):
+ if path != self.transfer_path:
+ return
+ print "Transfer finished"
+ mainloop.quit()
+
+ def transfer_error(self, error, path):
+ if path != self.transfer_path:
+ return
+ print "Transfer finished with an error: %s" % (error)
+ mainloop.quit()
+
+ def change_folder(self, new_dir):
+ for node in new_dir.split("/"):
+ self.ftp.ChangeFolder(node)
+
+ def list_folder(self):
+ for i in self.ftp.ListFolder():
+ if i["Type"] == "folder":
+ print "%s/" % (i["Name"])
+ else:
+ print "%s" % (i["Name"])
+
+ def put_file(self, filename):
+ self.ftp.PutFile(os.path.abspath(filename),
+ os.path.basename(filename),
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+ def get_file(self, filename):
+ self.ftp.GetFile(os.path.abspath(filename),
+ os.path.basename(filename),
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+ def remove_file(self, filename):
+ self.ftp.Delete(filename,
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+ def move_file(self, filename, destname):
+ self.ftp.MoveFile(filename,
+ destname,
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+ def copy_file(self, filename, destname):
+ self.ftp.CopyFile(filename,
+ destname,
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)

if __name__ == '__main__':

@@ -129,41 +127,33 @@ if __name__ == '__main__':
bus = dbus.SessionBus()
mainloop = gobject.MainLoop()

- path = "/test/agent"
- agent = Agent(bus, path, options.verbose)
-
client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
"org.openobex.Client")

+ print "Creating Session"
session_path = client.CreateSession("", options.device, "ftp", dict())

- session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
- "org.openobex.Session")
-
- session.AssignAgent(path)
-
- ftp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
- "org.openobex.FileTransfer")
+ ftp_client = FtpClient(session_path)

if options.new_dir:
- change_folder(ftp, options.new_dir)
+ ftp_client.change_folder(options.new_dir)

if options.list_dir:
- list_folder(ftp)
+ ftp_client.list_folder()

if options.get_file:
- get_file(ftp, options.get_file)
+ ftp_client.get_file(options.get_file)

if options.put_file:
- put_file(ftp, options.put_file)
+ ftp_client.put_file(options.put_file)

if options.move_file:
- move_file(ftp, options.move_file, options.dest_file)
+ ftp_client.move_file(options.move_file, options.dest_file)

if options.copy_file:
- copy_file(ftp, options.copy_file, options.dest_file)
+ ftp_client.copy_file(options.copy_file, options.dest_file)

if options.remove_file:
- remove_file(ftp, options.remove_file)
+ ftp_client.remove_file(options.remove_file)

mainloop.run()
--
1.7.6.4


2011-12-08 15:27:54

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 20/21] client: report size in GET operations

Some apps might be interested in the size of an ongoing GET transfer. In
order to expose this value in D-Bus, gobex needs to be extended, so that
such size can be reported using a specific callback for this purpose.
---
client/transfer.c | 36 ++++++++++++++++++++++++++++++++----
gobex/gobex-defs.h | 1 +
gobex/gobex-transfer.c | 28 +++++++++++++++++++++++++++-
gobex/gobex.h | 1 +
4 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/client/transfer.c b/client/transfer.c
index 38c832c..3fa848a 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -29,6 +29,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
@@ -476,12 +477,31 @@ static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
transfer_notify_complete(transfer);
}

+static gboolean get_xfer_size(gsize size, gpointer user_data)
+{
+ struct obc_transfer *transfer = user_data;
+
+ if (transfer->size != 0)
+ return TRUE;
+
+ transfer->size = size;
+
+ obex_dbus_signal_property_changed(transfer->conn,
+ transfer->path,
+ TRANSFER_INTERFACE, "Size",
+ DBUS_TYPE_INT64,
+ &transfer->size);
+
+ return TRUE;
+}
+
static gboolean get_xfer_progress(const void *buf, gsize len,
gpointer user_data)
{
struct obc_transfer *transfer = user_data;
gssize size;
GError *err = NULL;
+ char msg[8];

if (transfer->file_location != NULL) {
struct file_location *location = transfer->file_location;
@@ -517,7 +537,14 @@ static gboolean get_xfer_progress(const void *buf, gsize len,
assert((transfer->transferred <= transfer->size) ||
(transfer->size == 0));

- DBG("GET progress: %lu bytes", transfer->transferred);
+ if (transfer->size == 0)
+ msg[0] = '\0';
+ else {
+ sprintf(msg, " (%d%%)", (int) (100 * transfer->transferred /
+ transfer->size));
+ }
+
+ DBG("GET progress: %lu bytes%s", transfer->transferred, msg);

transfer_notify_progress(transfer);

@@ -594,9 +621,10 @@ static void obc_transfer_start_get(struct obc_transfer *transfer, GObex *obex)
transfer->params->data,
transfer->params->size);

- transfer->xfer = g_obex_get_req_pkt(obex, req, get_xfer_progress,
- xfer_complete, transfer,
- &err);
+ transfer->xfer = g_obex_get_req_pkt(obex, req, get_xfer_size,
+ get_xfer_progress,
+ xfer_complete,
+ transfer, &err);
if (transfer->xfer == 0)
goto fail;

diff --git a/gobex/gobex-defs.h b/gobex/gobex-defs.h
index 9c2ab53..3720f07 100644
--- a/gobex/gobex-defs.h
+++ b/gobex/gobex-defs.h
@@ -43,6 +43,7 @@ typedef enum {
} GObexError;

typedef gssize (*GObexDataProducer) (void *buf, gsize len, gpointer user_data);
+typedef gboolean (*GObexDataSizeFunc) (gsize len, gpointer user_data);
typedef gboolean (*GObexDataConsumer) (const void *buf, gsize len,
gpointer user_data);

diff --git a/gobex/gobex-transfer.c b/gobex/gobex-transfer.c
index f5222cd..b84a020 100644
--- a/gobex/gobex-transfer.c
+++ b/gobex/gobex-transfer.c
@@ -45,6 +45,7 @@ struct transfer {
guint get_id;
guint abort_id;

+ GObexDataSizeFunc data_size_func;
GObexDataProducer data_producer;
GObexDataConsumer data_consumer;
GObexFunc complete_func;
@@ -140,6 +141,30 @@ static gboolean handle_get_body(struct transfer *transfer, GObexPacket *rsp,
const guint8 *buf;
gsize len;

+ if (transfer->data_size_func != NULL) {
+ GObexHeader *hdr;
+
+ hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_LENGTH);
+
+ if (hdr != NULL) {
+ guint32 size;
+ g_obex_header_get_uint32(hdr, &size);
+
+ ret = transfer->data_size_func(size,
+ transfer->user_data);
+
+ transfer->data_size_func = NULL;
+
+ if (ret == FALSE) {
+ g_set_error(err, G_OBEX_ERROR,
+ G_OBEX_ERROR_CANCELLED,
+ "Data size consumer callback failed");
+
+ return FALSE;
+ }
+ }
+ }
+
if (body == NULL)
return TRUE;

@@ -392,7 +417,6 @@ guint g_obex_put_rsp(GObex *obex, GObexPacket *req,
transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
transfer->data_consumer = data_func;

-
va_start(args, first_hdr_id);
transfer_put_req_first(transfer, req, first_hdr_id, args);
va_end(args);
@@ -413,6 +437,7 @@ guint g_obex_put_rsp(GObex *obex, GObexPacket *req,
}

guint g_obex_get_req_pkt(GObex *obex, GObexPacket *req,
+ GObexDataSizeFunc data_size_func,
GObexDataConsumer data_func, GObexFunc complete_func,
gpointer user_data, GError **err)
{
@@ -424,6 +449,7 @@ guint g_obex_get_req_pkt(GObex *obex, GObexPacket *req,
return 0;

transfer = transfer_new(obex, G_OBEX_OP_GET, complete_func, user_data);
+ transfer->data_size_func = data_size_func;
transfer->data_consumer = data_func;

transfer->req_id = g_obex_send_req(obex, req, FIRST_PACKET_TIMEOUT,
diff --git a/gobex/gobex.h b/gobex/gobex.h
index 1b20333..d54b2f3 100644
--- a/gobex/gobex.h
+++ b/gobex/gobex.h
@@ -105,6 +105,7 @@ guint g_obex_get_req(GObex *obex, GObexDataConsumer data_func,
GError **err, guint8 first_hdr_id, ...);

guint g_obex_get_req_pkt(GObex *obex, GObexPacket *req,
+ GObexDataSizeFunc data_size_func,
GObexDataConsumer data_func, GObexFunc complete_func,
gpointer user_data, GError **err);

--
1.7.6.4


2011-12-08 15:27:55

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 21/21] client: update copyright statement

---
client/ftp.c | 1 +
client/manager.c | 1 +
client/opp.c | 1 +
client/pbap.c | 1 +
client/session.c | 1 +
client/session.h | 1 +
client/sync.c | 1 +
client/transfer.c | 1 +
client/transfer.h | 1 +
doc/client-api.txt | 1 +
10 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 15b2b48..5bf7da9 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/manager.c b/client/manager.c
index 219da68..e33cb12 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/opp.c b/client/opp.c
index 5379222..338e69f 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/pbap.c b/client/pbap.c
index da2c22d..bd3d320 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2007-2010 Intel Corporation
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/session.c b/client/session.c
index 98edaae..4fac72e 100644
--- a/client/session.c
+++ b/client/session.c
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/session.h b/client/session.h
index 2078e24..65fe586 100644
--- a/client/session.h
+++ b/client/session.h
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/sync.c b/client/sync.c
index eb65c61..dfd69c1 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2007-2010 Intel Corporation
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/transfer.c b/client/transfer.c
index 3fa848a..a275367 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/client/transfer.h b/client/transfer.h
index afe23bb..4edaef6 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -3,6 +3,7 @@
* OBEX Client
*
* Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+ * Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/doc/client-api.txt b/doc/client-api.txt
index e0dd29d..feabbb9 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -2,6 +2,7 @@ OBEX client API description
***************************

Copyright (C) 2007-2010 Marcel Holtmann <[email protected]>
+Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.


Client hierarchy
--
1.7.6.4


2011-12-08 15:27:51

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 17/21] client: Synchronization sessions return transports

---
client/sync.c | 76 +++++++++++++++++++++++++++------------------------------
1 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/client/sync.c b/client/sync.c
index 25600e6..eb65c61 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -84,40 +84,21 @@ static DBusMessage *sync_setlocation(DBusConnection *connection,
return dbus_message_new_method_return(message);
}

-static void sync_getphonebook_callback(struct obc_session *session,
- GError *err,
- const struct obc_transfer *transfer,
- void *user_data)
-{
- struct sync_data *sync = user_data;
- DBusMessage *reply;
- const void *buf;
-
- if (err) {
- reply = g_dbus_create_error(sync->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- goto done;
- }
-
- reply = dbus_message_new_method_return(sync->msg);
-
- buf = obc_transfer_get_buffer(transfer);
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &buf,
- DBUS_TYPE_INVALID);
-
-done:
- g_dbus_send_message(conn, reply);
- dbus_message_unref(sync->msg);
- sync->msg = NULL;
-}
-
static DBusMessage *sync_getphonebook(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct sync_data *sync = user_data;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;
+ const char *targetfile;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &targetfile,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments",
+ "Invalid arguments in method call");

if (sync->msg)
return g_dbus_create_error(message,
@@ -128,14 +109,19 @@ static DBusMessage *sync_getphonebook(DBusConnection *connection,
sync->phonebook_path = g_strdup("telecom/pb.vcf");

if (obc_session_get(sync->session, "phonebook", sync->phonebook_path,
- NULL, NULL, 0, sync_getphonebook_callback,
- sync, NULL) < 0)
+ targetfile, NULL, 0, NULL, NULL, &transfer) < 0)
return g_dbus_create_error(message,
ERROR_INF ".Failed", "Failed");

- sync->msg = dbus_message_ref(message);
+ path = obc_transfer_get_path(transfer);
+
+ reply = dbus_message_new_method_return(message);

- return NULL;
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static DBusMessage *sync_putphonebook(DBusConnection *connection,
@@ -144,6 +130,9 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
struct sync_data *sync = user_data;
const char *buf;
char *buffer;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &buf,
@@ -158,19 +147,26 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
buffer = g_strdup(buf);

if (obc_session_put_mem(sync->session, sync->phonebook_path,
- buffer, strlen(buffer), g_free, NULL) < 0)
+ buffer, strlen(buffer), g_free,
+ &transfer) < 0)
return g_dbus_create_error(message,
ERROR_INF ".Failed", "Failed");

- return dbus_message_new_method_return(message);
+ path = obc_transfer_get_path(transfer);
+
+ reply = dbus_message_new_method_return(message);
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ return reply;
}

static GDBusMethodTable sync_methods[] = {
{ "SetLocation", "s", "", sync_setlocation },
- { "GetPhonebook", "", "s", sync_getphonebook,
- G_DBUS_METHOD_FLAG_ASYNC },
- { "PutPhonebook", "s", "", sync_putphonebook,
- G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetPhonebook", "s", "o", sync_getphonebook },
+ { "PutPhonebook", "s", "o", sync_putphonebook },
{}
};

--
1.7.6.4


2011-12-08 15:27:52

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 18/21] client-doc: PhonebookAccess sessions return transports

---
doc/client-api.txt | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index b17eee9..e0dd29d 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -198,10 +198,18 @@ Methods void Select(string location, string phonebook)
"mch": missing call history
"cch": combination of ich och mch

- string PullAll()
+ object PullAll(string targetfile)

Return the entire phonebook object from the PSE server
- in plain string with vcard format.
+ in plain string with vcard format, and store it in
+ a local file.
+
+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.

array{string vcard, string name} List()

@@ -209,10 +217,17 @@ Methods void Select(string location, string phonebook)
vcard : name paired string, for example "1.vcf" :
"John".

- string Pull(string vcard)
+ object Pull(string vcard, string targetfile)

Retrieve the vcard in the current phonebook object
- for example : Pull("0.vcf")
+ for example : Pull("0.vcf", "pull-result.vcf")
+
+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.

array{string vcard, string name}
Search(string field, string value)
--
1.7.6.4


2011-12-08 15:27:39

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 05/21] client: replace SendFiles with SendFile

---
client/opp.c | 28 +++++++++++++---------------
test/send-files | 5 +++--
2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/client/opp.c b/client/opp.c
index 5af18b5..bd83c25 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -49,29 +49,27 @@ struct pull_data {

static DBusConnection *conn = NULL;

-static DBusMessage *opp_send_files(DBusConnection *connection,
+static DBusMessage *opp_send_file(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct opp_data *opp = user_data;
- DBusMessageIter iter, array;
+ DBusMessageIter iter;
+ char *filename;
+ char *basename;

dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
- char *filename;
- char *basename;

- dbus_message_iter_get_basic(&array, &filename);
- basename = g_path_get_basename(filename);
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ ERROR_INF ".InvalidArguments", NULL);

- if (obc_session_send(opp->session, filename, basename) < 0) {
- g_free(basename);
- break;
- }
+ dbus_message_iter_get_basic(&iter, &filename);
+ basename = g_path_get_basename(filename);

+ if (obc_session_send(opp->session, filename, basename) < 0) {
g_free(basename);
- dbus_message_iter_next(&array);
+ return g_dbus_create_error(message,
+ ERROR_INF ".Failed", NULL);
}

return dbus_message_new_method_return(message);
@@ -135,7 +133,7 @@ static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
}

static GDBusMethodTable opp_methods[] = {
- { "SendFiles", "as", "", opp_send_files,
+ { "SendFile", "s", "", opp_send_file,
G_DBUS_METHOD_FLAG_ASYNC },
{ "PullBusinessCard", "s", "", opp_pull_business_card,
G_DBUS_METHOD_FLAG_ASYNC },
diff --git a/test/send-files b/test/send-files
index 6d634f5..e84d10f 100755
--- a/test/send-files
+++ b/test/send-files
@@ -18,5 +18,6 @@ session_path = client.CreateSession({"Destination": sys.argv[1],
"Target": "OPP"})
opp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.ObjectPush")
-
-opp.SendFiles(files)
+for f in files:
+ print "Queueing '%s'" % f
+ opp.SendFile(f)
--
1.7.6.4


2011-12-08 15:27:48

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 14/21] client-doc: FileTransfer sessions return transports

---
doc/client-api.txt | 17 +++++++++++------
1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 6c388b1..3736982 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -137,21 +137,26 @@ Methods void ChangeFolder(string folder)
uint64 Accessed : Last access
uint64 Created : Creation date

- void GetFile(string targetfile, string sourcefile)
+ object GetFile(string targetfile, string sourcefile)

Copy the source file (from remote device) to the
target file (on local filesystem).

- A new Transfer object is created to represent this
- transaction.
+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.

- void PutFile(string sourcefile, string targetfile)
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.
+
+ object PutFile(string sourcefile, string targetfile)

Copy the source file (from local filesystem) to the
target file (on remote device).

- A new Transfer object is created to represent this
- transaction.
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.

void CopyFile(string sourcefile, string targetfile)

--
1.7.6.4


2011-12-08 15:27:41

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 07/21] client: GetCapabilities moved to session API

---
client/manager.c | 99 ------------------------------------------------------
client/session.c | 75 +++++++++++++++++++++++++++++++++++-----
2 files changed, 65 insertions(+), 109 deletions(-)

diff --git a/client/manager.c b/client/manager.c
index efc6745..99c495a 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -218,110 +218,11 @@ static DBusMessage *remove_session(DBusConnection *connection,
return dbus_message_new_method_return(message);
}

-static void capabilities_complete_callback(struct obc_session *session,
- GError *err, void *user_data)
-{
- struct obc_transfer *transfer = obc_session_get_transfer(session);
- struct send_data *data = user_data;
- const char *capabilities;
- int size;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- goto done;
- }
-
- capabilities = obc_transfer_get_buffer(transfer, &size);
- if (size == 0)
- capabilities = "";
-
- g_dbus_send_reply(data->connection, data->message,
- DBUS_TYPE_STRING, &capabilities,
- DBUS_TYPE_INVALID);
-
-done:
-
- shutdown_session(session);
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data);
-}
-
-static void capability_obc_session_callback(struct obc_session *session,
- GError *err, void *user_data)
-{
- struct send_data *data = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(data->message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(data->connection, error);
- shutdown_session(session);
- goto done;
- }
-
- obc_session_pull(session, "x-obex/capability", NULL,
- capabilities_complete_callback, data);
-
- return;
-
-done:
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data);
-}
-
-static DBusMessage *get_capabilities(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- DBusMessageIter iter, dict;
- struct obc_session *session;
- struct send_data *data;
- const char *source = NULL, *dest = NULL, *target = NULL;
- uint8_t channel = 0;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &dict);
-
- parse_device_dict(&dict, &source, &dest, &target, &channel);
- if ((dest == NULL) || (target == NULL))
- return g_dbus_create_error(message,
- "org.openobex.Error.InvalidArguments", NULL);
-
- data = g_try_malloc0(sizeof(*data));
- if (data == NULL)
- return g_dbus_create_error(message,
- "org.openobex.Error.NoMemory", NULL);
-
- data->connection = dbus_connection_ref(connection);
- data->message = dbus_message_ref(message);
-
- session = obc_session_create(source, dest, target, channel,
- dbus_message_get_sender(message),
- capability_obc_session_callback, data);
- if (session != NULL) {
- sessions = g_slist_append(sessions, session);
- return NULL;
- }
-
- dbus_message_unref(data->message);
- dbus_connection_unref(data->connection);
- g_free(data);
-
- return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
-}
-
static GDBusMethodTable client_methods[] = {
{ "CreateSession", "a{sv}", "o", create_session,
G_DBUS_METHOD_FLAG_ASYNC },
{ "RemoveSession", "o", "", remove_session,
G_DBUS_METHOD_FLAG_ASYNC },
- { "GetCapabilities", "a{sv}", "s", get_capabilities,
- G_DBUS_METHOD_FLAG_ASYNC },
{ }
};

diff --git a/client/session.c b/client/session.c
index 9f02512..0d56a1c 100644
--- a/client/session.c
+++ b/client/session.c
@@ -91,7 +91,6 @@ struct obc_session {
gchar *path; /* Session path */
DBusConnection *conn;
DBusConnection *conn_system; /* system bus connection */
- DBusMessage *msg;
GObex *obex;
GIOChannel *io;
struct obc_agent *agent;
@@ -100,7 +99,6 @@ struct obc_session {
guint watch;
GSList *pending;
GSList *pending_calls;
- void *priv;
char *adapter;
};

@@ -694,6 +692,7 @@ static void adapter_reply(DBusPendingCall *call, void *user_data)
struct callback_data *callback = user_data;
struct obc_session *session = callback->session;
struct pending_req *req = find_session_request(session, call);
+ GError *gerr = NULL;

reply = dbus_pending_call_steal_reply(call);

@@ -702,19 +701,26 @@ static void adapter_reply(DBusPendingCall *call, void *user_data)

dbus_error_init(&err);
if (dbus_set_error_from_message(&err, reply)) {
- error("manager replied with an error: %s, %s",
- err.name, err.message);
+ gerr = g_error_new(OBEX_IO_ERROR, -EIO,
+ "adapter replied with an error: %s, %s",
+ err.name, err.message);
+ error(gerr->message);
dbus_error_free(&err);
-
goto failed;
}

- if (session_connect(session, callback) < 0)
+ if (session_connect(session, callback) < 0) {
+ gerr = g_error_new(OBEX_IO_ERROR, -EIO,
+ "session connect error");
goto failed;
+ }

goto proceed;

failed:
+ callback->func(session, gerr, callback->data);
+ g_clear_error(&gerr);
+
obc_session_unref(session);
g_free(callback);

@@ -730,6 +736,7 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
struct callback_data *callback = user_data;
struct obc_session *session = callback->session;
struct pending_req *req = find_session_request(session, call);
+ GError *gerr = NULL;

reply = dbus_pending_call_steal_reply(call);

@@ -738,10 +745,11 @@ static void manager_reply(DBusPendingCall *call, void *user_data)

dbus_error_init(&err);
if (dbus_set_error_from_message(&err, reply)) {
- error("manager replied with an error: %s, %s",
- err.name, err.message);
+ gerr = g_error_new(OBEX_IO_ERROR, -EIO,
+ "manager replied with an error: %s, %s",
+ err.name, err.message);
+ error(gerr->message);
dbus_error_free(&err);
-
goto failed;
}

@@ -756,8 +764,11 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
BT_ADAPTER_IFACE, "RequestSession",
adapter_reply, callback,
DBUS_TYPE_INVALID);
- if (!req)
+ if (!req) {
+ gerr = g_error_new(OBEX_IO_ERROR, -EIO,
+ "RequestSession failed");
goto failed;
+ }

session->pending_calls = g_slist_prepend(session->pending_calls,
req);
@@ -767,6 +778,9 @@ static void manager_reply(DBusPendingCall *call, void *user_data)
goto proceed;

failed:
+ callback->func(session, gerr, callback->data);
+ g_clear_error(&gerr);
+
obc_session_unref(session);
g_free(callback);

@@ -1013,10 +1027,51 @@ static DBusMessage *session_get_properties(DBusConnection *connection,
return reply;
}

+static void capabilities_complete_callback(struct obc_session *session,
+ GError *err, void *user_data)
+{
+ struct obc_transfer *transfer = obc_session_get_transfer(session);
+ DBusMessage *message = user_data;
+ const char *capabilities;
+ int size;
+
+ if (err != NULL) {
+ DBusMessage *error = g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "%s", err->message);
+ g_dbus_send_message(session->conn, error);
+ goto done;
+ }
+
+ capabilities = obc_transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ capabilities = "";
+
+ g_dbus_send_reply(session->conn, message,
+ DBUS_TYPE_STRING, &capabilities,
+ DBUS_TYPE_INVALID);
+
+done:
+ dbus_message_unref(message);
+}
+
+static DBusMessage *get_capabilities(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct obc_session *session = user_data;
+
+ obc_session_pull(session, "x-obex/capability", NULL,
+ capabilities_complete_callback,
+ dbus_message_ref(message));
+
+ return NULL;
+}
+
static GDBusMethodTable session_methods[] = {
{ "GetProperties", "", "a{sv}", session_get_properties },
{ "AssignAgent", "o", "", assign_agent },
{ "ReleaseAgent", "o", "", release_agent },
+ { "GetCapabilities", "", "s", get_capabilities },
{ }
};

--
1.7.6.4


2011-12-08 15:27:35

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 01/21] client-doc: minor formatting changes

---
doc/client-api.txt | 78 ++++++++++++++++++++++++++++-----------------------
1 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3e61cf7..ceb3c35 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -22,7 +22,8 @@ Methods void SendFiles(dict device, array{string} files, object agent)
Request the business card from a remote device and
store it in the local file.

- void ExchangeBusinessCards(dict device, string clientfile, string file)
+ void ExchangeBusinessCards(dict device, string clientfile,
+ string file)

Push the client's business card to the remote device
and then retrieve the remote business card and store
@@ -49,7 +50,6 @@ Properties string Target

byte Channel

-
Session hierarchy
=================

@@ -70,12 +70,11 @@ Methods dict GetProperties()

Release a previously assigned OBEX agent.

-Properties string Source [read-only]
-
- string Destination [read-only]
+Properties string Source [readonly]

- byte Channel [read-only]
+ string Destination [readonly]

+ byte Channel [readonly]

File Transfer hierarchy
=======================
@@ -101,11 +100,13 @@ Methods void ChangeFolder(string folder)

string Name : Object name in UTF-8 format
string Type : Either "folder" or "file"
- uint64 Size : Object size or number of items in folder
- string Permission : Group, owner and other permission
- guint64 Modified : Last change
- guint64 Accessed : Last access
- guint64 Created : Creation date
+ uint64 Size : Object size or number of items in
+ folder
+ string Permission : Group, owner and other
+ permission
+ uint64 Modified : Last change
+ uint64 Accessed : Last access
+ uint64 Created : Creation date

void GetFile(string targetfile, string sourcefile)

@@ -137,7 +138,6 @@ Methods void ChangeFolder(string folder)

Deletes the specified file/folder.

-
Phonebook Access hierarchy
=======================

@@ -150,7 +150,8 @@ Methods void Select(string location, string phonebook)
Select the phonebook object for other operations. Should
be call before all the other operations.

- location : Where the phonebook is stored, possible inputs :
+ location : Where the phonebook is stored, possible
+ inputs :
"INT" ( "INTERNAL" which is default )
"SIM" ( "SIM1" )
"SIM2"
@@ -171,7 +172,8 @@ Methods void Select(string location, string phonebook)
array{string vcard, string name} List()

Return an array of vcard-listing data which contains the
- vcard : name paired string, for example "1.vcf" : "John".
+ vcard : name paired string, for example "1.vcf" :
+ "John".

string Pull(string vcard)

@@ -190,36 +192,40 @@ Methods void Select(string location, string phonebook)

uint16 GetSize()

- Return the number of the non-null entries in the selected
- phonebook object.
+ Return the number of the non-null entries in the
+ selected phonebook object.

void SetFormat(string format)

- Indicate the format of the vcard that should be return by
- related methods.
+ Indicate the format of the vcard that should be return
+ by related methods.

format : { "vcard21" (default) | "vcard30" }

void SetOrder(string order)

- Indicate the sorting method of the vcard-listing data returned
- by List and Search methods.
+ Indicate the sorting method of the vcard-listing data
+ returned by List and Search methods.

- order : { "indexed" (default) | "alphanumeric" | "phonetic" }
+ order : { "indexed" (default) | "alphanumeric" |
+ "phonetic" }

void SetFilter(array{string})

- Indicate fields that should be contained in vcards return by
- related methods.
+ Indicate fields that should be contained in vcards
+ return by related methods.

- Give an empty array will clear the filter and return all fields
- available in vcards. And this is the default behavior.
+ Give an empty array will clear the filter and return
+ all fields available in vcards. And this is the default
+ behavior.

- Possible filter fields : "VERSION", "FN", ..., "ALL", "bit[0-63]"
+ Possible filter fields : "VERSION", "FN", ..., "ALL",
+ "bit[0-63]"

array{string} ListFilterFields()

- Return All Available fields that can be used in SefFilter method.
+ Return All Available fields that can be used in
+ SefFilter method.

array{string} GetFilter()

@@ -234,10 +240,12 @@ Object path [variable prefix]/{session0,session1,...}

Methods void SetLocation(string location)

- Set the phonebook object store location for other operations. Should
- be called before all the other operations.
+ Set the phonebook object store location for other
+ operations. Should be called before all the other
+ operations.

- location: Where the phonebook is stored, possible values:
+ location: Where the phonebook is stored, possible
+ values:
"INT" ( "INTERNAL" which is default )
"SIM1"
"SIM2"
@@ -245,7 +253,8 @@ Methods void SetLocation(string location)

string GetPhonebook()

- Retrieve an entire Phonebook Object store from remote device
+ Retrieve an entire Phonebook Object store from remote
+ device

void PutPhonebook(string obj)

@@ -267,20 +276,19 @@ Methods dict GetProperties()

Cancels this transfer.

-Properties string Name [read-only]
+Properties string Name [readonly]

Name of the transferred object.

- uint64 Size [read-only]
+ uint64 Size [readonly]

Size of the transferred object. If the size is
unknown, then this property will not be present.

- string Filename [read-only]
+ string Filename [readonly]

Complete name of the file being received or sent.

-
Agent hierarchy
===============

--
1.7.6.4


2011-12-08 15:27:46

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 12/21] client-doc: ObjectPush sessions return transports

---
doc/client-api.txt | 28 +++++++++++++++++++++++++---
1 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 0c30312..6c388b1 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -67,22 +67,44 @@ Service org.openobex.client
Interface org.openobex.ObjectPush
Object path [variable prefix]/{session0,session1,...}

-Methods void SendFile(string file, string destination)
+Methods object SendFile(string file, string destination)

Send one local file to the remote device for a given
destination.

- void PullBusinessCard(string targetfile)
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.
+
+ object PullBusinessCard(string targetfile)

Request the business card from a remote device and
store it in the local file.

- void ExchangeBusinessCards(string clientfile, string targetfile)
+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.
+
+ This object will represent the whole list of files in a
+ single transfer.
+
+ object ExchangeBusinessCards(string clientfile,
+ string targetfile)

Push the client's business card to the remote device
and then retrieve the remote business card and store
it in a local file.

+ If an empty target file is given, a name will be
+ automatically calculated for the temporary file.
+
+ The returned path represents the newly created transfer,
+ which should be used to find out if the content has been
+ successfully transferred or if the operation fails.
+
File Transfer hierarchy
=======================

--
1.7.6.4


2011-12-08 15:27:36

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 02/21] client-doc: wrap OPP into specific session type

This modification makes the OPP API more consistent with the rest of the
supported target types, and also it allows to perform several operations
on the same session.
---
doc/client-api.txt | 43 ++++++++++++++++++++++++-------------------
1 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index ceb3c35..65f2c0a 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -11,25 +11,7 @@ Service org.openobex.client
Interface org.openobex.Client
Object path /

-Methods void SendFiles(dict device, array{string} files, object agent)
-
- Send one or multiple local files to the specified
- device. The device is configured via properties. At
- least the Destination property should be specified.
-
- void PullBusinessCard(dict device, string file)
-
- Request the business card from a remote device and
- store it in the local file.
-
- void ExchangeBusinessCards(dict device, string clientfile,
- string file)
-
- Push the client's business card to the remote device
- and then retrieve the remote business card and store
- it in a local file.
-
- object CreateSession(dict device)
+Methods object CreateSession(dict device)

Create a new OBEX session. The device is configured
via properties like in SendFiles.
@@ -76,6 +58,29 @@ Properties string Source [readonly]

byte Channel [readonly]

+Object Push hierarchy
+=====================
+
+Service org.openobex.client
+Interface org.openobex.ObjectPush
+Object path [variable prefix]/{session0,session1,...}
+
+Methods void SendFiles(array{string} files, string destination)
+
+ Send one or multiple local files to the remote device,
+ and the given destination.
+
+ void PullBusinessCard(string targetfile)
+
+ Request the business card from a remote device and
+ store it in the local file.
+
+ void ExchangeBusinessCards(string clientfile, string targetfile)
+
+ Push the client's business card to the remote device
+ and then retrieve the remote business card and store
+ it in a local file.
+
File Transfer hierarchy
=======================

--
1.7.6.4


2011-12-08 15:27:38

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v2 04/21] client-doc: replace SendFiles with SendFile

Now that OPP sessions exist, sending multiple files can be achieved with
consecutive calls to SendFile. Note that within a session the pending
operations will be queued and sequentially executed.
---
doc/client-api.txt | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 65f2c0a..43521ff 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -65,10 +65,10 @@ Service org.openobex.client
Interface org.openobex.ObjectPush
Object path [variable prefix]/{session0,session1,...}

-Methods void SendFiles(array{string} files, string destination)
+Methods void SendFile(string file, string destination)

- Send one or multiple local files to the remote device,
- and the given destination.
+ Send one local file to the remote device for a given
+ destination.

void PullBusinessCard(string targetfile)

--
1.7.6.4