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
Openobex-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/openobex-users

Reply via email to