From 6dfb501487c3256e766f3992559d1b1216c1b7c7 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 31 Mar 2010 17:30:28 -0300 Subject: [PATCH] obexd: service data structure cleanup Mimetype driver callbacks should not access directly obex_session or obex_object_t. This patch makes PBAP mimetype drivers independent of the obex session context. --- obexd/plugins/filesystem.c | 14 ++-- obexd/plugins/filesystem.h | 2 +- obexd/plugins/pbap.c | 117 ++++++++++++++++++++++++---------- obexd/plugins/syncevolution.c | 4 +- obexd/src/mimetype.h | 2 +- obexd/src/obex-priv.h | 1 - obexd/src/obex.c | 30 +++++---- 7 files changed, 117 insertions(+), 53 deletions(-) diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c index 9d7136a48..c1568f1b0 100644 --- a/obexd/plugins/filesystem.c +++ b/obexd/plugins/filesystem.c @@ -204,7 +204,7 @@ static int filesystem_close(gpointer object) return 0; } -static ssize_t filesystem_read(gpointer object, void *buf, size_t count) +static ssize_t filesystem_read(gpointer object, void *buf, size_t count, guint8 *hi) { ssize_t ret; @@ -212,6 +212,8 @@ static ssize_t filesystem_read(gpointer object, void *buf, size_t count) if (ret < 0) return -errno; + *hi = OBEX_HDR_BODY; + return ret; } @@ -465,11 +467,13 @@ int string_free(gpointer object) return 0; } -ssize_t string_read(gpointer object, void *buf, size_t count) +ssize_t string_read(gpointer object, void *buf, size_t count, guint8 *hi) { GString *string = object; ssize_t len; + *hi = OBEX_HDR_BODY; + if (string->len == 0) return 0; @@ -480,16 +484,18 @@ ssize_t string_read(gpointer object, void *buf, size_t count) return len; } -static ssize_t capability_read(gpointer object, void *buf, size_t count) +static ssize_t capability_read(gpointer object, void *buf, size_t count, + guint8 *hi) { struct capability_object *obj = object; if (obj->buffer) - return string_read(obj->buffer, buf, count); + return string_read(obj->buffer, buf, count, hi); if (obj->pid >= 0) return -EAGAIN; + *hi = OBEX_HDR_BODY; return read(obj->output, buf, count); } diff --git a/obexd/plugins/filesystem.h b/obexd/plugins/filesystem.h index 636ddb27a..1e1b352aa 100644 --- a/obexd/plugins/filesystem.h +++ b/obexd/plugins/filesystem.h @@ -22,4 +22,4 @@ */ int string_free(gpointer object); -ssize_t string_read(gpointer object, void *buf, size_t count); +ssize_t string_read(gpointer object, void *buf, size_t count, guint8 *hi); diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c index 12ecc29a7..0117b8e7f 100644 --- a/obexd/plugins/pbap.c +++ b/obexd/plugins/pbap.c @@ -142,12 +142,10 @@ struct cache_entry { }; struct pbap_session { - struct obex_session *os; struct apparam_field *params; gchar *folder; GString *buffer; guint16 phonebooksize; - obex_object_t *object; struct cache cache; }; @@ -330,7 +328,6 @@ static gpointer pbap_connect(struct obex_session *os, int *err) pbap = g_new0(struct pbap_session, 1); pbap->folder = g_strdup("/"); - pbap->os = os; if (err) *err = 0; @@ -394,7 +391,6 @@ static int pbap_get(struct obex_session *os, obex_object_t *obj, *stream = TRUE; pbap->params = params; - pbap->object = obj; ret = obex_get_stream_start(os, path, pbap); failed: @@ -474,11 +470,10 @@ static struct obex_service_driver pbap = { .chkput = pbap_chkput }; -static gpointer vobject_open(const char *name, int oflag, mode_t mode, +static gpointer vobject_pull_open(const char *name, int oflag, mode_t mode, gpointer context, size_t *size, int *err) { struct pbap_session *pbap = context; - const gchar *type = obex_get_type(pbap->os); phonebook_cb cb; int ret; @@ -492,23 +487,80 @@ static gpointer vobject_open(const char *name, int oflag, mode_t mode, else cb = query_result; - if (g_strcmp0(type, "x-bt/phonebook") == 0) - ret = phonebook_pull(name, pbap->params, cb, pbap); - else if (g_strcmp0(type, "x-bt/vcard-listing") == 0) { - /* FIXME: */ - cache_add(&pbap->cache, NULL); - cache_foreach(&pbap->cache, NULL, NULL, NULL); - ret = phonebook_list(name, pbap->params, cb, pbap); - } else if (g_strcmp0(type, "x-bt/vcard") == 0) { - /* FIXME: */ - gpointer id = cache_find(&pbap->cache, name); - debug("cache entry id: %p", id); - ret = phonebook_get_entry(name, pbap->params, query_result, pbap); - } else { - ret = -EINVAL; + ret = phonebook_pull(name, pbap->params, cb, pbap); + if (ret < 0) + goto fail; + + if (size) + *size = OBJECT_SIZE_UNKNOWN; + + return pbap; + +fail: + if (err) + *err = ret; + + return NULL; +} + +static gpointer vobject_list_open(const char *name, int oflag, mode_t mode, + gpointer context, size_t *size, int *err) +{ + struct pbap_session *pbap = context; + phonebook_cb cb; + int ret; + + if (oflag != O_RDONLY) { + ret = -EPERM; + goto fail; + } + + if (pbap->params->maxlistcount == 0) + cb = phonebook_size_result; + else + cb = query_result; + + /* FIXME: PullvCardList should read data from the cache only */ + cache_add(&pbap->cache, NULL); + cache_foreach(&pbap->cache, NULL, NULL, NULL); + + ret = phonebook_list(name, pbap->params, cb, pbap); + if (ret < 0) + goto fail; + + if (size) + *size = OBJECT_SIZE_UNKNOWN; + + return pbap; + +fail: + if (err) + *err = ret; + + return NULL; +} + + +static gpointer vobject_vcard_open(const char *name, int oflag, mode_t mode, + gpointer context, size_t *size, int *err) +{ + struct pbap_session *pbap = context; + gpointer id; + int ret; + + if (oflag != O_RDONLY) { + ret = -EPERM; + goto fail; + } + + id = cache_find(&pbap->cache, name); + if (!id) { + ret = -ENOENT; goto fail; } + /* FIXME: use id */ + ret = phonebook_get_entry(name, pbap->params, query_result, pbap); if (ret < 0) goto fail; @@ -524,9 +576,10 @@ fail: return NULL; } -static ssize_t vobject_read(gpointer object, void *buf, size_t count) +static ssize_t vobject_read(gpointer object, void *buf, size_t count, guint8 *hi) { struct pbap_session *pbap = object; + ssize_t ret = -EAGAIN; /* PhoneBookSize */ if (pbap->params->maxlistcount == 0) { @@ -539,16 +592,16 @@ static ssize_t vobject_read(gpointer object, void *buf, size_t count) hdr->len = PHONEBOOKSIZE_LEN; memcpy(hdr->val, &phonebooksize, sizeof(phonebooksize)); - obex_aparam_write(pbap->os, pbap->object, data, sizeof(data)); - - return 0; + memcpy(buf, data, sizeof(data)); + *hi = OBEX_HDR_APPARAM; + ret = 0; + } else if (pbap->buffer) { + /* Stream data */ + *hi = OBEX_HDR_BODY; + ret = string_read(pbap->buffer, buf, count, hi); } - /* Stream data */ - if (pbap->buffer) - return string_read(pbap->buffer, buf, count); - - return -EAGAIN; + return ret; } static int vobject_close(gpointer object) @@ -566,7 +619,7 @@ static int vobject_close(gpointer object) static struct obex_mime_type_driver mime_pull = { .target = PBAP_TARGET, .mimetype = "x-bt/phonebook", - .open = vobject_open, + .open = vobject_pull_open, .close = vobject_close, .read = vobject_read, }; @@ -574,7 +627,7 @@ static struct obex_mime_type_driver mime_pull = { static struct obex_mime_type_driver mime_list = { .target = PBAP_TARGET, .mimetype = "x-bt/vcard-listing", - .open = vobject_open, + .open = vobject_list_open, .close = vobject_close, .read = vobject_read, }; @@ -582,7 +635,7 @@ static struct obex_mime_type_driver mime_list = { static struct obex_mime_type_driver mime_vcard = { .target = PBAP_TARGET, .mimetype = "x-bt/vcard", - .open = vobject_open, + .open = vobject_vcard_open, .close = vobject_close, .read = vobject_read, }; diff --git a/obexd/plugins/syncevolution.c b/obexd/plugins/syncevolution.c index 12cf78b45..a646cc6eb 100644 --- a/obexd/plugins/syncevolution.c +++ b/obexd/plugins/syncevolution.c @@ -327,7 +327,7 @@ done: return 0; } -static ssize_t synce_read(gpointer object, void *buf, size_t count) +static ssize_t synce_read(gpointer object, void *buf, size_t count, guint8 *hi) { struct synce_context *context = object; struct obex_session *os = context->os; @@ -340,7 +340,7 @@ static ssize_t synce_read(gpointer object, void *buf, size_t count) DBusPendingCall *call; if (context->buffer) - return string_read(context->buffer, buf, count); + return string_read(context->buffer, buf, count, hi); conn = obex_dbus_get_connection(); if (conn == NULL) diff --git a/obexd/src/mimetype.h b/obexd/src/mimetype.h index dc1624046..6b558e281 100644 --- a/obexd/src/mimetype.h +++ b/obexd/src/mimetype.h @@ -33,7 +33,7 @@ struct obex_mime_type_driver { gpointer (*open) (const char *name, int oflag, mode_t mode, gpointer driver_data, size_t *size, int *err); int (*close) (gpointer object); - ssize_t (*read) (gpointer object, void *buf, size_t count); + ssize_t (*read) (gpointer object, void *buf, size_t count, guint8 *hi); ssize_t (*write) (gpointer object, const void *buf, size_t count); int (*remove) (const char *name); int (*set_io_watch) (gpointer object, obex_object_io_func func, diff --git a/obexd/src/obex-priv.h b/obexd/src/obex-priv.h index 8406bc07c..932f27537 100644 --- a/obexd/src/obex-priv.h +++ b/obexd/src/obex-priv.h @@ -60,7 +60,6 @@ struct obex_session { obex_object_t *obj; struct obex_mime_type_driver *driver; gboolean finished; - gboolean stream; }; gint obex_session_start(GIOChannel *io, struct server *server); diff --git a/obexd/src/obex.c b/obexd/src/obex.c index aa0dfb151..16cc840b2 100644 --- a/obexd/src/obex.c +++ b/obexd/src/obex.c @@ -374,8 +374,10 @@ static gint obex_write_stream(struct obex_session *os, obex_t *obex, obex_object_t *obj) { obex_headerdata_t hd; - gint32 len; guint8 *ptr; + gint32 len; + guint flags; + guint8 hi; debug("obex_write_stream: name=%s type=%s tx_mtu=%d file=%p", os->name ? os->name : "", os->type ? os->type : "", @@ -393,7 +395,7 @@ static gint obex_write_stream(struct obex_session *os, goto add_header; } - len = os->driver->read(os->object, os->buf, os->tx_mtu); + len = os->driver->read(os->object, os->buf, os->tx_mtu, &hi); if (len < 0) { error("read(): %s (%d)", strerror(-len), -len); if (len == -EAGAIN) @@ -406,18 +408,24 @@ static gint obex_write_stream(struct obex_session *os, return len; } - if (!os->stream) - return 0; - ptr = os->buf; add_header: hd.bs = ptr; + switch (hi) { + case OBEX_HDR_BODY: + flags = (len ? OBEX_FL_STREAM_DATA : OBEX_FL_STREAM_DATAEND); + break; + case OBEX_HDR_APPARAM: + flags = 0; + break; + } + + OBEX_ObjectAddHeader(obex, obj, hi, hd, len, flags); + if (len == 0) { - OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, 0, - OBEX_FL_STREAM_DATAEND); g_free(os->buf); os->buf = NULL; return len; @@ -425,9 +433,6 @@ add_header: os->offset += len; - OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, len, - OBEX_FL_STREAM_DATA); - return len; } @@ -472,6 +477,7 @@ proceed: static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj) { obex_headerdata_t hd; + gboolean stream; guint hlen; guint8 hi; int err; @@ -550,7 +556,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj) } } - err = os->service->get(os, obj, &os->stream, os->service_data); + err = os->service->get(os, obj, &stream, os->service_data); if (err < 0) goto done; @@ -566,7 +572,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj) if (os->size == 0) OBEX_ObjectAddHeader (obex, obj, OBEX_HDR_BODY, hd, 0, OBEX_FL_FIT_ONE_PACKET); - else if (!os->stream) { + else if (!stream) { /* Asynchronous operation that doesn't use stream */ OBEX_SuspendRequest(obex, obj); os->obj = obj; -- 2.47.3