diff --git a/obexd/plugins/filesystem.c b/obexd/plugins/filesystem.c
index 9d7136a..c1568f1 100644
--- a/obexd/plugins/filesystem.c
+++ b/obexd/plugins/filesystem.c
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;
if (ret < 0)
return -errno;
+ *hi = OBEX_HDR_BODY;
+
return ret;
}
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;
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 636ddb2..1e1b352 100644
--- a/obexd/plugins/filesystem.h
+++ b/obexd/plugins/filesystem.h
*/
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 12ecc29..0117b8e 100644
--- a/obexd/plugins/pbap.c
+++ b/obexd/plugins/pbap.c
};
struct pbap_session {
- struct obex_session *os;
struct apparam_field *params;
gchar *folder;
GString *buffer;
guint16 phonebooksize;
- obex_object_t *object;
struct cache cache;
};
pbap = g_new0(struct pbap_session, 1);
pbap->folder = g_strdup("/");
- pbap->os = os;
if (err)
*err = 0;
*stream = TRUE;
pbap->params = params;
- pbap->object = obj;
ret = obex_get_stream_start(os, path, pbap);
failed:
.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;
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;
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) {
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)
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,
};
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,
};
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 12cf78b..a646cc6 100644
--- a/obexd/plugins/syncevolution.c
+++ b/obexd/plugins/syncevolution.c
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;
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 dc16240..6b558e2 100644
--- a/obexd/src/mimetype.h
+++ b/obexd/src/mimetype.h
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 8406bc0..932f275 100644
--- a/obexd/src/obex-priv.h
+++ b/obexd/src/obex-priv.h
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 aa0dfb1..16cc840 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
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 : "",
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)
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;
os->offset += len;
- OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, len,
- OBEX_FL_STREAM_DATA);
-
return len;
}
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;
}
}
- 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;
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;