From: Mikel Astiz <[email protected]>
This second version makes the filename property of transfers optional. For transfers initiated internally by the modules (where filename == NULL), the D-Bus property will not be present, and internally the filename will be set to NULL.
This simplifies patch v0 02/14 by avoiding the additional flag needed to distinguish whether the file should be removed or not on success.
>From original cover letter:
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 (15):
client: Make transfer filename optional
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 | 92 +++++++++++++++++++----
client/transfer.h | 4 +
doc/client-api.txt | 116 ++++++++++++++++++++++++-----
test/ftp-client | 159 ++++++++++++++++++++++++----------------
test/opp-client | 101 +++++++++++++++++++++++++
test/pbap-client | 187 ++++++++++++++++++++++++++++++++++++++---------
test/pull-business-card | 40 ----------
test/send-files | 23 ------
14 files changed, 662 insertions(+), 432 deletions(-)
create mode 100755 test/opp-client
delete mode 100755 test/pull-business-card
delete mode 100755 test/send-files
--
1.7.7.6
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
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). In this case, the filename
will not be exposed in D-Bus.
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 | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/client/transfer.c b/client/transfer.c
index e7852e1..e6ca72d 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -295,8 +295,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);
@@ -307,13 +308,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 */
+ g_free(filename);
+ } else {
+ g_free(transfer->filename);
+ transfer->filename = filename;
+ }
done:
transfer->fd = fd;
@@ -346,6 +353,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) {
@@ -435,10 +448,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->op == G_OBEX_OP_GET && transfer->filename != NULL)
+ 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
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 2c7c03c..5a3e252 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
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
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
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 a57f6c2..2c7c03c 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
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
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 4963665..b807014 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 17c15bb..2165c22 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
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
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
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 5a3e252..17c15bb 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
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
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 3b5444d..a57f6c2 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
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 | 64 ++++++++++++++++++++++++++++++++++++++++++----------
client/transfer.h | 3 ++
2 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/client/transfer.c b/client/transfer.c
index e6ca72d..4963665 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -84,6 +84,21 @@ 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);
+
+ if (transfer->filename != NULL)
+ 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)
{
@@ -96,24 +111,47 @@ 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);
+ obc_transfer_append_dbus_properties(transfer, &dict);
- if (transfer->filename != NULL)
- obex_dbus_dict_append(&dict, "Filename", DBUS_TYPE_STRING,
- &transfer->filename);
+ dbus_message_iter_close_container(&iter, &dict);
- if (transfer->obex != NULL)
- obex_dbus_dict_append(&dict, "Progress", DBUS_TYPE_UINT64,
- &transfer->progress);
+ return reply;
+}
- dbus_message_iter_close_container(&iter, &dict);
+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;
}
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
From: Mikel Astiz <[email protected]>
The property might not exist for certain transfers, typically when they
have been initiated internally.
---
client/transfer.c | 4 +++-
doc/client-api.txt | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/client/transfer.c b/client/transfer.c
index 14006ef..e7852e1 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -104,7 +104,9 @@ static DBusMessage *obc_transfer_get_properties(DBusConnection *connection,
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,
+
+ if (transfer->filename != NULL)
+ obex_dbus_dict_append(&dict, "Filename", DBUS_TYPE_STRING,
&transfer->filename);
if (transfer->obex != NULL)
diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3c6a2e1..3b5444d 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -299,7 +299,7 @@ Properties string Name [readonly]
Size of the transferred object. If the size is
unknown, then this property will not be present.
- string Filename [readonly]
+ string Filename [readonly, optional]
Complete name of the file being received or sent.
--
1.7.7.6