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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

diff --git a/client/pbap.c b/client/pbap.c
index 8e21cb5..da2c22d 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -411,39 +411,6 @@ static void read_return_apparam(const struct obc_transfer *transfer,
 	}
 }
 
-static void pull_phonebook_callback(struct obc_session *session,
-					GError *err,
-					const struct obc_transfer *transfer,
-					void *user_data)
-{
-	struct pbap_data *pbap = user_data;
-	DBusMessage *reply;
-	const void *buf;
-
-	if (pbap->msg == NULL)
-		return;
-
-	if (err) {
-		reply = g_dbus_create_error(pbap->msg,
-						"org.openobex.Error.Failed",
-						"%s", err->message);
-		goto send;
-	}
-
-	reply = dbus_message_new_method_return(pbap->msg);
-
-	buf = obc_transfer_get_buffer(transfer);
-
-	dbus_message_append_args(reply,
-			DBUS_TYPE_STRING, &buf,
-			DBUS_TYPE_INVALID);
-
-send:
-	g_dbus_send_message(conn, reply);
-	dbus_message_unref(pbap->msg);
-	pbap->msg = NULL;
-}
-
 static void phonebook_size_callback(struct obc_session *session,
 					GError *err,
 					const struct obc_transfer *transfer,
@@ -521,12 +488,16 @@ send:
 
 static DBusMessage *pull_phonebook(struct pbap_data *pbap,
 					DBusMessage *message, guint8 type,
-					const char *name, uint64_t filter,
+					const char *name,
+					const char *targetname,
+					uint64_t filter,
 					guint8 format, guint16 maxlistcount,
-					guint16 liststartoffset)
+					guint16 liststartoffset,
+					struct obc_transfer **transfer)
 {
 	struct pullphonebook_apparam apparam;
 	session_transfer_callback_t func;
+	int ret;
 
 	if (pbap->msg)
 		return g_dbus_create_error(message,
@@ -548,7 +519,7 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
 
 	switch (type) {
 	case PULLPHONEBOOK:
-		func = pull_phonebook_callback;
+		func = NULL;
 		break;
 	case GETPHONEBOOKSIZE:
 		func = phonebook_size_callback;
@@ -558,14 +529,23 @@ static DBusMessage *pull_phonebook(struct pbap_data *pbap,
 		return NULL;
 	}
 
-	if (obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
+	if (targetname != NULL)
+		ret = obc_session_get(pbap->session, "x-bt/phonebook", name,
+					targetname,
+					(guint8 *) &apparam, sizeof(apparam),
+					func, pbap, transfer);
+	else
+		ret = obc_session_get_mem(pbap->session, "x-bt/phonebook", name,
 					(guint8 *) &apparam, sizeof(apparam),
-					func, pbap, NULL) < 0)
+					func, pbap, transfer);
+
+	if (ret < 0)
 		return g_dbus_create_error(message,
 				"org.openobex.Error.Failed",
 				"Failed");
 
-	pbap->msg = dbus_message_ref(message);
+	if (func != NULL)
+		pbap->msg = dbus_message_ref(message);
 
 	return NULL;
 }
@@ -795,18 +775,40 @@ static DBusMessage *pbap_pull_all(DBusConnection *connection,
 	struct pbap_data *pbap = user_data;
 	DBusMessage * err;
 	char *name;
+	const char *target_file;
+	DBusMessage *reply;
+	struct obc_transfer *transfer;
+	const char *path;
+
+	if (dbus_message_get_args(message, NULL,
+				DBUS_TYPE_STRING, &target_file,
+				DBUS_TYPE_INVALID) == FALSE)
+		return g_dbus_create_error(message,
+				"org.openobex.Error.InvalidArguments", NULL);
 
 	if (!pbap->path)
 		return g_dbus_create_error(message,
-				ERROR_INF ".Forbidden", "Call Select first of all");
+			ERROR_INF ".Forbidden", "Call Select first of all");
 
 	name = g_strconcat(pbap->path, ".vcf", NULL);
 
-	err = pull_phonebook(pbap, message, PULLPHONEBOOK, name,
+	err = pull_phonebook(pbap, message, PULLPHONEBOOK, name, target_file,
 				pbap->filter, pbap->format,
-				DEFAULT_COUNT, DEFAULT_OFFSET);
+				DEFAULT_COUNT, DEFAULT_OFFSET, &transfer);
 	g_free(name);
-	return err;
+
+	if (err != NULL)
+		return err;
+
+	path = obc_transfer_get_path(transfer);
+
+	reply = dbus_message_new_method_return(message);
+
+	dbus_message_append_args(reply,
+			DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID);
+
+	return reply;
 }
 
 static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
@@ -814,7 +816,10 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
 {
 	struct pbap_data *pbap = user_data;
 	struct pullvcardentry_apparam apparam;
-	const char *name;
+	const char *name, *target_file;
+	DBusMessage *reply;
+	struct obc_transfer *transfer;
+	const char *path;
 
 	if (!pbap->path)
 		return g_dbus_create_error(message,
@@ -823,6 +828,7 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
 
 	if (dbus_message_get_args(message, NULL,
 			DBUS_TYPE_STRING, &name,
+			DBUS_TYPE_STRING, &target_file,
 			DBUS_TYPE_INVALID) == FALSE)
 		return g_dbus_create_error(message,
 				ERROR_INF ".InvalidArguments", NULL);
@@ -839,15 +845,22 @@ static DBusMessage *pbap_pull_vcard(DBusConnection *connection,
 	apparam.format_len = FORMAT_LEN;
 	apparam.format = pbap->format;
 
-	if (obc_session_get_mem(pbap->session, "x-bt/vcard", name,
+	if (obc_session_get(pbap->session, "x-bt/vcard", name, target_file,
 			(guint8 *) &apparam, sizeof(apparam),
-			pull_phonebook_callback, pbap, NULL) < 0)
+			NULL, NULL, &transfer) < 0)
 		return g_dbus_create_error(message,
 				"org.openobex.Error.Failed",
 				"Failed");
 
-	pbap->msg = dbus_message_ref(message);
-	return NULL;
+	path = obc_transfer_get_path(transfer);
+
+	reply = dbus_message_new_method_return(message);
+
+	dbus_message_append_args(reply,
+			DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID);
+
+	return reply;
 }
 
 static DBusMessage *pbap_list(DBusConnection *connection,
@@ -910,9 +923,9 @@ static DBusMessage *pbap_get_size(DBusConnection *connection,
 
 	name = g_strconcat(pbap->path, ".vcf", NULL);
 
-	err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name,
+	err = pull_phonebook(pbap, message, GETPHONEBOOKSIZE, name, NULL,
 				pbap->filter, pbap->format, 0,
-				DEFAULT_OFFSET);
+				DEFAULT_OFFSET, NULL);
 	g_free(name);
 	return err;
 }
@@ -1025,10 +1038,8 @@ static DBusMessage *pbap_list_filter_fields(DBusConnection *connection,
 static GDBusMethodTable pbap_methods[] = {
 	{ "Select",	"ss",	"",	pbap_select,
 					G_DBUS_METHOD_FLAG_ASYNC },
-	{ "PullAll",	"",	"s",	pbap_pull_all,
-					G_DBUS_METHOD_FLAG_ASYNC },
-	{ "Pull",	"s",	"s",	pbap_pull_vcard,
-					G_DBUS_METHOD_FLAG_ASYNC },
+	{ "PullAll",	"s",	"o",	pbap_pull_all },
+	{ "Pull",	"ss",	"o",	pbap_pull_vcard },
 	{ "List",	"",	"a(ss)",	pbap_list,
 					G_DBUS_METHOD_FLAG_ASYNC },
 	{ "Search",	"ss",	"a(ss)",	pbap_search,
diff --git a/test/pbap-client b/test/pbap-client
index f87f33c..7eb528c 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -1,41 +1,161 @@
 #!/usr/bin/python
 
+import gobject
+
 import sys
 import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+class Transfer:
+    def __init__(self, callback_func):
+        self.callback_func = callback_func
+        self.path = None
+        self.filename = None
+
+class PbapClient:
+    def __init__(self, session_path):
+        self.pending_transfers = 0
+        self.transfer_dict = dict()
+        self.flush_func = None
+        bus = dbus.SessionBus()
+        self.session = dbus.Interface(bus.get_object("org.openobex.client",
+                                                     session_path),
+                                      "org.openobex.Session")
+        self.pbap = dbus.Interface(bus.get_object("org.openobex.client",
+                                                  session_path),
+                                   "org.openobex.PhonebookAccess")
+        bus.add_signal_receiver(
+            self.transfer_added,
+            dbus_interface="org.openobex.Session",
+            signal_name="TransferAdded")
+        bus.add_signal_receiver(
+            self.transfer_complete,
+            dbus_interface="org.openobex.Transfer",
+            signal_name="Complete",
+            path_keyword="path")
+        bus.add_signal_receiver(
+            self.transfer_error,
+            dbus_interface="org.openobex.Transfer",
+            signal_name="Error",
+            path_keyword="path")
+
+    def register(self, path, transfer):
+        print "Transfer created: %s" % path
+        transfer.path = path
+        self.transfer_dict[path] = transfer
+
+    def error(self, err):
+        print err
+        mainloop.quit()
+
+    def transfer_added(self, path, properties):
+        req = self.transfer_dict.get(path)
+        if req == None:
+            return
+        req.filename = properties.get("Location")
+
+    def transfer_complete(self, path):
+        req = self.transfer_dict.get(path)
+        if req == None:
+            return
+        self.pending_transfers -= 1
+        print "Transfer %s finished an stored in %s" % (path, req.filename)
+        f = open(req.filename, "r")
+        lines = f.readlines()
+        del self.transfer_dict[path]
+        req.callback_func(lines)
+
+        if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
+            if self.flush_func != None:
+                f = self.flush_func
+                self.flush_func = None
+                f()
+
+    def transfer_error(self, error, path):
+        req = self.transfer_dict.get(path)
+        if req == None:
+            return
+        print "Transfer %s finished with an error: %s" % (path, error)
+        mainloop.quit()
+
+    def pull(self, vcard, func):
+        req = Transfer(func)
+        self.pbap.Pull(vcard, "",
+                       reply_handler=lambda p: self.register(p, req),
+                       error_handler=self.error)
+        self.pending_transfers += 1
+
+    def pull_all(self, func):
+        req = Transfer(func)
+        self.pbap.PullAll("",
+                          reply_handler=lambda p: self.register(p, req),
+                          error_handler=self.error)
+        self.pending_transfers += 1
+
+    def flush_transfers(self, func):
+        if (len(self.transfer_dict) == 0) and (self.pending_transfers == 0):
+            return
+        self.flush_func = func
+
+    def interface(self):
+        return self.pbap
+
+if  __name__ == '__main__':
+
+    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+    bus = dbus.SessionBus()
+    mainloop = gobject.MainLoop()
+
+    client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
+                            "org.openobex.Client")
+
+    if (len(sys.argv) < 2):
+	print "Usage: %s <device>" % (sys.argv[0])
+	sys.exit(1)
+
+    print "Creating Session"
+    session_path = client.CreateSession("", sys.argv[1], "pbap", dict())
+
+    pbap_client = PbapClient(session_path)
+
+    def process_result(lines, header):
+        print header,
+        for line in lines:
+            print line,
+        print
+
+    def test_paths(paths):
+        if len(paths) == 0:
+            print
+            print "FINISHED"
+            mainloop.quit()
+            return
+
+        path = paths[0]
+
+        print "\n--- Select Phonebook %s ---\n" % (path)
+        pbap_client.interface().Select("int", path)
+
+        print "\n--- GetSize ---\n"
+        ret = pbap_client.interface().GetSize()
+        print "Size = %d\n" % (ret)
+
+        print "\n--- List vCard ---\n"
+        ret = pbap_client.interface().List()
+        for item in ret:
+                print "%s : %s" % (item[0], item[1])
+                pbap_client.interface().SetFormat("vcard30")
+                pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
+                pbap_client.pull(item[0], lambda x: process_result(x, ""))
+
+        pbap_client.interface().SetFormat("vcard30")
+        pbap_client.interface().SetFilter(["VERSION", "FN", "TEL"]);
+        pbap_client.pull_all(lambda x: process_result(x, "\n--- PullAll ---\n"))
+
+        pbap_client.flush_transfers(lambda: test_paths(paths[1:]))
+
+    test_paths(["PB", "ICH", "OCH", "MCH", "CCH"])
 
-bus = dbus.SessionBus()
-
-client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
-						"org.openobex.Client")
-
-print "Creating Session"
-session_path = client.CreateSession("", sys.argv[1], "PBAP", dict())
-pbap = dbus.Interface(bus.get_object("org.openobex.client", session_path),
-						"org.openobex.PhonebookAccess")
-session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
-							"org.openobex.Session")
-
-paths = ["PB", "ICH", "OCH", "MCH", "CCH"]
-
-for path in paths:
-	print "\n--- Select Phonebook %s ---\n" % (path)
-	pbap.Select("int", path)
-
-	print "\n--- GetSize ---\n"
-	ret = pbap.GetSize()
-	print "Size = %d\n" % (ret)
-
-	print "\n--- List vCard ---\n"
-	ret = pbap.List()
-	for item in ret:
-		print "%s : %s" % (item[0], item[1])
-		pbap.SetFormat("vcard30")
-		pbap.SetFilter(["VERSION", "FN", "TEL"]);
-		ret = pbap.Pull(item[0])
-		print "%s" % (ret)
-
-	print "\n--- PullAll ---\n"
-	pbap.SetFormat("vcard30")
-	pbap.SetFilter(["VERSION", "FN", "TEL"]);
-	ret = pbap.PullAll()
-	print "%s" % (ret)
+    mainloop.run()
-- 
1.7.6.4

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux