* [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml
@ 2012-07-03 18:28 Luiz Augusto von Dentz
2012-07-03 18:28 ` [PATCH obexd 02/10] test: Update map-client to the changes in GetFolderListing Luiz Augusto von Dentz
` (9 more replies)
0 siblings, 10 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This parses the response and return as a list of dictionary where each
entry is a folder and its properties, similar to what
FileTransfer.ListFolder does.
---
client/map.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 2 deletions(-)
diff --git a/client/map.c b/client/map.c
index 5242cb3..4475ad5 100644
--- a/client/map.c
+++ b/client/map.c
@@ -29,6 +29,7 @@
#include <glib.h>
#include <gdbus.h>
+#include "dbus.h"
#include "log.h"
#include "map.h"
@@ -132,6 +133,88 @@ done:
dbus_message_unref(map->msg);
}
+static void folder_element(GMarkupParseContext *ctxt, const gchar *element,
+ const gchar **names, const gchar **values,
+ gpointer user_data, GError **gerr)
+{
+ DBusMessageIter dict, *iter = user_data;
+ const gchar *key;
+ gint i;
+
+ if (strcasecmp("folder", element) != 0)
+ return;
+
+ 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);
+
+ for (i = 0, key = names[i]; key; key = names[++i]) {
+ if (strcasecmp("name", key) == 0)
+ obex_dbus_dict_append(&dict, "Name", DBUS_TYPE_STRING,
+ &values[i]);
+ }
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static const GMarkupParser folder_parser = {
+ folder_element,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void folder_listing_cb(struct obc_session *session,
+ struct obc_transfer *transfer,
+ GError *err, void *user_data)
+{
+ struct map_data *map = user_data;
+ GMarkupParseContext *ctxt;
+ DBusMessage *reply;
+ DBusMessageIter iter, array;
+ char *contents;
+ size_t size;
+ int perr;
+
+ if (err != NULL) {
+ reply = g_dbus_create_error(map->msg,
+ ERROR_INTERFACE ".Failed",
+ "%s", err->message);
+ goto done;
+ }
+
+ perr = obc_transfer_get_contents(transfer, &contents, &size);
+ if (perr < 0) {
+ reply = g_dbus_create_error(map->msg,
+ ERROR_INTERFACE ".Failed",
+ "Error reading contents: %s",
+ strerror(-perr));
+ goto done;
+ }
+
+ reply = dbus_message_new_method_return(map->msg);
+ if (reply == NULL)
+ return;
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+ ctxt = g_markup_parse_context_new(&folder_parser, 0, &array, NULL);
+ g_markup_parse_context_parse(ctxt, contents, size, NULL);
+ g_markup_parse_context_free(ctxt);
+ dbus_message_iter_close_container(&iter, &array);
+ g_free(contents);
+
+done:
+ g_dbus_send_message(conn, reply);
+ dbus_message_unref(map->msg);
+}
+
static DBusMessage *map_get_folder_listing(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -144,7 +227,8 @@ static DBusMessage *map_get_folder_listing(DBusConnection *connection,
if (transfer == NULL)
goto fail;
- if (obc_session_queue(map->session, transfer, buffer_cb, map, &err)) {
+ if (obc_session_queue(map->session, transfer, folder_listing_cb, map,
+ &err)) {
map->msg = dbus_message_ref(message);
return NULL;
}
@@ -196,7 +280,7 @@ static const GDBusMethodTable map_methods[] = {
map_setpath) },
{ GDBUS_ASYNC_METHOD("GetFolderListing",
GDBUS_ARGS({ "dummy", "a{ss}" }),
- GDBUS_ARGS({ "content", "s" }),
+ GDBUS_ARGS({ "content", "aa{sv}" }),
map_get_folder_listing) },
{ GDBUS_ASYNC_METHOD("GetMessageListing",
GDBUS_ARGS({ "folder", "s" }, { "dummy", "a{ss}" }),
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH obexd 02/10] test: Update map-client to the changes in GetFolderListing 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 03/10] client-doc: Add documentation of MessageAccess.GetFolderListing Luiz Augusto von Dentz ` (8 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This makes map-client to print only the name of the folders similar to what ftp-client does. --- test/map-client | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/map-client b/test/map-client index bf843f3..da357a9 100755 --- a/test/map-client +++ b/test/map-client @@ -50,7 +50,8 @@ if __name__ == '__main__': set_folder(map, options.new_dir) if options.ls_dir: - print map.GetFolderListing(dict()) + for i in map.GetFolderListing(dict()): + print "%s/" % (i["Name"]) if options.ls_msg is not None: print map.GetMessageListing(options.ls_msg, dict()) -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 03/10] client-doc: Add documentation of MessageAccess.GetFolderListing 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 02/10] test: Update map-client to the changes in GetFolderListing Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 04/10] client: Change MessageAccess.GetMessageListing to not return raw xml Luiz Augusto von Dentz ` (7 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- doc/client-api.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/client-api.txt b/doc/client-api.txt index 58a824d..5a960e1 100644 --- a/doc/client-api.txt +++ b/doc/client-api.txt @@ -352,6 +352,15 @@ Methods void SetFolder(string name) Set working directory for current session, *name* may be the directory name or '..[/dir]'. + array{dict} GetFolderListing(dict filter) + + Returns a dictionary containing information about + the current folder content. + + The following keys are defined: + + string Name : Folder name + Transfer hierarchy ================== -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 04/10] client: Change MessageAccess.GetMessageListing to not return raw xml 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 02/10] test: Update map-client to the changes in GetFolderListing Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 03/10] client-doc: Add documentation of MessageAccess.GetFolderListing Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 05/10] test: Update map-client to the changes in GetMessageListing Luiz Augusto von Dentz ` (6 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This parses the response and return as a list of dictionary where each entry is a message and its properties, --- client/map.c | 406 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 369 insertions(+), 37 deletions(-) diff --git a/client/map.c b/client/map.c index 4475ad5..2c52095 100644 --- a/client/map.c +++ b/client/map.c @@ -42,12 +42,41 @@ #define OBEX_MAS_UUID_LEN 16 #define MAP_INTERFACE "org.bluez.obex.MessageAccess" +#define MAP_MSG_INTERFACE "org.bluez.obex.Message" #define ERROR_INTERFACE "org.bluez.obex.Error" #define MAS_UUID "00001132-0000-1000-8000-00805f9b34fb" struct map_data { struct obc_session *session; DBusMessage *msg; + GHashTable *messages; +}; + +#define MAP_MSG_FLAG_PRIORITY 0x01 +#define MAP_MSG_FLAG_READ 0x02 +#define MAP_MSG_FLAG_SENT 0x04 +#define MAP_MSG_FLAG_PROTECTED 0x08 + +struct map_msg { + struct map_data *data; + char *path; + char *handle; + char *subject; + char *timestamp; + char *sender; + char *sender_address; + char *replyto; + char *recipient; + char *recipient_address; + char *type; + uint64_t size; + char *status; + uint8_t flags; +}; + +struct map_parser { + struct map_data *data; + DBusMessageIter *iter; }; static DBusConnection *conn = NULL; @@ -98,41 +127,6 @@ static DBusMessage *map_setpath(DBusConnection *connection, return NULL; } -static void buffer_cb(struct obc_session *session, - struct obc_transfer *transfer, - GError *err, void *user_data) -{ - struct map_data *map = user_data; - DBusMessage *reply; - char *contents; - size_t size; - int perr; - - if (err != NULL) { - reply = g_dbus_create_error(map->msg, - ERROR_INTERFACE ".Failed", - "%s", err->message); - goto done; - } - - perr = obc_transfer_get_contents(transfer, &contents, &size); - if (perr < 0) { - reply = g_dbus_create_error(map->msg, - ERROR_INTERFACE ".Failed", - "Error reading contents: %s", - strerror(-perr)); - goto done; - } - - reply = g_dbus_create_reply(map->msg, DBUS_TYPE_STRING, &contents, - DBUS_TYPE_INVALID); - - g_free(contents); -done: - g_dbus_send_message(conn, reply); - dbus_message_unref(map->msg); -} - static void folder_element(GMarkupParseContext *ctxt, const gchar *element, const gchar **names, const gchar **values, gpointer user_data, GError **gerr) @@ -240,6 +234,329 @@ fail: return reply; } +static void map_msg_free(void *data) +{ + struct map_msg *msg = data; + + g_free(msg->path); + g_free(msg->subject); + g_free(msg->handle); + g_free(msg->timestamp); + g_free(msg->sender); + g_free(msg->sender_address); + g_free(msg->replyto); + g_free(msg->recipient); + g_free(msg->recipient_address); + g_free(msg->type); + g_free(msg->status); + g_free(msg); +} + +static const GDBusMethodTable map_msg_methods[] = { + { } +}; + +static struct map_msg *map_msg_create(struct map_data *data, const char *handle) +{ + struct map_msg *msg; + + msg = g_new0(struct map_msg, 1); + msg->data = data; + msg->path = g_strdup_printf("%s/message%s", + obc_session_get_path(data->session), + handle); + + if (!g_dbus_register_interface(conn, msg->path, MAP_MSG_INTERFACE, + map_msg_methods, NULL, NULL, + msg, map_msg_free)) { + map_msg_free(msg); + return NULL; + } + + msg->handle = g_strdup(handle); + g_hash_table_insert(data->messages, msg->handle, msg); + + return msg; +} + +static void parse_subject(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->subject); + msg->subject = g_strdup(value); + obex_dbus_dict_append(iter, "Subject", DBUS_TYPE_STRING, &value); +} + +static void parse_datetime(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->timestamp); + msg->timestamp = g_strdup(value); + obex_dbus_dict_append(iter, "Timestamp", DBUS_TYPE_STRING, &value); +} + +static void parse_sender(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->sender); + msg->sender = g_strdup(value); + obex_dbus_dict_append(iter, "Sender", DBUS_TYPE_STRING, &value); +} + +static void parse_sender_address(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->sender_address); + msg->sender_address = g_strdup(value); + obex_dbus_dict_append(iter, "SenderAddress", DBUS_TYPE_STRING, + &value); +} + +static void parse_replyto(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->replyto); + msg->replyto = g_strdup(value); + obex_dbus_dict_append(iter, "ReplyTo", DBUS_TYPE_STRING, &value); +} + +static void parse_recipient(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->recipient); + msg->recipient = g_strdup(value); + obex_dbus_dict_append(iter, "Recipient", DBUS_TYPE_STRING, &value); +} + +static void parse_recipient_address(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->recipient_address); + msg->recipient_address = g_strdup(value); + obex_dbus_dict_append(iter, "RecipientAddress", DBUS_TYPE_STRING, + &value); +} + +static void parse_type(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->type); + msg->type = g_strdup(value); + obex_dbus_dict_append(iter, "Type", DBUS_TYPE_STRING, &value); +} + +static void parse_status(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + g_free(msg->status); + msg->status = g_strdup(value); + obex_dbus_dict_append(iter, "Status", DBUS_TYPE_STRING, &value); +} + +static void parse_size(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + msg->size = g_ascii_strtoll(value, NULL, 10); + obex_dbus_dict_append(iter, "Size", DBUS_TYPE_UINT64, &msg->size); +} + +static void parse_priority(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + gboolean flag = strcasecmp(value, "no"); + + if (flag) + msg->flags |= MAP_MSG_FLAG_PRIORITY; + else + msg->flags &= ~MAP_MSG_FLAG_PRIORITY; + + obex_dbus_dict_append(iter, "Priority", DBUS_TYPE_BOOLEAN, &flag); +} + +static void parse_read(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + gboolean flag = strcasecmp(value, "no"); + + if (flag) + msg->flags |= MAP_MSG_FLAG_READ; + else + msg->flags &= ~MAP_MSG_FLAG_READ; + + obex_dbus_dict_append(iter, "Read", DBUS_TYPE_BOOLEAN, &flag); +} + +static void parse_sent(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + gboolean flag = strcasecmp(value, "no"); + + if (flag) + msg->flags |= MAP_MSG_FLAG_SENT; + else + msg->flags &= ~MAP_MSG_FLAG_SENT; + + obex_dbus_dict_append(iter, "Sent", DBUS_TYPE_BOOLEAN, &flag); +} + +static void parse_protected(struct map_msg *msg, const char *value, + DBusMessageIter *iter) +{ + gboolean flag = strcasecmp(value, "no"); + + if (flag) + msg->flags |= MAP_MSG_FLAG_PROTECTED; + else + msg->flags &= ~MAP_MSG_FLAG_PROTECTED; + + obex_dbus_dict_append(iter, "Protected", DBUS_TYPE_BOOLEAN, &flag); +} + +static struct map_msg_parser { + const char *name; + void (*func) (struct map_msg *msg, const char *value, + DBusMessageIter *iter); +} msg_parsers[] = { + { "subject", parse_subject }, + { "datetime", parse_datetime }, + { "sender_name", parse_sender }, + { "sender_addressing", parse_sender_address }, + { "replyto_addressing", parse_replyto }, + { "recipient_name", parse_recipient }, + { "recipient_addressing", parse_recipient_address }, + { "type", parse_type }, + { "reception_status", parse_status }, + { "size", parse_size }, + { "priority", parse_priority }, + { "read", parse_read }, + { "sent", parse_sent }, + { "protected", parse_protected }, + { } +}; + +static void msg_element(GMarkupParseContext *ctxt, const gchar *element, + const gchar **names, const gchar **values, + gpointer user_data, GError **gerr) +{ + struct map_parser *parser = user_data; + struct map_data *data = parser->data; + DBusMessageIter entry, dict, *iter = parser->iter; + struct map_msg *msg; + const gchar *key; + gint i; + + if (strcasecmp("msg", element) != 0) + return; + + for (i = 0, key = names[i]; key; key = names[++i]) { + if (strcasecmp(key, "handle") == 0) + break; + } + + msg = g_hash_table_lookup(data->messages, key); + if (msg == NULL) { + msg = map_msg_create(data, values[i]); + if (msg == NULL) + return; + } + + dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, + &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH, + &msg->path); + + dbus_message_iter_open_container(&entry, 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); + + for (i = 0, key = names[i]; key; key = names[++i]) { + struct map_msg_parser *parser; + + for (parser = msg_parsers; parser && parser->name; parser++) { + if (strcasecmp(key, parser->name) == 0) { + parser->func(msg, values[i], &dict); + break; + } + } + } + + dbus_message_iter_close_container(&entry, &dict); + dbus_message_iter_close_container(iter, &entry); +} + +static const GMarkupParser msg_parser = { + msg_element, + NULL, + NULL, + NULL, + NULL +}; + +static void message_listing_cb(struct obc_session *session, + struct obc_transfer *transfer, + GError *err, void *user_data) +{ + struct map_data *map = user_data; + struct map_parser *parser; + GMarkupParseContext *ctxt; + DBusMessage *reply; + DBusMessageIter iter, array; + char *contents; + size_t size; + int perr; + + if (err != NULL) { + reply = g_dbus_create_error(map->msg, + ERROR_INTERFACE ".Failed", + "%s", err->message); + goto done; + } + + perr = obc_transfer_get_contents(transfer, &contents, &size); + if (perr < 0) { + reply = g_dbus_create_error(map->msg, + ERROR_INTERFACE ".Failed", + "Error reading contents: %s", + strerror(-perr)); + goto done; + } + + reply = dbus_message_new_method_return(map->msg); + if (reply == NULL) + return; + + 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_OBJECT_PATH_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &array); + + parser = g_new(struct map_parser, 1); + parser->data = map; + parser->iter = &array; + + ctxt = g_markup_parse_context_new(&msg_parser, 0, parser, NULL); + g_markup_parse_context_parse(ctxt, contents, size, NULL); + g_markup_parse_context_free(ctxt); + dbus_message_iter_close_container(&iter, &array); + g_free(contents); + g_free(parser); + +done: + g_dbus_send_message(conn, reply); + dbus_message_unref(map->msg); +} + static DBusMessage *map_get_message_listing(DBusConnection *connection, DBusMessage *message, void *user_data) { @@ -262,7 +579,8 @@ static DBusMessage *map_get_message_listing(DBusConnection *connection, if (transfer == NULL) goto fail; - if (obc_session_queue(map->session, transfer, buffer_cb, map, &err)) { + if (obc_session_queue(map->session, transfer, message_listing_cb, map, + &err)) { map->msg = dbus_message_ref(message); return NULL; } @@ -284,16 +602,28 @@ static const GDBusMethodTable map_methods[] = { map_get_folder_listing) }, { GDBUS_ASYNC_METHOD("GetMessageListing", GDBUS_ARGS({ "folder", "s" }, { "dummy", "a{ss}" }), - GDBUS_ARGS({ "messages", "s" }), + GDBUS_ARGS({ "messages", "a{oa{sv}}" }), map_get_message_listing) }, { } }; +static void map_msg_remove(void *data) +{ + struct map_msg *msg = data; + char *path; + + path = msg->path; + msg->path = NULL; + g_dbus_unregister_interface(conn, path, MAP_MSG_INTERFACE); + g_free(path); +} + static void map_free(void *data) { struct map_data *map = data; obc_session_unref(map->session); + g_hash_table_unref(map->messages); g_free(map); } @@ -311,6 +641,8 @@ static int map_probe(struct obc_session *session) return -ENOMEM; map->session = obc_session_ref(session); + map->messages = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + map_msg_remove); if (!g_dbus_register_interface(conn, path, MAP_INTERFACE, map_methods, NULL, NULL, map, map_free)) { -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 05/10] test: Update map-client to the changes in GetMessageListing 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (2 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 04/10] client: Change MessageAccess.GetMessageListing to not return raw xml Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 06/10] client-doc: Add documentation of MessageAccess.GetMessageListing Luiz Augusto von Dentz ` (5 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This makes map-client to print the object path and properties of each message found. --- test/map-client | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/map-client b/test/map-client index da357a9..be3c307 100755 --- a/test/map-client +++ b/test/map-client @@ -6,6 +6,27 @@ import dbus import dbus.mainloop.glib from optparse import OptionParser +from pprint import pformat + +def unwrap(x): + """Hack to unwrap D-Bus values, so that they're easier to read when + printed. Taken from d-feet """ + + if isinstance(x, list): + return map(unwrap, x) + + if isinstance(x, tuple): + return tuple(map(unwrap, x)) + + if isinstance(x, dict): + return dict([(unwrap(k), unwrap(v)) for k, v in x.iteritems()]) + + for t in [unicode, str, long, int, float, bool]: + if isinstance(x, t): + return t(x) + + return x + def parse_options(): parser.add_option("-d", "--device", dest="device", help="Device to connect", metavar="DEVICE") @@ -54,6 +75,7 @@ if __name__ == '__main__': print "%s/" % (i["Name"]) if options.ls_msg is not None: - print map.GetMessageListing(options.ls_msg, dict()) + ret = map.GetMessageListing(options.ls_msg, dict()) + print pformat(unwrap(ret)) mainloop.run() -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 06/10] client-doc: Add documentation of MessageAccess.GetMessageListing 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (3 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 05/10] test: Update map-client to the changes in GetMessageListing Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 07/10] client: Use filter instead of dummy as argument name in MAP Luiz Augusto von Dentz ` (4 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- doc/client-api.txt | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/doc/client-api.txt b/doc/client-api.txt index 5a960e1..6f7d13f 100644 --- a/doc/client-api.txt +++ b/doc/client-api.txt @@ -361,6 +361,82 @@ Methods void SetFolder(string name) string Name : Folder name + array{object, dict} GetMessageListing(string folder, dict filter) + + Returns an array containing the messages found in the + given folder. + + Each message is represented by an object path followed + by a dictionary of the properties. + + Properties: + + string Handle: + + Message handle + + string Subject: + + Message subject + + string Timestamp: + + Message timestamp + + string Sender: + + Message sender name + + string SenderAddress: + + Message sender address + + string ReplyTo: + + Message Reply-To address + + string Recipient: + + Message recipient name + + string RecipientAddress: + + Message recipient address + + string Type: + + Message type + + Possible values: "EMAIL", "SMS_GSM", + "SMS_CDMA" and "MMS" + + uint64 Size: + + Message size in bytes + + string Status: + + Message reception status + + Possible values: "complete", + "fractioned" and "notification" + + boolean Priority: + + Message priority flag + + boolean Read: + + Message read flag + + boolean Sent: + + Message sent flag + + boolean Protected: + + Message protected flag + Transfer hierarchy ================== -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 07/10] client: Use filter instead of dummy as argument name in MAP 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (4 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 06/10] client-doc: Add documentation of MessageAccess.GetMessageListing Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 08/10] client-doc: Add documentation of org.bluez.obex.Message Luiz Augusto von Dentz ` (3 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This is aligned with the documentation that uses filter as well. --- client/map.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/map.c b/client/map.c index 2c52095..4137dbe 100644 --- a/client/map.c +++ b/client/map.c @@ -597,11 +597,11 @@ static const GDBusMethodTable map_methods[] = { GDBUS_ARGS({ "name", "s" }), NULL, map_setpath) }, { GDBUS_ASYNC_METHOD("GetFolderListing", - GDBUS_ARGS({ "dummy", "a{ss}" }), + GDBUS_ARGS({ "filter", "a{ss}" }), GDBUS_ARGS({ "content", "aa{sv}" }), map_get_folder_listing) }, { GDBUS_ASYNC_METHOD("GetMessageListing", - GDBUS_ARGS({ "folder", "s" }, { "dummy", "a{ss}" }), + GDBUS_ARGS({ "folder", "s" }, { "filter", "a{ss}" }), GDBUS_ARGS({ "messages", "a{oa{sv}}" }), map_get_message_listing) }, { } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 08/10] client-doc: Add documentation of org.bluez.obex.Message 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (5 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 07/10] client: Use filter instead of dummy as argument name in MAP Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 09/10] client: Add Message.Get implementation Luiz Augusto von Dentz ` (2 subsequent siblings) 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> org.bluez.obex.Message have Get method which can be used to download the contents of message represented by the object. --- doc/client-api.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/client-api.txt b/doc/client-api.txt index 6f7d13f..1938a38 100644 --- a/doc/client-api.txt +++ b/doc/client-api.txt @@ -437,6 +437,27 @@ Methods void SetFolder(string name) Message protected flag +Message hierarchy +================= + +Service org.bluez.obex.client +Interface org.bluez.obex.Message +Object path [variable prefix]/{session0,session1,...}/{message0,...} + +Methods object, dict Get(string targetfile) + + Download message and store it in the target file. + + If an empty target file is given, a temporary file + will be automatically generated. + + 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. + Transfer hierarchy ================== -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 09/10] client: Add Message.Get implementation 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (6 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 08/10] client-doc: Add documentation of org.bluez.obex.Message Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 10/10] test: Add support for Message.Get to map-client Luiz Augusto von Dentz 2012-07-18 12:14 ` [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Johan Hedberg 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> --- client/map.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/client/map.c b/client/map.c index 4137dbe..e606cb2 100644 --- a/client/map.c +++ b/client/map.c @@ -252,7 +252,44 @@ static void map_msg_free(void *data) g_free(msg); } +static DBusMessage *map_msg_get(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct map_msg *msg = 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_INTERFACE ".InvalidArguments", NULL); + + transfer = obc_transfer_get("x-bt/message", msg->handle, target_file, + &err); + if (transfer == NULL) + goto fail; + + if (!obc_session_queue(msg->data->session, transfer, NULL, NULL, &err)) + goto fail; + + return obc_transfer_create_dbus_reply(transfer, message); + +fail: + reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s", + err->message); + g_error_free(err); + return reply; +} + static const GDBusMethodTable map_msg_methods[] = { + { GDBUS_METHOD("Get", + GDBUS_ARGS({ "targetfile", "s" }), + GDBUS_ARGS({ "transfer", "o" }, + { "properties", "a{sv}" }), + map_msg_get) }, { } }; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH obexd 10/10] test: Add support for Message.Get to map-client 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (7 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 09/10] client: Add Message.Get implementation Luiz Augusto von Dentz @ 2012-07-03 18:28 ` Luiz Augusto von Dentz 2012-07-18 12:14 ` [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Johan Hedberg 9 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-07-03 18:28 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This adds -g/--get <handle> option to map-client so it downloads and prints the contents of the message. In addition add MapClient class to handle transfer signals similar to what other scripts do. --- test/map-client | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/test/map-client b/test/map-client index be3c307..ac1a8ca 100755 --- a/test/map-client +++ b/test/map-client @@ -2,6 +2,8 @@ import gobject +import sys +import os import dbus import dbus.mainloop.glib from optparse import OptionParser @@ -37,12 +39,87 @@ def parse_options(): parser.add_option("-v", "--verbose", action="store_true", dest="verbose") parser.add_option("-L", "--lsmsg", action="store", dest="ls_msg", help="List messages in supplied CWD subdir") + parser.add_option("-g", "--get", action="store", dest="get_msg", + help="Get message contents") return parser.parse_args() def set_folder(session, new_dir): session.SetFolder(new_dir) +class MapClient: + def __init__(self, session_path, verbose=False): + self.progress = 0 + self.transfer_path = None + self.props = dict() + self.verbose = verbose + self.path = session_path + bus = dbus.SessionBus() + obj = bus.get_object("org.bluez.obex.client", session_path) + self.session = dbus.Interface(obj, "org.bluez.obex.Session") + self.map = dbus.Interface(obj, "org.bluez.obex.MessageAccess") + bus.add_signal_receiver(self.transfer_complete, + dbus_interface="org.bluez.obex.Transfer", + signal_name="Complete", + path_keyword="path") + bus.add_signal_receiver(self.transfer_error, + dbus_interface="org.bluez.obex.Transfer", + signal_name="Error", + path_keyword="path") + + def create_transfer_reply(self, reply): + (path, properties) = reply + self.transfer_path = path + self.props[path] = properties + if self.verbose: + print "Transfer created: %s (file %s)" % (path, + properties["Filename"]) + + 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" + properties = self.props.get(path) + if properties == None: + return + f = open(properties["Filename"], "r") + os.remove(properties["Filename"]) + print f.readlines() + + 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 set_folder(self, new_dir): + self.map.SetFolder(new_dir) + + def list_folders(self): + for i in self.map.GetFolderListing(dict()): + print "%s/" % (i["Name"]) + + def list_messages(self, folder): + ret = self.map.GetMessageListing(folder, dict()) + print pformat(unwrap(ret)) + + def get_message(self, handle): + self.map.GetMessageListing("", dict()) + path = self.path + "/message" + handle + obj = bus.get_object("org.bluez.obex.client", path) + msg = dbus.Interface(obj, "org.bluez.obex.Message") + msg.Get("",reply_handler=self.create_transfer_reply, + error_handler=self.error) + if __name__ == '__main__': dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) @@ -61,21 +138,21 @@ if __name__ == '__main__': client = dbus.Interface(bus.get_object("org.bluez.obex.client", "/"), "org.bluez.obex.Client") + print "Creating Session" path = client.CreateSession(options.device, { "Target": "map" }) - obj = bus.get_object("org.bluez.obex.client", path) - session = dbus.Interface(obj, "org.bluez.obex.Session") - map = dbus.Interface(obj, "org.bluez.obex.MessageAccess") + map_client = MapClient(path, options.verbose) if options.new_dir: - set_folder(map, options.new_dir) + map_client.set_folder(options.new_dir) if options.ls_dir: - for i in map.GetFolderListing(dict()): - print "%s/" % (i["Name"]) + map_client.list_folders() if options.ls_msg is not None: - ret = map.GetMessageListing(options.ls_msg, dict()) - print pformat(unwrap(ret)) + map_client.list_messages(options.ls_msg) + + if options.get_msg is not None: + map_client.get_message(options.get_msg) mainloop.run() -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz ` (8 preceding siblings ...) 2012-07-03 18:28 ` [PATCH obexd 10/10] test: Add support for Message.Get to map-client Luiz Augusto von Dentz @ 2012-07-18 12:14 ` Johan Hedberg 9 siblings, 0 replies; 12+ messages in thread From: Johan Hedberg @ 2012-07-18 12:14 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hi Luiz, On Tue, Jul 03, 2012, Luiz Augusto von Dentz wrote: > This parses the response and return as a list of dictionary where each > entry is a folder and its properties, similar to what > FileTransfer.ListFolder does. > --- > client/map.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 86 insertions(+), 2 deletions(-) This set has been pushed upstream. Thanks. Johan ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml @ 2012-06-27 12:04 Luiz Augusto von Dentz 0 siblings, 0 replies; 12+ messages in thread From: Luiz Augusto von Dentz @ 2012-06-27 12:04 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This parses the response and return as a list of dictionary where each entry is a folder and its properties, similar to what FileTransfer.ListFolder does. --- client/map.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/client/map.c b/client/map.c index 5242cb3..e3a6c6c 100644 --- a/client/map.c +++ b/client/map.c @@ -29,6 +29,7 @@ #include <glib.h> #include <gdbus.h> +#include "dbus.h" #include "log.h" #include "map.h" @@ -132,6 +133,91 @@ done: dbus_message_unref(map->msg); } +static void folder_element(GMarkupParseContext *ctxt, const gchar *element, + const gchar **names, const gchar **values, + gpointer user_data, GError **gerr) +{ + DBusMessageIter dict, *iter = user_data; + gchar *key; + gint i; + + if (strcasecmp("folder", element) != 0) + return; + + 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); + + i = 0; + for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) { + key[0] = g_ascii_toupper(key[0]); + + if (!g_str_equal("Name", key)) + continue; + + obex_dbus_dict_append(&dict, key, DBUS_TYPE_STRING, + &values[i]); + } + + dbus_message_iter_close_container(iter, &dict); +} + +static const GMarkupParser folder_parser = { + folder_element, + NULL, + NULL, + NULL, + NULL +}; + +static void folder_listing_cb(struct obc_session *session, + struct obc_transfer *transfer, + GError *err, void *user_data) +{ + struct map_data *map = user_data; + GMarkupParseContext *ctxt; + DBusMessage *reply; + DBusMessageIter iter, array; + char *contents; + size_t size; + int perr; + + if (err != NULL) { + reply = g_dbus_create_error(map->msg, + ERROR_INTERFACE ".Failed", + "%s", err->message); + goto done; + } + + perr = obc_transfer_get_contents(transfer, &contents, &size); + if (perr < 0) { + reply = g_dbus_create_error(map->msg, + ERROR_INTERFACE ".Failed", + "Error reading contents: %s", + strerror(-perr)); + goto done; + } + + reply = dbus_message_new_method_return(map->msg); + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array); + ctxt = g_markup_parse_context_new(&folder_parser, 0, &array, NULL); + g_markup_parse_context_parse(ctxt, contents, size, NULL); + g_markup_parse_context_free(ctxt); + dbus_message_iter_close_container(&iter, &array); + g_free(contents); + +done: + g_dbus_send_message(conn, reply); + dbus_message_unref(map->msg); +} + static DBusMessage *map_get_folder_listing(DBusConnection *connection, DBusMessage *message, void *user_data) { @@ -144,7 +230,8 @@ static DBusMessage *map_get_folder_listing(DBusConnection *connection, if (transfer == NULL) goto fail; - if (obc_session_queue(map->session, transfer, buffer_cb, map, &err)) { + if (obc_session_queue(map->session, transfer, folder_listing_cb, map, + &err)) { map->msg = dbus_message_ref(message); return NULL; } @@ -196,7 +283,7 @@ static const GDBusMethodTable map_methods[] = { map_setpath) }, { GDBUS_ASYNC_METHOD("GetFolderListing", GDBUS_ARGS({ "dummy", "a{ss}" }), - GDBUS_ARGS({ "content", "s" }), + GDBUS_ARGS({ "content", "aa{sv}" }), map_get_folder_listing) }, { GDBUS_ASYNC_METHOD("GetMessageListing", GDBUS_ARGS({ "folder", "s" }, { "dummy", "a{ss}" }), -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2012-07-18 12:14 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-07-03 18:28 [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 02/10] test: Update map-client to the changes in GetFolderListing Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 03/10] client-doc: Add documentation of MessageAccess.GetFolderListing Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 04/10] client: Change MessageAccess.GetMessageListing to not return raw xml Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 05/10] test: Update map-client to the changes in GetMessageListing Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 06/10] client-doc: Add documentation of MessageAccess.GetMessageListing Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 07/10] client: Use filter instead of dummy as argument name in MAP Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 08/10] client-doc: Add documentation of org.bluez.obex.Message Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 09/10] client: Add Message.Get implementation Luiz Augusto von Dentz 2012-07-03 18:28 ` [PATCH obexd 10/10] test: Add support for Message.Get to map-client Luiz Augusto von Dentz 2012-07-18 12:14 ` [PATCH obexd 01/10] client: Change MessageAccess.GetFolderListing to not return raw xml Johan Hedberg -- strict thread matches above, loose matches on Subject: below -- 2012-06-27 12:04 Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).