diff --git a/obexd/plugins/syncevolution.c b/obexd/plugins/syncevolution.c
index 8abd287..fa4b686 100644
--- a/obexd/plugins/syncevolution.c
+++ b/obexd/plugins/syncevolution.c
#include "plugin.h"
#include "obex.h"
#include "service.h"
+#include "mimetype.h"
#include "logging.h"
#include "dbus.h"
#include "btio.h"
#include "obexd.h"
#include "gdbus.h"
+#include "filesystem.h"
#define SYNCML_TARGET_SIZE 11
struct obex_session *os;
DBusConnection *dbus_conn;
gchar *conn_obj;
- gboolean reply_received;
guint reply_watch;
guint abort_watch;
+ GString *buffer;
+ int lasterr;
};
-struct callback_data {
- obex_t *obex;
- obex_object_t *obj;
-};
-
-static GSList *context_list = NULL;
-
-static struct synce_context *find_context(struct obex_session *os)
-{
- GSList *l;
-
- for (l = context_list; l != NULL; l = l->next) {
- struct synce_context *context = l->data;
-
- if (context->os == os)
- return context;
- }
-
- return NULL;
-}
-
static void append_dict_entry(DBusMessageIter *dict, const char *key,
int type, void *val)
{
void *data)
{
struct synce_context *context = data;
- struct obex_session *os = context->os;
const char *path = dbus_message_get_path(msg);
DBusMessageIter iter, array_iter;
gchar *value;
gint length;
- if (strcmp(context->conn_obj, path) != 0)
+ if (strcmp(context->conn_obj, path) != 0) {
+ obex_object_set_io_flags(context, G_IO_ERR, -EPERM);
+ context->lasterr = -EPERM;
return FALSE;
+ }
dbus_message_iter_init(msg, &iter);
dbus_message_iter_recurse(&iter, &array_iter);
dbus_message_iter_get_fixed_array(&array_iter, &value, &length);
- if (length == 0)
- return TRUE;
-
- os->buf = g_malloc(length);
- memcpy(os->buf, value, length);
- os->size = length;
- os->finished = TRUE;
- context->reply_received = TRUE;
- OBEX_ResumeRequest(os->obex);
+ context->buffer = g_string_new_len(value, length);
+ obex_object_set_io_flags(context, G_IO_IN, 0);
+ context->lasterr = 0;
return TRUE;
}
void *data)
{
struct synce_context *context = data;
- struct obex_session *os = context->os;
-
- os->size = 0;
- os->finished = TRUE;
- OBEX_ResumeRequest(os->obex);
- OBEX_TransportDisconnect(os->obex);
+ obex_object_set_io_flags(context, G_IO_ERR, -EPERM);
+ context->lasterr = -EPERM;
return TRUE;
}
static void connect_cb(DBusPendingCall *call, void *user_data)
{
- struct callback_data *cb_data = user_data;
- obex_t *obex = cb_data->obex;
- obex_object_t *obj = cb_data->obj;
- struct obex_session *os = OBEX_GetUserData(obex);
- struct synce_context *context;
+ struct synce_context *context = user_data;
DBusConnection *conn;
DBusMessage *reply;
DBusError err;
gchar *path;
- obex_headerdata_t hd;
-
- context = find_context(os);
- if (!context) {
- g_free(cb_data);
- goto failed;
- }
conn = context->dbus_conn;
abort_signal, context, NULL);
dbus_message_unref(reply);
- g_free(cb_data);
-
- /* Append received UUID in WHO header */
- manager_register_session(os);
-
- hd.bs = SYNCML_TARGET;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_WHO, hd, SYNCML_TARGET_SIZE,
- OBEX_FL_FIT_ONE_PACKET);
- hd.bq4 = os->cid;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_CONNECTION, hd, 4,
- OBEX_FL_FIT_ONE_PACKET);
- OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
- OBEX_ResumeRequest(obex);
return;
failed:
- OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
- OBEX_ResumeRequest(obex);
+ obex_object_set_io_flags(context, G_IO_ERR, -EPERM);
+ context->lasterr = -EPERM;
}
static void process_cb(DBusPendingCall *call, void *user_data)
{
+ struct synce_context *context = user_data;
DBusMessage *reply;
DBusError derr;
error("process_cb(): syncevolution replied with an error:"
" %s, %s", derr.name, derr.message);
dbus_error_free(&derr);
+
+ obex_object_set_io_flags(context, G_IO_ERR, -EPERM);
+ context->lasterr = -EPERM;
+ goto done;
}
+ obex_object_set_io_flags(context, G_IO_OUT, 0);
+ context->lasterr = 0;
+
+done:
dbus_message_unref(reply);
}
static int synce_connect(struct OBEX_session *os)
{
+ manager_register_session(os);
+
+ return 0;
+}
+
+static int synce_put(struct OBEX_session *os)
+{
+ return 0;
+}
+
+static int synce_get(struct OBEX_session *os, obex_object_t *obj)
+{
+ return 0;
+}
+
+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);
+}
+
+static void synce_disconnect(struct OBEX_session *os)
+{
+
+}
+
+static gpointer synce_open(const char *name, int oflag, mode_t mode,
+ size_t *size, struct OBEX_session *os, int *err)
+{
DBusConnection *conn;
- GError *err = NULL;
- gchar address[18], id[36], transport[36], transport_description[24];
- const char *session;
- guint8 channel;
- DBusMessage *msg;
- DBusMessageIter iter, dict;
- gboolean authenticate;
- DBusPendingCall *call;
- struct callback_data *cb_data;
struct synce_context *context;
conn = obex_dbus_get_connection();
if (!conn)
goto failed;
- bt_io_get(os->io, BT_IO_RFCOMM, &err,
- BT_IO_OPT_DEST, address,
- BT_IO_OPT_CHANNEL, &channel,
- BT_IO_OPT_INVALID);
+ context = g_new0(struct synce_context, 1);
+ context->os = os;
+ context->dbus_conn = conn;
+ context->lasterr = -EAGAIN;
+
+ if (err)
+ *err = 0;
+
+ return context;
+
+failed:
+ if (err)
+ *err = -EPERM;
+
+ return NULL;
+}
+
+static int synce_close(gpointer object)
+{
+ struct synce_context *context = object;
+ DBusMessage *msg;
+ const gchar *error;
+ gboolean normal;
+ DBusPendingCall *call;
+
+ if (!context->conn_obj)
+ goto done;
- if (err) {
- error("%s", err->message);
- g_error_free(err);
+ msg = dbus_message_new_method_call(SYNCE_BUS_NAME, context->conn_obj,
+ SYNCE_CONN_INTERFACE, "Close");
+ if (!msg)
+ goto failed;
+
+ normal = TRUE;
+ error = "none";
+ dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &normal,
+ DBUS_TYPE_STRING, &error, DBUS_TYPE_INVALID);
+
+ dbus_connection_send_with_reply(context->dbus_conn, msg, &call, -1);
+ dbus_pending_call_set_notify(call, close_cb, NULL, NULL);
+ dbus_message_unref(msg);
+ dbus_pending_call_unref(call);
+
+failed:
+ g_dbus_remove_watch(context->dbus_conn, context->reply_watch);
+ context->reply_watch = 0;
+ g_dbus_remove_watch(context->dbus_conn, context->abort_watch);
+ context->abort_watch = 0;
+
+ g_free(context->conn_obj);
+ context->conn_obj = NULL;
+
+done:
+ dbus_connection_unref(context->dbus_conn);
+ g_free(context);
+ return 0;
+}
+
+static ssize_t synce_read(gpointer object, void *buf, size_t count)
+{
+ struct synce_context *context = object;
+ struct OBEX_session *os = context->os;
+ DBusConnection *conn;
+ gchar *id, transport[36], transport_description[24];
+ const char *session;
+ DBusMessage *msg;
+ DBusMessageIter iter, dict;
+ gboolean authenticate;
+ DBusPendingCall *call;
+
+ if (context->buffer)
+ return string_read(context->buffer, buf, count);
+
+ conn = obex_dbus_get_connection();
+ if (conn == NULL)
goto failed;
- }
msg = dbus_message_new_method_call(SYNCE_BUS_NAME, SYNCE_PATH,
SYNCE_SERVER_INTERFACE, "Connect");
if (!msg)
goto failed;
+ id = obex_get_id(os);
+ if (id == NULL) {
+ dbus_message_unref(msg);
+ goto failed;
+ }
+
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);
append_dict_entry(&dict, "id", DBUS_TYPE_STRING, id);
+ g_free(id);
snprintf(transport, sizeof(transport), "%s.obexd",
OPENOBEX_SERVICE);
goto failed;
}
- /* FIXME: completely broken */
-
- cb_data = g_malloc0(sizeof(struct callback_data));
-#if 0
- cb_data->obex = os->obex;
- cb_data->obj = os->obj;
-#endif
- dbus_pending_call_set_notify(call, connect_cb, cb_data, NULL);
-
- context = g_new0(struct synce_context, 1);
- context->os = os;
- context->dbus_conn = conn;
- context_list = g_slist_append(context_list, context);
+ dbus_pending_call_set_notify(call, connect_cb, context, NULL);
dbus_pending_call_unref(call);
dbus_message_unref(msg);
-#if 0
- /* FIXME: broken */
- OBEX_SuspendRequest(obex, obj);
-#endif
- return 0;
+
+ return -EAGAIN;
failed:
return -EPERM;
}
-static int synce_put(struct OBEX_session *os)
+static ssize_t synce_write(gpointer object, const void *buf, size_t count)
{
- struct synce_context *context;
+ struct synce_context *context = object;
DBusMessage *msg;
DBusMessageIter iter, array_iter;
DBusPendingCall *call;
- const char *type = obex_get_type(os);
+ const char *type = obex_get_type(context->os);
- context = find_context(os);
- if (!context)
- return -EFAULT;
+ if (context->lasterr == 0)
+ return count;
if (!context->conn_obj)
return -EFAULT;
dbus_message_iter_init_append(msg, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
DBUS_TYPE_BYTE_AS_STRING, &array_iter);
- /* FIXME: broken */
-#if 0
+
dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
- &os->buf, os->offset);
-#endif
+ &buf, count);
dbus_message_iter_close_container(&iter, &array_iter);
dbus_message_append_args(msg, DBUS_TYPE_STRING, &type,
return -EPERM;
}
- dbus_pending_call_set_notify(call, process_cb, os, NULL);
-
- dbus_message_unref(msg);
- dbus_pending_call_unref(call);
-
- return 0;
-}
-
-static int synce_get(struct OBEX_session *os, obex_object_t *obj)
-{
- struct synce_context *context;
-
- context = find_context(os);
- if (!context)
- return -EPERM;
-
- return 0;
-}
-
-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);
-}
-
-static void synce_disconnect(struct OBEX_session *os)
-{
- struct synce_context *context;
- DBusMessage *msg;
- const gchar *error;
- gboolean normal;
- DBusPendingCall *call;
-
- context = find_context(os);
- if (!context)
- return;
-
- if (!context->conn_obj)
- goto done;
-
- msg = dbus_message_new_method_call(SYNCE_BUS_NAME, context->conn_obj,
- SYNCE_CONN_INTERFACE, "Close");
- if (!msg)
- goto failed;
-
- normal = TRUE;
- error = "none";
- dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &normal,
- DBUS_TYPE_STRING, &error, DBUS_TYPE_INVALID);
+ dbus_pending_call_set_notify(call, process_cb, context, NULL);
- dbus_connection_send_with_reply(context->dbus_conn, msg, &call, -1);
- dbus_pending_call_set_notify(call, close_cb, NULL, NULL);
dbus_message_unref(msg);
dbus_pending_call_unref(call);
-failed:
- g_dbus_remove_watch(context->dbus_conn, context->reply_watch);
- context->reply_watch = 0;
- g_dbus_remove_watch(context->dbus_conn, context->abort_watch);
- context->abort_watch = 0;
-
- g_free(context->conn_obj);
- context->conn_obj = NULL;
-
-done:
- dbus_connection_unref(context->dbus_conn);
- context_list = g_slist_remove(context_list, context);
- g_free(context);
+ return -EAGAIN;
}
-static void synce_reset(struct OBEX_session *os)
-{
- struct synce_context *context = find_context(os);
-
- if (context)
- context->reply_received = 0;
-}
+struct obex_mime_type_driver synce_driver = {
+ .target = SYNCML_TARGET,
+ .open = synce_open,
+ .close = synce_close,
+ .read = synce_read,
+ .write = synce_write,
+};
struct obex_service_driver synce = {
.name = "OBEX server for SyncML, using SyncEvolution",
.put = synce_put,
.connect = synce_connect,
.disconnect = synce_disconnect,
- .reset = synce_reset
};
static int synce_init(void)