diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2009-10-30 16:16:28 -0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-11-03 17:06:17 +0200 |
commit | 69a62bd3bd44cfc965edf15d592407da3ebee44f (patch) | |
tree | 74dea5ca7c050f7373c3970e6824171ccad4dcd0 | |
parent | a9e02bf5b5b3dbbcc5f0072bb14d9badcf55bd0d (diff) | |
download | obexd-69a62bd3bd44cfc965edf15d592407da3ebee44f.tar.gz |
Introduce phonebook and telephony drivers.
Those will be used by pbap plugin which is now builtin as opp and ftp and
can be set on build time using --with-phonebook and --with-telephony
(default are dummy drivers) e.g:
./configure --with-phonebook=ebook
This will expand to plugins/phonebook-ebook.c which then will be linked as
plugins/phonebook.c.
-rw-r--r-- | Makefile.am | 27 | ||||
-rwxr-xr-x | bootstrap-configure | 2 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | plugins/pbap.c (renamed from plugins/ebook.c) | 423 | ||||
-rw-r--r-- | plugins/phonebook-dummy.c | 52 | ||||
-rw-r--r-- | plugins/phonebook-ebook.c | 433 | ||||
-rw-r--r-- | plugins/phonebook.h | 39 | ||||
-rw-r--r-- | plugins/telephony-dummy.c | 38 | ||||
-rw-r--r-- | plugins/telephony.h | 25 |
9 files changed, 626 insertions, 431 deletions
diff --git a/Makefile.am b/Makefile.am index 20b0feb..f5ca3b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,6 +38,11 @@ builtin_sources += plugins/opp.c builtin_modules += ftp builtin_sources += plugins/ftp.c +builtin_modules += pbap +builtin_sources += plugins/pbap.c + +builtin_nodist += plugins/phonebook.c plugins/telephony.c + libexec_PROGRAMS += src/obexd src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) \ @@ -49,7 +54,8 @@ src_obexd_SOURCES = $(gdbus_sources) $(builtin_sources) \ src/service.h src/service.c src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \ - @OPENOBEX_LIBS@ @BLUEZ_LIBS@ -ldl + @EBOOK_LIBS@ @OPENOBEX_LIBS@ \ + @BLUEZ_LIBS@ -ldl src_obexd_LDFLAGS = -Wl,--export-dynamic @@ -61,17 +67,6 @@ plugindir = $(libdir)/obex/plugins plugin_LTLIBRARIES = -if EBOOK -plugin_LTLIBRARIES += plugins/ebook.la - -plugins_ebook_la_SOURCES = plugins/ebook.c - -plugins_ebook_la_LIBADD = @EBOOK_LIBS@ - -plugins_ebook_la_CFLAGS = -fvisibility=hidden @EBOOK_CFLAGS@ -plugins_ebook_la_LDFLAGS = -no-undefined -module -avoid-version -endif - noinst_PROGRAMS = test/obex-test test_obex_test_SOURCES = $(gwobex_sources) test/main.c @@ -100,7 +95,7 @@ endif service_DATA = $(service_in_files:.service.in=.service) -AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ \ +AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \ -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\" @@ -119,3 +114,9 @@ MAINTAINERCLEANFILES = Makefile.in \ %.service: %.service.in config.log $(AM_V_GEN)$(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + +plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@ + $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@ + +plugins/telephony.c: plugins/@TELEPHONY_DRIVER@ + $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@ diff --git a/bootstrap-configure b/bootstrap-configure index 6f7c0d4..73e993a 100755 --- a/bootstrap-configure +++ b/bootstrap-configure @@ -11,4 +11,4 @@ fi --libexec=/usr/lib/obex \ --mandir=/usr/share/man \ --sysconfdir=/etc \ - --enable-ebook $* + --with-phonebook=ebook $* diff --git a/configure.ac b/configure.ac index 587edbd..39ab903 100644 --- a/configure.ac +++ b/configure.ac @@ -103,13 +103,12 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], fi ]) -AC_ARG_ENABLE(ebook, AC_HELP_STRING([--enable-ebook], - [enable EBook plugin]), [ - enable_ebook=${enableval} +phonebook_driver=dummy +AC_ARG_WITH(phonebook, AC_HELP_STRING([--with-phonebook=DRIVER], [select phonebook driver]), [ + phonebook_driver=${withval} ]) -AM_CONDITIONAL(EBOOK, test "${enable_ebook}" = "yes") -if (test "${enable_ebook}" = "yes"); then +if (test "${phonebook_driver}" = "ebook"); then AC_DEFINE(NEED_THREADS, 1, [Define if threading support is required]) PKG_CHECK_MODULES(EBOOK, libebook-1.2, dummy=yes, @@ -123,6 +122,15 @@ if (test "${enable_ebook}" = "yes"); then AC_SUBST(GTHREAD_LIBS) fi +AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c]) + +telephony_driver=dummy +AC_ARG_WITH(telephony, AC_HELP_STRING([--with-telephony=DRIVER], [select telephony driver]), [ + telephony_driver=${withval} +]) + +AC_SUBST([TELEPHONY_DRIVER], [telephony-${telephony_driver}.c]) + AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server], [disable compilation of OBEX server]), [ enable_server=${enableval} diff --git a/plugins/ebook.c b/plugins/pbap.c index a5b43c8..c553deb 100644 --- a/plugins/ebook.c +++ b/plugins/pbap.c @@ -34,12 +34,12 @@ #include <openobex/obex.h> #include <openobex/obex_const.h> -#include <libebook/e-book.h> - #include "plugin.h" #include "logging.h" #include "obex.h" #include "service.h" +#include "phonebook.h" +#include "telephony.h" #define PHONEBOOK_TYPE "x-bt/phonebook" #define VCARDLISTING_TYPE "x-bt/vcard-listing" @@ -70,17 +70,6 @@ #define DEFAULT_COUNT 65535 -#define EOL_CHARS "\n" -#define VL_VERSION "<?xml version=\"1.0\"?>" EOL_CHARS -#define VL_TYPE "<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">" EOL_CHARS -#define VL_BODY_BEGIN "<vCard-listing version=\"1.0\">" EOL_CHARS -#define VL_BODY_END "</vCard-listing>" EOL_CHARS -#define VL_ELEMENT "<card handle = \"%d.vcf\" name = \"%s\"/>" EOL_CHARS - -#define QUERY_FAMILY_NAME "(contains \"family_name\" \"%s\")" -#define QUERY_GIVEN_NAME "(contains \"given_name\" \"%s\")" -#define QUERY_PHONE "(contains \"phone\" \"%s\")" - #define APPARAM_HDR_SIZE 2 #define get_be64(val) GUINT64_FROM_BE(bt_get_unaligned((guint64 *) val)) @@ -137,400 +126,10 @@ struct apparam_hdr { uint8_t val[0]; } __attribute__ ((packed)); -struct apparam_field { - guint64 filter; - guint16 maxlistcount; - guint16 liststartoffset; - guint8 format; - guint8 order; - guint8 searchattrib; - guint8 *searchval; -}; - -struct phonebook_data { - obex_t *obex; - obex_object_t *obj; - struct apparam_field params; -}; - static const guint8 PBAP_TARGET[TARGET_SIZE] = { 0x79, 0x61, 0x35, 0xF0, 0xF0, 0xC5, 0x11, 0xD8, 0x09, 0x66, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66 }; -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 void ebookpull_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; - GList *contacts = list; - GString *pb; - gchar *result; - gint32 size; - - 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; - - 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); - 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); -} - -static int ebook_pullphonebook(obex_t *obex, obex_object_t *obj, - struct apparam_field params) -{ - 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; - } - - 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++; - } - - 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); -} - -static int ebook_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) -{ - 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); -} - -static int ebook_pullvcardentry(obex_t *obex, obex_object_t *obj, - struct apparam_field params) -{ - 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; - } - - 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); - - OBEX_SuspendRequest(obex, obj); - - return 0; -} - static int pbap_parse_apparam_header(obex_t *obex, obex_object_t *obj, struct apparam_field *apparam) { @@ -704,7 +303,7 @@ static int pbap_pullphonebook(obex_t *obex, obex_object_t *obj, goto done; } - err = ebook_pullphonebook(obex, obj, params); + err = phonebook_pullphonebook(obex, obj, params); if (err < 0) return err; @@ -741,7 +340,7 @@ static int pbap_pullvcardlisting(obex_t *obex, obex_object_t *obj, goto done; } - err = ebook_pullvcardlisting(obex, obj, params); + err = phonebook_pullvcardlisting(obex, obj, params); if (err < 0) goto done; @@ -772,7 +371,7 @@ static int pbap_pullvcardentry(obex_t *obex, obex_object_t *obj) if (err < 0) return err; - err = ebook_pullvcardentry(obex, obj, params); + err = phonebook_pullvcardentry(obex, obj, params); g_free(params.searchval); return err; @@ -929,7 +528,7 @@ static void pbap_setpath(obex_t *obex, obex_object_t *obj) OBEX_ObjectSetRsp(obj, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS); } -struct obex_service_driver driver = { +struct obex_service_driver pbap = { .name = "Phonebook Access server", .service = OBEX_PBAP, .channel = PBAP_CHANNEL, @@ -939,14 +538,14 @@ struct obex_service_driver driver = { .setpath = pbap_setpath }; -static int ebook_init(void) +static int pbap_init(void) { - return obex_service_driver_register(&driver); + return obex_service_driver_register(&pbap); } -static void ebook_exit(void) +static void pbap_exit(void) { - obex_service_driver_unregister(&driver); + obex_service_driver_unregister(&pbap); } -OBEX_PLUGIN_DEFINE("ebook", ebook_init, ebook_exit) +OBEX_PLUGIN_DEFINE(pbap, pbap_init, pbap_exit) diff --git a/plugins/phonebook-dummy.c b/plugins/phonebook-dummy.c new file mode 100644 index 0000000..abcdce7 --- /dev/null +++ b/plugins/phonebook-dummy.c @@ -0,0 +1,52 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2009 Intel Corporation + * Copyright (C) 2007-2009 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> + +#include <openobex/obex.h> +#include <openobex/obex_const.h> + +#include "phonebook.h" + +int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + return 0; +} + +int phonebook_pullvcardlisting(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + return 0; +} + +int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + return 0; +} diff --git a/plugins/phonebook-ebook.c b/plugins/phonebook-ebook.c new file mode 100644 index 0000000..cc9d016 --- /dev/null +++ b/plugins/phonebook-ebook.c @@ -0,0 +1,433 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2009 Intel Corporation + * Copyright (C) 2007-2009 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <errno.h> +#include <glib.h> +#include <bluetooth/bluetooth.h> + +#include <openobex/obex.h> +#include <openobex/obex_const.h> + +#include <libebook/e-book.h> + +#include "logging.h" +#include "obex.h" +#include "service.h" +#include "phonebook.h" + +#define EOL_CHARS "\n" +#define VL_VERSION "<?xml version=\"1.0\"?>" EOL_CHARS +#define VL_TYPE "<!DOCTYPE vcard-listing SYSTEM \"vcard-listing.dtd\">" EOL_CHARS +#define VL_BODY_BEGIN "<vCard-listing version=\"1.0\">" EOL_CHARS +#define VL_BODY_END "</vCard-listing>" EOL_CHARS +#define VL_ELEMENT "<card handle = \"%d.vcf\" name = \"%s\"/>" EOL_CHARS + +#define QUERY_FAMILY_NAME "(contains \"family_name\" \"%s\")" +#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; +}; + +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 void ebookpull_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; + GList *contacts = list; + GString *pb; + gchar *result; + gint32 size; + + 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; + + 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); + 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); +} + +int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + 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; + } + + 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++; + } + + 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) +{ + 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); +} + +int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + 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; + } + + 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); + + OBEX_SuspendRequest(obex, obj); + + return 0; +} diff --git a/plugins/phonebook.h b/plugins/phonebook.h new file mode 100644 index 0000000..4d1c4c0 --- /dev/null +++ b/plugins/phonebook.h @@ -0,0 +1,39 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2007-2009 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 + * + */ + +struct apparam_field { + guint64 filter; + guint16 maxlistcount; + guint16 liststartoffset; + guint8 format; + guint8 order; + guint8 searchattrib; + 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); diff --git a/plugins/telephony-dummy.c b/plugins/telephony-dummy.c new file mode 100644 index 0000000..9a4ec82 --- /dev/null +++ b/plugins/telephony-dummy.c @@ -0,0 +1,38 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2009 Intel Corporation + * Copyright (C) 2007-2009 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> + +#include "telephony.h" + +int telephony_pullmissedcalls(guint8 *missedcalls) +{ + *missedcalls = 0; + + return 0; +} diff --git a/plugins/telephony.h b/plugins/telephony.h new file mode 100644 index 0000000..8f9a4c0 --- /dev/null +++ b/plugins/telephony.h @@ -0,0 +1,25 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2007-2009 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 telephony_pullmissedcalls(guint8 *missedcalls); |