There are now three steps for sending an object: a prepare step where a new
TX message is written to the TX buffer, a transmit step where the object
is transmitted and the decision step on wether the whole object is finished.
The goal is to allow sending incomplete message buffers on non-blocking sockets.
---
lib/obex_main.c | 30 +++++++---
lib/obex_main.h | 4 +-
lib/obex_object.c | 154 +++++++++++++++++++++++++++++++++++++----------------
lib/obex_object.h | 5 ++
4 files changed, 136 insertions(+), 57 deletions(-)
diff --git a/lib/obex_main.c b/lib/obex_main.c
index 1d39cd8..884c9e3 100644
--- a/lib/obex_main.c
+++ b/lib/obex_main.c
@@ -210,23 +210,20 @@ void obex_response_request(obex_t *self, uint8_t opcode)
obex_return_if_fail(self != NULL);
msg = buf_reuse(self->tx_msg);
-
- obex_data_request(self, msg, opcode | OBEX_FINAL);
+ obex_data_request_prepare(self, msg, opcode | OBEX_FINAL);
+ obex_data_request(self, msg);
}
/*
- * Function obex_data_request (self, opcode, cmd)
+ * Function obex_data_request_prepare (self, opcode, cmd)
*
- * Send response or command code along with optional headers/data.
+ * Prepare response or command code along with optional headers/data
+ * to send.
*
*/
-int obex_data_request(obex_t *self, buf_t *msg, int opcode)
+void obex_data_request_prepare(obex_t *self, buf_t *msg, int opcode)
{
obex_common_hdr_t *hdr;
- int status;
-
- obex_return_val_if_fail(self != NULL, -1);
- obex_return_val_if_fail(msg != NULL, -1);
/* Insert common header */
hdr = buf_reserve_begin(msg, sizeof(*hdr));
@@ -235,6 +232,21 @@ int obex_data_request(obex_t *self, buf_t *msg, int opcode)
hdr->len = htons((uint16_t) msg->data_size);
DUMPBUFFER(1, "Tx", msg);
+}
+
+/*
+ * Function obex_data_request (self, opcode)
+ *
+ * Send message.
+ *
+ */
+int obex_data_request(obex_t *self, buf_t *msg)
+{
+ int status;
+
+ obex_return_val_if_fail(self != NULL, -1);
+ obex_return_val_if_fail(msg != NULL, -1);
+
DEBUG(1, "len = %lu bytes\n", (unsigned long) msg->data_size);
do {
diff --git a/lib/obex_main.h b/lib/obex_main.h
index 3c3098c..53d2768 100644
--- a/lib/obex_main.h
+++ b/lib/obex_main.h
@@ -71,7 +71,9 @@ int obex_get_buffer_status(buf_t *msg);
int obex_data_indication(struct obex *self);
void obex_response_request(struct obex *self, uint8_t opcode);
-int obex_data_request(struct obex *self, struct databuffer *msg, int opcode);
+void obex_data_request_prepare(struct obex *self, struct databuffer *msg,
+ int opcode);
+int obex_data_request(struct obex *self, struct databuffer *msg);
int obex_cancelrequest(struct obex *self, int nice);
char *obex_response_to_string(int rsp);
diff --git a/lib/obex_object.c b/lib/obex_object.c
index 3fcd10a..f888a2d 100644
--- a/lib/obex_object.c
+++ b/lib/obex_object.c
@@ -446,30 +446,54 @@ static unsigned int obex_object_send_srm_flags (uint8_t
flag)
}
}
+static int obex_object_get_real_opcode(obex_object_t *object,
+ int allowfinalcmd, int forcefinalbit)
+{
+ int real_opcode = object->opcode;
+
+ /* Decide which command to use, and if to use final-bit */
+ DEBUG(4, "allowfinalcmd: %d forcefinalbit:%d\n", allowfinalcmd,
+ forcefinalbit);
+
+ /* Have more headers (or body) to send? */
+ if (!slist_is_empty(object->tx_headerq)) {
+ /* In server, final bit is always set.
+ * In client, final bit is set only when we finish sending. */
+ if (forcefinalbit)
+ real_opcode |= OBEX_FINAL;
+
+ } else {
+ /* Have no more headers to send */
+ if (allowfinalcmd != FALSE) {
+ /* Allowed to send final command (== end data we are
+ * sending) */
+ real_opcode = object->lastopcode;
+ }
+
+ real_opcode |= OBEX_FINAL;
+ }
+
+ return real_opcode;
+}
+
/*
- * Function obex_object_send()
+ * Function obex_object_prepare_send()
*
- * Send away all headers attached to an object. Returns:
- * 1 on sucessfully done
- * 0 on progress made
- * < 0 on error
+ * Prepare to send away all headers attached to an object.
+ * Returns:
+ * 1 when a message was created
+ * 0 when no message was created
+ * -1 on error
*/
-int obex_object_send(obex_t *self, obex_object_t *object,
- int allowfinalcmd, int forcefinalbit)
+int obex_object_prepare_send(obex_t *self, obex_object_t *object,
+ int allowfinalcmd, int forcefinalbit)
{
buf_t *txmsg;
- int actual, real_opcode, finished = 0, addmore = TRUE;
+ int actual, real_opcode, addmore = TRUE;
uint16_t tx_left;
unsigned int srm_flags = 0;
- DEBUG(4, "allowfinalcmd: %d forcefinalbit:%d\n", allowfinalcmd,
- forcefinalbit);
-
- /* Return finished if aborted */
- if (object->abort)
- return 1;
-
- /* Don't do anything of object is suspended */
+ /* Don't do anything if object is suspended */
if (object->suspend)
return 0;
@@ -539,8 +563,8 @@ int obex_object_send(obex_t *self, obex_object_t *object,
object->suspend = 1;
if (h->hi == OBEX_HDR_SRM_FLAGS)
- srm_flags =
-
obex_object_send_srm_flags(h->buf->data[0]);
+ srm_flags = obex_object_send_srm_flags(
+ h->buf->data[0]);
/* Remove from tx-queue */
object->tx_headerq =
@@ -570,46 +594,82 @@ int obex_object_send(obex_t *self, obex_object_t *object,
addmore = FALSE;
}
- /* Decide which command to use, and if to use final-bit */
- if (object->tx_headerq) {
- /* Have more headers (or body) to send */
- real_opcode = object->opcode;
+ real_opcode = obex_object_get_real_opcode(self->object, allowfinalcmd,
+ forcefinalbit);
+ DEBUG(4, "Generating packet with opcode %d\n", real_opcode);
+ obex_data_request_prepare(self, self->tx_msg, real_opcode);
- /* In server, final bit is always set.
- * In client, final bit is set only when we finish sending. */
- if (forcefinalbit)
- real_opcode |= OBEX_FINAL;
+ self->srm_flags &= ~OBEX_SRM_FLAG_WAIT_REMOTE;
+ self->srm_flags |= srm_flags;
- finished = 0;
- } else {
- /* Have no more headers to send */
- if (allowfinalcmd == FALSE) {
- /* Not allowed to send final command (== server,
- * receiving incomming request) */
- real_opcode = object->opcode;
+ return 1;
+}
- } else {
- /* Allowed to send final command (== end data we are
- * sending) */
- real_opcode = object->lastopcode;
- }
+int obex_object_finished(obex_t *self, obex_object_t *object, int
allowfinalcmd)
+{
+ int finished = 0;
- real_opcode |= OBEX_FINAL;
+ if (object->abort)
+ return 1;
+
+ if (object->suspend)
+ return 0;
+
+ if (slist_is_empty(object->tx_headerq))
finished = !!allowfinalcmd;
+
+ return finished;
+}
+
+int obex_object_send_transmit(obex_t *self, obex_object_t *object)
+{
+ int ret;
+
+ if (!buf_empty(self->tx_msg)) {
+ ret = obex_data_request(self, self->tx_msg);
+ if (ret < 0) {
+ DEBUG(4, "Send error\n");
+ return -1;
+ }
}
- DEBUG(4, "Sending package with opcode %d\n", real_opcode);
- actual = obex_data_request(self, txmsg, real_opcode);
+ return buf_empty(self->tx_msg);
+}
- if (actual < 0) {
- DEBUG(4, "Send error\n");
- return -1;
+/*
+ * Function obex_object_send()
+ *
+ * Send away an object packet.
+ * Returns:
+ * 1 complete
+ * 0 incomplete but no error
+ * -1 error
+ */
+int obex_object_send(obex_t *self, obex_object_t *object, int allowfinalcmd,
+ int forcefinalbit)
+{
+ int ret;
+
+ /* Return finished if aborted */
+ if (object->abort) {
+ (void)buf_reuse(self->tx_msg);
+ return 1;
}
- self->srm_flags &= ~OBEX_SRM_FLAG_WAIT_REMOTE;
- self->srm_flags |= srm_flags;
+ if (buf_empty(self->tx_msg)) {
+ ret = obex_object_prepare_send(self, object, allowfinalcmd,
+ forcefinalbit);
+ if (ret == -1) {
+ DEBUG(4, "Packet prepare error\n");
+ return -1;
+ } else if (ret == 0)
+ return 0;
+ }
- return finished;
+ ret = obex_object_send_transmit(self, object);
+ if (ret == 1)
+ ret = obex_object_finished(self, object, allowfinalcmd);
+ return ret;
}
/*
diff --git a/lib/obex_object.h b/lib/obex_object.h
index fd2904a..eef3458 100644
--- a/lib/obex_object.h
+++ b/lib/obex_object.h
@@ -96,6 +96,11 @@ int obex_object_getnextheader(struct obex *self, struct
obex_object *object, uin
int obex_object_reparseheaders(struct obex *self, struct obex_object *object);
void obex_object_setcmd(struct obex_object *object, uint8_t cmd);
int obex_object_setrsp(struct obex_object *object, uint8_t rsp, uint8_t
lastrsp);
+int obex_object_prepare_send(obex_t *self, obex_object_t *object,
+ int allowfinalcmd, int forcefinalbit);
+int obex_object_finished(obex_t *self, obex_object_t *object,
+ int allowfinalcmd);
+int obex_object_send_transmit(obex_t *self, obex_object_t *object);
int obex_object_send(struct obex *self, struct obex_object *object,
int allowfinalcmd, int forcefinalbit);
--
1.7.5.4
------------------------------------------------------------------------------
Got Input? Slashdot Needs You.
Take our quick survey online. Come on, we don't ask for help often.
Plus, you'll get a chance to win $100 to spend on ThinkGeek.
http://p.sf.net/sfu/slashdot-survey
_______________________________________________
Openobex-users mailing list
[email protected]
http://lists.sourceforge.net/lists/listinfo/openobex-users