[PATCH obexd 3/5] Add get_next_header() function

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

 



This adds the function for mime drivers that allows adding OBEX headers
before body streaming is started.
---
 src/mimetype.h  |    2 +
 src/obex-priv.h |    1 +
 src/obex.c      |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/mimetype.h b/src/mimetype.h
index 8472684..511ab6a 100644
--- a/src/mimetype.h
+++ b/src/mimetype.h
@@ -33,6 +33,8 @@ struct obex_mime_type_driver {
 	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/src/obex-priv.h b/src/obex-priv.h
index 8c722dc..51a7739 100644
--- a/src/obex-priv.h
+++ b/src/obex-priv.h
@@ -46,6 +46,7 @@ struct obex_session {
 	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/src/obex.c b/src/obex.c
index 3ab81d4..596da6a 100644
--- a/src/obex.c
+++ b/src/obex.c
@@ -310,6 +310,7 @@ static void os_reset_session(struct obex_session *os)
 	os->pending = 0;
 	os->offset = 0;
 	os->size = OBJECT_SIZE_DELETE;
+	os->headers_sent = FALSE;
 	os->streaming = FALSE;
 }
 
@@ -685,6 +686,53 @@ static int obex_write_stream(struct obex_session *os,
 	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)
 {
@@ -697,16 +745,19 @@ static gboolean handle_async_io(void *object, int flags, int err,
 	}
 
 	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;
 }
@@ -729,6 +780,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
 
 	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)) {
@@ -813,7 +865,7 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
 
 	/* 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;
-- 
1.7.4.1

--
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