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