linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing
@ 2012-03-06 17:42 Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 2/5] MAP/dummy: Add basic logic for " Slawomir Bochenski
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Slawomir Bochenski @ 2012-03-06 17:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski

---
 plugins/messages-dummy.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index 511857e..3ba333c 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -36,8 +36,23 @@ static char *root_folder = NULL;
 struct session {
 	char *cwd;
 	char *cwd_absolute;
+	void *request;
 };
 
+struct folder_listing_data {
+	struct session *session;
+	const char *name;
+	uint16_t max;
+	uint16_t offset;
+	messages_folder_listing_cb callback;
+	void *user_data;
+};
+
+static gboolean get_folder_listing(void *d)
+{
+	return FALSE;
+}
+
 int messages_init(void)
 {
 	char *tmp;
@@ -142,12 +157,28 @@ int messages_set_folder(void *s, const char *name, gboolean cdup)
 	return 0;
 }
 
-int messages_get_folder_listing(void *session, const char *name, uint16_t max,
+int messages_get_folder_listing(void *s, const char *name, uint16_t max,
 					uint16_t offset,
 					messages_folder_listing_cb callback,
 					void *user_data)
 {
-	return -ENOSYS;
+	struct session *session =  s;
+	struct folder_listing_data *fld;
+
+	fld = g_new0(struct folder_listing_data, 1);
+	fld->session = session;
+	fld->name = name;
+	fld->max = max;
+	fld->offset = offset;
+	fld->callback = callback;
+	fld->user_data = user_data;
+
+	session->request = fld;
+
+	g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, get_folder_listing,
+								fld, g_free);
+
+	return 0;
 }
 
 int messages_get_messages_listing(void *session, const char *name,
@@ -173,6 +204,12 @@ int messages_update_inbox(void *session, messages_update_inbox_cb callback,
 	return -ENOSYS;
 }
 
-void messages_abort(void *session)
+void messages_abort(void *s)
 {
+	struct session *session = s;
+
+	if (session->request) {
+		g_idle_remove_by_data(session->request);
+		session->request = NULL;
+	}
 }
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 2/5] MAP/dummy: Add basic logic for folder listing
  2012-03-06 17:42 [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing Slawomir Bochenski
@ 2012-03-06 17:42 ` Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval Slawomir Bochenski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Slawomir Bochenski @ 2012-03-06 17:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski

---
 plugins/messages-dummy.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index 3ba333c..db15a75 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -25,6 +25,8 @@
 #include <config.h>
 #endif
 
+#include <sys/types.h>
+#include <dirent.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
@@ -48,8 +50,39 @@ struct folder_listing_data {
 	void *user_data;
 };
 
+static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
+{
+	return 0;
+}
+
+static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
+{
+	struct session *session = fld->session;
+
+	fld->callback(session, 0, 0, NULL, fld->user_data);
+}
+
 static gboolean get_folder_listing(void *d)
 {
+	struct folder_listing_data *fld = d;
+	ssize_t n;
+	GSList *list = NULL;
+
+	n = get_subdirs(fld, &list);
+
+	if (n < 0) {
+		fld->callback(fld->session, n, 0, NULL, fld->user_data);
+		return FALSE;
+	}
+
+	if (fld->max == 0) {
+		fld->callback(fld->session, 0, n, NULL, fld->user_data);
+		return FALSE;
+	}
+
+	return_folder_listing(fld, list);
+	g_slist_free_full(list, g_free);
+
 	return FALSE;
 }
 
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval
  2012-03-06 17:42 [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 2/5] MAP/dummy: Add basic logic for " Slawomir Bochenski
@ 2012-03-06 17:42 ` Slawomir Bochenski
  2012-03-08 23:36   ` Johan Hedberg
  2012-03-06 17:42 ` [PATCH obexd 4/5] MAP/dummy: Code for returning folder listing Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 5/5] MAP/dummy: Add sorting of " Slawomir Bochenski
  3 siblings, 1 reply; 6+ messages in thread
From: Slawomir Bochenski @ 2012-03-06 17:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski

---
 plugins/messages-dummy.c |   61 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index db15a75..daa7ae4 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -31,6 +31,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "log.h"
+
 #include "messages.h"
 
 static char *root_folder = NULL;
@@ -50,9 +52,66 @@ struct folder_listing_data {
 	void *user_data;
 };
 
+static char *get_next_subdir(DIR *dp, char *path)
+{
+	struct dirent *ep;
+	char *abs, *name;
+
+	for (;;) {
+		if ((ep = readdir(dp)) == NULL)
+			return NULL;
+
+		if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+			continue;
+
+		abs = g_build_filename(path, ep->d_name, NULL);
+
+		if (g_file_test(abs, G_FILE_TEST_IS_DIR)) {
+			g_free(abs);
+			break;
+		}
+
+		g_free(abs);
+	}
+
+	name = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL);
+
+	if (name == NULL) {
+		DBG("g_filename_to_utf8(): invalid filename");
+		return NULL;
+	}
+
+	return name;
+}
+
 static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
 {
-	return 0;
+	DIR *dp;
+	char *path, *name;
+	size_t n = 0;
+
+	path = g_build_filename(fld->session->cwd_absolute, fld->name, NULL);
+	dp = opendir(path);
+
+	if (dp == NULL) {
+		int err = errno;
+
+		DBG("opendir(): %d, %s", err, strerror(err));
+		g_free(path);
+
+		return -err;
+	}
+
+	while ((name = get_next_subdir(dp, path)) != NULL) {
+		++n;
+		if (fld->max != 0)
+			*list = g_slist_prepend(*list, name);
+	}
+
+	closedir(dp);
+	g_free(path);
+
+	return n;
 }
 
 static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 4/5] MAP/dummy: Code for returning folder listing
  2012-03-06 17:42 [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 2/5] MAP/dummy: Add basic logic for " Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval Slawomir Bochenski
@ 2012-03-06 17:42 ` Slawomir Bochenski
  2012-03-06 17:42 ` [PATCH obexd 5/5] MAP/dummy: Add sorting of " Slawomir Bochenski
  3 siblings, 0 replies; 6+ messages in thread
From: Slawomir Bochenski @ 2012-03-06 17:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski

---
 plugins/messages-dummy.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index daa7ae4..b98bedc 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -117,6 +117,28 @@ static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
 static void return_folder_listing(struct folder_listing_data *fld, GSList *list)
 {
 	struct session *session = fld->session;
+	GSList *cur;
+	uint16_t n = 0;
+	uint16_t o = 0;
+
+	/* XXX: This isn't really documented for MAP. I need to take a look how
+	 * other implementations choose to deal with parent folder.
+	 */
+	if (session->cwd[0] != 0 && fld->offset == 0) {
+		++n;
+		fld->callback(session, -EAGAIN, 0, "..", fld->user_data);
+	} else {
+		++o;
+	}
+
+	for (cur = list; o < fld->offset; ++o) {
+		cur = cur->next;
+		if (cur == NULL)
+			break;
+	}
+
+	for (; cur != NULL && n < fld->max; cur = cur->next, ++n)
+		fld->callback(session, -EAGAIN, 0, cur->data, fld->user_data);
 
 	fld->callback(session, 0, 0, NULL, fld->user_data);
 }
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 5/5] MAP/dummy: Add sorting of folder listing
  2012-03-06 17:42 [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing Slawomir Bochenski
                   ` (2 preceding siblings ...)
  2012-03-06 17:42 ` [PATCH obexd 4/5] MAP/dummy: Code for returning folder listing Slawomir Bochenski
@ 2012-03-06 17:42 ` Slawomir Bochenski
  3 siblings, 0 replies; 6+ messages in thread
From: Slawomir Bochenski @ 2012-03-06 17:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski

---
 plugins/messages-dummy.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
index b98bedc..2a4cdbc 100644
--- a/plugins/messages-dummy.c
+++ b/plugins/messages-dummy.c
@@ -52,6 +52,36 @@ struct folder_listing_data {
 	void *user_data;
 };
 
+/* NOTE: Neither IrOBEX nor MAP specs says that folder listing needs to
+ * be sorted (in IrOBEX examples it is not). However existing implementations
+ * seem to follow the fig. 3-2 from MAP specification v1.0, and I've seen a
+ * test suite requiring folder listing to be in that order.
+ */
+static gint folder_names_cmp(gconstpointer a, gconstpointer b,
+						gpointer user_data)
+{
+	static const char *order[] = {
+		"inbox", "outbox", "sent", "deleted", "draft", NULL
+	};
+	struct session *session = user_data;
+	int ia, ib;
+
+	if (g_strcmp0(session->cwd, "telecom/msg") == 0) {
+		for (ia = 0; order[ia]; ++ia) {
+			if (g_strcmp0(a, order[ia]) == 0)
+				break;
+		}
+		for (ib = 0; order[ib]; ++ib) {
+			if (g_strcmp0(b, order[ib]) == 0)
+				break;
+		}
+		if (ia != ib)
+			return ia - ib;
+	}
+
+	return g_strcmp0(a, b);
+}
+
 static char *get_next_subdir(DIR *dp, char *path)
 {
 	struct dirent *ep;
@@ -111,6 +141,8 @@ static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
 	closedir(dp);
 	g_free(path);
 
+	*list = g_slist_sort_with_data(*list, folder_names_cmp, fld->session);
+
 	return n;
 }
 
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval
  2012-03-06 17:42 ` [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval Slawomir Bochenski
@ 2012-03-08 23:36   ` Johan Hedberg
  0 siblings, 0 replies; 6+ messages in thread
From: Johan Hedberg @ 2012-03-08 23:36 UTC (permalink / raw)
  To: Slawomir Bochenski; +Cc: linux-bluetooth

Hi Slawek,

On Tue, Mar 06, 2012, Slawomir Bochenski wrote:
> ---
>  plugins/messages-dummy.c |   61 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 60 insertions(+), 1 deletions(-)

I've applied the first two in this set, but this one had some minor
stylistic issues:

>  static ssize_t get_subdirs(struct folder_listing_data *fld, GSList **list)
>  {
> -	return 0;
> +	DIR *dp;
> +	char *path, *name;
> +	size_t n = 0;

Please leave this initialization later in the function.

> +	path = g_build_filename(fld->session->cwd_absolute, fld->name, NULL);
> +	dp = opendir(path);
> +
> +	if (dp == NULL) {
> +		int err = errno;

For consistency, variables called "err" should have a negative value to
indicate error or 0 to indicate no error. So this should be:

	err = -errno;

> +	while ((name = get_next_subdir(dp, path)) != NULL) {
> +		++n;

When it doesn't really matter whether you use post- or pre-increment
just use post-increment since I think that's the most widely used one in
the code base.

> +		if (fld->max != 0)

I'd prefer to have the test as > 0

Johan

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-03-08 23:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-06 17:42 [PATCH obexd 1/5] MAP/dummy: Add stub for asynchronous folder listing Slawomir Bochenski
2012-03-06 17:42 ` [PATCH obexd 2/5] MAP/dummy: Add basic logic for " Slawomir Bochenski
2012-03-06 17:42 ` [PATCH obexd 3/5] MAP/dummy: Actual code for folder listing retrieval Slawomir Bochenski
2012-03-08 23:36   ` Johan Hedberg
2012-03-06 17:42 ` [PATCH obexd 4/5] MAP/dummy: Code for returning folder listing Slawomir Bochenski
2012-03-06 17:42 ` [PATCH obexd 5/5] MAP/dummy: Add sorting of " Slawomir Bochenski

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).