[PATCH] Implements the OBEX server/SyncML binding for syncEvolution (http://syncevolution.org/).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



OBEX/SyncML binding spec is at http://www.openmobilealliance.net/
Technical/release_program/docs/Common/V1_2_1-20070813-A/OMA-TS-SyncML_OBEXBinding-V1_2-20070221-A.pdf
---
This is the refined patch according to Patrick's comments.

 Makefile.am         |    2 +-
 src/main.c          |   17 ++-
 src/manager.c       |   33 +++++
 src/obex.c          |   47 +++++--
 src/obex.h          |   10 ++
 src/syncevolution.c |  362 +++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 458 insertions(+), 13 deletions(-)
 create mode 100644 src/syncevolution.c

diff --git a/Makefile.am b/Makefile.am
index 63f7478..49817ee 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,7 +31,7 @@ src_obexd_SOURCES = $(gdbus_sources) \
 			src/main.c src/obexd.h src/plugin.h src/plugin.c \
 			src/logging.h src/logging.c src/btio.h src/btio.c \
 			src/dbus.h src/manager.c src/obex.h src/obex.c \
-			src/opp.c src/ftp.c src/pbap.c \
+			src/opp.c src/ftp.c src/pbap.c src/syncevolution.c \
 			src/bluetooth.h src/bluetooth.c \
 			src/phonebook.h src/phonebook.c
 
diff --git a/src/main.c b/src/main.c
index abd2bcc..520973f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -53,6 +53,7 @@
 #define OPP_CHANNEL	9
 #define FTP_CHANNEL	10
 #define PBAP_CHANNEL	15
+#define SYNCEVOLUTION_CHANNEL	16
 #define PCSUITE_CHANNEL	24
 
 #define DEFAULT_ROOT_PATH "/tmp"
@@ -172,6 +173,7 @@ static gboolean option_ftp = FALSE;
 static gboolean option_pbap = FALSE;
 static gboolean option_pcsuite = FALSE;
 static gboolean option_symlinks = FALSE;
+static gboolean option_syncevolution = FALSE;
 
 static GOptionEntry options[] = {
 	{ "nodaemon", 'n', G_OPTION_FLAG_REVERSE,
@@ -199,6 +201,8 @@ static GOptionEntry options[] = {
 				"Enable Phonebook Access server" },
 	{ "pcsuite", 's', 0, G_OPTION_ARG_NONE, &option_pcsuite,
 				"Enable PC Suite Services server" },
+	{ "syncevolution", 'e', 0, G_OPTION_ARG_NONE, &option_syncevolution,
+				"Enable OBEX server for SyncEvolution" },
 	{ NULL },
 };
 
@@ -337,9 +341,9 @@ int main(int argc, char *argv[])
 		log_option |= LOG_PERROR;
 
 	if (option_opp == FALSE && option_ftp == FALSE &&
-						option_pbap == FALSE) {
+		option_pbap == FALSE && option_syncevolution == FALSE) {
 		fprintf(stderr, "No server selected (use either "
-					"--opp or --ftp or both)\n");
+				"--opp, --ftp, --pbap or --syncevolution)\n");
 		exit(EXIT_FAILURE);
 	}
 
@@ -408,6 +412,15 @@ int main(int argc, char *argv[])
 				option_capability);
 	}
 
+	/* FIXME: move "SyncEvolution" from ServiceName to ProviderName */
+	if (option_syncevolution == TRUE) {
+		services |= OBEX_SYNCEVOLUTION;
+		bluetooth_init(OBEX_SYNCEVOLUTION, "OBEX server for SyncML,"
+				" using SyncEvolution", NULL,
+				SYNCEVOLUTION_CHANNEL, TRUE, FALSE, FALSE,
+				NULL);
+	}
+
 	if (option_devnode)
 		devnode_setup();
 
diff --git a/src/manager.c b/src/manager.c
index 24ed3db..c36ecfd 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -216,6 +216,35 @@ static const gchar *pcsuite_record =
   </attribute>									\
 </record>";
 
+static const gchar *syncevolution_record =
+"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>					\
+<record>									\
+ <attribute id=\"0x0001\">							\
+    <sequence>									\
+      <uuid value=\"00000002-0000-1000-8000-0002ee000002\"/>			\
+    </sequence>									\
+ </attribute>									\
+										\
+ <attribute id=\"0x0004\">							\
+    <sequence>									\
+      <sequence>								\
+        <uuid value=\"0x0100\"/>						\
+      </sequence>								\
+      <sequence>								\
+        <uuid value=\"0x0003\"/>						\
+        <uint8 value=\"%u\" name=\"channel\"/>					\
+      </sequence>								\
+      <sequence>								\
+        <uuid value=\"0x0008\"/>						\
+      </sequence>								\
+    </sequence>									\
+ </attribute>									\
+										\
+ <attribute id=\"0x0100\">							\
+    <text value=\"%s\" name=\"name\"/>						\
+ </attribute>									\
+</record>";
+
 #define TRANSFER_INTERFACE OPENOBEX_SERVICE ".Transfer"
 #define SESSION_INTERFACE OPENOBEX_SERVICE ".Session"
 
@@ -525,6 +554,10 @@ static gchar *create_xml_record(const char *name,
 	case OBEX_PCSUITE:
 		xml = g_markup_printf_escaped(pcsuite_record, channel, name);
 		break;
+	case OBEX_SYNCEVOLUTION:
+		xml = g_markup_printf_escaped(syncevolution_record, channel,
+								name);
+		break;
 	default:
 		xml = NULL;
 		break;
diff --git a/src/obex.c b/src/obex.c
index 9ec9c5b..61fc5c5 100644
--- a/src/obex.c
+++ b/src/obex.c
@@ -53,6 +53,7 @@
 #define DEFAULT_TX_MTU 32767
 
 #define TARGET_SIZE 16
+#define SYNCML_TARGET_SIZE 11
 
 static const guint8 FTP_TARGET[TARGET_SIZE] = {
 			0xF9, 0xEC, 0x7B, 0xC4,  0x95, 0x3C, 0x11, 0xD2,
@@ -62,6 +63,10 @@ static const guint8 PBAP_TARGET[TARGET_SIZE] = {
 			0x79, 0x61, 0x35, 0xF0,  0xF0, 0xC5, 0x11, 0xD8,
 			0x09, 0x66, 0x08, 0x00,  0x20, 0x0C, 0x9A, 0x66  };
 
+static const guint8 SYNCML_TARGET[SYNCML_TARGET_SIZE] = {
+			0x53, 0x59, 0x4E, 0x43, 0x4D, 0x4C, 0x2D, 0x53,
+			0x59, 0x4E, 0x43 };
+
 /* Connection ID */
 static guint32 cid = 0x0000;
 
@@ -91,6 +96,11 @@ struct obex_commands pbap = {
 	.setpath	= pbap_setpath,
 };
 
+struct obex_commands synce = {
+	.put		= synce_put,
+	.get		= synce_get,
+};
+
 static void os_reset_session(struct obex_session *os)
 {
 	if (os->fd > 0) {
@@ -119,6 +129,7 @@ static void os_reset_session(struct obex_session *os)
 	os->offset = 0;
 	os->size = OBJECT_SIZE_DELETE;
 	os->finished = 0;
+	os->reply_received = 0;
 }
 
 static void os_session_mark_aborted(struct obex_session *os)
@@ -145,6 +156,9 @@ static void obex_session_free(struct obex_session *os)
 
 	if (os->target && !memcmp(os->target, PBAP_TARGET, TARGET_SIZE))
 		pbap_phonebook_context_destroy(os);
+	else if (os->target && !memcmp(os->target, SYNCML_TARGET,
+					SYNCML_TARGET_SIZE))
+		synce_destroy(os);
 
 	g_free(os);
 }
@@ -202,7 +216,7 @@ static void cmd_connect(struct obex_session *os,
 	obex_connect_hdr_t *nonhdr;
 	obex_headerdata_t hd;
 	uint8_t *buffer;
-	guint hlen, newsize;
+	guint hlen, newsize, target_size;
 	guint16 mtu;
 	guint8 hi;
 
@@ -227,8 +241,20 @@ static void cmd_connect(struct obex_session *os,
 	os->cid = ++cid;
 
 	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
-		if (hi != OBEX_HDR_TARGET || hlen != TARGET_SIZE)
+		if (hi != OBEX_HDR_TARGET || (hlen != TARGET_SIZE &&
+					hlen != SYNCML_TARGET_SIZE))
 			continue;
+		target_size = hlen;
+
+		if (memcmp(hd.bs, SYNCML_TARGET, SYNCML_TARGET_SIZE) == 0 &&
+				os->server->services & OBEX_SYNCEVOLUTION) {
+			if (!synce_connect(os))
+				break;
+
+			os->target = SYNCML_TARGET;
+			os->cmds = &synce;
+			break;
+		}
 
 		if (memcmp(hd.bs, FTP_TARGET, TARGET_SIZE) == 0 &&
 				os->server->services &
@@ -270,7 +296,7 @@ static void cmd_connect(struct obex_session *os,
 	/* Append received UUID in WHO header */
 	hd.bs = os->target;
 	OBEX_ObjectAddHeader(obex, obj,
-			OBEX_HDR_WHO, hd, TARGET_SIZE,
+			OBEX_HDR_WHO, hd, target_size,
 			OBEX_FL_FIT_ONE_PACKET);
 	hd.bq4 = cid;
 	OBEX_ObjectAddHeader(obex, obj,
@@ -337,7 +363,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
 		os->name = NULL;
 	}
 
-	if (os->buf) {
+	if (os->buf && memcmp(os->target, SYNCML_TARGET, SYNCML_TARGET_SIZE)) {
 		g_free(os->buf);
 		os->buf = NULL;
 	}
@@ -599,15 +625,15 @@ static gint obex_read_stream(struct obex_session *os, obex_t *obex,
 	}
 
 	if (os->fd < 0 && size > 0) {
-		if (os->buf) {
+		if (os->buf && memcmp(os->target, SYNCML_TARGET,
+					SYNCML_TARGET_SIZE)) {
 			error("Got more data but there is still a pending buffer");
 			return -EIO;
 		}
 
-		os->buf = g_malloc0(os->rx_mtu);
-		memcpy(os->buf, buffer, size);
-		os->offset = size;
-
+		os->buf = g_realloc(os->buf, os->offset + size);
+		memcpy(os->buf + os->offset, buffer, size);
+		os->offset += size;
 		debug("Stored %u bytes into temporary buffer", size);
 
 		return 0;
@@ -710,7 +736,8 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
 
 	OBEX_ObjectReParseHeaders(obex, obj);
 
-	if (!os->name) {
+	if (!os->name && memcmp(os->target, SYNCML_TARGET,
+					SYNCML_TARGET_SIZE)) {
 		OBEX_ObjectSetRsp(obj, OBEX_RSP_BAD_REQUEST,
 				OBEX_RSP_BAD_REQUEST);
 		g_free(os->type);
diff --git a/src/obex.h b/src/obex.h
index 94a273e..b9af4ed 100644
--- a/src/obex.h
+++ b/src/obex.h
@@ -27,6 +27,7 @@
 #include <config.h>
 #endif
 
+#include <dbus/dbus.h>
 #include <glib.h>
 
 #include "phonebook.h"
@@ -36,6 +37,7 @@
 #define OBEX_BIP	(1 << 3)
 #define OBEX_PBAP	(1 << 4)
 #define OBEX_PCSUITE	(1 << 5)
+#define OBEX_SYNCEVOLUTION	(1 << 6)
 
 #define OBJECT_SIZE_UNKNOWN -1
 #define OBJECT_SIZE_DELETE -2
@@ -86,6 +88,9 @@ struct obex_session {
 	obex_t		*obex;
 	struct phonebook_context *pbctx;
 	gboolean	finished;
+	DBusConnection	*dbus_conn;
+	gchar		*conn_obj;
+	gboolean	reply_received;
 };
 
 gint obex_session_start(GIOChannel *io, struct server *server);
@@ -106,6 +111,11 @@ gboolean pbap_phonebook_context_create(struct obex_session *session);
 void pbap_phonebook_context_destroy(struct obex_session *session);
 struct obex_session *pbap_get_session(struct phonebook_context *context);
 
+gboolean synce_connect(struct obex_session *os);
+void synce_put(obex_t *obex, obex_object_t *obj);
+void synce_get(obex_t *obex, obex_object_t *obj);
+void synce_destroy(struct obex_session *os);
+
 gint os_prepare_get(struct obex_session *os, gchar *file, guint32 *size);
 gint os_prepare_put(struct obex_session *os);
 
diff --git a/src/syncevolution.c b/src/syncevolution.c
new file mode 100644
index 0000000..c65fce9
--- /dev/null
+++ b/src/syncevolution.c
@@ -0,0 +1,362 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2007-2008  Intel Corporation
+ *  Copyright (C) 2007-2009  Marcel Holtmann <marcel@xxxxxxxxxxxx>
+ *
+ *
+ *  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 <stdio.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+
+#include <openobex/obex.h>
+#include <openobex/obex_const.h>
+
+#include "logging.h"
+#include "obex.h"
+#include "obexd.h"
+#include "dbus.h"
+#include "btio.h"
+
+#define SYNCE_BUS_NAME	"org.syncevolution"
+#define SYNCE_PATH	"/org/syncevolution/Server"
+#define SYNCE_SERVER_INTERFACE	"org.syncevolution.Server"
+#define SYNCE_CONN_INTERFACE	"org.syncevolution.Connection"
+
+static char match_string[256];
+
+struct cb_data {
+	struct obex_session *os;
+	obex_object_t *obj;
+} process_cb_data;
+
+static GSList *os_list = NULL;
+
+static void dbus_message_iter_append_dict_entry(DBusMessageIter *dict,
+				const char *key, int type, void *val)
+{
+	DBusMessageIter entry;
+
+	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+						NULL, &entry);
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &val);
+	dbus_message_iter_close_container(dict, &entry);
+}
+
+static void handle_connection_reply_signal(DBusMessage *msg,
+				const char *obj_path, void *data)
+{
+	struct obex_session *os = data;
+	DBusMessageIter iter, array_iter;
+	gchar *value;
+	gint length = 0;
+
+	if (strcmp(os->conn_obj, obj_path))
+		return;
+
+	dbus_message_iter_init(msg, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+		error("Unexpected signature in Reply signal");
+	}
+
+	dbus_message_iter_recurse(&iter, &array_iter);
+	dbus_message_iter_get_fixed_array(&array_iter, &value, &length);
+
+	if (length) {
+		os->buf = g_try_malloc(length);
+		memcpy(os->buf, value, length);
+		os->size = length;
+		os->reply_received = TRUE;
+		os->finished = TRUE;
+		OBEX_ResumeRequest(os->obex);
+	}
+}
+
+static void handle_connection_abort_signal(DBusMessage *msg,
+				const char *obj_path, void *data)
+{
+	struct obex_session *os = data;
+
+	OBEX_TransportDisconnect(os->obex);
+}
+
+static DBusHandlerResult signal_filter(DBusConnection *conn,
+				DBusMessage *msg, void *data)
+{
+	const char *path = dbus_message_get_path(msg);
+	struct obex_session *os = NULL;
+	GSList *l;
+
+	if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	for (l = os_list; l != NULL; l = l->next) {
+		struct obex_session *tmp_os = l->data;
+		if (!strcmp(tmp_os->conn_obj, path)) {
+			os = tmp_os;
+			break;
+		}
+	}
+	if (!os)
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	if (dbus_message_is_signal(msg, SYNCE_CONN_INTERFACE, "Reply")) {
+		debug("Reply signal is received.");
+		handle_connection_reply_signal(msg, path, os);
+	} else if (dbus_message_is_signal(msg, SYNCE_CONN_INTERFACE, "Abort")) {
+		debug("Abort signal is received.");
+		handle_connection_abort_signal(msg, path, os);
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void connect_cb(DBusPendingCall *call, void *user_data)
+{
+	static gboolean signal_filter_added = FALSE;
+	struct obex_session *os = user_data;
+	DBusConnection *conn = os->dbus_conn;
+	DBusMessage *reply;
+	gchar *path;
+
+	reply = dbus_pending_call_steal_reply(call);
+
+	dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+						DBUS_TYPE_INVALID);
+	info("Got conn object %s from syncevolution", path);
+	os->conn_obj = g_strdup(path);
+
+	/* add signal filter */
+	if (!signal_filter_added) {
+		if (!dbus_connection_add_filter(conn, signal_filter,
+							os, NULL)) {
+			error("Can't add signal filter");
+			dbus_message_unref(reply);
+			return;
+		}
+		signal_filter_added = TRUE;
+	}
+	os_list = g_slist_append(os_list, os);
+	snprintf(match_string, sizeof(match_string), "type=signal,interface=%s,"
+				"path=%s", SYNCE_CONN_INTERFACE, os->conn_obj);
+	dbus_bus_add_match(conn, match_string, NULL);
+	dbus_connection_flush(conn);
+
+	dbus_message_unref(reply);
+}
+
+static void process_cb(DBusPendingCall *call, void *user_data)
+{
+	DBusMessage *reply;
+	DBusError derr;
+
+	info("At the begin of process_cb().");
+	reply = dbus_pending_call_steal_reply(call);
+	dbus_error_init(&derr);
+	if (dbus_set_error_from_message(&derr, reply)) {
+		error("process_cb(): syncevolution replied with an error:"
+					" %s, %s", derr.name, derr.message);
+		dbus_error_free(&derr);
+	}
+	dbus_message_unref(reply);
+}
+
+gboolean synce_connect(struct obex_session *os)
+{
+	DBusConnection *conn = NULL;
+	GError *err = NULL;
+	char address[18];
+	guint8 channel;
+	DBusMessage *msg;
+	DBusMessageIter iter, dict;
+	gchar id[36];
+	gchar transport[36];
+	gchar transport_description[24];
+	gboolean authenticate = FALSE;
+	char *session = "";
+	DBusPendingCall *call;
+
+	conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+	if (conn == NULL)
+		return FALSE;
+
+	bt_io_get(os->io, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_DEST, address,
+			BT_IO_OPT_CHANNEL, &channel,
+			BT_IO_OPT_INVALID);
+
+	msg = dbus_message_new_method_call(SYNCE_BUS_NAME, SYNCE_PATH,
+				SYNCE_SERVER_INTERFACE, "Connect");
+	dbus_message_iter_init_append(msg, &iter);
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+		DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+		DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
+		DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	snprintf(id, sizeof(id), "%s+%u", address, channel);
+	dbus_message_iter_append_dict_entry(&dict, "id", DBUS_TYPE_STRING, id);
+
+	snprintf(transport, sizeof(transport), "%s.obexd",
+					OPENOBEX_SERVICE);
+	dbus_message_iter_append_dict_entry(&dict, "transport",
+				DBUS_TYPE_STRING, transport);
+
+	snprintf(transport_description, sizeof(transport_description),
+					"version %s", VERSION);
+	dbus_message_iter_append_dict_entry(&dict, "transport_description",
+				DBUS_TYPE_STRING, transport_description);
+	dbus_message_iter_close_container(&iter, &dict);
+	dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &authenticate,
+			DBUS_TYPE_STRING, &session, DBUS_TYPE_INVALID);
+
+	if (!dbus_connection_send_with_reply(conn, msg, &call, -1)) {
+		error("D-Bus call to %s failed.", SYNCE_SERVER_INTERFACE);
+		dbus_message_unref(msg);
+		return FALSE;
+	}
+
+	dbus_pending_call_set_notify(call, connect_cb, os, NULL);
+
+	os->dbus_conn = conn;
+
+	dbus_pending_call_unref(call);
+	dbus_message_unref(msg);
+	return TRUE;
+}
+
+void synce_put(obex_t *obex, obex_object_t *obj)
+{
+	struct obex_session *os;
+	DBusMessage *msg;
+	DBusMessageIter iter, array_iter;
+	DBusPendingCall *call;
+
+	os = OBEX_GetUserData(obex);
+	if (os == NULL)
+		return;
+
+	if (!os->conn_obj) {
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_SERVICE_UNAVAILABLE,
+					OBEX_RSP_SERVICE_UNAVAILABLE);
+		return;
+	}
+
+	msg = dbus_message_new_method_call(SYNCE_BUS_NAME, os->conn_obj,
+					SYNCE_CONN_INTERFACE, "Process");
+	dbus_message_iter_init_append(msg, &iter);
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+				DBUS_TYPE_BYTE_AS_STRING, &array_iter);
+	dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
+						&os->buf, os->offset);
+	dbus_message_iter_close_container(&iter, &array_iter);
+
+	dbus_message_append_args(msg, DBUS_TYPE_STRING, &os->type,
+						DBUS_TYPE_INVALID);
+
+	if (!dbus_connection_send_with_reply(os->dbus_conn, msg, &call, -1)) {
+		error("D-Bus call to %s failed.", SYNCE_CONN_INTERFACE);
+		dbus_message_unref(msg);
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		return;
+	}
+
+	dbus_pending_call_set_notify(call, process_cb, os, NULL);
+
+	dbus_message_unref(msg);
+	dbus_pending_call_unref(call);
+
+	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+	return;
+}
+
+void synce_get(obex_t *obex, obex_object_t *obj)
+{
+	obex_headerdata_t hd;
+	struct obex_session *os;
+
+	os = OBEX_GetUserData(obex);
+	if (os == NULL)
+		return;
+
+	if (!os->reply_received) {
+		debug("in synce_get() OBEX_SuspendRequest() is called");
+		OBEX_SuspendRequest(obex, obj);
+	}
+
+	hd.bs = NULL;
+	OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, 0,
+					OBEX_FL_STREAM_START);
+
+	OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+	return;
+}
+
+static void close_cb(DBusPendingCall *call, void *user_data)
+{
+	DBusMessage *reply;
+	DBusError derr;
+
+	reply = dbus_pending_call_steal_reply(call);
+	dbus_error_init(&derr);
+	if (dbus_set_error_from_message(&derr, reply)) {
+		error("close_cb(): syncevolution replied with an error:"
+					" %s, %s", derr.name, derr.message);
+		dbus_error_free(&derr);
+	}
+
+	dbus_message_unref(reply);
+}
+
+void synce_destroy(struct obex_session *os)
+{
+	DBusMessage *msg;
+	gboolean normal = TRUE;
+	gchar *error = "none";
+	DBusPendingCall *call;
+
+	debug("At the begin of synce_destroy().");
+	if (os->conn_obj) {
+		msg = dbus_message_new_method_call(SYNCE_BUS_NAME, os->conn_obj,
+						SYNCE_CONN_INTERFACE, "Close");
+		dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &normal,
+				DBUS_TYPE_STRING, &error, DBUS_TYPE_INVALID);
+		dbus_connection_send_with_reply(os->dbus_conn, msg, &call, -1);
+		dbus_pending_call_set_notify(call, close_cb, NULL, NULL);
+		dbus_message_unref(msg);
+		dbus_pending_call_unref(call);
+
+		snprintf(match_string, sizeof(match_string),
+			"type=signal,interface=%s,path=%s",
+			SYNCE_CONN_INTERFACE, os->conn_obj);
+		dbus_bus_remove_match(os->dbus_conn, match_string, NULL);
+		g_free(os->conn_obj);
+		os->conn_obj = NULL;
+	}
+	dbus_connection_unref(os->dbus_conn);
+	os_list = g_slist_remove(os_list, os);
+}
-- 
1.5.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux