diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c
index f94dd73..168058b 100644
--- a/obexd/plugins/filesystem.c
+++ b/obexd/plugins/filesystem.c
return 0;
}
-ssize_t string_read(gpointer object, void *buf, size_t count, guint8 *hi)
+ssize_t string_read(gpointer object, void *buf, size_t count)
{
GString *string = object;
ssize_t len;
- *hi = OBEX_HDR_BODY;
-
if (string->len == 0)
return 0;
return len;
}
+static ssize_t folder_read(gpointer object, void *buf, size_t count, guint8 *hi)
+{
+ *hi = OBEX_HDR_BODY;
+ return string_read(object, buf, count);
+}
+
static ssize_t capability_read(gpointer object, void *buf, size_t count,
guint8 *hi)
{
struct capability_object *obj = object;
+ *hi = OBEX_HDR_BODY;
+
if (obj->buffer)
- return string_read(obj->buffer, buf, count, hi);
+ return string_read(obj->buffer, buf, count);
if (obj->pid >= 0)
return -EAGAIN;
- *hi = OBEX_HDR_BODY;
return read(obj->output, buf, count);
}
.mimetype = "x-obex/folder-listing",
.open = folder_open,
.close = string_free,
- .read = string_read,
+ .read = folder_read,
};
static struct obex_mime_type_driver pcsuite = {
.mimetype = "x-obex/folder-listing",
.open = pcsuite_open,
.close = string_free,
- .read = string_read,
+ .read = folder_read,
};
static int filesystem_init(void)
diff --git a/obexd/plugins/filesystem.h b/obexd/plugins/filesystem.h
index 1e1b352..636ddb2 100644
--- a/obexd/plugins/filesystem.h
+++ b/obexd/plugins/filesystem.h
*/
int string_free(gpointer object);
-ssize_t string_read(gpointer object, void *buf, size_t count, guint8 *hi);
+ssize_t string_read(gpointer object, void *buf, size_t count);
diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index f7b7b9b..af6ae39 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
#include <config.h>
#endif
+#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#define MCH "telecom/mch.vcf"
#define SIM1_MCH "SIM1/telecom/mch.vcf"
-#define DEFAULT_COUNT 65535
-
-#define APPARAM_HDR_SIZE 2
-
#define PBAP_CHANNEL 15
#define PBAP_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
struct cache {
gboolean ready;
+ gboolean valid;
+ guint32 index;
+ gchar *folder;
GSList *entries;
};
struct cache_entry {
- gchar *handle;
- gpointer id;
+ guint32 handle;
+ gchar *id;
gchar *name;
gchar *sound;
gchar *tel;
struct apparam_field *params;
gchar *folder;
GString *buffer;
- guint16 phonebooksize;
struct cache cache;
};
typedef int (*cache_sort_f) (struct cache_entry *entry, gpointer user_data);
typedef void (*cache_element_f) (struct cache_entry *entry, gpointer user_data);
-static gint entry_handle_cmp(gconstpointer a, gconstpointer b)
-{
- const struct cache_entry *entry = a;
- const char* handle = b;
-
- return strcmp(entry->handle, handle);
-}
-
static void cache_entry_free(struct cache_entry *entry)
{
- g_free(entry->handle);
g_free(entry->id);
g_free(entry->name);
g_free(entry->sound);
g_free(entry->tel);
g_free(entry);
}
-
+#if 0
static void cache_foreach(struct cache *cache, cache_sort_f sort,
cache_element_f elem, gpointer user_data)
{
elem(entry, user_data);
}
}
+#endif
-static gpointer cache_find(struct cache *cache, const gchar *handle)
+static const gchar *cache_find(struct cache *cache, guint32 handle)
{
- struct cache_entry *entry;
GSList *l;
- l = g_slist_find_custom(cache->entries, handle, entry_handle_cmp);
- if (!l)
- return NULL;
-
- entry = l->data;
+ for (l = cache->entries; l; l = l->next) {
+ struct cache_entry *entry = l->data;
- return entry->id;
-}
+ if (entry->handle == handle)
+ return entry->id;
+ }
-static void cache_add(struct cache *cache, struct cache_entry *entry)
-{
- cache->entries = g_slist_append(cache->entries, entry);
+ return NULL;
}
static void cache_clear(struct cache *cache)
{
+ g_free(cache->folder);
g_slist_foreach(cache->entries, (GFunc) cache_entry_free, NULL);
g_slist_free(cache->entries);
cache->entries = NULL;
gint vcards, gint missed, gpointer user_data)
{
struct pbap_session *pbap = user_data;
+ gchar aparam[4];
+ struct aparam_header *hdr = (struct aparam_header *) aparam;
+ guint16 phonebooksize;
+
+ phonebooksize = htons(vcards);
- pbap->phonebooksize = vcards;
+ hdr->tag = PHONEBOOKSIZE_TAG;
+ hdr->len = PHONEBOOKSIZE_LEN;
+ memcpy(hdr->val, &phonebooksize, sizeof(phonebooksize));
+
+ pbap->buffer = g_string_new_len(aparam, sizeof(aparam));
obex_object_set_io_flags(pbap, G_IO_IN, 0);
}
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)
+{
+ 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;
+ entry->id = g_strdup(id);
+ entry->name = g_strdup(name);
+ entry->sound = g_strdup(sound);
+ entry->tel = g_strdup(tel);
+
+ cache->entries = g_slist_append(cache->entries, entry);
+}
+
+static void cache_ready_notify(gpointer user_data)
+{
+ struct pbap_session *pbap = user_data;
+
+ if (pbap->params->maxlistcount == 0) {
+ /* Ignore all other parameter and return PhoneBookSize */
+ gchar aparam[4];
+ struct aparam_header *hdr = (struct aparam_header *) aparam;
+ guint16 size = g_slist_length(pbap->cache.entries);
+
+ hdr->tag = PHONEBOOKSIZE_TAG;
+ hdr->len = PHONEBOOKSIZE_LEN;
+ memcpy(hdr->val, &size, sizeof(size));
+
+ pbap->buffer = g_string_new_len(aparam, sizeof(aparam));
+ } else {
+ GSList *l;
+
+ pbap->buffer = g_string_new(VCARD_LISTING_BEGIN);
+ l = g_slist_nth(pbap->cache.entries,
+ pbap->params->liststartoffset);
+
+ for (; l; l = l->next) {
+ struct cache_entry *entry = l->data;
+
+ /* FIXME: check if the entry matches */
+
+ g_string_append_printf(pbap->buffer,
+ VCARD_LISTING_ELEMENT,
+ entry->handle, entry->name);
+ }
+
+ pbap->buffer = g_string_append(pbap->buffer, VCARD_LISTING_END);
+ }
+
+ if (!pbap->cache.valid) {
+ pbap->cache.valid = TRUE;
+ obex_object_set_io_flags(pbap, G_IO_IN, 0);
+ }
+}
+
static struct apparam_field *parse_aparam(const guint8 *buffer, guint32 hlen)
{
struct apparam_field *param;
if (type == NULL)
return -EBADR;
- if (strcmp(type, PHONEBOOK_TYPE) == 0)
+ rsize = obex_aparam_read(os, obj, &buffer);
+ if (rsize < 0)
+ return -EBADR;
+
+ params = parse_aparam(buffer, rsize);
+ if (params == NULL)
+ return -EBADR;
+
+ if (pbap->params) {
+ g_free(pbap->params->searchval);
+ g_free(pbap->params);
+ }
+
+ pbap->params = params;
+
+ if (strcmp(type, PHONEBOOK_TYPE) == 0) {
/* Always contains the absolute path */
path = g_strdup(name);
- else if (strcmp(type, VCARDLISTING_TYPE) == 0)
+ *stream = (params->maxlistcount == 0 ? FALSE : TRUE);
+ } else if (strcmp(type, VCARDLISTING_TYPE) == 0) {
/* Always relative */
if (!name || strlen(name) == 0)
/* Current folder */
/* Current folder + relative path */
path = g_build_filename(pbap->folder, name, NULL);
- else if (strcmp(type, VCARDENTRY_TYPE) == 0)
- /* Always relative */
- path = g_build_filename(pbap->folder, name, NULL);
- else
- return -EBADR;
-
- rsize = obex_aparam_read(os, obj, &buffer);
- if (rsize < 0) {
- ret = -EBADR;
- goto failed;
- }
-
- params = parse_aparam(buffer, rsize);
- if (params == NULL) {
- ret = -EBADR;
- goto failed;
- }
-
- if (pbap->params) {
- g_free(pbap->params->searchval);
- g_free(pbap->params);
- }
-
- if (params->maxlistcount == 0)
- *stream = FALSE;
- else
+ *stream = (params->maxlistcount == 0 ? FALSE : TRUE);
+ } else if (strcmp(type, VCARDENTRY_TYPE) == 0) {
+ /* File name only */
+ path = g_strdup(name);
*stream = TRUE;
+ } else
+ return -EBADR;
pbap->params = params;
-
ret = obex_get_stream_start(os, path, pbap);
-failed:
+
g_free(path);
return ret;
}
-
static int pbap_setpath(struct obex_session *os, obex_object_t *obj,
- gpointer user_data)
+ gpointer user_data)
{
struct pbap_session *pbap = user_data;
const gchar *name;
set_folder(pbap, fullname);
+ /*
+ * FIXME: Define a criteria to mark the cache as invalid
+ */
+ pbap->cache.valid = FALSE;
+ pbap->cache.index = 0;
+ cache_clear(&pbap->cache);
+
g_free(fullname);
return 0;
gpointer context, size_t *size, int *err)
{
struct pbap_session *pbap = context;
- phonebook_cb cb;
int ret;
if (oflag != O_RDONLY) {
goto fail;
}
- if (pbap->params->maxlistcount == 0)
- cb = phonebook_size_result;
- else
- cb = query_result;
+ /* PullvCardListing always get the contacts from the cache */
- /* FIXME: PullvCardList should read data from the cache only */
- cache_add(&pbap->cache, NULL);
- cache_foreach(&pbap->cache, NULL, NULL, NULL);
+ /*
+ * FIXME: When the name is given and the OBEX non header flags are
+ * provided it is necessary to check if the cache still valid.
+ */
+ if (pbap->cache.valid) {
+ cache_ready_notify(pbap);
+ goto done;
+ }
+
+ ret = phonebook_create_cache(name,
+ cache_entry_notify, cache_ready_notify, pbap);
- ret = phonebook_list(name, pbap->params, cb, pbap);
if (ret < 0)
goto fail;
+done:
if (size)
*size = OBJECT_SIZE_UNKNOWN;
return NULL;
}
-
static gpointer vobject_vcard_open(const char *name, int oflag, mode_t mode,
- gpointer context, size_t *size, int *err)
+ gpointer context, size_t *size, int *err)
{
struct pbap_session *pbap = context;
- gpointer id;
+ const gchar *id;
+ guint32 handle;
int ret;
if (oflag != O_RDONLY) {
goto fail;
}
- id = cache_find(&pbap->cache, name);
+ sscanf(name, "%u.vcf", &handle);
+ id = cache_find(&pbap->cache, handle);
if (!id) {
ret = -ENOENT;
goto fail;
}
- /* FIXME: use id */
- ret = phonebook_get_entry(name, pbap->params, query_result, pbap);
+ ret = phonebook_get_entry(id, pbap->params, query_result, pbap);
if (ret < 0)
goto fail;
return NULL;
}
-static ssize_t vobject_read(gpointer object, void *buf, size_t count,
+static ssize_t vobject_pull_read(gpointer object, void *buf, size_t count,
guint8 *hi)
{
struct pbap_session *pbap = object;
- ssize_t ret = -EAGAIN;
+
+ if (!pbap->buffer)
+ return -EAGAIN;
/* PhoneBookSize */
- if (pbap->params->maxlistcount == 0) {
- guint8 data[4];
- guint16 phonebooksize;
- struct aparam_header *hdr = (struct aparam_header *) data;
+ if (pbap->params->maxlistcount == 0)
+ *hi = OBEX_HDR_APPARAM;
+ else
+ /* Stream data */
+ *hi = OBEX_HDR_BODY;
- phonebooksize = htons(pbap->phonebooksize);
- hdr->tag = PHONEBOOKSIZE_TAG;
- hdr->len = PHONEBOOKSIZE_LEN;
- memcpy(hdr->val, &phonebooksize, sizeof(phonebooksize));
+ return string_read(pbap->buffer, buf, count);
+}
+
+static ssize_t vobject_list_read(gpointer object, void *buf, size_t count,
+ guint8 *hi)
+{
+ struct pbap_session *pbap = object;
+
+ /* Backend still busy reading contacts */
+ if (!pbap->cache.valid)
+ return -EAGAIN;
- memcpy(buf, data, sizeof(data));
+ if (pbap->params->maxlistcount == 0)
*hi = OBEX_HDR_APPARAM;
- ret = 0;
- } else if (pbap->buffer) {
- /* Stream data */
+ else
*hi = OBEX_HDR_BODY;
- ret = string_read(pbap->buffer, buf, count, hi);
- }
- return ret;
+ return string_read(pbap->buffer, buf, count);
+}
+
+static ssize_t vobject_vcard_read(gpointer object, void *buf, size_t count,
+ guint8 *hi)
+{
+ struct pbap_session *pbap = object;
+
+ if (!pbap->buffer)
+ return -EAGAIN;
+
+ *hi = OBEX_HDR_BODY;
+ return string_read(pbap->buffer, buf, count);
}
static int vobject_close(gpointer object)
.mimetype = "x-bt/phonebook",
.open = vobject_pull_open,
.close = vobject_close,
- .read = vobject_read,
+ .read = vobject_pull_read,
};
static struct obex_mime_type_driver mime_list = {
.mimetype = "x-bt/vcard-listing",
.open = vobject_list_open,
.close = vobject_close,
- .read = vobject_read,
+ .read = vobject_list_read,
};
static struct obex_mime_type_driver mime_vcard = {
.mimetype = "x-bt/vcard",
.open = vobject_vcard_open,
.close = vobject_close,
- .read = vobject_read,
+ .read = vobject_vcard_read,
};
static int pbap_init(void)
diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index 38736a2..02edf2a 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
return 0;
}
-int phonebook_get_entry(const gchar *name, const struct apparam_field *params,
+int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data)
{
return -1;
}
-int phonebook_list(const gchar *name, const struct apparam_field *params,
- phonebook_cb cb, gpointer user_data)
+int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb,
+ phonebook_cache_ready_cb ready_cb, gpointer user_data)
{
- return -1;
+ return 0;
}
diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c
index c401a28..7afcf09 100644
--- a/obexd/plugins/phonebook-ebook.c
+++ b/obexd/plugins/phonebook-ebook.c
#include "service.h"
#include "phonebook.h"
-#define EOL "\r\n"
-#define VCARD_LISTING_BEGIN \
- "<?xml version=\"1.0\"?>" EOL \
- "<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">" EOL \
- "<vCard-listing version=\"1.0\">" EOL
-#define VCARD_LISTING_ELEMENT "<card handle = \"%d.vcf\" name = \"%s\"/>" EOL
-#define VCARD_LISTING_END "</vCard-listing>"
-
#define QUERY_FN "(contains \"family_name\" \"%s\")"
#define QUERY_NAME "(contains \"given_name\" \"%s\")"
#define QUERY_PHONE "(contains \"phone\" \"%s\")"
-struct query_data {
+struct contacts_query {
const struct apparam_field *params;
phonebook_cb cb;
gpointer user_data;
};
+struct cache_query {
+ phonebook_entry_cb entry_cb;
+ phonebook_cache_ready_cb ready_cb;
+ gpointer user_data;
+};
+
static EBook *ebook = NULL;
static gchar *attribute_mask[] = {
return vcard;
}
-static void ebookpull_cb(EBook *book, EBookStatus status, GList *contacts,
+static void ebookpull_cb(EBook *book, EBookStatus estatus, GList *contacts,
gpointer user_data)
{
- struct query_data *data = user_data;
+ struct contacts_query *data = user_data;
GString *string = g_string_new("");
- GList *l = g_list_nth(contacts, data->params->liststartoffset);
- guint count = 0, maxcount = data->params->maxlistcount;
+ guint count = 0, maxcount;
+ GList *l;
+
+ if (estatus != E_BOOK_ERROR_OK) {
+ error("E-Book query failed: status %d", estatus);
+ goto done;
+ }
+
+ maxcount = data->params->maxlistcount;
+ l = g_list_nth(contacts, data->params->liststartoffset);
/* FIXME: Missing 0.vcf */
EVCard *evcard = E_VCARD(contact);
gchar *vcard;
- vcard = evcard_to_string(evcard,
- data->params->format, data->params->filter);
+ vcard = evcard_to_string(evcard, data->params->format,
+ data->params->filter);
string = g_string_append(string, vcard);
g_free(vcard);
}
+done:
data->cb(string->str, string->len, count, 0, data->user_data);
g_string_free(string, TRUE);
g_free(data);
}
+static void ebook_entry_cb(EBook *book, EBookStatus estatus,
+ EContact *contact, gpointer user_data)
+{
+ struct contacts_query *data = user_data;
+ EVCard *evcard;
+ gchar *vcard;
+ size_t len;
+
+ if (estatus != E_BOOK_ERROR_OK) {
+ error("E-Book query failed: status %d", estatus);
+ data->cb(NULL, 0, 1, 0, data->user_data);
+ g_free(data);
+ return;
+ }
+
+ evcard = E_VCARD(contact);
+
+ vcard = evcard_to_string(evcard, data->params->format,
+ data->params->filter);
+
+ len = vcard ? strlen(vcard) : 0;
+
+ data->cb(vcard, len, 1, 0, data->user_data);
+
+ g_free(data);
+}
+
static gchar *evcard_name_attribute_to_string(EVCard *evcard)
{
EVCardAttribute *attrib;
return g_string_free(name, FALSE);
}
-static void ebooklist_cb(EBook *book, EBookStatus status, GList *contacts,
+static void cache_cb(EBook *book, EBookStatus estatus, GList *contacts,
gpointer user_data)
{
- struct query_data *data = user_data;
- GString *string = g_string_new(VCARD_LISTING_BEGIN);
- GList *l = g_list_nth(contacts, data->params->liststartoffset);
- guint count = 0, maxcount = data->params->maxlistcount;
+ struct cache_query *data = user_data;
+ GList *l;
- for (; l && count < maxcount; l = g_list_next(l), count++) {
+ if (estatus != E_BOOK_ERROR_OK) {
+ error("E-Book query failed: status %d", estatus);
+ goto done;
+ }
+
+ for (l = contacts; l; l = g_list_next(l)) {
EContact *contact = E_CONTACT(l->data);
EVCard *evcard = E_VCARD(contact);
- gchar *element, *name;
+ EVCardAttribute *attrib;
+ gchar *uid, *tel, *name;
name = evcard_name_attribute_to_string(evcard);
if (!name)
continue;
- element = g_strdup_printf(VCARD_LISTING_ELEMENT, count, name);
+ attrib = e_vcard_get_attribute(evcard, EVC_UID);
+ if (!attrib)
+ continue;
- string = g_string_append(string, element);
- g_free(name);
- g_free(element);
- }
+ uid = e_vcard_attribute_get_value(attrib);
+ if (!uid)
+ continue;
- string = g_string_append(string, VCARD_LISTING_END);
+ attrib = e_vcard_get_attribute(evcard, EVC_TEL);
+ if (!attrib)
+ continue;
- data->cb(string->str, string->len, count, 0, data->user_data);
+ tel = e_vcard_attribute_get_value(attrib);
- g_string_free(string, TRUE);
- g_free(data);
+ data->entry_cb(uid, name, NULL, tel, data->user_data);
+ g_free(name);
+ g_free(uid);
+ g_free(tel);
+ }
+done:
+ data->ready_cb(data->user_data);
}
int phonebook_init(void)
gboolean root, child;
int ret;
- root = (!current_folder || strlen(current_folder) == 0);
+ root = (g_strcmp0("/", current_folder) == 0);
child = (new_folder && strlen(new_folder) != 0);
/* Evolution back-end will support telecom/pb folder only */
/* Go down 1 level */
if (root)
ret = (strcmp("telecom", new_folder) != 0) ? -EBADR: 0;
- else if (strcmp("telecom", current_folder) == 0)
+ else if (strcmp("/telecom", current_folder) == 0)
ret = (strcmp("pb", new_folder) != 0) ? -EBADR: 0;
else
ret = -EBADR;
return 0;
/* /telecom or /telecom/pb */
- if (strcmp("telecom", current_folder) == 0)
+ if (strcmp("/telecom", current_folder) == 0)
ret = (strcmp("telecom", new_folder) != 0) ? -EBADR : 0;
- else if (strcmp("telecom/pb", current_folder) == 0)
+ else if (strcmp("/telecom/pb", current_folder) == 0)
ret = (strcmp("pb", new_folder) != 0) ? -EBADR : 0;
else
ret = -EBADR;
}
gint phonebook_pull(const gchar *name, const struct apparam_field *params,
- phonebook_cb cb, gpointer user_data)
+ phonebook_cb cb, gpointer user_data)
{
- struct query_data *data;
+ struct contacts_query *data;
EBookQuery *query;
query = e_book_query_any_field_contains("");
- data = g_new0(struct query_data, 1);
+ data = g_new0(struct contacts_query, 1);
data->cb = cb;
data->params = params;
data->user_data = user_data;
return 0;
}
-int phonebook_get_entry(const gchar *name, const struct apparam_field *params,
+int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data)
{
- return -1;
-}
-
-static EBookQuery *create_query(guint8 attrib, guint8 *searchval)
-{
- EBookQuery *query;
- gchar *fam, *str, **values;
-
- if (!searchval || strlen((gchar *) searchval) == 0)
- return e_book_query_any_field_contains("");
-
- switch (attrib) {
- case 0:
- /* Name */
- values = g_strsplit((gchar *) searchval, ";", 2);
-
- str = NULL;
-
- fam = (values[0] ? g_strdup_printf(QUERY_FN, values[0]) : NULL);
-
- if (values[1]) {
- char *given = g_strdup_printf(QUERY_NAME, values[1]);
-
- str = fam ?
- g_strconcat(fam, " and ", given, NULL) : given;
+ struct contacts_query *data;
- g_free(fam);
- g_free(given);
- }
-
- if (!str)
- str = fam;
+ data = g_new0(struct contacts_query, 1);
+ data->cb = cb;
+ data->params = params;
+ data->user_data = user_data;
- g_strfreev(values);
- break;
- case 1:
- /* Number */
- str = g_strdup_printf(QUERY_PHONE, searchval);
- break;
- case 2:
- /* Sound */
- /* TODO: not yet implemented */
- default:
- return NULL;
+ if (e_book_async_get_contact(ebook, id, ebook_entry_cb, data)) {
+ g_free(data);
+ return -EPERM;
}
- query = e_book_query_from_string(str);
- g_free(str);
-
- return query;
+ return 0;
}
-int phonebook_list(const gchar *name, const struct apparam_field *params,
- phonebook_cb cb, gpointer user_data)
+int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb,
+ phonebook_cache_ready_cb ready_cb, gpointer user_data)
{
- struct query_data *data;
+ struct cache_query *data;
EBookQuery *query;
+ gboolean ret;
- query = create_query(params->searchattrib, params->searchval);
- if (!query)
- return -EBADR;
+ query = e_book_query_any_field_contains("");
- data = g_new0(struct query_data, 1);
- data->cb = cb;
- data->params = params;
+ data = g_new0(struct cache_query, 1);
+ data->entry_cb = entry_cb;
+ data->ready_cb = ready_cb;
data->user_data = user_data;
- e_book_async_get_contacts(ebook, query, ebooklist_cb, data);
+ ret = e_book_async_get_contacts(ebook, query, cache_cb, data);
e_book_query_unref(query);
- return 0;
+ return (ret == FALSE ? 0 : -EBADR);
}
diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h
index b0878fb..5d3e33d 100644
--- a/obexd/plugins/phonebook.h
+++ b/obexd/plugins/phonebook.h
*
*/
+#define EOL "\r\n"
+#define VCARD_LISTING_BEGIN \
+ "<?xml version=\"1.0\"?>" EOL\
+ "<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">" EOL\
+ "<vCard-listing version=\"1.0\">" EOL
+#define VCARD_LISTING_ELEMENT "<card handle = \"%d.vcf\" name = \"%s\"/>" EOL
+#define VCARD_LISTING_END "</vCard-listing>"
+
struct apparam_field {
/* list and pull attributes */
guint16 maxlistcount;
guint8 *searchval;
};
+/*
+ * Interface between the PBAP core and backends to retrieve
+ * all contacts that match the application parameters rules.
+ * Contacts will be returned in the vcard format.
+ */
typedef void (*phonebook_cb) (const gchar *buffer, size_t bufsize,
gint vcards, gint missed, gpointer user_data);
+/*
+ * 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);
+
+/*
+ * After notify all entries to PBAP core, the backend
+ * needs to notify that the operation has finished.
+ */
+typedef void (*phonebook_cache_ready_cb) (gpointer user_data);
+
+
int phonebook_init(void);
void phonebook_exit(void);
int phonebook_set_folder(const gchar *current_folder,
const gchar *new_folder, guint8 flags);
+/*
+ * PullPhoneBook never use cached entries. PCE use this
+ * function to get all entries of a given folder.
+ */
int phonebook_pull(const gchar *name, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data);
-int phonebook_get_entry(const gchar *name, const struct apparam_field *params,
+int phonebook_get_entry(const gchar *id, const struct apparam_field *params,
phonebook_cb cb, gpointer user_data);
-int phonebook_list(const gchar *name, const struct apparam_field *params,
- phonebook_cb cb, gpointer user_data);
+/*
+ * PBAP core will keep the contacts cache per folder. SetPhoneBook or
+ * PullvCardListing can invalidate the cache if the current folder changes.
+ */
+int phonebook_create_cache(const gchar *name, phonebook_entry_cb entry_cb,
+ phonebook_cache_ready_cb ready_cb, gpointer user_data);
diff --git a/obexd/plugins/syncevolution.c b/obexd/plugins/syncevolution.c
index a646cc6..7a76a49 100644
--- a/obexd/plugins/syncevolution.c
+++ b/obexd/plugins/syncevolution.c
gboolean authenticate;
DBusPendingCall *call;
- if (context->buffer)
- return string_read(context->buffer, buf, count, hi);
+ if (context->buffer) {
+ *hi = OBEX_HDR_BODY;
+ return string_read(context->buffer, buf, count);
+ }
conn = obex_dbus_get_connection();
if (conn == NULL)