From 01cd007c0e4417181c0a9608a1e4fcd1a1270ebc Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 12 Apr 2010 11:09:50 -0300 Subject: [PATCH] obexd: Implement contacts cache for dummy back-end Initial support for contacts cache. It doesn't implement all required features. Values(name and tel) are hard-coded since it is necessary to use a library to parse the vcards content. --- obexd/plugins/pbap.c | 11 ++-- obexd/plugins/phonebook-dummy.c | 94 +++++++++++++++++++++++++++++---- obexd/plugins/phonebook-ebook.c | 3 +- obexd/plugins/phonebook.h | 6 ++- 4 files changed, 99 insertions(+), 15 deletions(-) diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c index 3381f4bf4..fc7753834 100644 --- a/obexd/plugins/pbap.c +++ b/obexd/plugins/pbap.c @@ -251,14 +251,19 @@ static void query_result(const gchar *buffer, size_t bufsize, gint vcards, obex_object_set_io_flags(pbap, G_IO_IN, 0); } -static void cache_entry_notify(const gchar *id, const gchar *name, - const gchar *sound, const gchar *tel, gpointer user_data) +static void cache_entry_notify(const gchar *id, guint32 handle, + const gchar *name, const gchar *sound, + const gchar *tel, gpointer user_data) { struct pbap_session *pbap = user_data; struct cache_entry *entry = g_new0(struct cache_entry, 1); struct cache *cache = &pbap->cache; - entry->handle = ++pbap->cache.index; + if (handle != PHONEBOOK_INVALID_HANDLE) + entry->handle = handle; + else + entry->handle = ++pbap->cache.index; + entry->id = g_strdup(id); entry->name = g_strdup(name); entry->sound = g_strdup(sound); diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c index be37656c1..72bd124a5 100644 --- a/obexd/plugins/phonebook-dummy.c +++ b/obexd/plugins/phonebook-dummy.c @@ -26,7 +26,10 @@ #include #endif +#include #include +#include +#include #include #include #include @@ -53,8 +56,15 @@ struct dummy_data { int fd; }; +struct cache_query { + phonebook_entry_cb entry_cb; + phonebook_cache_ready_cb ready_cb; + void *user_data; + DIR *dp; +}; + static gchar *root_folder = NULL; -static int dirfd = -1; +static int folderfd = -1; static void dummy_free(gpointer user_data) { @@ -66,6 +76,16 @@ static void dummy_free(gpointer user_data) g_free(dummy); } +static void query_free(void *user_data) +{ + struct cache_query *query = user_data; + + if (query->dp) + closedir(query->dp); + + g_free(query); +} + int phonebook_init(void) { /* FIXME: It should NOT be hard-coded */ @@ -78,8 +98,8 @@ void phonebook_exit(void) { g_free(root_folder); - if (dirfd >= 0) - close(dirfd); + if (folderfd >= 0) + close(folderfd); } static gboolean dummy_result(gpointer data) @@ -91,6 +111,40 @@ static gboolean dummy_result(gpointer data) return FALSE; } +static gboolean create_cache(void *user_data) +{ + struct cache_query *query = user_data; + struct dirent *ep; + + while ((ep = readdir(query->dp))) { + char *filename; + uint32_t handle; + + if (ep->d_name[0] == '.') + continue; + + filename = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL); + if (filename == NULL) { + error("g_filename_to_utf8: invalid filename"); + continue; + } + + if (sscanf(filename, "%u.vcf", &handle) != 1) { + g_free(filename); + continue; + } + + query->entry_cb(filename, handle, "FIXME:name", NULL, + "FIXME:tel", query->user_data); + + g_free(filename); + } + + query->ready_cb(query->user_data); + + return FALSE; +} + static gboolean read_entry(gpointer user_data) { struct dummy_data *dummy = user_data; @@ -216,11 +270,11 @@ done: g_free(relative); relative = NULL; } else { - /* Keep the current dirfd open */ - if (dirfd >= 0) - close(dirfd); + /* Keep the current folderfd open */ + if (folderfd >= 0) + close(folderfd); - dirfd = fd; + folderfd = fd; } g_free(absolute); @@ -252,10 +306,10 @@ int phonebook_get_entry(const gchar *id, const struct apparam_field *params, struct dummy_data *dummy; int fd; - if (dirfd < 0) + if (folderfd < 0) return -EBADR; - fd = openat(dirfd, id, 0); + fd = openat(folderfd, id, 0); if (fd < 0) { int err = errno; debug("openat(): %s(%d)", strerror(err), err); @@ -276,5 +330,27 @@ int phonebook_get_entry(const gchar *id, const struct apparam_field *params, int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb, phonebook_cache_ready_cb ready_cb, gpointer user_data) { + struct cache_query *query; + char *foldername; + DIR *dp; + + foldername = g_build_filename(root_folder, name, NULL); + dp = opendir(foldername); + g_free(foldername); + + if (dp == NULL) { + int err = errno; + debug("opendir(): %s(%d)", strerror(err), err); + return -EBADR; + } + + query = g_new0(struct cache_query, 1); + query->entry_cb = entry_cb; + query->ready_cb = ready_cb; + query->user_data = user_data; + query->dp = dp; + + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, create_cache, query, + query_free); return 0; } diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c index 4d299946b..a61ca8311 100644 --- a/obexd/plugins/phonebook-ebook.c +++ b/obexd/plugins/phonebook-ebook.c @@ -258,7 +258,8 @@ static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts, tel = e_vcard_attribute_get_value(attrib); - data->entry_cb(uid, name, NULL, tel, data->user_data); + data->entry_cb(uid, PHONEBOOK_INVALID_HANDLE, name, NULL, + tel, data->user_data); g_free(name); g_free(uid); g_free(tel); diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h index 0f4f2287d..324fc52ef 100644 --- a/obexd/plugins/phonebook.h +++ b/obexd/plugins/phonebook.h @@ -56,8 +56,10 @@ typedef void (*phonebook_cb) (const gchar *buffer, size_t bufsize, * Interface between the PBAP core and backends to * append a new entry in the PBAP folder cache. */ -typedef void (*phonebook_entry_cb) (const gchar *id, const gchar *name, - const gchar *sound, const gchar *tel, gpointer user_data); +#define PHONEBOOK_INVALID_HANDLE 0xffffffff +typedef void (*phonebook_entry_cb) (const char *id, uint32_t handle, + const char *name, const char *sound, + const char *tel, void *user_data); /* * After notify all entries to PBAP core, the backend -- 2.47.3