diff -Nurd obexd-0.20/configure.ac obexd-0.20+fso/configure.ac --- obexd-0.20/configure.ac 2009-12-07 23:12:10.000000000 +0100 +++ obexd-0.20+fso/configure.ac 2009-12-20 20:14:36.000000000 +0100 @@ -122,6 +122,10 @@ AC_SUBST(GTHREAD_LIBS) fi +if (test "${phonebook_driver}" = "fso"); then + PKG_CHECK_MODULES(FRAMEWORKD_GLIB, libframeworkd-glib) +fi + AC_SUBST([PHONEBOOK_DRIVER], [phonebook-${phonebook_driver}.c]) telephony_driver=dummy @@ -129,6 +133,10 @@ telephony_driver=${withval} ]) +if (test "${telephony_driver}" = "fso"); then + PKG_CHECK_MODULES(FRAMEWORKD_GLIB, libframeworkd-glib) +fi + AC_SUBST([TELEPHONY_DRIVER], [telephony-${telephony_driver}.c]) AC_ARG_ENABLE(server, AC_HELP_STRING([--disable-server], diff -Nurd obexd-0.20/Makefile.am obexd-0.20+fso/Makefile.am --- obexd-0.20/Makefile.am 2009-11-19 05:53:10.000000000 +0100 +++ obexd-0.20+fso/Makefile.am 2009-12-19 19:33:54.000000000 +0100 @@ -58,7 +58,7 @@ src_obexd_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ @GTHREAD_LIBS@ \ @EBOOK_LIBS@ @OPENOBEX_LIBS@ \ - @BLUEZ_LIBS@ -ldl + @BLUEZ_LIBS@ @FRAMEWORKD_GLIB_LIBS@ -ldl src_obexd_LDFLAGS = -Wl,--export-dynamic @@ -100,7 +100,8 @@ AM_CFLAGS = @OPENOBEX_CFLAGS@ @BLUEZ_CFLAGS@ @EBOOK_CFLAGS@ \ @GTHREAD_CFLAGS@ @GLIB_CFLAGS@ @DBUS_CFLAGS@ \ - -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\" + -DOBEX_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\" \ + @FRAMEWORKD_GLIB_CFLAGS@ INCLUDES = -I$(builddir)/src -I$(srcdir)/src -I$(srcdir)/plugins \ -I$(srcdir)/gdbus -I$(srcdir)/gwobex @@ -110,7 +111,7 @@ EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \ src/obexd.service.in client/obex-client.service.in \ plugins/phonebook-dummy.c plugins/phonebook-ebook.c \ - plugins/telephony-dummy.c + plugins/telephony-dummy.c plugins/telephony-fso.c DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server diff -Nurd obexd-0.20/plugins/phonebook-fso.c obexd-0.20+fso/plugins/phonebook-fso.c --- obexd-0.20/plugins/phonebook-fso.c 1970-01-01 01:00:00.000000000 +0100 +++ obexd-0.20+fso/plugins/phonebook-fso.c 2010-01-11 12:37:10.000000000 +0100 @@ -0,0 +1,509 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2009-2010 Thomas Zimmermann + * Copyright (C) 2009 Intel Corporation + * Copyright (C) 2007-2009 Marcel Holtmann + * + * + * 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 +#endif + +#include +#include + +#include +#include +#include + +#include "logging.h" +#include "obex.h" +#include "phonebook.h" + +#include +#include +#include + +#define EOL_CHARS "\n" +#define VL_VERSION "" EOL_CHARS +#define VL_TYPE "" EOL_CHARS +#define VL_BODY_BEGIN "" EOL_CHARS +#define VL_BODY_END "" EOL_CHARS +#define VL_ELEMENT "" EOL_CHARS + +typedef enum { + VCARD_21, + VCARD_30 +} VCardFormat; + +struct _contact_list_pack { + gpointer data; + int *count; + void (*callback)(gpointer, gpointer); + DBusGProxy *query; + obex_t *obex; + obex_object_t *obj; + struct apparam_field params; +}; + +static gint +_compare_contacts(gconstpointer _a, gconstpointer _b) +{ + GHashTable **a = (GHashTable **) _a; + GHashTable **b = (GHashTable **) _b; + gpointer p; + const char *name_a, *name_b; +/* Probably not best (sorting by just Name) but will have to do ATM */ + p = g_hash_table_lookup(*a, "Name"); + if (!p) { + name_a = ""; + g_debug("name a not found!!!!"); + } + else + name_a = g_value_get_string(p); + + p = g_hash_table_lookup(*b, "Name"); + if (!p) { + name_b = ""; + g_debug("name b not found!!!!"); + } + else + name_b = g_value_get_string(p); + + return (strcasecmp(name_a, name_b)); +} + +static void +_contact_list_result_callback(GError *error, GPtrArray *contacts, void *_data) +{ + (void) error; + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + + if (error || !contacts) { + return; + } + GString *pb; + gchar *result; + gint32 size; + int i; + + pb = g_string_new(NULL); + + struct apparam_field *params = &data->params; + struct obex_session *session = OBEX_GetUserData(data->obex); +/* + g_ptr_array_sort(contacts, _compare_contacts); +*/ + for (i = 0; i < contacts->len && i < params->maxlistcount; i++) + { + gpointer _c, p; + const char *tmp, *vcard, *name, *firstname; + _c = g_ptr_array_index (contacts, i); + GHashTable **c = (GHashTable **) _c; + + g_string_append_printf(pb, "BEGIN:VCARD\n"); + if (params->format == VCARD_30) + g_string_append_printf(pb, "VERSION:3.0\n"); + else + g_string_append_printf(pb, "VERSION:2.1\n"); + + p = g_hash_table_lookup(*c, "Name"); + if (p) + name = g_value_get_string(p); + p = g_hash_table_lookup(*c, "Surname"); + if (p) + firstname = g_value_get_string(p); + if (!name && !firstname) continue; + if (!name) name = ""; + if (!firstname) firstname = ""; + g_string_append_printf(pb, "N:%s;%s\n", name, firstname); + + if (params->format == VCARD_30) + g_string_append_printf(pb, "FN:%s %s\n", firstname, name); + + p = g_hash_table_lookup(*c, "Phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,pref:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(*c, "Home phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,home:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;HOME;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(*c, "Cell phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=cell:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;CELL:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(*c, "Work phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,work:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;WORK;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(*c, "Fax phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=fax,home:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;HOME;FAX:%s\n", g_value_get_string(p)); + + /*TODO: add other fields*/ + + g_string_append_printf(pb, "END:VCARD\n\n"); + } + + 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); + + opimd_contact_query_dispose(data->query, NULL, NULL); +} + +static void +_contact_list_count_callback(GError *error, const int count, gpointer _data) +{ + (void) error; + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + DBG("Contact query result gave %d entries", count); + *data->count = count; + opimd_contact_query_get_multiple_results(data->query, + count, _contact_list_result_callback, data); +} + + +static void +_contact_query_callback(GError *error, char *query_path, gpointer _data) +{ + if (error == NULL) { + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + data->query = (DBusGProxy *) + dbus_connect_to_opimd_contact_query(query_path); + opimd_contact_query_get_result_count(data->query, + _contact_list_count_callback, data); + } +} + +int phonebook_pullphonebook(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + int count = 0; + + struct _contact_list_pack *data = + malloc(sizeof(struct _contact_list_pack)); + data->count = (int *)count; + data->obex = obex; + data->obj = obj; + data->params = params; + + GHashTable *qry = g_hash_table_new_full + (g_str_hash, g_str_equal, NULL, NULL); + opimd_contacts_query(qry, _contact_query_callback, data); + g_hash_table_destroy(qry); + + OBEX_SuspendRequest(obex, obj); + + return count; +} + +static void +_contact_listing_result_callback(GError *error, GPtrArray *contacts, void *_data) +{ + (void) error; + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + + if (error || !contacts) { + return; + } + + gchar *result; + gint32 size; + int i; + GString *listing; + guint16 offset = 0, count = 0, index; + + listing = g_string_new(VL_VERSION); + listing = g_string_append(listing, VL_TYPE); + listing = g_string_append(listing, VL_BODY_BEGIN); + + struct apparam_field *params = &data->params; + struct obex_session *session = OBEX_GetUserData(data->obex); + + for (i = offset; i < contacts->len && i < params->maxlistcount; i++) + { + gchar *element = NULL; + const char *name = NULL, *path = NULL; + gpointer _c, p; + + _c = g_ptr_array_index (contacts, i); + GHashTable **c = (GHashTable **) _c; + + index = -1; + + p = g_hash_table_lookup(*c, "Path"); + if (p) + { + path = g_value_get_string(p); + sscanf(path, "/org/freesmartphone/PIM/Contacts/%d", &index); + } + + p = g_hash_table_lookup(*c, "Name"); + if (p) + { + name = g_value_get_string(p); + } + + if (name && index) + { + element = g_strdup_printf(VL_ELEMENT, index, name); + listing = g_string_append(listing, element); + } + g_free(element); + } + + 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); + + opimd_contact_query_dispose(data->query, NULL, NULL); +} + +static void +_contact_listing_count_callback(GError *error, const int count, gpointer _data) +{ + (void) error; + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + DBG("Contact query result gave %d entries", count); + *data->count = count; + opimd_contact_query_get_multiple_results(data->query, + count, _contact_listing_result_callback, data); +} + +static void +_contact_listing_callback(GError *error, char *query_path, gpointer _data) +{ + if (error == NULL) { + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + data->query = (DBusGProxy *) + dbus_connect_to_opimd_contact_query(query_path); + opimd_contact_query_get_result_count(data->query, + _contact_listing_count_callback, data); + } +} + +int phonebook_pullvcardlisting(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + struct _contact_list_pack *data = + malloc(sizeof(struct _contact_list_pack)); + data->obex = obex; + data->obj = obj; + data->params = params; + + GHashTable *qry = g_hash_table_new_full + (g_str_hash, g_str_equal, NULL, 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); + } + */ + + opimd_contacts_query(qry, _contact_listing_callback, data); + g_hash_table_destroy(qry); + + OBEX_SuspendRequest(obex, obj); + + return 0; +} + +static void +_contact_entry_callback(GError *error, GHashTable *c, void *_data) +{ + (void) error; + struct _contact_list_pack *data = + (struct _contact_list_pack *)_data; + + if (error || !c) { + return; + } + + GString *pb; + gchar *result; + gint32 size; + + pb = g_string_new(NULL); + + struct apparam_field *params = &data->params; + struct obex_session *session = OBEX_GetUserData(data->obex); + + gpointer p; + const char *tmp, *vcard, *name, *firstname; + + g_string_append_printf(pb, "BEGIN:VCARD\n"); + if (params->format == VCARD_30) + g_string_append_printf(pb, "VERSION:3.0\n"); + else + g_string_append_printf(pb, "VERSION:2.1\n"); + + p = g_hash_table_lookup(c, "Name"); + if (p) + name = g_value_get_string(p); + p = g_hash_table_lookup(c, "Surname"); + if (p) + firstname = g_value_get_string(p); + if (!name && !firstname) return; + if (!name) name = ""; + if (!firstname) firstname = ""; + g_string_append_printf(pb, "N:%s;%s\n", name, firstname); + + if (params->format == VCARD_30) + g_string_append_printf(pb, "FN:%s %s\n", firstname, name); + + p = g_hash_table_lookup(c, "Phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,pref:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(c, "Home phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,home:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;HOME;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(c, "Cell phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=cell:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;CELL:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(c, "Work phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=voice,work:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;WORK;VOICE:%s\n", g_value_get_string(p)); + + p = g_hash_table_lookup(c, "Fax phone"); + if (p) + if (params->format == VCARD_30) + g_string_append_printf(pb, "TEL;TYPE=fax,home:%s\n", g_value_get_string(p)); + else + g_string_append_printf(pb, "TEL;HOME;FAX:%s\n", g_value_get_string(p)); + + /*TODO: add other fields*/ + + g_string_append_printf(pb, "END:VCARD\n\n"); + + 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); +} + +int phonebook_pullvcardentry(obex_t *obex, obex_object_t *obj, + struct apparam_field params) +{ + guint16 index; + gchar *path; + struct _contact_list_pack *data = + malloc(sizeof(struct _contact_list_pack)); + data->obex = obex; + data->obj = obj; + data->params = params; + + struct obex_session *session = OBEX_GetUserData(obex); + sscanf(session->name, "%hu.vcf", &index); + g_snprintf(path, 1, "/org/freesmartphone/PIM/Contacts/%d", index); + + opimd_contact_get_content(path, _contact_entry_callback, data); + + OBEX_SuspendRequest(obex, obj); + + return 0; +} diff -Nurd obexd-0.20/plugins/telephony-fso.c obexd-0.20+fso/plugins/telephony-fso.c --- obexd-0.20/plugins/telephony-fso.c 1970-01-01 01:00:00.000000000 +0100 +++ obexd-0.20+fso/plugins/telephony-fso.c 2009-12-19 19:40:22.000000000 +0100 @@ -0,0 +1,74 @@ +/* + * + * OBEX Server + * + * Copyright (C) 2009 Thomas Zimmermann + * Copyright (C) 2009 Intel Corporation + * Copyright (C) 2007-2009 Marcel Holtmann + * + * + * 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 +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include + +#include "telephony.h" +#include "logging.h" + +#include + +static void _missed_calls_callback(GError *error, const int amount, gpointer userdata); +static int called; +static int calls; + +int telephony_pullmissedcalls(guint8 *missedcalls) +{ + called = -1; + calls = 0; + + opimd_calls_get_new_missed_calls(_missed_calls_callback, NULL); + + while (called != 0) + { +#ifdef HAVE_UNISTD_H + usleep(100); +#endif + } + + *missedcalls = calls; + return calls; +} + +static void _missed_calls_callback(GError *error, const int amount, gpointer userdata) +{ + (void)userdata; + + if (error) { + DBG("_missed_calls_callback: error %d: %s", error->code, error->message); + return; + } + + calls = amount; + called = 0; +} diff -Nurd obexd-0.20/src/obexd.service.in obexd-0.20+fso/src/obexd.service.in --- obexd-0.20/src/obexd.service.in 2008-10-04 15:05:03.000000000 +0200 +++ obexd-0.20+fso/src/obexd.service.in 2010-01-11 12:41:58.000000000 +0100 @@ -1,3 +1,3 @@ [D-BUS Service] Name=org.openobex -Exec=@libexecdir@/obexd --nodaemon --opp --ftp +Exec=@libexecdir@/obexd --nodaemon --opp --ftp --pbap