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


------------------------------------------------------------------------------
AppSumo Presents a FREE Video for the SourceForge Community by Eric 
Ries, the creator of the Lean Startup Methodology on "Lean Startup 
Secrets Revealed." This video shows you how to validate your ideas, 
optimize your ideas and identify your business strategy.
http://p.sf.net/sfu/appsumosfdev2dev
_______________________________________________
Openobex-users mailing list
Openobex-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/openobex-users

Reply via email to