2011-12-08 13:07:53

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 1/6] gobex: Add translating error codes to strings

---
gobex/gobex.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gobex/gobex.h | 2 ++
2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/gobex/gobex.c b/gobex/gobex.c
index b374b06..38d6812 100644
--- a/gobex/gobex.c
+++ b/gobex/gobex.c
@@ -114,6 +114,62 @@ struct setpath_data {
guint8 constants;
} __attribute__ ((packed));

+struct error_code {
+ guint8 code;
+ const char *name;
+} obex_errors[] = {
+ { G_OBEX_RSP_CONTINUE, "Continue" },
+ { G_OBEX_RSP_SUCCESS, "Success" },
+ { G_OBEX_RSP_CREATED, "Created" },
+ { G_OBEX_RSP_ACCEPTED, "Accepted" },
+ { G_OBEX_RSP_NON_AUTHORITATIVE, "Non Authoritative" },
+ { G_OBEX_RSP_NO_CONTENT, "No Content" },
+ { G_OBEX_RSP_RESET_CONTENT, "Reset Content" },
+ { G_OBEX_RSP_PARTIAL_CONTENT, "Partial Content" },
+ { G_OBEX_RSP_MULTIPLE_CHOICES, "Multiple Choices" },
+ { G_OBEX_RSP_MOVED_PERMANENTLY, "Moved Permanently" },
+ { G_OBEX_RSP_MOVED_TEMPORARILY, "Moved Temporarily" },
+ { G_OBEX_RSP_SEE_OTHER, "See Other" },
+ { G_OBEX_RSP_NOT_MODIFIED, "Not Modified" },
+ { G_OBEX_RSP_USE_PROXY, "Use Proxy" },
+ { G_OBEX_RSP_BAD_REQUEST, "Bad Request" },
+ { G_OBEX_RSP_UNAUTHORIZED, "Unauthorized" },
+ { G_OBEX_RSP_PAYMENT_REQUIRED, "Payment Required" },
+ { G_OBEX_RSP_FORBIDDEN, "Forbidden" },
+ { G_OBEX_RSP_NOT_FOUND, "Not Found" },
+ { G_OBEX_RSP_METHOD_NOT_ALLOWED, "Method Not Allowed" },
+ { G_OBEX_RSP_NOT_ACCEPTABLE, "Not Acceptable" },
+ { G_OBEX_RSP_PROXY_AUTH_REQUIRED, "Proxy Authentication Required" },
+ { G_OBEX_RSP_REQUEST_TIME_OUT, "Request Time Out" },
+ { G_OBEX_RSP_CONFLICT, "Conflict" },
+ { G_OBEX_RSP_GONE, "Gone" },
+ { G_OBEX_RSP_LENGTH_REQUIRED, "Length Required" },
+ { G_OBEX_RSP_PRECONDITION_FAILED, "Precondition Failed" },
+ { G_OBEX_RSP_REQ_ENTITY_TOO_LARGE, "Request Entity Too Large" },
+ { G_OBEX_RSP_REQ_URL_TOO_LARGE, "Request URL Too Large" },
+ { G_OBEX_RSP_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type" },
+ { G_OBEX_RSP_INTERNAL_SERVER_ERROR, "Internal Server Error" },
+ { G_OBEX_RSP_NOT_IMPLEMENTED, "Not Implemented" },
+ { G_OBEX_RSP_BAD_GATEWAY, "Bad Gateway" },
+ { G_OBEX_RSP_SERVICE_UNAVAILABLE, "Service Unavailable" },
+ { G_OBEX_RSP_GATEWAY_TIMEOUT, "Gateway Timeout" },
+ { G_OBEX_RSP_VERSION_NOT_SUPPORTED, "Version Not Supported" },
+ { G_OBEX_RSP_DATABASE_FULL, "Database Full" },
+ { G_OBEX_RSP_DATABASE_LOCKED, "Database Locked" },
+ { 0x00, NULL }
+};
+
+const char *g_obex_strerror(guint8 err_code)
+{
+ struct error_code *error;
+
+ for (error = obex_errors; error->name != NULL; error++)
+ if (error->code == err_code)
+ return error->name;
+
+ return "<unknown>";
+}
+
static ssize_t req_header_offset(guint8 opcode)
{
switch (opcode) {
diff --git a/gobex/gobex.h b/gobex/gobex.h
index 1b20333..81981ea 100644
--- a/gobex/gobex.h
+++ b/gobex/gobex.h
@@ -119,4 +119,6 @@ guint g_obex_get_rsp(GObex *obex, GObexDataProducer data_func,

gboolean g_obex_cancel_transfer(guint id);

+const char *g_obex_strerror(guint8 err_code);
+
#endif /* __GOBEX_H */
--
1.7.4.1



2011-12-09 13:58:08

by Bartosz Szatkowski

[permalink] [raw]
Subject: Re: [PATCH obexd 3/6] Add support for SetFolder in MAP client

On Fri, Dec 9, 2011 at 2:22 PM, Johan Hedberg <[email protected]> wrote:
> Hi Bartosz,
>
> On Thu, Dec 08, 2011, Bartosz Szatkowski wrote:
>> ---
>>  client/map.c       |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  doc/client-api.txt |    5 +++-
>>  2 files changed, 60 insertions(+), 1 deletions(-)
>
> The first two patches have been applied, but this had issues:
>
>> +#define ERROR_INF MAP_INTERFACE ".Error"
>> +#define ERROR_FAILED_PATH "org.openobex.Error.Failed"
>
> First of all, this is not a path or an interface. It's the error name.
> Secondly, do you really need these defines since in some places you
> spell out the name inline in others you use a define. E.g. here it's
> inline:
>
>> +     else if (err_code != G_OBEX_RSP_SUCCESS)
>> +             reply = g_dbus_create_error(map->msg,
>> +                                             "org.openobex.Error.Response",
>> +                                             "%s (0x%02x)",
>> +                                             g_obex_strerror(err_code),
>> +                                             err_code);
>
> So please be consistent. Also think about whether we need MAP specific
> errors at all or if we can just use generic ones for the entire client
> (and maybe server too).

Ok, so for keeping things consistent with most common style in client
code, I'll go with inlined "org.openobex.Error.*"

--
Pozdrowienia - Cheers,
Bartosz Szatkowski

2011-12-09 13:22:06

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH obexd 3/6] Add support for SetFolder in MAP client

Hi Bartosz,

On Thu, Dec 08, 2011, Bartosz Szatkowski wrote:
> ---
> client/map.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> doc/client-api.txt | 5 +++-
> 2 files changed, 60 insertions(+), 1 deletions(-)

The first two patches have been applied, but this had issues:

> +#define ERROR_INF MAP_INTERFACE ".Error"
> +#define ERROR_FAILED_PATH "org.openobex.Error.Failed"

First of all, this is not a path or an interface. It's the error name.
Secondly, do you really need these defines since in some places you
spell out the name inline in others you use a define. E.g. here it's
inline:

> + else if (err_code != G_OBEX_RSP_SUCCESS)
> + reply = g_dbus_create_error(map->msg,
> + "org.openobex.Error.Response",
> + "%s (0x%02x)",
> + g_obex_strerror(err_code),
> + err_code);

So please be consistent. Also think about whether we need MAP specific
errors at all or if we can just use generic ones for the entire client
(and maybe server too).

Johan

2011-12-08 13:07:58

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 6/6] Add support for PullMessagesListing in MAP client

Just basic functionality for now, returning whole listing as a string
(no parsing) and no apparams handling.
---
client/map.c | 31 +++++++++++++++++++++++++++++++
test/map-client | 5 +++++
2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/client/map.c b/client/map.c
index 397c170..0ce2a14 100644
--- a/client/map.c
+++ b/client/map.c
@@ -144,6 +144,35 @@ static DBusMessage *map_get_folder_listing(DBusConnection *connection,
NULL, NULL, NULL, 0,
buffer_cb, map);
if (err < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Failed");
+
+ map->msg = dbus_message_ref(message);
+
+ return NULL;
+}
+
+static DBusMessage *map_get_messages_listing(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct map_data *map = user_data;
+ int err;
+ const char *folder;
+ DBusMessageIter msg_iter;
+
+ dbus_message_iter_init(message, &msg_iter);
+
+ if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRING)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ dbus_message_iter_get_basic(&msg_iter, &folder);
+
+ err = obc_session_get(map->session, "x-bt/MAP-msg-listing", folder,
+ NULL, NULL, 0,
+ buffer_cb, map);
+ if (err < 0)
return g_dbus_create_error(message, ERROR_FAILED_PATH,
"Failed");

@@ -157,6 +186,8 @@ static GDBusMethodTable map_methods[] = {
G_DBUS_METHOD_FLAG_ASYNC },
{ "GetFolderListing", "a{ss}", "s", map_get_folder_listing,
G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetMessagesListing", "sa{ss}", "s", map_get_messages_listing,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ }
};

diff --git a/test/map-client b/test/map-client
index bcd2e66..1a4afdb 100755
--- a/test/map-client
+++ b/test/map-client
@@ -14,6 +14,8 @@ def parse_options():
parser.add_option("-l", "--lsdir", action="store_true", dest="ls_dir",
help="List folders in current directory")
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")

return parser.parse_args()

@@ -54,4 +56,7 @@ if __name__ == '__main__':
if options.ls_dir:
print map.GetFolderListing(dict())

+ if options.ls_msg is not None:
+ print map.GetMessagesListing(options.ls_msg, dict())
+
mainloop.run()
--
1.7.4.1


2011-12-08 13:07:57

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 5/6] Add basic support for MAP folder listing

For now just basic functionality - returning whole listing as a string
(no parsing for now) and no apparams handling.
---
client/map.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
test/map-client | 5 +++++
2 files changed, 57 insertions(+), 1 deletions(-)

diff --git a/client/map.c b/client/map.c
index bc45a13..397c170 100644
--- a/client/map.c
+++ b/client/map.c
@@ -104,8 +104,59 @@ static DBusMessage *map_setpath(DBusConnection *connection,
return NULL;
}

+static void buffer_cb(struct obc_session *session, GError *err,
+ void *user_data)
+{
+ struct obc_transfer *transfer = obc_session_get_transfer(session);
+ struct map_data *map = user_data;
+ DBusMessage *reply;
+ const char *buf;
+ int size;
+
+ if (err != NULL) {
+ reply = g_dbus_create_error(map->msg, ERROR_FAILED_PATH, "%s",
+ err->message);
+ goto done;
+ }
+
+ buf = obc_transfer_get_buffer(transfer, &size);
+ if (size == 0)
+ buf = "";
+
+ reply = g_dbus_create_reply(map->msg, DBUS_TYPE_STRING, &buf,
+ DBUS_TYPE_INVALID);
+
+ obc_transfer_clear_buffer(transfer);
+
+done:
+ g_dbus_send_message(conn, reply);
+ dbus_message_unref(map->msg);
+ obc_transfer_unregister(transfer);
+}
+
+static DBusMessage *map_get_folder_listing(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct map_data *map = user_data;
+ int err;
+
+ err = obc_session_get(map->session, "x-obex/folder-listing",
+ NULL, NULL, NULL, 0,
+ buffer_cb, map);
+ if (err < 0)
+ return g_dbus_create_error(message, ERROR_FAILED_PATH,
+ "Failed");
+
+ map->msg = dbus_message_ref(message);
+
+ return NULL;
+}
+
static GDBusMethodTable map_methods[] = {
- { "SetFolder", "s", "", map_setpath, G_DBUS_METHOD_FLAG_ASYNC },
+ { "SetFolder", "s", "", map_setpath,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetFolderListing", "a{ss}", "s", map_get_folder_listing,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ }
};

diff --git a/test/map-client b/test/map-client
index 5ee4331..bcd2e66 100755
--- a/test/map-client
+++ b/test/map-client
@@ -11,6 +11,8 @@ def parse_options():
help="Device to connect", metavar="DEVICE")
parser.add_option("-c", "--chdir", dest="new_dir",
help="Change current directory to DIR", metavar="DIR")
+ parser.add_option("-l", "--lsdir", action="store_true", dest="ls_dir",
+ help="List folders in current directory")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose")

return parser.parse_args()
@@ -49,4 +51,7 @@ if __name__ == '__main__':
if options.new_dir:
set_folder(map, options.new_dir)

+ if options.ls_dir:
+ print map.GetFolderListing(dict())
+
mainloop.run()
--
1.7.4.1


2011-12-08 13:07:56

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 4/6] Add simple helper for MAP client

---
Makefile.am | 3 ++-
test/map-client | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 1 deletions(-)
create mode 100755 test/map-client

diff --git a/Makefile.am b/Makefile.am
index c371f8a..f65a3dc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,8 @@ doc_files = doc/obexd-api.txt doc/agent-api.txt doc/client-api.txt

test_files = test/simple-agent test/send-files \
test/pull-business-card test/exchange-business-cards \
- test/list-folders test/pbap-client test/ftp-client
+ test/list-folders test/pbap-client test/ftp-client \
+ test/map-client

gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \
gdbus/object.c gdbus/polkit.c
diff --git a/test/map-client b/test/map-client
new file mode 100755
index 0000000..5ee4331
--- /dev/null
+++ b/test/map-client
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+import gobject
+
+import dbus
+import dbus.mainloop.glib
+from optparse import OptionParser
+
+def parse_options():
+ parser.add_option("-d", "--device", dest="device",
+ help="Device to connect", metavar="DEVICE")
+ parser.add_option("-c", "--chdir", dest="new_dir",
+ help="Change current directory to DIR", metavar="DIR")
+ parser.add_option("-v", "--verbose", action="store_true", dest="verbose")
+
+ return parser.parse_args()
+
+def set_folder(session, new_dir):
+ for node in new_dir.split("/"):
+ session.SetFolder(node)
+
+if __name__ == '__main__':
+
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ parser = OptionParser()
+
+ (options, args) = parse_options()
+
+ if not options.device:
+ parser.print_help()
+ exit(0)
+
+ bus = dbus.SessionBus()
+ mainloop = gobject.MainLoop()
+
+ client = dbus.Interface(bus.get_object("org.openobex.client", "/"),
+ "org.openobex.Client")
+
+ session_path = client.CreateSession({ "Destination": options.device,
+ "Target": "map"})
+
+ session = dbus.Interface(bus.get_object("org.openobex.client", session_path),
+ "org.openobex.Session")
+
+ map = dbus.Interface(bus.get_object("org.openobex.client", session_path),
+ "org.openobex.MessageAccess")
+
+ if options.new_dir:
+ set_folder(map, options.new_dir)
+
+ mainloop.run()
--
1.7.4.1


2011-12-08 13:07:54

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 2/6] Add basic support for MAP client in obex-client

---
Makefile.am | 1 +
client/manager.c | 2 +
client/map.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
client/map.h | 24 +++++++++
doc/client-api.txt | 9 ++++
5 files changed, 171 insertions(+), 0 deletions(-)
create mode 100644 client/map.c
create mode 100644 client/map.h

diff --git a/Makefile.am b/Makefile.am
index bdb961f..c371f8a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,6 +120,7 @@ client_obex_client_SOURCES = $(gdbus_sources) $(gobex_sources) \
client/pbap.h client/pbap.c \
client/ftp.h client/ftp.c \
client/opp.h client/opp.c \
+ client/map.h client/map.c \
client/transfer.h client/transfer.c \
client/agent.h client/agent.c \
client/driver.h client/driver.c \
diff --git a/client/manager.c b/client/manager.c
index dfb282b..f6628d7 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -42,6 +42,7 @@
#include "ftp.h"
#include "pbap.h"
#include "sync.h"
+#include "map.h"

#define CLIENT_SERVICE "org.openobex.client"

@@ -567,6 +568,7 @@ static struct target_module {
{ "ftp", ftp_init, ftp_exit },
{ "pbap", pbap_init, pbap_exit },
{ "sync", sync_init, sync_exit },
+ { "map", map_init, map_exit },
{ }
};

diff --git a/client/map.c b/client/map.c
new file mode 100644
index 0000000..bee49c5
--- /dev/null
+++ b/client/map.c
@@ -0,0 +1,135 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2011 Bartosz Szatkowski <[email protected]> for Comarch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <glib.h>
+#include <gdbus.h>
+
+#include "log.h"
+
+#include "map.h"
+#include "transfer.h"
+#include "session.h"
+#include "driver.h"
+
+#define OBEX_MAS_UUID \
+ "\xBB\x58\x2B\x40\x42\x0C\x11\xDB\xB0\xDE\x08\x00\x20\x0C\x9A\x66"
+#define OBEX_MAS_UUID_LEN 16
+
+#define MAP_INTERFACE "org.openobex.MessageAccess"
+#define MAS_UUID "00001132-0000-1000-8000-00805f9b34fb"
+
+struct map_data {
+ struct obc_session *session;
+ DBusMessage *msg;
+};
+
+static DBusConnection *conn = NULL;
+
+static GDBusMethodTable map_methods[] = {
+ { }
+};
+
+static void map_free(void *data)
+{
+ struct map_data *map = data;
+
+ obc_session_unref(map->session);
+ g_free(map);
+}
+
+static int map_probe(struct obc_session *session)
+{
+ struct map_data *map;
+ const char *path;
+
+ path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ map = g_try_new0(struct map_data, 1);
+ if (!map)
+ return -ENOMEM;
+
+ map->session = obc_session_ref(session);
+
+ if (!g_dbus_register_interface(conn, path, MAP_INTERFACE, map_methods,
+ NULL, NULL, map, map_free)) {
+ map_free(map);
+
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void map_remove(struct obc_session *session)
+{
+ const char *path = obc_session_get_path(session);
+
+ DBG("%s", path);
+
+ g_dbus_unregister_interface(conn, path, MAP_INTERFACE);
+}
+
+static struct obc_driver map = {
+ .service = "MAP",
+ .uuid = MAS_UUID,
+ .target = OBEX_MAS_UUID,
+ .target_len = OBEX_MAS_UUID_LEN,
+ .probe = map_probe,
+ .remove = map_remove
+};
+
+int map_init(void)
+{
+ int err;
+
+ DBG("");
+
+ conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!conn)
+ return -EIO;
+
+ err = obc_driver_register(&map);
+ if (err < 0) {
+ dbus_connection_unref(conn);
+ conn = NULL;
+ return err;
+ }
+
+ return 0;
+}
+
+void map_exit(void)
+{
+ DBG("");
+
+ dbus_connection_unref(conn);
+ conn = NULL;
+
+ obc_driver_unregister(&map);
+}
diff --git a/client/map.h b/client/map.h
new file mode 100644
index 0000000..86f6b95
--- /dev/null
+++ b/client/map.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * OBEX Client
+ *
+ * Copyright (C) 2011 Bartosz Szatkowski <[email protected]> for Comarch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int map_init(void);
+void map_exit(void);
diff --git a/doc/client-api.txt b/doc/client-api.txt
index 3e61cf7..ee8951f 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -251,6 +251,15 @@ Methods void SetLocation(string location)

Send an entire Phonebook Object store to remote device

+Message Access hierarchy
+=========================
+
+Service org.openobex.client
+Interface org.openobex.MessageAccess
+Object path [variable prefix]/{session0,session1,...}
+
+Methods
+
Transfer hierarchy
==================

--
1.7.4.1


2011-12-08 13:07:55

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH obexd 3/6] Add support for SetFolder in MAP client

---
client/map.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++
doc/client-api.txt | 5 +++-
2 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/client/map.c b/client/map.c
index bee49c5..bc45a13 100644
--- a/client/map.c
+++ b/client/map.c
@@ -40,6 +40,9 @@
#define OBEX_MAS_UUID_LEN 16

#define MAP_INTERFACE "org.openobex.MessageAccess"
+#define ERROR_INF MAP_INTERFACE ".Error"
+#define ERROR_FAILED_PATH "org.openobex.Error.Failed"
+
#define MAS_UUID "00001132-0000-1000-8000-00805f9b34fb"

struct map_data {
@@ -49,7 +52,60 @@ struct map_data {

static DBusConnection *conn = NULL;

+static void simple_cb(GObex *obex, GError *err, GObexPacket *rsp,
+ gpointer user_data)
+{
+ DBusMessage *reply;
+ struct map_data *map = user_data;
+ guint8 err_code = g_obex_packet_get_operation(rsp, NULL);
+
+ if (err != NULL)
+ reply = g_dbus_create_error(map->msg, ERROR_FAILED_PATH,
+ "%s", err->message);
+ else if (err_code != G_OBEX_RSP_SUCCESS)
+ reply = g_dbus_create_error(map->msg,
+ "org.openobex.Error.Response",
+ "%s (0x%02x)",
+ g_obex_strerror(err_code),
+ err_code);
+ else
+ reply = dbus_message_new_method_return(map->msg);
+
+ g_dbus_send_message(conn, reply);
+ dbus_message_unref(map->msg);
+}
+
+static DBusMessage *map_setpath(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct map_data *map = user_data;
+ const char *folder;
+ GObex *obex;
+ GError *err = NULL;
+
+ if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &folder,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ ERROR_INF ".InvalidArguments", NULL);
+
+ obex = obc_session_get_obex(map->session);
+
+ g_obex_setpath(obex, folder, simple_cb, map, &err);
+ if (err != NULL) {
+ DBusMessage *reply;
+ reply = g_dbus_create_error(message, ERROR_FAILED_PATH,
+ "%s", err->message);
+ g_error_free(err);
+ return reply;
+ }
+
+ map->msg = dbus_message_ref(message);
+
+ return NULL;
+}
+
static GDBusMethodTable map_methods[] = {
+ { "SetFolder", "s", "", map_setpath, G_DBUS_METHOD_FLAG_ASYNC },
{ }
};

diff --git a/doc/client-api.txt b/doc/client-api.txt
index ee8951f..fb5a8b2 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -258,7 +258,10 @@ Service org.openobex.client
Interface org.openobex.MessageAccess
Object path [variable prefix]/{session0,session1,...}

-Methods
+Methods void SetFolder(string name)
+
+ Set working directory for current session, *name* may
+ be the directory name or '..[/dir]'.

Transfer hierarchy
==================
--
1.7.4.1


2011-12-08 11:07:10

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH obexd 1/6] gobex: Add translating error codes to strings

Hi Bartosz,

On Mon, Dec 05, 2011, Bartosz Szatkowski wrote:
> +struct error_code {
> + guint8 code;
> + const char *name;
> +} obex_errors[] = {
> + { G_OBEX_RSP_CONTINUE, "Continue" },
> + { G_OBEX_RSP_SUCCESS, "Success" },
> + { G_OBEX_RSP_CREATED, "Created" },
> + { G_OBEX_RSP_ACCEPTED, "Accepted" },
> + { G_OBEX_RSP_NON_AUTHORITATIVE, "Non Authoritative" },
> + { G_OBEX_RSP_NO_CONTENT, "No Content" },
> + { G_OBEX_RSP_RESET_CONTENT, "Reset Content" },
> + { G_OBEX_RSP_PARTIAL_CONTENT, "Partial Content" },
> + { G_OBEX_RSP_MULTIPLE_CHOICES, "Multiple Choices" },
> + { G_OBEX_RSP_MOVED_PERMANENTLY, "Moved Permanently" },
> + { G_OBEX_RSP_MOVED_TEMPORARILY, "Moved Temporarily" },
> + { G_OBEX_RSP_SEE_OTHER, "See Other" },
> + { G_OBEX_RSP_NOT_MODIFIED, "Not Modified" },
> + { G_OBEX_RSP_USE_PROXY, "Use Proxy" },
> + { G_OBEX_RSP_BAD_REQUEST, "Bad Request" },
> + { G_OBEX_RSP_UNAUTHORIZED, "Unauthorized" },
> + { G_OBEX_RSP_PAYMENT_REQUIRED, "Payment Required" },
> + { G_OBEX_RSP_FORBIDDEN, "Forbidden" },
> + { G_OBEX_RSP_NOT_FOUND, "Not Found" },
> + { G_OBEX_RSP_METHOD_NOT_ALLOWED, "Method Not Allowed" },
> + { G_OBEX_RSP_NOT_ACCEPTABLE, "Not Acceptable" },
> + { G_OBEX_RSP_PROXY_AUTH_REQUIRED, "Proxy Auth Required" },
> + { G_OBEX_RSP_REQUEST_TIME_OUT, "Request Time Out" },
> + { G_OBEX_RSP_CONFLICT, "Conflict" },
> + { G_OBEX_RSP_GONE, "Gone" },
> + { G_OBEX_RSP_LENGTH_REQUIRED, "Length Required" },
> + { G_OBEX_RSP_PRECONDITION_FAILED, "Precondition Failed" },
> + { G_OBEX_RSP_REQ_ENTITY_TOO_LARGE, "Req Entity Too Large" },
> + { G_OBEX_RSP_REQ_URL_TOO_LARGE, "Req Url Too Large" },
> + { G_OBEX_RSP_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type" },
> + { G_OBEX_RSP_INTERNAL_SERVER_ERROR, "Internal Server Error" },
> + { G_OBEX_RSP_NOT_IMPLEMENTED, "Not Implemented" },
> + { G_OBEX_RSP_BAD_GATEWAY, "Bad Gateway" },
> + { G_OBEX_RSP_SERVICE_UNAVAILABLE, "Service Unavailable" },
> + { G_OBEX_RSP_GATEWAY_TIMEOUT, "Gateway Timeout" },
> + { G_OBEX_RSP_VERSION_NOT_SUPPORTED, "Version Not Supported" },
> + { G_OBEX_RSP_DATABASE_FULL, "Database Full" },
> + { G_OBEX_RSP_DATABASE_LOCKED, "Database Locked" },
> + { }
> +};

Could you indent the strings (with tabs) so that they all start at the
same column? That'd make it easier to read the table.

> +const char *g_obex_strerror(guint8 err_code)
> +{
> + struct error_code *error;
> +
> + for (error = obex_errors; error != NULL; error++)
> + if (error->code == err_code)
> + return error->name;
> +
> + return "<unknown>";
> +}

I guess you never tested this function with a code that's not in the
table? The loop will go past the end in such a case. You're assigning a
pointer to the table in the beginning and then just incrementing the
pointer. What makes you think that the pointer would magically become
NULL suddenly? What would work is if you make the last entry
{ 0x00, NULL }, and then check for error->name != NULL in the for-loop.

Johan