2011-12-13 16:44:03

by Mikel Astiz

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

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

This second version includes the corrections proposed by Luiz, mainly:

1. Async flag in get_capabilities (was also included previously but in a wrong patch).
2. CreateSession: type (target) and source address left inside the dictionary.
3. In session.h, transfer returned as return-value and errors as parameter.
4. opp_pull_business_card directly stores the result in a file.
5. obc_session_get now takes void* instead of guint8*.
6. The transfer size request for GET operations (RFC v2 20/21) has been dropped, to be discussed later.

Other minor fixes have also been included:

1. Better error reporting (still to be improved).
2. OPP test scripts merged into opp-client.
3. Synchronization.PutPhonebook changes so it takes a filename, instead of phonebook content.

Mikel Astiz (20):
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: move GetCapabilities to session API
client: move GetCapabilities 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 transfers
client: ObjectPush sessions return transfers
client-doc: FileTransfer sessions return transfers
client: FileTransfer sessions return transfers
client-doc: Synchronization sessions return transfers
client: Synchronization sessions return transfers
client-doc: PhonebookAccess sessions return transfers
client: PhonebookAccess sessions return transfers
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 | 203 ++++--
client/manager.c | 386 +-----------
client/opp.c | 169 +++++-
client/pbap.c | 216 ++++---
client/session.c | 1432 ++++++++++++++++++++----------------------
client/session.h | 82 ++--
client/sync.c | 89 ++--
client/transfer.c | 895 +++++++++++++++------------
client/transfer.h | 74 ++-
client/transferqueue.c | 238 +++++++
client/transferqueue.h | 47 ++
doc/client-api.txt | 274 +++++----
test/exchange-business-cards | 9 +-
test/ftp-client | 191 +++---
test/get-capabilities | 15 +-
test/list-folders | 2 +-
test/opp-client | 100 +++
test/pbap-client | 193 +++++--
test/pull-business-card | 34 -
test/send-files | 82 ---
25 files changed, 2931 insertions(+), 2419 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
create mode 100755 test/opp-client
delete mode 100755 test/pull-business-card
delete mode 100755 test/send-files

--
1.7.6.4



2011-12-13 16:44:23

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 20/20] 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 214cebd..eae5406 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 5448719..11e072b 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 5000281..18b2f9f 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 2d10f0d..3bec60b 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 1ed7cfb..5adf03f 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 5e4f83d..2b70a3d 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 b0f828b..93daad7 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 a63e10b..455227e 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 e450c58..3d3895e 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 b887d16..7e9e91a 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-13 16:44:22

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 19/20] client: PhonebookAccess sessions return transfers

---
client/pbap.c | 128 ++++++++++++++++++++----------------
test/pbap-client | 193 ++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 229 insertions(+), 92 deletions(-)

diff --git a/client/pbap.c b/client/pbap.c
index 6e5d2b7..2d10f0d 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,13 +488,17 @@ 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 **result_transfer)
{
struct pullphonebook_apparam apparam;
session_transfer_callback_t func;
gboolean dbus_expose;
+ struct obc_transfer *transfer;
int err;

if (pbap->msg)
@@ -550,7 +521,7 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,

switch (type) {
case PULLPHONEBOOK:
- func = pull_phonebook_callback;
+ func = NULL;
dbus_expose = TRUE;
break;
case GETPHONEBOOKSIZE:
@@ -562,14 +533,26 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
return NULL;
}

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

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

return NULL;
}
@@ -801,18 +784,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,
@@ -820,7 +825,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;
int err;

if (!pbap->path)
@@ -830,6 +838,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);
@@ -846,15 +855,24 @@ 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,
- (guint8 *) &apparam, sizeof(apparam),
- pull_phonebook_callback, pbap, TRUE, &err) == NULL)
+ transfer = obc_session_get(pbap->session, "x-bt/vcard", name,
+ target_file, &apparam, sizeof(apparam),
+ NULL, NULL, TRUE, &err);
+
+ if (err < 0)
return g_dbus_create_error(message,
"org.openobex.Error.Failed",
"%s", strerror(err));

- 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,
@@ -917,9 +935,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;
}
@@ -1032,10 +1050,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 ecca14f..c574580 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -1,41 +1,162 @@
#!/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], { "Target": "PBAP" })
+
+ pbap_client = PbapClient(session_path)
+
+ def process_result(lines, header):
+ if header != None:
+ 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, None))
+
+ 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], { "Target": "PBAP" })
-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-13 16:44:21

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 18/20] client-doc: PhonebookAccess sessions return transfers

---
client/sync.c | 12 ++++--------
doc/client-api.txt | 23 +++++++++++++++++++----
2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/client/sync.c b/client/sync.c
index 83f37bf..b0f828b 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -132,15 +132,14 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct sync_data *sync = user_data;
- const char *buf;
- char *buffer;
+ const char *sourcefile;
DBusMessage *reply;
struct obc_transfer *transfer;
const char *path;
int err;

if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &buf,
+ DBUS_TYPE_STRING, &sourcefile,
DBUS_TYPE_INVALID) == FALSE)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);
@@ -149,11 +148,8 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
if (!sync->phonebook_path)
sync->phonebook_path = g_strdup("telecom/pb.vcf");

- buffer = g_strdup(buf);
-
- transfer = obc_session_put_mem(sync->session, sync->phonebook_path,
- buffer, strlen(buffer), g_free, TRUE,
- &err);
+ transfer = obc_session_put(sync->session, sync->phonebook_path,
+ sourcefile, TRUE, &err);

if (err < 0)
return g_dbus_create_error(message,
diff --git a/doc/client-api.txt b/doc/client-api.txt
index 5030909..b887d16 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -202,10 +202,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()

@@ -213,10 +221,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-13 16:44:20

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 17/20] client: Synchronization sessions return transfers

Additionally the parameter in PutPhonebook has been changed such that
instead of taking the content of the phonebook, the name of a file is
passed. This should reduce the D-Bus traffic significantly.
---
client/sync.c | 84 ++++++++++++++++++++++++++--------------------------
doc/client-api.txt | 2 +-
2 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/client/sync.c b/client/sync.c
index 4c8d19a..83f37bf 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -84,42 +84,23 @@ 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;
int err;

+ 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,
ERROR_INF ".InProgress", "Transfer in progress");
@@ -128,15 +109,23 @@ static DBusMessage *sync_getphonebook(DBusConnection *connection,
if (!sync->phonebook_path)
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, TRUE, &err) == NULL)
+ transfer = obc_session_get(sync->session, "phonebook",
+ sync->phonebook_path,
+ targetfile, NULL, 0, NULL, NULL, TRUE, &err);
+
+ if (err < 0)
return g_dbus_create_error(message,
ERROR_INF ".Failed", "%s", strerror(err));

- 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,
@@ -145,6 +134,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;
int err;

if (dbus_message_get_args(message, NULL,
@@ -159,21 +151,29 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,

buffer = g_strdup(buf);

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

- 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 },
{}
};

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 92e4e42..5030909 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -301,7 +301,7 @@ Methods void SetLocation(string location)
which should be used to find out if the content has been
successfully transferred or if the operation fails.

- object PutPhonebook(string obj)
+ object PutPhonebook(string sourcefile)

Send an entire Phonebook Object store to remote device.

--
1.7.6.4


2011-12-13 16:44:19

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 16/20] client-doc: Synchronization sessions return transfers

---
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 2e8c37a..92e4e42 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -289,14 +289,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.

Message Access hierarchy
=========================
--
1.7.6.4


2011-12-13 16:44:18

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 15/20] client: FileTransfer sessions return transfers

---
client/ftp.c | 68 ++++++++++----------
test/ftp-client | 188 ++++++++++++++++++++++++++-----------------------------
2 files changed, 122 insertions(+), 134 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 66cb34d..214cebd 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,
@@ -326,6 +303,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;
int err;

if (dbus_message_get_args(message, NULL,
@@ -335,16 +315,24 @@ static DBusMessage *get_file(DBusConnection *connection,
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);

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

- 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,
@@ -353,6 +341,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;
int err;

if (dbus_message_get_args(message, NULL,
@@ -363,13 +354,22 @@ static DBusMessage *put_file(DBusConnection *connection,
"org.openobex.Error.InvalidArguments",
"Invalid arguments in method call");

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

- 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,
@@ -507,10 +507,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 825f591..c2621c4 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, { "Target": "ftp" })

- 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-13 16:44:17

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 14/20] client-doc: FileTransfer sessions return transfers

---
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 00f56e1..2e8c37a 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -141,21 +141,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-13 16:44:16

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 13/20] client: ObjectPush sessions return transfers

---
client/opp.c | 74 ++++++++++++++---------------------
test/opp-client | 100 +++++++++++++++++++++++++++++++++++++++++++++++
test/pull-business-card | 40 -------------------
test/send-files | 22 ----------
4 files changed, 129 insertions(+), 107 deletions(-)
create mode 100755 test/opp-client
delete mode 100755 test/pull-business-card
delete mode 100755 test/send-files

diff --git a/client/opp.c b/client/opp.c
index a8251f9..5000281 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -31,6 +31,7 @@
#include "log.h"

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

@@ -42,11 +43,6 @@ 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 +52,9 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
DBusMessageIter iter;
char *filename;
char *basename;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
+ const char *path;
int err;

dbus_message_iter_init(message, &iter);
@@ -67,7 +66,8 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
dbus_message_iter_get_basic(&iter, &filename);
basename = g_path_get_basename(filename);

- obc_session_put(opp->session, basename, filename, TRUE, &err);
+ transfer = obc_session_put(opp->session, basename, filename, TRUE,
+ &err);

g_free(basename);

@@ -76,29 +76,15 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
ERROR_INF ".Failed",
"%s", strerror(err));

- 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,
@@ -106,9 +92,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;
int err;

dbus_message_iter_init(message, &iter);
@@ -119,17 +107,8 @@ 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");
-
- data->connection = connection;
- data->message = dbus_message_ref(message);
-
- obc_session_get(opp->session, "text/x-vcard", filename, NULL,
- NULL, 0,
- pull_complete_callback, data,
+ transfer = obc_session_get(opp->session, "text/x-vcard", NULL, filename,
+ NULL, 0, NULL, NULL,
TRUE, &err);

if (err < 0)
@@ -137,7 +116,15 @@ static DBusMessage *opp_pull_business_card(DBusConnection *connection,
ERROR_INF ".Failed",
"%s", strerror(err));

- 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 *opp_exchange_business_cards(DBusConnection *connection,
@@ -147,12 +134,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 },
{ }
};

diff --git a/test/opp-client b/test/opp-client
new file mode 100755
index 0000000..894b824
--- /dev/null
+++ b/test/opp-client
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+
+import sys
+import dbus
+import gobject
+import dbus.mainloop.glib
+import os.path
+from optparse import OptionParser
+
+def parse_options():
+ parser.add_option("-d", "--device", dest="device",
+ help="Device to connect", metavar="DEVICE")
+ parser.add_option("-g", "--pull", dest="pull_to_file",
+ help="Pull vcard and store in FILE", metavar="FILE")
+ parser.add_option("-p", "--send", dest="send_file",
+ help="Send FILE", metavar="FILE")
+
+ return parser.parse_args()
+
+class OppClient:
+ 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.opp = dbus.Interface(bus.get_object("org.openobex.client",
+ session_path),
+ "org.openobex.ObjectPush")
+ 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 pull_business_card(self, filename):
+ self.opp.PullBusinessCard(os.path.abspath(filename),
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+ def send_file(self, filename):
+ self.opp.SendFile(os.path.abspath(filename),
+ reply_handler=self.create_transfer_reply,
+ error_handler=self.error)
+
+if __name__ == '__main__':
+
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ parser = OptionParser()
+
+ (options, args) = parse_options()
+
+ if not options.device:
+ parser.print_help()
+ sys.exit(0)
+
+ bus = dbus.SessionBus()
+ mainloop = gobject.MainLoop()
+
+ client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
+ "org.openobex.Client")
+
+ print "Creating Session"
+ session_path = client.CreateSession(options.device, { "Target": "OPP" })
+
+ opp_client = OppClient(session_path)
+
+ if options.pull_to_file:
+ opp_client.pull_business_card(options.pull_to_file)
+
+ if options.send_file:
+ opp_client.send_file(options.send_file)
+
+ mainloop.run()
diff --git a/test/pull-business-card b/test/pull-business-card
deleted file mode 100755
index 6f9267b..0000000
--- a/test/pull-business-card
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import dbus
-import gobject
-import dbus.mainloop.glib
-
-def success():
- mainloop.quit()
- return
-
-def failure(error):
- print error
- mainloop.quit()
- return
-
-
-if __name__ == '__main__':
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-
- mainloop = gobject.MainLoop()
-
- 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>" % (sys.argv[0])
- sys.exit(1)
-
- print "Creating Session"
- session_path = client.CreateSession(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
deleted file mode 100755
index f1e8aed..0000000
--- a/test/send-files
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/python
-
-import os
-import sys
-import dbus
-
-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)
-
-files = [os.path.realpath(f) for f in sys.argv[2:]]
-
-print "Creating Session"
-session_path = client.CreateSession(sys.argv[1], { "Target": "OPP" })
-opp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
- "org.openobex.ObjectPush")
-
-opp.SendFiles(files)
--
1.7.6.4


2011-12-13 16:44:15

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 12/20] client-doc: ObjectPush sessions return transfers

---
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 50b0b6f..00f56e1 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -72,21 +72,43 @@ Service org.openobex.client
Interface org.openobex.ObjectPush
Object path [variable prefix]/{session0,session1,...}

-Methods void SendFile(string sourcefile)
+Methods object SendFile(string sourcefile)

Send one local file to the remote device.

- 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-13 16:44:13

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 10/20] 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 | 72 ++++++++++++++++++---------------------------------
1 files changed, 26 insertions(+), 46 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3b87cb5..50b0b6f 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -45,25 +45,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
=====================

@@ -299,54 +300,33 @@ 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)
-
- Accept or reject a new transfer (client and server)
- and provide the filename for it.
+ Size of the transferred object(s). If the size is
+ unknown, then this property will not be present.

- 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.
+ uint64 Progress [readonly, optional]

- Possible errors: org.openobex.Error.Rejected
- org.openobex.Error.Canceled
+ 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.

- void Progress(object transfer, uint64 transferred)
+Signals PropertyChanged(string name, variant value)

- Progress within the transfer has been made. The
- number of transferred bytes is given as second
- argument for convenience.
+ This signal indicates a changed value of the given
+ property.

- 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-13 16:44:12

by Mikel Astiz

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

---
client/manager.c | 20 ++++++++++++++------
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, 20 insertions(+), 16 deletions(-)

diff --git a/client/manager.c b/client/manager.c
index 50b8bcb..5d229b7 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -103,8 +103,7 @@ done:
}

static int parse_device_dict(DBusMessageIter *iter,
- const char **source, const char **dest, const char **target,
- uint8_t *channel)
+ const char **source, const char **target, uint8_t *channel)
{
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
DBusMessageIter entry, value;
@@ -120,8 +119,6 @@ static int parse_device_dict(DBusMessageIter *iter,
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;
@@ -161,9 +158,20 @@ 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, &dest);
+ 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);
+ parse_device_dict(&dict, &source, &target, &channel);
if (dest == NULL || target == NULL)
return g_dbus_create_error(message,
"org.openobex.Error.InvalidArguments", NULL);
@@ -220,7 +228,7 @@ static DBusMessage *remove_session(DBusConnection *connection,
}

static GDBusMethodTable client_methods[] = {
- { "CreateSession", "a{sv}", "o", create_session,
+ { "CreateSession", "sa{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..4abe426 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], { "Target": "OPP" })
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..825f591 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, { "Target": "ftp" })

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..7239d6d 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], { "Target": "ftp" })

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..ecca14f 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], { "Target": "PBAP" })
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..6f9267b 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], { "Target": "OPP" })
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 504a066..f1e8aed 100755
--- a/test/send-files
+++ b/test/send-files
@@ -15,8 +15,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], { "Target": "OPP" })
opp = dbus.Interface(bus.get_object("org.openobex.client", session_path),
"org.openobex.ObjectPush")

--
1.7.6.4


2011-12-13 16:44:11

by Mikel Astiz

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

Required arguments are passed 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 | 24 +++++++++++++++---------
1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 7a47d78..3b87cb5 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -11,22 +11,28 @@ Service org.openobex.client
Interface org.openobex.Client
Object path /

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

- Create a new OBEX session. The device is configured
- via properties like in SendFiles.
+ Create a new OBEX session for the given remote address.

- void RemoveSession(object session)
+ The last parameter is a dictionary to hold optional or
+ type-specific parameters. Typical parameters that can
+ be set in this dictionary include the following:

- Unregister session and abort pending transfers.
+ string "Target" : type of session to be created
+ string "Source" : local address to be used
+ byte "Channel"

-Properties string Target
+ The currently supported targets are the following:

- string Source
+ "OPP"
+ "FTP"
+ "SYNC"
+ "PBAP"

- string Destination
+ void RemoveSession(object session)

- byte Channel
+ Unregister session and abort pending transfers.

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


2011-12-13 16:44:10

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 07/20] client: move GetCapabilities to session API

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

diff --git a/client/manager.c b/client/manager.c
index 7c9bbb3..50b8bcb 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -219,110 +219,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 3bd9dc4..19bf759 100644
--- a/client/session.c
+++ b/client/session.c
@@ -1027,10 +1027,59 @@ 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;
+ int err;
+
+ err = obc_session_pull(session, "x-obex/capability", NULL,
+ capabilities_complete_callback, message);
+
+ if (err < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "%s", strerror(err));
+
+ 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,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ }
};

--
1.7.6.4


2011-12-13 16:44:09

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 06/20] client-doc: move GetCapabilities 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 f5d31a0..7a47d78 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-13 16:44:08

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 05/20] client: replace SendFiles with SendFile

---
client/opp.c | 28 +++++++++++++---------------
1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/client/opp.c b/client/opp.c
index 3b24f85..396be1b 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -48,29 +48,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);
@@ -134,7 +132,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 },
--
1.7.6.4


2011-12-13 16:44:06

by Mikel Astiz

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

---
client/manager.c | 249 ++----------------------------------------
client/opp.c | 171 ++++++++++++++++++++++++++++-
client/session.c | 34 ++++--
test/exchange-business-cards | 10 ++-
test/get-capabilities | 15 +--
test/pull-business-card | 9 ++-
test/send-files | 85 ++------------
7 files changed, 239 insertions(+), 334 deletions(-)

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

static GSList *sessions = NULL;
@@ -82,7 +78,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,
@@ -93,44 +89,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);
}

@@ -169,192 +137,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;
@@ -393,10 +175,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;
@@ -404,7 +186,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);
@@ -467,7 +248,6 @@ done:
shutdown_session(session);
dbus_message_unref(data->message);
dbus_connection_unref(data->connection);
- g_free(data->sender);
g_free(data);
}

@@ -493,7 +273,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);
}

@@ -510,7 +289,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);

@@ -521,12 +300,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);
@@ -535,19 +311,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..3b24f85 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,189 @@
#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/client/session.c b/client/session.c
index 9f02512..3bd9dc4 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);

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..504a066 100755
--- a/test/send-files
+++ b/test/send-files
@@ -1,82 +1,23 @@
#!/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-13 16:44:07

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 04/20] 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 | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

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

-Methods void SendFiles(array{string} files)
+Methods void SendFile(string sourcefile)

- Send one or multiple local files to the remote device.
+ Send one local file to the remote device.

void PullBusinessCard(string targetfile)

--
1.7.6.4


2011-12-13 16:44:05

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 02/20] 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 | 42 +++++++++++++++++++++++-------------------
1 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index a3c9ab7..9936b1e 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,28 @@ 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)
+
+ Send one or multiple local files to the remote device.
+
+ 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-13 16:44:04

by Mikel Astiz

[permalink] [raw]
Subject: [RFC obexd v3 01/20] 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 ee8951f..a3c9ab7 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)

@@ -276,20 +285,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