diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c
index dcc03ff..9775bcb 100644
--- a/obexd/plugins/filesystem.c
+++ b/obexd/plugins/filesystem.c
#include "obex.h"
#include "mimetype.h"
#include "service.h"
+#include "filesystem.h"
#define EOL_CHARS "\n"
return NULL;
}
-static int string_free(gpointer object)
+int string_free(gpointer object)
{
GString *string = object;
return 0;
}
-static ssize_t string_read(gpointer object, void *buf, size_t count)
+ssize_t string_read(gpointer object, void *buf, size_t count)
{
GString *string = object;
ssize_t len;
if (string->len == 0)
return 0;
- len = count > string->len ? string->len : count;
+ len = MIN(string->len, count);
memcpy(buf, string->str, len);
string = g_string_erase(string, 0, len);
diff --git a/obexd/plugins/filesystem.h b/obexd/plugins/filesystem.h
new file mode 100644
index 0000000..636ddb2
--- /dev/null
+++ b/obexd/plugins/filesystem.h
+/*
+ *
+ * OBEX Server
+ *
+ * Copyright (C) 2007-2010 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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 string_free(gpointer object);
+ssize_t string_read(gpointer object, void *buf, size_t count);
diff --git a/obexd/plugins/ftp.c b/obexd/plugins/ftp.c
index fe775f4..0bd5a5e 100644
--- a/obexd/plugins/ftp.c
+++ b/obexd/plugins/ftp.c
return OBEX_RSP_SUCCESS;
}
-static obex_rsp_t ftp_get(struct OBEX_session *os)
+static obex_rsp_t ftp_get(struct OBEX_session *os, obex_object_t *obj)
{
const char *folder = obex_get_folder(os);
const char *type = obex_get_type(os);
diff --git a/obexd/plugins/opp.c b/obexd/plugins/opp.c
index d003f21..3325d08 100644
--- a/obexd/plugins/opp.c
+++ b/obexd/plugins/opp.c
return OBEX_RSP_SUCCESS;
}
-static obex_rsp_t opp_get(struct OBEX_session *os)
+static obex_rsp_t opp_get(struct OBEX_session *os, obex_object_t *obj)
{
const char *type;
diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
index 53d4a9c..2a7d6d1 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
#include <string.h>
#include <errno.h>
#include <glib.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <bluetooth/bluetooth.h>
#include <openobex/obex.h>
#include "service.h"
#include "phonebook.h"
#include "telephony.h"
+#include "mimetype.h"
+#include "filesystem.h"
#include "dbus.h"
#define PHONEBOOK_TYPE "x-bt/phonebook"
uint8_t val[0];
} __attribute__ ((packed));
+struct phonebook_query {
+ const char *type;
+ GString *buffer;
+ struct OBEX_session *os;
+};
+
static const guint8 PBAP_TARGET[TARGET_SIZE] = {
0x79, 0x61, 0x35, 0xF0, 0xF0, 0xC5, 0x11, 0xD8,
0x09, 0x66, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66 };
-static int pbap_parse_apparam_header(obex_t *obex, obex_object_t *obj,
- struct apparam_field *apparam)
-{
- obex_headerdata_t hd;
- guint8 hi;
- guint32 hlen;
-
- while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
- void *ptr = (void *) hd.bs;
- uint32_t len = hlen;
-
- if (hi != OBEX_HDR_APPARAM)
- continue;
-
- if (hlen < APPARAM_HDR_SIZE) {
- g_free(apparam->searchval);
- error("PBAP pullphonebook app parameters header"
- " is too short: %d", hlen);
- return -1;
- }
-
- while (len > APPARAM_HDR_SIZE) {
- struct apparam_hdr *hdr = ptr;
-
- if (hdr->len > len - APPARAM_HDR_SIZE) {
- g_free(apparam->searchval);
- error("Unexpected PBAP pullphonebook app"
- " length, tag %d, len %d",
- hdr->tag, hdr->len);
- return -1;
- }
-
- switch (hdr->tag) {
- case ORDER_TAG:
- if (hdr->len == ORDER_LEN)
- apparam->order = hdr->val[0];
- break;
- case SEARCHATTRIB_TAG:
- if (hdr->len == SEARCHATTRIB_LEN)
- apparam->searchattrib = hdr->val[0];
- break;
- case SEARCHVALUE_TAG:
- apparam->searchval = g_try_malloc(hdr->len + 1);
- if (apparam->searchval != NULL) {
- memcpy(apparam->searchval, hdr->val,
- hdr->len);
- apparam->searchval[hdr->len] = '\0';
- }
- break;
- case FILTER_TAG:
- if (hdr->len == FILTER_LEN) {
- guint64 val;
- memcpy(&val, hdr->val, sizeof(val));
- apparam->filter = get_be64(&val);
- }
- break;
- case FORMAT_TAG:
- if (hdr->len == FORMAT_LEN)
- apparam->format = hdr->val[0];
- break;
- case MAXLISTCOUNT_TAG:
- if (hdr->len == MAXLISTCOUNT_LEN) {
- guint16 val;
- memcpy(&val, hdr->val, sizeof(val));
- apparam->maxlistcount = get_be16(&val);
- }
- break;
- case LISTSTARTOFFSET_TAG:
- if (hdr->len == LISTSTARTOFFSET_LEN) {
- guint16 val;
- memcpy(&val, hdr->val, sizeof(val));
- apparam->liststartoffset = get_be16(&val);
- }
- break;
- default:
- g_free(apparam->searchval);
- error("Unexpected PBAP pullphonebook app"
- " parameter, tag %d, len %d",
- hdr->tag, hdr->len);
- return -1;
- }
-
- ptr += APPARAM_HDR_SIZE + hdr->len;
- len -= APPARAM_HDR_SIZE + hdr->len;
- }
-
- /* Ignore multiple app param headers */
- break;
- }
-
- return 0;
-}
-
-/* Add app parameter header, that is sent back to PBAP client */
-static int pbap_add_result_apparam_header(obex_t *obex, obex_object_t *obj,
- guint16 maxlistcount, gchar *path_name,
- guint16 phonebooksize,
- guint8 newmissedcalls, gboolean *addbody)
-{
- guint8 rspsize = 0;
- gboolean addmissedcalls = FALSE;
- obex_headerdata_t hd;
-
- if (maxlistcount == 0) {
- rspsize += APPARAM_HDR_SIZE + PHONEBOOKSIZE_LEN;
- *addbody = FALSE;
- }
-
- if (g_str_equal(path_name, SIM1_MCH) == TRUE ||
- g_str_equal(path_name, MCH) == TRUE) {
- rspsize += APPARAM_HDR_SIZE + NEWMISSEDCALLS_LEN;
- addmissedcalls = TRUE;
- }
-
- if (rspsize > 0) {
- void *buf, *ptr;
-
- buf = g_try_malloc0(rspsize);
- if (buf == NULL)
- return -ENOMEM;
-
- ptr = buf;
-
- if (maxlistcount == 0) {
- struct apparam_hdr *hdr = ptr;
- guint16 val = GUINT16_TO_BE(phonebooksize);
-
- hdr->tag = PHONEBOOKSIZE_TAG;
- hdr->len = PHONEBOOKSIZE_LEN;
- memcpy(hdr->val, &val, sizeof(val));
-
- ptr += APPARAM_HDR_SIZE + PHONEBOOKSIZE_LEN;
- }
-
- if (addmissedcalls == TRUE) {
- struct apparam_hdr *hdr = ptr;
-
- hdr->tag = NEWMISSEDCALLS_TAG;
- hdr->len = NEWMISSEDCALLS_LEN;
- hdr->val[0] = newmissedcalls;
-
- ptr += APPARAM_HDR_SIZE + NEWMISSEDCALLS_LEN;
- }
-
- hd.bs = buf;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_APPARAM,
- hd, rspsize, 0);
- g_free(buf);
- }
-
- return 0;
-}
-
-static int pbap_pullphonebook(obex_t *obex, obex_object_t *obj,
- gboolean *addbody)
-{
- struct obex_session *session = OBEX_GetUserData(obex);
- struct apparam_field params;
- guint8 newmissedcalls = 0;
- guint16 phonebooksize = 0;
- int err;
-
- memset(¶ms, 0, sizeof(struct apparam_field));
-
- err = pbap_parse_apparam_header(obex, obj, ¶ms);
- if (err < 0)
- return err;
-
- if (params.maxlistcount == 0) {
- phonebooksize = DEFAULT_COUNT;
- goto done;
- }
-
- err = phonebook_pullphonebook(obex, obj, params);
- if (err < 0)
- return err;
-
-done:
- return pbap_add_result_apparam_header(obex, obj, params.maxlistcount,
- session->name, phonebooksize,
- newmissedcalls, addbody);
-}
-
-static int pbap_pullvcardlisting(obex_t *obex, obex_object_t *obj,
- gboolean *addbody)
-{
- struct obex_session *session = OBEX_GetUserData(obex);
- gchar *fullname;
- struct apparam_field params;
- guint8 newmissedcalls = 0;
- guint16 phonebooksize = 0;
- int err;
-
- memset(¶ms, 0, sizeof(struct apparam_field));
-
- err = pbap_parse_apparam_header(obex, obj, ¶ms);
- if (err < 0)
- return err;
-
- if (params.maxlistcount == 0) {
- phonebooksize = DEFAULT_COUNT;
- goto proceed;
- }
-
- /* libebook does not support sound attribute */
- if (params.searchattrib >= 2) {
- DBG("libebook does not support sound attribute");
- goto done;
- }
-
- err = phonebook_pullvcardlisting(obex, obj, params);
- if (err < 0)
- goto done;
-
-proceed:
-
- fullname = g_build_filename(session->current_folder, session->name,
- NULL);
- if (fullname != NULL)
- fullname = g_strconcat(fullname, ".vcf", NULL);
-
- err = pbap_add_result_apparam_header(obex, obj, params.maxlistcount,
- fullname, phonebooksize,
- newmissedcalls, addbody);
- g_free(fullname);
-
-done:
- g_free(params.searchval);
- return err;
-}
-
-static int pbap_pullvcardentry(obex_t *obex, obex_object_t *obj)
-{
- struct apparam_field params;
- int err;
-
- memset(¶ms, 0, sizeof(struct apparam_field));
- err = pbap_parse_apparam_header(obex, obj, ¶ms);
- if (err < 0)
- return err;
-
- err = phonebook_pullvcardentry(obex, obj, params);
-
- g_free(params.searchval);
- return err;
-}
-
static obex_rsp_t pbap_connect(struct OBEX_session *os)
{
manager_register_session(os);
return OBEX_RSP_SUCCESS;
}
-static obex_rsp_t pbap_get(struct OBEX_session *os)
+static obex_rsp_t pbap_get(struct OBEX_session *os, obex_object_t *obj)
{
- int addbody = TRUE;
- const char *type = obex_get_type(os);
- const char *name = obex_get_name(os);
- int err;
+ const gchar *type = obex_get_type(os);
+ const gchar *folder = obex_get_folder(os);
+ const gchar *name = obex_get_name(os);
+ gchar *path;
+ gint ret;
if (type == NULL)
- goto fail;
+ return OBEX_RSP_BAD_REQUEST;
- if (g_str_equal(type, VCARDLISTING_TYPE) == FALSE
- && name == NULL)
- goto fail;
+ if (strcmp(type, PHONEBOOK_TYPE) == 0)
+ /* Always contains the absolute path */
+ path = g_strdup(name);
+ else if (strcmp(type, VCARDLISTING_TYPE) == 0)
+ /* Always relative */
+ if (!name || strlen(name) == 0)
+ /* Current folder */
+ path = g_strdup(folder);
+ else
+ /* Current folder + relative path */
+ path = g_build_filename(folder, name, NULL);
- /* FIXME: broken */
-#if 0
- OBEX_ObjectReParseHeaders(, obj);
-#endif
- if (g_str_equal(type, PHONEBOOK_TYPE) == TRUE)
- err = pbap_pullphonebook(NULL, NULL, NULL);
- else if (g_str_equal(type, VCARDLISTING_TYPE) == TRUE)
- err = pbap_pullvcardlisting(NULL, NULL, NULL);
- else if (g_str_equal(type, VCARDENTRY_TYPE) == TRUE)
- err = pbap_pullvcardentry(NULL, NULL);
+ else if (strcmp(type, VCARDENTRY_TYPE) == 0)
+ /* Always relative */
+ path = g_build_filename(folder, name, NULL);
else
- goto fail;
+ return OBEX_RSP_BAD_REQUEST;
- if (err < 0)
- goto fail;
+ ret = obex_stream_start(os, path);
+ g_free(path);
- if (addbody == TRUE) {
-#if 0
- OBEX_SuspendRequest(obex, obj);
- session->size = 0;
+ switch (ret) {
+ case 0:
+ return OBEX_RSP_SUCCESS;
+ case -ENOENT:
+ return OBEX_RSP_NOT_FOUND;
+ default:
+ return OBEX_RSP_FORBIDDEN;
- /* Add body header */
- hd.bs = NULL;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
- hd, 0, OBEX_FL_STREAM_START);
-#endif
}
-
-#if 0
- OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
-#endif
-
- return OBEX_RSP_SUCCESS;
-
-fail:
- return OBEX_RSP_FORBIDDEN;
}
static gboolean pbap_is_valid_folder(struct obex_session *session)
.chkput = pbap_chkput
};
+static void query_result(const gchar *buffer, size_t bufsize,
+ gint vcards, gint missed, gpointer user_data)
+{
+ struct phonebook_query *query = user_data;
+
+ if (!query->buffer)
+ query->buffer = g_string_new_len(buffer, bufsize);
+ else
+ query->buffer = g_string_append_len(query->buffer, buffer, bufsize);
+
+ obex_object_set_io_flags(query, G_IO_IN, 0);
+}
+
+static gpointer vobject_open(const char *name, int oflag, mode_t mode,
+ size_t *size, struct OBEX_session *os, int *err)
+{
+ const gchar *type = obex_get_type(os);
+ struct phonebook_query *query;
+
+ if (oflag != O_RDONLY)
+ goto fail;
+
+ /* TODO: mch? */
+
+ /* TODO: get application parameter */
+ query = g_new0(struct phonebook_query, 1);
+ query->type = type;
+ query->os = os;
+
+ if (phonebook_query(name, query_result, query) < 0) {
+ g_free(query);
+ goto fail;
+ }
+
+ if (size)
+ *size = 1;
+
+ return query;
+
+fail:
+ if (err)
+ *err = -EPERM;
+
+ return NULL;
+}
+
+static ssize_t vobject_read(gpointer object, void *buf, size_t count)
+{
+ struct phonebook_query *query = object;
+
+ if (query->buffer)
+ return string_read(query->buffer, buf, count);
+
+ return -EAGAIN;
+}
+
+static int vobject_close(gpointer object)
+{
+ struct phonebook_query *query = object;
+
+ if (query->buffer)
+ string_free(query->buffer);
+
+ g_free(query);
+
+ return 0;
+}
+
+struct obex_mime_type_driver mime_pull = {
+ .target = PBAP_TARGET,
+ .mimetype = "x-bt/phonebook",
+ .open = vobject_open,
+ .close = vobject_close,
+ .read = vobject_read,
+};
+
+struct obex_mime_type_driver mime_list = {
+ .target = PBAP_TARGET,
+ .mimetype = "x-bt/vcard-listing",
+ .open = vobject_open,
+ .close = vobject_close,
+ .read = vobject_read,
+};
+
+struct obex_mime_type_driver mime_vcard = {
+ .target = PBAP_TARGET,
+ .mimetype = "x-bt/vcard",
+ .open = vobject_open,
+ .close = vobject_close,
+ .read = vobject_read,
+};
+
static int pbap_init(void)
{
+ int err;
+
+ err = phonebook_init();
+ if (err < 0)
+ return err;
+
+ err = obex_mime_type_driver_register(&mime_pull);
+ if (err < 0)
+ return err;
+
+ err = obex_mime_type_driver_register(&mime_list);
+ if (err < 0)
+ return err;
+
+ err = obex_mime_type_driver_register(&mime_vcard);
+ if (err < 0)
+ return err;
+
return obex_service_driver_register(&pbap);
}
static void pbap_exit(void)
{
obex_service_driver_unregister(&pbap);
+ obex_mime_type_driver_unregister(&mime_pull);
+ obex_mime_type_driver_unregister(&mime_list);
+ obex_mime_type_driver_unregister(&mime_vcard);
+ phonebook_exit();
}
OBEX_PLUGIN_DEFINE(pbap, pbap_init, pbap_exit)
diff --git a/obexd/plugins/phonebook-dummy.c b/obexd/plugins/phonebook-dummy.c
index df3760c..38b2803 100644
--- a/obexd/plugins/phonebook-dummy.c
+++ b/obexd/plugins/phonebook-dummy.c
#include <config.h>
#endif
+#include <string.h>
#include <glib.h>
#include <openobex/obex.h>
#include <openobex/obex_const.h>
+#include "logging.h"
#include "phonebook.h"
-int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
+#define VCARD0 \
+ "BEGIN:VCARD\n" \
+ "VERSION:3.0\n" \
+ "N:Klaus;Santa\n" \
+ "FN:\n" \
+ "TEL:+001122334455\n" \
+ "END:VCARD\n"
+
+
+struct dummy_data {
+ phonebook_cb cb;
+ gpointer user_data;
+};
+
+int phonebook_init(void)
{
return 0;
}
-int phonebook_pullvcardlisting(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
+void phonebook_exit(void)
{
- return 0;
}
-int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
+static gboolean dummy_result(gpointer data)
{
+ struct dummy_data *dummy = data;
+
+ dummy->cb(VCARD0, strlen(VCARD0), 1, 0, dummy->user_data);
+
+ return FALSE;
+}
+
+int phonebook_query(const gchar *name, phonebook_cb cb, gpointer user_data)
+{
+ struct dummy_data *dummy;
+
+ dummy = g_new0(struct dummy_data, 1);
+ dummy->cb = cb;
+ dummy->user_data = user_data;
+
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+ dummy_result, dummy, g_free);
return 0;
}
diff --git a/obexd/plugins/phonebook-ebook.c b/obexd/plugins/phonebook-ebook.c
index b25ce25..e1a7996 100644
--- a/obexd/plugins/phonebook-ebook.c
+++ b/obexd/plugins/phonebook-ebook.c
#define QUERY_GIVEN_NAME "(contains \"given_name\" \"%s\")"
#define QUERY_PHONE "(contains \"phone\" \"%s\")"
-struct phonebook_data {
- obex_t *obex;
- obex_object_t *obj;
- struct apparam_field params;
+struct query_data {
+ phonebook_cb cb;
+ gpointer user_data;
};
-static char *vcard_attribs[29] = { EVC_VERSION, EVC_FN, EVC_N, EVC_PHOTO,
- EVC_BDAY, EVC_ADR, EVC_LABEL, EVC_TEL,
- EVC_EMAIL, EVC_MAILER, NULL, EVC_GEO,
- EVC_TITLE, EVC_ROLE, EVC_LOGO, NULL,
- EVC_ORG, EVC_NOTE, EVC_REV, NULL, EVC_URL,
- EVC_UID, EVC_KEY, EVC_NICKNAME, EVC_CATEGORIES,
- EVC_PRODID, NULL, NULL, NULL };
+static EBook *ebook = NULL;
-static void ebookpull_cb(EBook *book, EBookStatus status, GList *list,
+static void ebookpull_cb(EBook *book, EBookStatus status, GList *contacts,
gpointer user_data)
{
- struct phonebook_data *pb_data = user_data;
- struct apparam_field *params = &pb_data->params;
- struct obex_session *session = OBEX_GetUserData(pb_data->obex);
- guint16 offset = 0, count = 0;
- GList *contacts = list;
- GString *pb;
- gchar *result;
- gint32 size;
+ struct query_data *data = user_data;
+ GString *string = g_string_new("");
+ GList *l;
- pb = g_string_new(NULL);
-
- /* Mandatory attributes for vCard 3.0 are VERSION, N, FN and TEL */
- if (params->filter != 0 && params->format == EVC_FORMAT_VCARD_30)
- params->filter |= 0x87;
-
- for (; contacts != NULL; contacts = g_list_next(contacts)) {
- EContact *contact = NULL;
- EVCard *evcard = NULL, *evcard_filtered = NULL;
- GList *attrib_list = NULL, *l;
- char *vcard;
-
- if (offset < params->liststartoffset) {
- offset++;
- continue;
- }
-
- if (count < params->maxlistcount)
- count++;
- else
- break;
+ for (l = contacts; l; l = g_list_next(l)) {
+ EContact *contact;
+ EVCard *evcard;
+ gchar *vcard;
contact = E_CONTACT(contacts->data);
evcard = E_VCARD(contact);
- attrib_list = e_vcard_get_attributes(evcard);
-
- if (!params->filter) {
- vcard = e_vcard_to_string(evcard, params->format);
- goto done;
- }
-
- evcard_filtered = e_vcard_new();
- for (l = attrib_list; l; l = l->next) {
- int i;
- const char *attrib_name = e_vcard_attribute_get_name(
- (EVCardAttribute *) l->data);
-
- for (i = 0; i <= 28; i++) {
- int mask;
-
- mask = 1 << i;
- if (!(params->filter & mask))
- continue;
- if (g_strcmp0(vcard_attribs[i], attrib_name))
- continue;
- e_vcard_add_attribute(evcard_filtered,
- e_vcard_attribute_copy(
- (EVCardAttribute *) l->data));
- break;
- }
- }
- vcard = e_vcard_to_string(evcard_filtered, params->format);
- g_object_unref(evcard_filtered);
-
-done: g_string_append_printf(pb, "%s\n", vcard);
+ vcard = e_vcard_to_string(evcard, EVC_FORMAT_VCARD_30);
+ string = g_string_append(string, vcard);
g_free(vcard);
}
- result = g_string_free(pb, FALSE);
- size = strlen(result);
-
- if (size != 0) {
- session->buf = g_realloc(session->buf, session->size + size);
- memcpy(session->buf + session->size, result, size);
- session->size += size;
- }
-
- session->finished = 1;
- OBEX_ResumeRequest(session->obex);
-
- g_free(result);
- g_free(pb_data);
- g_object_unref(book);
+ data->cb(string->str, string->len,
+ g_list_length(contacts), 0, data->user_data);
}
-int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
+int phonebook_init(void)
{
- struct phonebook_data *pb_data;
- EBook *book;
- EBookQuery *query;
-
- if (params.format != EVC_FORMAT_VCARD_30) {
- DBG("libebook does not support e_vcard_to_string_vcard_21()");
- return -1;
+ GError *gerr = NULL;
+
+ ebook = e_book_new_default_addressbook(&gerr);
+ if (!ebook) {
+ error("Can't create user's default address book: %s",
+ gerr->message);
+ g_error_free(gerr);
+ return -EIO;
}
- pb_data = g_new0(struct phonebook_data, 1);
- pb_data->obex = obex;
- pb_data->obj = obj;
- pb_data->params = params;
-
- book = e_book_new_default_addressbook(NULL);
-
- e_book_open(book, FALSE, NULL);
-
- query = e_book_query_any_field_contains("");
-
- e_book_async_get_contacts(book, query, ebookpull_cb, pb_data);
-
- e_book_query_unref(query);
-
- OBEX_SuspendRequest(obex, obj);
-
- return 0;
-}
-
-static void ebooklist_cb(EBook *book, EBookStatus status, GList *list,
- gpointer user_data)
-{
- struct phonebook_data *pb_data = user_data;
- struct apparam_field *params = &pb_data->params;
- struct obex_session *session = OBEX_GetUserData(pb_data->obex);
- guint16 offset = 0, count = 0;
- GString *listing;
- GList *contacts = list;
- gchar *result;
- gint32 size;
-
- listing = g_string_new(VL_VERSION);
- listing = g_string_append(listing, VL_TYPE);
- listing = g_string_append(listing, VL_BODY_BEGIN);
-
- for (; contacts != NULL; contacts = g_list_next(contacts)) {
- EContact *contact = NULL;
- EVCard *evcard = NULL;
- EVCardAttribute *name_attrib = NULL;
- GList *name_values = NULL;
- gchar *name = NULL, *name_part = NULL, *element = NULL;
-
- if (offset < params->liststartoffset) {
- offset++;
- continue;
- }
-
- if (count < params->maxlistcount)
- count++;
- else
- break;
-
- contact = E_CONTACT(contacts->data);
- evcard = E_VCARD(contact);
- name_attrib = e_vcard_get_attribute(evcard, EVC_N);
-
- if (name_attrib) {
- name_values = e_vcard_attribute_get_values(name_attrib);
- for (; name_values; name_values = name_values->next) {
- if (!name_part) {
- name_part = g_strdup(name_values->data);
- continue;
- }
- name = g_strjoin(";", name_part,
- name_values->data, NULL);
- g_free(name_part);
- name_part = name;
- }
-
- element = g_strdup_printf(VL_ELEMENT, offset, name);
- listing = g_string_append(listing, element);
-
- g_free(name);
- g_free(element);
- }
-
- offset++;
+ if (!e_book_open(ebook, FALSE, &gerr)) {
+ error("Can't open e-book address book: %s", gerr->message);
+ g_error_free(gerr);
+ return -EIO;
}
- listing = g_string_append(listing, VL_BODY_END);
- result = g_string_free(listing, FALSE);
- size = strlen(result);
-
- if (size != 0) {
- session->buf = g_realloc(session->buf, session->size + size);
- memcpy(session->buf + session->size, result, size);
- session->size += size;
- }
-
- session->finished = 1;
- OBEX_ResumeRequest(session->obex);
-
- g_free(result);
- g_free(pb_data);
- g_object_unref(book);
-}
-
-int phonebook_pullvcardlisting(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
-{
- struct phonebook_data *pb_data;
- EBook *book;
- EBookQuery *query = NULL, *query1 = NULL, *query2 = NULL;
- gchar *str1 = NULL, *str2 = NULL;
- gchar **value_list = NULL;
-
- pb_data = g_new0(struct phonebook_data, 1);
- pb_data->obex = obex;
- pb_data->obj = obj;
- pb_data->params = params;
-
- book = e_book_new_default_addressbook(NULL);
-
- e_book_open(book, FALSE, NULL);
-
- /* All the vCards shall be returned if SearchValue header is
- * not specified */
- if (!params.searchval || !strlen((char *) params.searchval)) {
- query = e_book_query_any_field_contains("");
- goto done;
- }
-
- if (params.searchattrib == 0) {
- value_list = g_strsplit((gchar *) params.searchval, ";", 5);
-
- if (value_list[0])
- str1 = g_strdup_printf(QUERY_FAMILY_NAME,
- value_list[0]);
- if (value_list[1])
- str2 = g_strdup_printf(QUERY_GIVEN_NAME, value_list[1]);
-
- if (str1)
- query1 = e_book_query_from_string(str1);
- if (str2)
- query2 = e_book_query_from_string(str2);
- if (query1 && query2)
- query = e_book_query_andv(query1, query2, NULL);
- else
- query = query1;
- } else {
- str1 = g_strdup_printf(QUERY_PHONE, params.searchval);
- query = e_book_query_from_string((char *) params.searchval);
- }
-
-done:
- e_book_async_get_contacts(book, query, ebooklist_cb, pb_data);
-
- g_free(str1);
- g_free(str2);
- if (query1 && query1 != query)
- e_book_query_unref(query1);
- if (query2)
- e_book_query_unref(query2);
- e_book_query_unref(query);
- g_strfreev(value_list);
-
- OBEX_SuspendRequest(obex, obj);
-
return 0;
}
-static void ebookpullentry_cb(EBook *book, EBookStatus status, GList *list,
- gpointer user_data)
+void phonebook_exit(void)
{
- struct phonebook_data *pb_data = user_data;
- struct apparam_field *params = &pb_data->params;
- struct obex_session *session = OBEX_GetUserData(pb_data->obex);
- guint16 i = 0, index;
- GList *contacts = list, *attrib_list = NULL, *l;
- EContact *contact = NULL;
- EVCard *evcard = NULL, *evcard_filtered = NULL;
- gint32 size = 0;
- char *vcard = NULL;
-
- if (params->filter != 0 && params->format == EVC_FORMAT_VCARD_30)
- params->filter |= 0x87;
-
- sscanf(session->name, "%hu.vcf", &index);
-
- for (; contacts != NULL; contacts = g_list_next(contacts)) {
- if (i < index) {
- i++;
- continue;
- }
-
- contact = E_CONTACT(contacts->data);
- evcard = E_VCARD(contact);
-
- if (!params->filter) {
- vcard = e_vcard_to_string(evcard, params->format);
- break;
- }
-
- attrib_list = e_vcard_get_attributes(evcard);
- evcard_filtered = e_vcard_new();
- for (l = attrib_list; l; l = l->next) {
- int i;
- const char *attrib_name = e_vcard_attribute_get_name(
- (EVCardAttribute *) l->data);
- for (i = 0; i <= 28; i++) {
- int mask;
-
- mask = 1 << i;
- if (!(params->filter & mask))
- continue;
- if (g_strcmp0(vcard_attribs[i], attrib_name))
- continue;
-
- e_vcard_add_attribute(evcard_filtered,
- e_vcard_attribute_copy(
- (EVCardAttribute *) l->data));
- break;
- }
- }
- vcard = e_vcard_to_string(evcard_filtered, params->format);
- g_object_unref(evcard_filtered);
- break;
- }
-
- if (vcard) {
- size = strlen(vcard);
- session->buf = g_realloc(session->buf, session->size + size);
- memcpy(session->buf + session->size, vcard, size);
- session->size += size;
- }
-
- session->finished = 1;
- OBEX_ResumeRequest(session->obex);
-
- g_free(vcard);
- g_free(pb_data);
- g_object_unref(book);
+ if (ebook)
+ g_object_unref(ebook);
}
-int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj,
- struct apparam_field params)
+int phonebook_query(const gchar *name, phonebook_cb cb, gpointer user_data)
{
- struct phonebook_data *pb_data;
- EBook *book;
+ struct query_data *data;
EBookQuery *query;
- if (params.format != EVC_FORMAT_VCARD_30) {
- DBG("libebook does not support e_vcard_to_string_vcard_21()");
- return -1;
- }
-
- pb_data = g_new0(struct phonebook_data, 1);
- pb_data->obex = obex;
- pb_data->obj = obj;
- pb_data->params = params;
-
- book = e_book_new_default_addressbook(NULL);
-
- e_book_open(book, FALSE, NULL);
-
query = e_book_query_any_field_contains("");
- e_book_async_get_contacts(book, query, ebookpullentry_cb, pb_data);
+ data = g_new0(struct query_data, 1);
+ data->cb = cb;
+ data->user_data = user_data;
- OBEX_SuspendRequest(obex, obj);
+ e_book_async_get_contacts(ebook, query, ebookpull_cb, data);
+
+ e_book_query_unref(query);
return 0;
}
diff --git a/obexd/plugins/phonebook.h b/obexd/plugins/phonebook.h
index cc5743e..dc8e5e0 100644
--- a/obexd/plugins/phonebook.h
+++ b/obexd/plugins/phonebook.h
guint8 *searchval;
};
-int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj,
- struct apparam_field params);
-int phonebook_pullvcardlisting(obex_t *obex, obex_object_t *obj,
- struct apparam_field params);
-int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj,
- struct apparam_field params);
+typedef void (*phonebook_cb) (const gchar *buffer, size_t bufsize,
+ gint vcards, gint missed, gpointer user_data);
+
+int phonebook_init(void);
+void phonebook_exit(void);
+
+int phonebook_setfolder(const gchar *name);
+
+int phonebook_query(const gchar *name, phonebook_cb cb, gpointer user_data);
diff --git a/obexd/plugins/syncevolution.c b/obexd/plugins/syncevolution.c
index 5f78952..60cd15d 100644
--- a/obexd/plugins/syncevolution.c
+++ b/obexd/plugins/syncevolution.c
return OBEX_RSP_SUCCESS;
}
-static obex_rsp_t synce_get(struct OBEX_session *os)
+static obex_rsp_t synce_get(struct OBEX_session *os, obex_object_t *obj)
{
struct synce_context *context;
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index 0484523..0b0c0f2 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
}
}
- rsp = os->service->get(os);
+ rsp = os->service->get(os, obj);
if (rsp == OBEX_RSP_SUCCESS) {
hd.bq4 = os->size;
OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_LENGTH, hd, 4, 0);
diff --git a/obexd/src/service.h b/obexd/src/service.h
index 4bd78fe..b6fc289 100644
--- a/obexd/src/service.h
+++ b/obexd/src/service.h
const gchar *record;
obex_rsp_t (*connect) (struct OBEX_session *os);
void (*progress) (struct OBEX_session *os);
- obex_rsp_t (*get) (struct OBEX_session *os);
+ obex_rsp_t (*get) (struct OBEX_session *os, obex_object_t *obj);
obex_rsp_t (*put) (struct OBEX_session *os);
gint (*chkput) (struct OBEX_session *os);
obex_rsp_t (*setpath) (struct OBEX_session *os, obex_object_t *obj);