diff --git a/obexd/src/mimetype.h b/obexd/src/mimetype.h
index f3a2b34..3426cac 100644
--- a/obexd/src/mimetype.h
+++ b/obexd/src/mimetype.h
void *(*open) (const char *name, int oflag, mode_t mode,
void *driver_data, size_t *size, int *err);
int (*close) (void *object);
+ ssize_t (*get_next_header)(void *object, void *buf, size_t mtu,
+ uint8_t *hi);
ssize_t (*read) (void *object, void *buf, size_t count, uint8_t *hi);
ssize_t (*write) (void *object, const void *buf, size_t count);
int (*flush) (void *object);
diff --git a/obexd/src/obex-priv.h b/obexd/src/obex-priv.h
index 02249b4..d640ae0 100644
--- a/obexd/src/obex-priv.h
+++ b/obexd/src/obex-priv.h
obex_object_t *obj;
struct obex_mime_type_driver *driver;
gboolean streaming;
+ gboolean headers_sent;
};
int obex_session_start(GIOChannel *io, uint16_t tx_mtu, uint16_t rx_mtu,
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index aeca79d..b4f3714 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
os->pending = 0;
os->offset = 0;
os->size = OBJECT_SIZE_DELETE;
+ os->headers_sent = FALSE;
os->streaming = FALSE;
}
return 0;
}
+static int obex_write(struct obex_session *os, obex_t *obex, obex_object_t *obj)
+{
+ obex_headerdata_t hd;
+ ssize_t len;
+ uint8_t hi;
+
+ DBG("name=%s type=%s tx_mtu=%d file=%p",
+ os->name ? os->name : "", os->type ? os->type : "",
+ os->tx_mtu, os->object);
+
+ if (os->aborted)
+ return -EPERM;
+
+ if (os->object == NULL)
+ return -EIO;
+
+ if (os->headers_sent)
+ return obex_write_stream(os, obex, obj);
+
+ if (!os->driver->get_next_header)
+ goto skip;
+
+ while ((len = os->driver->get_next_header(os->object, os->buf,
+ os->tx_mtu, &hi)) != 0) {
+ if (len < 0) {
+ error("get_next_header(): %s (%zd)", strerror(-len),
+ -len);
+
+ if (len == -EAGAIN)
+ return len;
+
+ g_free(os->buf);
+ os->buf = NULL;
+
+ return len;
+ }
+
+ hd.bs = os->buf;
+ OBEX_ObjectAddHeader(obex, obj, hi, hd, len, 0);
+ }
+
+skip:
+ os->headers_sent = TRUE;
+
+ return obex_write_stream(os, obex, obj);
+}
+
static gboolean handle_async_io(void *object, int flags, int err,
void *user_data)
{
}
if (flags & (G_IO_IN | G_IO_PRI))
- ret = obex_write_stream(os, os->obex, os->obj);
+ ret = obex_write(os, os->obex, os->obj);
else if ((flags & G_IO_OUT) && os->pending > 0)
ret = obex_read_stream(os, os->obex, os->obj);
proceed:
- if (ret < 0) {
+ if (ret == -EAGAIN) {
+ return TRUE;
+ } else if (ret < 0) {
os_set_response(os->obj, ret);
OBEX_CancelRequest(os->obex, TRUE);
- } else
+ } else {
OBEX_ResumeRequest(os->obex);
+ }
return FALSE;
}
g_return_if_fail(chk_cid(obex, obj, os->cid));
+ os->headers_sent = FALSE;
os->streaming = FALSE;
while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
/* Try to write to stream and suspend the stream immediately
* if no data available to send. */
- err = obex_write_stream(os, obex, obj);
+ err = obex_write(os, obex, obj);
if (err == -EAGAIN) {
OBEX_SuspendRequest(obex, obj);
os->obj = obj;