2012-06-01 10:51:09

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 00/14] client: Return transfer object in D-Bus API

From: Mikel Astiz <[email protected]>

This patch series proposes changes in the D-Bus API so that all transfer-initiating methods will return the transfer path. This has several benefits including the possibility to cancel the transfer.

Along with the transfer path, the properties corresponding to this transfer will also be returned, for both performance reasons (avoid a call to GetProperties) and also race conditions (transfer might have been destroyed by the time the client calls to GetProperties).

In addition, temporary files can now easily be used by the clients, by passing empty strings in the D-Bus API. The actual name of the created temporary file will be included in the transfer properties.

Mikel Astiz (14):
client-doc: ObjectPush sessions return transfers
client: Support empty filename in obc_transfer_get
client: Expose D-Bus data in internal transfer API
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-test: ftp-client uses new API
client-test: pbap-client uses new API
client-test: Add opp-client
client: Update copyright statement

client/ftp.c | 46 ++++--------
client/opp.c | 71 +++---------------
client/pbap.c | 161 +++++++++++++++++++----------------------
client/session.c | 1 +
client/session.h | 1 +
client/sync.c | 92 ++++++++---------------
client/transfer.c | 91 +++++++++++++++++++----
client/transfer.h | 4 +
doc/client-api.txt | 114 ++++++++++++++++++++++++-----
test/ftp-client | 159 ++++++++++++++++++++++++----------------
test/opp-client | 101 +++++++++++++++++++++++++
test/pbap-client | 187 ++++++++++++++++++++++++++++++++++++++---------
test/pull-business-card | 40 ----------
test/send-files | 23 ------
14 files changed, 660 insertions(+), 431 deletions(-)
create mode 100755 test/opp-client
delete mode 100755 test/pull-business-card
delete mode 100755 test/send-files

--
1.7.7.6



2012-06-01 10:51:21

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 12/14] client-test: pbap-client uses new API

From: Mikel Astiz <[email protected]>

---
test/pbap-client | 187 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 151 insertions(+), 36 deletions(-)

diff --git a/test/pbap-client b/test/pbap-client
index ecca14f..2432acf 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -1,41 +1,156 @@
#!/usr/bin/python

+import gobject
+
import sys
+import os
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_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, reply, transfer):
+ (path, properties) = reply
+ transfer.path = path
+ transfer.filename = properties["Filename"]
+ self.transfer_dict[path] = transfer
+ print "Transfer created: %s (file %s)" % (path, transfer.filename)
+
+ def error(self, err):
+ print err
+ mainloop.quit()
+
+ def transfer_complete(self, path):
+ req = self.transfer_dict.get(path)
+ if req == None:
+ return
+ self.pending_transfers -= 1
+ print "Transfer %s finished" % path
+ f = open(req.filename, "r")
+ os.remove(req.filename)
+ 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, code, message, path):
+ req = self.transfer_dict.get(path)
+ if req == None:
+ return
+ print "Transfer finished with error %s: %s" % (code, message)
+ mainloop.quit()
+
+ def pull(self, vcard, func):
+ req = Transfer(func)
+ self.pbap.Pull(vcard, "",
+ reply_handler=lambda r: self.register(r, req),
+ error_handler=self.error)
+ self.pending_transfers += 1
+
+ def pull_all(self, func):
+ req = Transfer(func)
+ self.pbap.PullAll("",
+ reply_handler=lambda r: self.register(r, 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.7.6


2012-06-01 10:51:12

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 03/14] client: Expose D-Bus data in internal transfer API

From: Mikel Astiz <[email protected]>

Expose in transfer API the D-Bus path and properties as should be
returned by transfer-initiating D-Bus methods.
---
client/transfer.c | 62 ++++++++++++++++++++++++++++++++++++++++++----------
client/transfer.h | 3 ++
2 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/client/transfer.c b/client/transfer.c
index 04533b8..c4eda84 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -85,6 +85,19 @@ static GQuark obc_transfer_error_quark(void)
return g_quark_from_static_string("obc-transfer-error-quark");
}

+static void obc_transfer_append_dbus_properties(struct obc_transfer *transfer,
+ DBusMessageIter *dict)
+{
+ obex_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING, &transfer->name);
+ obex_dbus_dict_append(dict, "Size", DBUS_TYPE_UINT64, &transfer->size);
+ obex_dbus_dict_append(dict, "Filename", DBUS_TYPE_STRING,
+ &transfer->filename);
+
+ if (transfer->obex != NULL)
+ obex_dbus_dict_append(dict, "Progress", DBUS_TYPE_UINT64,
+ &transfer->progress);
+}
+
static DBusMessage *obc_transfer_get_properties(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -97,26 +110,51 @@ static DBusMessage *obc_transfer_get_properties(DBusConnection *connection,
return NULL;

dbus_message_iter_init_append(reply, &iter);
-
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ OBC_PROPERTIES_ARRAY_SIGNATURE,
+ &dict);

- obex_dbus_dict_append(&dict, "Name", DBUS_TYPE_STRING, &transfer->name);
- obex_dbus_dict_append(&dict, "Size", DBUS_TYPE_UINT64, &transfer->size);
- obex_dbus_dict_append(&dict, "Filename", DBUS_TYPE_STRING,
- &transfer->filename);
-
- if (transfer->obex != NULL)
- obex_dbus_dict_append(&dict, "Progress", DBUS_TYPE_UINT64,
- &transfer->progress);
+ obc_transfer_append_dbus_properties(transfer, &dict);

dbus_message_iter_close_container(&iter, &dict);

return reply;
}

+static void obc_transfer_append_dbus_data(struct obc_transfer *transfer,
+ DBusMessageIter *iter)
+{
+ const char *path = transfer->path;
+ DBusMessageIter entry, dict;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH, &path);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
+ OBC_PROPERTIES_ARRAY_SIGNATURE,
+ &dict);
+
+ obc_transfer_append_dbus_properties(transfer, &dict);
+
+ dbus_message_iter_close_container(&entry, &dict);
+ dbus_message_iter_close_container(iter, &entry);
+}
+
+DBusMessage *obc_transfer_create_dbus_reply(struct obc_transfer *transfer,
+ DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+ obc_transfer_append_dbus_data(transfer, &iter);
+
+ return reply;
+}
+
static void abort_complete(GObex *obex, GError *err, gpointer user_data)
{
struct obc_transfer *transfer = user_data;
diff --git a/client/transfer.h b/client/transfer.h
index 15c157a..eb5275c 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -57,3 +57,6 @@ int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,

const char *obc_transfer_get_path(struct obc_transfer *transfer);
gint64 obc_transfer_get_size(struct obc_transfer *transfer);
+
+DBusMessage *obc_transfer_create_dbus_reply(struct obc_transfer *transfer,
+ DBusMessage *message);
--
1.7.7.6


2012-06-01 10:51:18

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 09/14] client-doc: PhonebookAccess sessions return transfers

From: Mikel Astiz <[email protected]>

---
doc/client-api.txt | 31 ++++++++++++++++++++++++++-----
1 files changed, 26 insertions(+), 5 deletions(-)

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

- string PullAll()
+ object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.

array{string vcard, string name} List()

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

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

- Retrieve the vcard in the current phonebook object
- for example : Pull("0.vcf")
+ Retrieve the vcard in the current phonebook object 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.

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


2012-06-01 10:51:22

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 13/14] client-test: Add opp-client

From: Mikel Astiz <[email protected]>

This new scripts replaces previous pull-business-card and send-files.
---
test/opp-client | 101 +++++++++++++++++++++++++++++++++++++++++++++++
test/pull-business-card | 40 ------------------
test/send-files | 23 -----------
3 files changed, 101 insertions(+), 63 deletions(-)
create mode 100755 test/opp-client
delete mode 100755 test/pull-business-card
delete mode 100755 test/send-files

diff --git a/test/opp-client b/test/opp-client
new file mode 100755
index 0000000..2f591b9
--- /dev/null
+++ b/test/opp-client
@@ -0,0 +1,101 @@
+#!/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("-p", "--pull", dest="pull_to_file",
+ help="Pull vcard and store in FILE", metavar="FILE")
+ parser.add_option("-s", "--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, reply):
+ (path, properties) = reply
+ 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, code, message, path):
+ if path != self.transfer_path:
+ return
+ print "Transfer finished with error %s: %s" % (code, message)
+ 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 5310c06..0000000
--- a/test/send-files
+++ /dev/null
@@ -1,23 +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")
-
-for f in files:
- opp.SendFile(f)
--
1.7.7.6


2012-06-01 10:51:19

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 10/14] client: PhonebookAccess sessions return transfers

From: Mikel Astiz <[email protected]>

Return the D-Bus path of the transfer representing the operation.
---
client/pbap.c | 161 ++++++++++++++++++++++++++------------------------------
1 files changed, 75 insertions(+), 86 deletions(-)

diff --git a/client/pbap.c b/client/pbap.c
index 3a771ab..e296eec 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -340,45 +340,6 @@ static void read_return_apparam(struct obc_transfer *transfer,
}
}

-static void pull_phonebook_callback(struct obc_session *session,
- struct obc_transfer *transfer,
- GError *err, void *user_data)
-{
- struct pending_request *request = user_data;
- DBusMessage *reply;
- char *contents;
- size_t size;
- int perr;
-
- if (err) {
- reply = g_dbus_create_error(request->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- goto send;
- }
-
- perr = obc_transfer_get_contents(transfer, &contents, &size);
- if (perr < 0) {
- reply = g_dbus_create_error(request->msg,
- "org.openobex.Error.Failed",
- "Error reading contents: %s",
- strerror(-perr));
- goto send;
- }
-
- reply = dbus_message_new_method_return(request->msg);
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &contents,
- DBUS_TYPE_INVALID);
-
- g_free(contents);
-
-send:
- g_dbus_send_message(conn, reply);
- pending_request_free(request);
-}
-
static void phonebook_size_callback(struct obc_session *session,
struct obc_transfer *transfer,
GError *err, void *user_data)
@@ -454,22 +415,23 @@ send:
pending_request_free(request);
}

-static DBusMessage *pull_phonebook(struct pbap_data *pbap,
- DBusMessage *message, guint8 type,
- const char *name, uint64_t filter,
- guint8 format, guint16 maxlistcount,
- guint16 liststartoffset)
+static struct obc_transfer *pull_phonebook(struct pbap_data *pbap,
+ DBusMessage *message,
+ guint8 type, const char *name,
+ const char *targetfile,
+ uint64_t filter, guint8 format,
+ guint16 maxlistcount,
+ guint16 liststartoffset,
+ GError **err)
{
struct pending_request *request;
- struct pullphonebook_apparam apparam;
struct obc_transfer *transfer;
+ struct pullphonebook_apparam apparam;
session_callback_t func;
- GError *err = NULL;
- DBusMessage *reply;

- transfer = obc_transfer_get("x-bt/phonebook", name, NULL, &err);
+ transfer = obc_transfer_get("x-bt/phonebook", name, targetfile, err);
if (transfer == NULL)
- goto fail;
+ return NULL;

apparam.filter_tag = FILTER_TAG;
apparam.filter_len = FILTER_LEN;
@@ -486,30 +448,29 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,

switch (type) {
case PULLPHONEBOOK:
- func = pull_phonebook_callback;
+ func = NULL;
+ request = NULL;
break;
case GETPHONEBOOKSIZE:
func = phonebook_size_callback;
+ request = pending_request_new(pbap, message);
break;
default:
error("Unexpected type : 0x%2x", type);
return NULL;
}

- request = pending_request_new(pbap, message);
-
obc_transfer_set_params(transfer, &apparam, sizeof(apparam));

- if (obc_session_queue(pbap->session, transfer, func, request, &err))
+ if (!obc_session_queue(pbap->session, transfer, func, request, err)) {
+ if (request != NULL)
+ pending_request_free(request);
+
return NULL;
+ }

- pending_request_free(request);

-fail:
- reply = g_dbus_create_error(message, "org.openobex.Error.Failed", "%s",
- err->message);
- g_error_free(err);
- return reply;
+ return transfer;
}

static guint8 *fill_apparam(guint8 *dest, void *buf, guint8 tag, guint8 len)
@@ -742,32 +703,48 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct pbap_data *pbap = user_data;
- DBusMessage * err;
+ struct obc_transfer *transfer;
+ const char *targetfile;
char *name;
+ GError *err = NULL;

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

+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &targetfile,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ ERROR_INF ".InvalidArguments", NULL);
+
name = g_strconcat(pbap->path, ".vcf", NULL);

- err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
- pbap->filter, pbap->format,
- DEFAULT_COUNT, DEFAULT_OFFSET);
+ transfer = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
+ targetfile, pbap->filter, pbap->format,
+ DEFAULT_COUNT, DEFAULT_OFFSET, &err);
g_free(name);
- return err;
+
+ if (transfer == NULL) {
+ DBusMessage *reply = g_dbus_create_error(message,
+ "org.openobex.Error.Failed", "%s",
+ err->message);
+ g_error_free(err);
+ return reply;
+ }
+
+ return obc_transfer_create_dbus_reply(transfer, message);
}

static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct pbap_data *pbap = user_data;
- struct pullvcardentry_apparam apparam;
- const char *name;
- struct pending_request *request;
struct obc_transfer *transfer;
- GError *err = NULL;
+ struct pullvcardentry_apparam apparam;
+ const char *name, *targetfile;
DBusMessage *reply;
+ GError *err = NULL;

if (!pbap->path)
return g_dbus_create_error(message,
@@ -776,11 +753,12 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,

if (dbus_message_get_args(message, NULL,
DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &targetfile,
DBUS_TYPE_INVALID) == FALSE)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);

- transfer = obc_transfer_get("x-bt/vcard", name, NULL, &err);
+ transfer = obc_transfer_get("x-bt/vcard", name, targetfile, &err);
if (transfer == NULL)
goto fail;

@@ -791,15 +769,12 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
apparam.format_len = FORMAT_LEN;
apparam.format = pbap->format;

- request = pending_request_new(pbap, message);
-
obc_transfer_set_params(transfer, &apparam, sizeof(apparam));

- if (obc_session_queue(pbap->session, transfer, pull_phonebook_callback,
- request, &err))
- return NULL;
+ if (!obc_session_queue(pbap->session, transfer, NULL, NULL, &err))
+ goto fail;

- pending_request_free(request);
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message, "org.openobex.Error.Failed", "%s",
@@ -859,8 +834,10 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct pbap_data *pbap = user_data;
- DBusMessage * err;
+ DBusMessage *reply;
+ struct obc_transfer *transfer;
char *name;
+ GError *err = NULL;

if (!pbap->path)
return g_dbus_create_error(message,
@@ -868,11 +845,20 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,

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

- err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
+ transfer = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name, NULL,
pbap->filter, pbap->format, 0,
- DEFAULT_OFFSET);
+ DEFAULT_OFFSET, &err);
+
g_free(name);
- return err;
+
+ if (transfer != NULL)
+ return NULL;
+
+ reply = g_dbus_create_error(message,
+ "org.openobex.Error.Failed", "%s",
+ err->message);
+ g_error_free(err);
+ return reply;
}

static DBusMessage *pbap_set_format(DBusConnection *connection,
@@ -984,13 +970,16 @@ static const GDBusMethodTable pbap_methods[] = {
{ GDBUS_ASYNC_METHOD("Select",
GDBUS_ARGS({ "location", "s" }, { "phonebook", "s" }),
NULL, pbap_select) },
- { GDBUS_ASYNC_METHOD("PullAll",
- NULL, GDBUS_ARGS({ "phonebook", "s" }),
- pbap_pull_all) },
- { GDBUS_ASYNC_METHOD("Pull",
- GDBUS_ARGS({ "phonebook_object", "s" }),
- GDBUS_ARGS({ "vcard", "s" }),
- pbap_pull_vcard) },
+ { GDBUS_METHOD("PullAll",
+ GDBUS_ARGS({ "targetfile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" },
+ { "properties", "a{sv}" }),
+ pbap_pull_all) },
+ { GDBUS_METHOD("Pull",
+ GDBUS_ARGS({ "vcard", "s" }, { "targetfile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" },
+ { "properties", "a{sv}" }),
+ pbap_pull_vcard) },
{ GDBUS_ASYNC_METHOD("List",
NULL, GDBUS_ARGS({ "vcard_listing", "a(ss)" }),
pbap_list) },
--
1.7.7.6


2012-06-01 10:51:23

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 14/14] client: Update copyright statement

From: Mikel Astiz <[email protected]>

---
client/session.c | 1 +
client/session.h | 1 +
client/transfer.c | 1 +
client/transfer.h | 1 +
doc/client-api.txt | 1 +
5 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/client/session.c b/client/session.c
index 9670968..ac5c7f2 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-2012 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 7f37d29..af71568 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-2012 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 c4eda84..94a1629 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-2012 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 eb5275c..071b6d3 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-2012 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 f709017..2f65e44 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-2012 BMW Car IT GmbH. All rights reserved.


Client hierarchy
--
1.7.7.6


2012-06-01 10:51:20

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 11/14] client-test: ftp-client uses new API

From: Mikel Astiz <[email protected]>

---
test/ftp-client | 159 +++++++++++++++++++++++++++++++++---------------------
1 files changed, 97 insertions(+), 62 deletions(-)

diff --git a/test/ftp-client b/test/ftp-client
index 8421ade..f8c33e9 100755
--- a/test/ftp-client
+++ b/test/ftp-client
@@ -32,56 +32,94 @@ def parse_options():

return parser.parse_args()

-def error(err):
- print err
-
-def void_reply():
- pass
-
-def transfer_complete():
- if options.verbose:
- print "Transfer finished"
- mainloop.quit()
-
-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=transfer_complete,
- error_handler=error)
-
-def get_file(session, filename):
- session.GetFile(os.path.abspath(filename),
- os.path.basename(filename),
- reply_handler=transfer_complete,
- 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, verbose=False):
+ self.transfer_path = None
+ self.verbose = verbose
+ 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, reply):
+ (path, properties) = reply
+ self.transfer_path = path
+ if self.verbose:
+ print "Transfer created: %s" % path
+
+ def generic_reply(self):
+ if self.verbose:
+ print "Operation succeeded"
+
+ def error(self, err):
+ print err
+ mainloop.quit()
+
+ def transfer_complete(self, path):
+ if path != self.transfer_path:
+ return
+ if self.verbose:
+ print "Transfer finished"
+ mainloop.quit()
+
+ def transfer_error(self, code, message, path):
+ if path != self.transfer_path:
+ return
+ print "Transfer finished with error %s: %s" % (code, message)
+ 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.generic_reply,
+ error_handler=self.error)
+
+ def move_file(self, filename, destname):
+ self.ftp.MoveFile(filename,
+ destname,
+ reply_handler=self.generic_reply,
+ error_handler=self.error)
+
+ def copy_file(self, filename, destname):
+ self.ftp.CopyFile(filename,
+ destname,
+ reply_handler=self.generic_reply,
+ error_handler=self.error)

if __name__ == '__main__':

@@ -101,33 +139,30 @@ if __name__ == '__main__':
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")
-
- 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.7.6


2012-06-01 10:51:15

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 06/14] client: FileTransfer sessions return transfers

From: Mikel Astiz <[email protected]>

Return the D-Bus path of the transfer representing the operation.
---
client/ftp.c | 46 ++++++++++++++--------------------------------
1 files changed, 14 insertions(+), 32 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 8c72413..58aa17f 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -143,24 +143,6 @@ static const GMarkupParser parser = {
NULL
};

-static void transfer_callback(struct obc_session *session,
- struct obc_transfer *transfer,
- GError *err, void *user_data)
-{
- DBusMessage *msg = user_data;
- DBusMessage *reply;
-
- if (err)
- reply = g_dbus_create_error(msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- else
- reply = dbus_message_new_method_return(msg);
-
- g_dbus_send_message(conn, reply);
- dbus_message_unref(msg);
-}
-
static void list_folder_callback(struct obc_session *session,
struct obc_transfer *transfer,
GError *err, void *user_data)
@@ -270,11 +252,10 @@ static DBusMessage *get_file(DBusConnection *connection,
if (transfer == NULL)
goto fail;

- if (obc_session_queue(session, transfer, transfer_callback, message,
- &err)) {
- dbus_message_ref(message);
- return NULL;
- }
+ if (!obc_session_queue(session, transfer, NULL, NULL, &err))
+ goto fail;
+
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message, "org.openobex.Error.Failed", "%s",
@@ -306,11 +287,10 @@ static DBusMessage *put_file(DBusConnection *connection,
if (transfer == NULL)
goto fail;

- if (obc_session_queue(session, transfer, transfer_callback, message,
- &err)) {
- dbus_message_ref(message);
- return NULL;
- }
+ if (!obc_session_queue(session, transfer, NULL, NULL, &err))
+ goto fail;
+
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message, "org.openobex.Error.Failed", "%s",
@@ -415,11 +395,13 @@ static const GDBusMethodTable ftp_methods[] = {
GDBUS_ARGS({ "folder", "s" }), NULL, create_folder) },
{ GDBUS_ASYNC_METHOD("ListFolder",
NULL, GDBUS_ARGS({ "folderinfo", "aa{sv}" }), list_folder) },
- { GDBUS_ASYNC_METHOD("GetFile",
- GDBUS_ARGS({ "targetfile", "s" }, { "sourcefile", "s" }), NULL,
+ { GDBUS_METHOD("GetFile",
+ GDBUS_ARGS({ "targetfile", "s" }, { "sourcefile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
get_file) },
- { GDBUS_ASYNC_METHOD("PutFile",
- GDBUS_ARGS({ "sourcefile", "s" }, { "targetfile", "s" }), NULL,
+ { GDBUS_METHOD("PutFile",
+ GDBUS_ARGS({ "sourcefile", "s" }, { "targetfile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
put_file) },
{ GDBUS_ASYNC_METHOD("CopyFile",
GDBUS_ARGS({ "sourcefile", "s" }, { "targetfile", "s" }), NULL,
--
1.7.7.6


2012-06-01 10:51:13

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 04/14] client: ObjectPush sessions return transfers

From: Mikel Astiz <[email protected]>

Return the D-Bus path of the transfer representing the operation.
---
client/opp.c | 71 ++++++++++-----------------------------------------------
1 files changed, 13 insertions(+), 58 deletions(-)

diff --git a/client/opp.c b/client/opp.c
index 67b01a9..a3899f8 100644
--- a/client/opp.c
+++ b/client/opp.c
@@ -45,23 +45,6 @@ struct opp_data {

static DBusConnection *conn = NULL;

-static void send_file_callback(struct obc_session *session,
- struct obc_transfer *transfer,
- GError *err, void *user_data)
-{
- DBusMessage *msg = user_data;
- DBusMessage *reply;
-
- if (err != NULL)
- reply = g_dbus_create_error(msg,
- ERROR_INF ".Failed", "%s", err->message);
- else
- reply = dbus_message_new_method_return(msg);
-
- g_dbus_send_message(conn, reply);
- dbus_message_unref(msg);
-}
-
static DBusMessage *opp_send_file(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -87,12 +70,10 @@ static DBusMessage *opp_send_file(DBusConnection *connection,
if (transfer == NULL)
goto fail;

- if (!obc_session_queue(opp->session, transfer, send_file_callback,
- message, &err))
+ if (!obc_session_queue(opp->session, transfer, NULL, NULL, &err))
goto fail;

- dbus_message_ref(message);
- return NULL;
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message,
@@ -101,55 +82,29 @@ fail:
return reply;
}

-static void pull_complete_callback(struct obc_session *session,
- struct obc_transfer *transfer,
- GError *err, void *user_data)
-{
- DBusMessage *message = user_data;
-
- if (err != NULL) {
- DBusMessage *error = g_dbus_create_error(message,
- "org.openobex.Error.Failed",
- "%s", err->message);
- g_dbus_send_message(conn, error);
- goto done;
- }
-
- g_dbus_send_reply(conn, message, DBUS_TYPE_INVALID);
-
-done:
- dbus_message_unref(message);
-}
-
static DBusMessage *opp_pull_business_card(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
struct opp_data *opp = user_data;
struct obc_transfer *pull;
- DBusMessageIter iter;
DBusMessage *reply;
const char *filename = NULL;
GError *err = NULL;

- dbus_message_iter_init(message, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &filename,
+ DBUS_TYPE_INVALID) == FALSE)
return g_dbus_create_error(message,
ERROR_INF ".InvalidArguments", NULL);

- dbus_message_iter_get_basic(&iter, &filename);
-
pull = obc_transfer_get("text/x-vcard", NULL, filename, &err);
if (pull == NULL)
goto fail;

- if (!obc_session_queue(opp->session, pull, pull_complete_callback,
- message, &err))
+ if (!obc_session_queue(opp->session, pull, NULL, NULL, &err))
goto fail;

- dbus_message_ref(message);
-
- return NULL;
+ return obc_transfer_create_dbus_reply(pull, message);

fail:
reply = g_dbus_create_error(message,
@@ -165,17 +120,17 @@ static DBusMessage *opp_exchange_business_cards(DBusConnection *connection,
}

static const GDBusMethodTable opp_methods[] = {
- { GDBUS_ASYNC_METHOD("SendFile",
+ { GDBUS_METHOD("SendFile",
GDBUS_ARGS({ "sourcefile", "s" }),
- NULL,
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
opp_send_file) },
- { GDBUS_ASYNC_METHOD("PullBusinessCard",
+ { GDBUS_METHOD("PullBusinessCard",
GDBUS_ARGS({ "targetfile", "s" }),
- NULL,
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
opp_pull_business_card) },
- { GDBUS_ASYNC_METHOD("ExchangeBusinessCards",
+ { GDBUS_METHOD("ExchangeBusinessCards",
GDBUS_ARGS({ "clientfile", "s" }, { "targetfile", "s" }),
- NULL,
+ GDBUS_ARGS({ "transfer", "o" }, { "properties", "a{sv}" }),
opp_exchange_business_cards) },
{ }
};
--
1.7.7.6


2012-06-01 10:51:17

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 08/14] client: Synchronization sessions return transfers

From: Mikel Astiz <[email protected]>

Return the D-Bus path of the transfer representing the operation.
---
client/sync.c | 92 ++++++++++++++++++++------------------------------------
1 files changed, 33 insertions(+), 59 deletions(-)

diff --git a/client/sync.c b/client/sync.c
index d56e066..035ab2e 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -84,53 +84,22 @@ static DBusMessage *sync_setlocation(DBusConnection *connection,
return dbus_message_new_method_return(message);
}

-static void sync_getphonebook_callback(struct obc_session *session,
- struct obc_transfer *transfer,
- GError *err, void *user_data)
-{
- struct sync_data *sync = user_data;
- DBusMessage *reply;
- char *contents;
- size_t size;
- int perr;
-
- if (err) {
- reply = g_dbus_create_error(sync->msg,
- "org.openobex.Error.Failed",
- "%s", err->message);
- goto send;
- }
-
- perr = obc_transfer_get_contents(transfer, &contents, &size);
- if (perr < 0) {
- reply = g_dbus_create_error(sync->msg,
- "org.openobex.Error.Failed",
- "Error reading contents: %s",
- strerror(-perr));
- goto send;
- }
-
- reply = dbus_message_new_method_return(sync->msg);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &contents,
- DBUS_TYPE_INVALID);
-
- g_free(contents);
-
-send:
- 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;
struct obc_transfer *transfer;
+ const char *target_file;
GError *err = NULL;
DBusMessage *reply;

+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &target_file,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ ERROR_INF ".InvalidArguments",
+ "Invalid arguments in method call");
+
if (sync->msg)
return g_dbus_create_error(message,
ERROR_INF ".InProgress", "Transfer in progress");
@@ -139,17 +108,15 @@ static DBusMessage *sync_getphonebook(DBusConnection *connection,
if (!sync->phonebook_path)
sync->phonebook_path = g_strdup("telecom/pb.vcf");

- transfer = obc_transfer_get("phonebook", sync->phonebook_path, NULL,
- &err);
+ transfer = obc_transfer_get("phonebook", sync->phonebook_path,
+ target_file, &err);
if (transfer == NULL)
goto fail;

- if (obc_session_queue(sync->session, transfer,
- sync_getphonebook_callback,
- sync, &err)) {
- sync->msg = dbus_message_ref(message);
- return NULL;
- }
+ if (!obc_session_queue(sync->session, transfer, NULL, NULL, &err))
+ goto fail;
+
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message, ERROR_INF ".Failed", "%s",
@@ -163,27 +130,30 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
{
struct sync_data *sync = user_data;
struct obc_transfer *transfer;
- const char *buf;
+ const char *source_file;
GError *err = NULL;
DBusMessage *reply;

if (dbus_message_get_args(message, NULL,
- DBUS_TYPE_STRING, &buf,
- DBUS_TYPE_INVALID) == FALSE)
+ DBUS_TYPE_STRING, &source_file,
+ DBUS_TYPE_INVALID) == FALSE)
return g_dbus_create_error(message,
- ERROR_INF ".InvalidArguments", NULL);
+ ERROR_INF ".InvalidArguments",
+ "Invalid arguments in method call");

/* set default phonebook_path to memory internal phonebook */
if (!sync->phonebook_path)
sync->phonebook_path = g_strdup("telecom/pb.vcf");

- transfer = obc_transfer_put(NULL, sync->phonebook_path, NULL, buf,
- strlen(buf), &err);
+ transfer = obc_transfer_put(NULL, sync->phonebook_path, source_file,
+ NULL, 0, &err);
if (transfer == NULL)
goto fail;

- if (obc_session_queue(sync->session, transfer, NULL, NULL, &err))
- return dbus_message_new_method_return(message);
+ if (!obc_session_queue(sync->session, transfer, NULL, NULL, &err))
+ goto fail;
+
+ return obc_transfer_create_dbus_reply(transfer, message);

fail:
reply = g_dbus_create_error(message, ERROR_INF ".Failed", "%s",
@@ -196,11 +166,15 @@ static const GDBusMethodTable sync_methods[] = {
{ GDBUS_METHOD("SetLocation",
GDBUS_ARGS({ "location", "s" }), NULL,
sync_setlocation) },
- { GDBUS_ASYNC_METHOD("GetPhonebook",
- NULL, GDBUS_ARGS({ "obj", "s" }),
+ { GDBUS_METHOD("GetPhonebook",
+ GDBUS_ARGS({ "targetfile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" },
+ { "properties", "a{sv}" }),
sync_getphonebook) },
- { GDBUS_ASYNC_METHOD("PutPhonebook",
- GDBUS_ARGS({ "obj", "s" }), NULL,
+ { GDBUS_METHOD("PutPhonebook",
+ GDBUS_ARGS({ "sourcefile", "s" }),
+ GDBUS_ARGS({ "transfer", "o" },
+ { "properties", "a{sv}" }),
sync_putphonebook) },
{ }
};
--
1.7.7.6


2012-06-01 10:51:16

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 07/14] client-doc: Synchronization sessions return transfers

From: Mikel Astiz <[email protected]>

Note that the parameter given to PutPhonebook now represents the file
name to be read, instead of containing the phonebook data.
---
doc/client-api.txt | 25 +++++++++++++++++++++----
1 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 8e0819d..189a7a0 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -292,14 +292,31 @@ Methods void SetLocation(string location)
"SIM2"
......

- string GetPhonebook()
+ object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.

- Send an entire Phonebook Object store to remote device
+ object, dict PutPhonebook(string sourcefile)
+
+ 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.

Message Access hierarchy
=========================
--
1.7.7.6


2012-06-01 10:51:14

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 05/14] client-doc: FileTransfer sessions return transfers

From: Mikel Astiz <[email protected]>

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

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 5377124..8e0819d 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -138,21 +138,32 @@ Methods void ChangeFolder(string folder)
uint64 Accessed : Last access
uint64 Created : Creation date

- void GetFile(string targetfile, string sourcefile)
+ object, dict 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.
+
+ 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 PutFile(string sourcefile, string targetfile)
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.
+
+ object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.

void CopyFile(string sourcefile, string targetfile)

--
1.7.7.6


2012-06-01 10:51:11

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 02/14] client: Support empty filename in obc_transfer_get

From: Mikel Astiz <[email protected]>

Passing an empty string as a filename for obc_transfer_get will be
similar to passing a NULL filename. This means a temporary file will be
created to store the content of the transfer.

NULL and "" are not exactly equivalent though: in case of NULL the file
will be automatically removed immediately after being open, which means
that the transfer initiator should also open the file to prevent it from
being removed (to be used from the modules).

On the other hand, if "" is given, the file will be removed only in case
of error. So after success the transfer initiator should decide whether
the file should be removed or not.

This change is convenient in order to expose the same API in D-Bus.
---
client/transfer.c | 28 +++++++++++++++++++++++-----
1 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/client/transfer.c b/client/transfer.c
index 14006ef..04533b8 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -77,6 +77,7 @@ struct obc_transfer {
gint64 transferred;
gint64 progress;
guint progress_id;
+ gboolean remove_file_on_error;
};

static GQuark obc_transfer_error_quark(void)
@@ -293,8 +294,9 @@ static gboolean transfer_open(struct obc_transfer *transfer, int flags,
mode_t mode, GError **err)
{
int fd;
+ char *filename;

- if (transfer->filename != NULL) {
+ if (transfer->filename != NULL && strcmp(transfer->filename, "") != 0) {
fd = open(transfer->filename, flags, mode);
if (fd < 0) {
error("open(): %s(%d)", strerror(errno), errno);
@@ -305,13 +307,19 @@ static gboolean transfer_open(struct obc_transfer *transfer, int flags,
goto done;
}

- fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, err);
+ fd = g_file_open_tmp("obex-clientXXXXXX", &filename, err);
if (fd < 0) {
error("g_file_open_tmp(): %s", (*err)->message);
return FALSE;
}

- remove(transfer->filename);
+ if (transfer->filename == NULL)
+ remove(filename); /* remove always only if NULL was given */
+ else
+ transfer->remove_file_on_error = TRUE;
+
+ g_free(transfer->filename);
+ transfer->filename = filename;

done:
transfer->fd = fd;
@@ -344,6 +352,12 @@ struct obc_transfer *obc_transfer_put(const char *type, const char *name,
struct stat st;
int perr;

+ if (filename == NULL || strcmp(filename, "") == 0) {
+ g_set_error(err, OBC_TRANSFER_ERROR, -EINVAL,
+ "Invalid filename given");
+ return NULL;
+ }
+
transfer = obc_transfer_create(G_OBEX_OP_PUT, filename, name, type);

if (contents != NULL) {
@@ -433,10 +447,14 @@ static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
g_dbus_emit_signal(transfer->conn, transfer->path,
TRANSFER_INTERFACE, "Complete",
DBUS_TYPE_INVALID);
- } else if (transfer->path != NULL) {
+ } else {
const char *code = "org.openobex.Error.Failed";

- g_dbus_emit_signal(transfer->conn, transfer->path,
+ if (transfer->remove_file_on_error)
+ remove(transfer->filename);
+
+ if (transfer->path != NULL)
+ g_dbus_emit_signal(transfer->conn, transfer->path,
TRANSFER_INTERFACE, "Error",
DBUS_TYPE_STRING,
&code,
--
1.7.7.6


2012-06-01 10:51:10

by Mikel Astiz

[permalink] [raw]
Subject: [PATCH obexd v0 01/14] client-doc: ObjectPush sessions return transfers

From: Mikel Astiz <[email protected]>

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

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3c6a2e1..5377124 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -63,21 +63,49 @@ Service org.openobex.client
Interface org.openobex.ObjectPush
Object path [variable prefix]/{session0,session1,...}

-Methods void SendFile(string sourcefile)
+Methods object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.
+
+ object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.
+
+ object, dict 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.
+
+ The properties of this transfer are also returned along
+ with the object path, to avoid a call to GetProperties.
+
File Transfer hierarchy
=======================

--
1.7.7.6