---
 lib/obex.c        |    8 +-
 lib/obex_client.c |  207 ++++++++++++++++++++++++++++++++--------------------
 lib/obex_client.h |    2 -
 lib/obex_main.c   |   36 +++++-----
 4 files changed, 148 insertions(+), 105 deletions(-)

diff --git a/lib/obex.c b/lib/obex.c
index e56ef74..991f06f 100644
--- a/lib/obex.c
+++ b/lib/obex.c
@@ -44,7 +44,6 @@
 #include "obex_main.h"
 #include "obex_object.h"
 #include "obex_connect.h"
-#include "obex_client.h"
 #include "databuffer.h"
 
 #include "fdobex.h"
@@ -511,10 +510,10 @@ int CALLAPI OBEX_GetFD(obex_t *self)
 }
 
 /**
-       Start a request (as client).
+       Schedule a request (as client).
        \param self OBEX handle
        \param object Object containing request
-       \return -1 or negative error code on error
+       \return -1 on error, 0 on success.
  */
 LIB_SYMBOL
 int CALLAPI OBEX_Request(obex_t *self, obex_object_t *object)
@@ -534,8 +533,9 @@ int CALLAPI OBEX_Request(obex_t *self, obex_object_t 
*object)
        self->object = object;
        self->mode = MODE_CLI;
         self->state = STATE_SEND;
+       self->substate = SUBSTATE_PREPARE_TX;
 
-       return obex_client_send(self, NULL, 0);
+       return 0;
 }
 
 /**
diff --git a/lib/obex_client.c b/lib/obex_client.c
index fd9962b..c8dc843 100644
--- a/lib/obex_client.c
+++ b/lib/obex_client.c
@@ -178,91 +178,135 @@ static int obex_client_recv(obex_t *self)
 
 }
 
-int obex_client_send(obex_t *self, buf_t *msg, int rsp)
+static int obex_client_send_transmit_tx(obex_t *self)
 {
        int ret;
 
-       /* In progress of sending request */
-       DEBUG(4, "STATE_SEND\n");
+       DEBUG(4, "STATE: SEND/TRANSMIT_TX\n");
 
-       if (self->object->first_packet_sent == 1) {
-               /* Any errors from peer? Win2k will send RSP_SUCCESS after
-                * every fragment sent so we have to accept that too.*/
-               switch (rsp) {
-               case OBEX_RSP_SUCCESS:
-               case OBEX_RSP_CONTINUE:
-                       break;
-
-               default:
-                       DEBUG(0, "STATE_SEND. request not accepted.\n");
-                       obex_deliver_event(self, OBEX_EV_REQDONE,
-                                               self->object->opcode, rsp, 
TRUE);
-                       /* This is not an Obex error, it is just that the peer
-                        * doesn't accept the request, so return 0 - Jean II */
-                       return 0;
-               }
-
-               if (msg_get_len(msg) > 3) {
-                       /* For Single Response Mode, this is actually not
-                        * unexpected. */
-                       if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL) {
-                               DEBUG(1, "STATE_SEND. Didn't excpect data from "
-                                               "peer (%u)\n", 
msg_get_len(msg));
-                               DUMPBUFFER(4, "unexpected data", msg);
-                               obex_deliver_event(self, OBEX_EV_UNEXPECTED,
-                                               self->object->opcode, 0, FALSE);
-                       }
-
-                       /* At this point, we are in the middle of sending our
-                        * request to the server, and it is already sending us
-                        * some data! This breaks the whole Request/Response
-                        * model! Most often, the server is sending some out of
-                        * band progress information for a PUT.
-                        * This is the way we will handle that:
-                        * Save this header in our Rx header list. We can have
-                        * duplicated headers, so no problem. User can check the
-                        * header in the next EV_PROGRESS, doing so will hide
-                        * the header (until reparse). If not, header will be
-                        * parsed at 'final', or just ignored (common case for
-                        * PUT).
-                        * No headeroffset needed because 'connect' is single
-                        * packet (or we deny it). */
-                       ret = -1;
-                       if (self->object->opcode == OBEX_CMD_CONNECT)
-                               ret = obex_object_receive(self, msg);
-                       if (ret < 0) {
-                               obex_deliver_event(self, OBEX_EV_PARSEERR,
-                                               self->object->opcode, 0, TRUE);
-                               self->mode = MODE_SRV;
-                               self->state = STATE_IDLE;
-                               return -1;
-                       }
-
-                       /* Note : we may want to get rid of received header,
-                        * however they are mixed with legitimate headers,
-                        * and the user may expect to consult them later.
-                        * So, leave them here (== overhead). */
-               }
-       }
-
-       ret = obex_object_send(self, self->object, TRUE, FALSE);
+       ret = obex_object_send_transmit(self, self->object);
        if (ret < 0) {
                /* Error while sending */
                obex_deliver_event(self, OBEX_EV_LINKERR,
                                        self->object->opcode, 0, TRUE);
                self->mode = MODE_SRV;
                self->state = STATE_IDLE;
-               return -1;
 
+       } else if (ret == 1) {
+               obex_deliver_event(self, OBEX_EV_PROGRESS, self->object->opcode,
+                                                                     0, FALSE);
+               if (obex_object_finished(self, self->object, TRUE)) {
+                       self->state = STATE_REC;
+                       self->substate = SUBSTATE_RECEIVE_RX;
+
+               } else {
+                       int check = 0;
+                       if (self->object->rsp_mode == OBEX_RSP_MODE_SINGLE &&
+                           !(self->srm_flags & OBEX_SRM_FLAG_WAIT_LOCAL)) {
+                               /* Still, we need to do a zero-wait check for an
+                                * negative response or for connection errors. 
*/
+                               check = obex_transport_handle_input(self, 0);
+                               if (check <= 0) /* no input */
+                                       self->substate = SUBSTATE_RECEIVE_RX;
+                               else
+                                       self->substate = SUBSTATE_PREPARE_TX;
+
+                       } else
+                               self->substate = SUBSTATE_RECEIVE_RX;
+               }
        }
 
-       self->object->first_packet_sent = 1;
-       obex_deliver_event(self, OBEX_EV_PROGRESS, self->object->opcode,
-                                                               0, FALSE);
-       if (ret > 0)
-               self->state = STATE_REC;
+       return ret;
+}
 
-       return 0;
+static int obex_client_send_prepare_tx(obex_t *self)
+{
+       int ret;
+
+       DEBUG(4, "STATE: SEND/PREPARE_TX\n");
+
+       ret = obex_object_prepare_send(self, self->object, TRUE, FALSE);
+       if (ret == 1) {
+               self->substate = SUBSTATE_TRANSMIT_TX;
+               return obex_client_send_transmit_tx(self);
+
+       } else
+               return ret;
+}
+
+static int obex_client_send(obex_t *self)
+{
+       int ret;
+       buf_t *msg = obex_data_receive(self);
+       int rsp;
+
+       DEBUG(4, "STATE: SEND/RECEIVE_RX\n");
+
+       if (msg == NULL)
+               return 0;
+       rsp = msg_get_rsp(msg);
+
+       /* Any errors from peer? Win2k will send RSP_SUCCESS after
+        * every fragment sent so we have to accept that too.*/
+       switch (rsp) {
+       case OBEX_RSP_SUCCESS:
+       case OBEX_RSP_CONTINUE:
+               break;
+
+       default:
+               DEBUG(0, "STATE_SEND. request not accepted.\n");
+               obex_deliver_event(self, OBEX_EV_REQDONE, self->object->opcode,
+                                                                    rsp, TRUE);
+               /* This is not an Obex error, it is just that the peer
+                * doesn't accept the request, so return 0 - Jean II */
+               return 0;
+       }
+
+       if (msg_get_len(msg) > 3) {
+               /* For Single Response Mode, this is actually not
+                * unexpected. */
+               if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL) {
+                       DEBUG(1, "STATE_SEND. Didn't excpect data from "
+                             "peer (%u)\n", msg_get_len(msg));
+                       DUMPBUFFER(4, "unexpected data", msg);
+                       obex_deliver_event(self, OBEX_EV_UNEXPECTED,
+                                               self->object->opcode, 0, FALSE);
+               }
+
+               /* At this point, we are in the middle of sending our
+                * request to the server, and it is already sending us
+                * some data! This breaks the whole Request/Response
+                * model! Most often, the server is sending some out of
+                * band progress information for a PUT.
+                * This is the way we will handle that:
+                * Save this header in our Rx header list. We can have
+                * duplicated headers, so no problem. User can check the
+                * header in the next EV_PROGRESS, doing so will hide
+                * the header (until reparse). If not, header will be
+                * parsed at 'final', or just ignored (common case for
+                * PUT).
+                * No headeroffset needed because 'connect' is single
+                * packet (or we deny it). */
+               ret = -1;
+               if (self->object->opcode == OBEX_CMD_CONNECT)
+                       ret = obex_object_receive(self, msg);
+               if (ret < 0) {
+                       obex_deliver_event(self, OBEX_EV_PARSEERR,
+                                                self->object->opcode, 0, TRUE);
+                       self->mode = MODE_SRV;
+                       self->state = STATE_IDLE;
+                       return -1;
+               }
+
+               /* Note : we may want to get rid of received header,
+                * however they are mixed with legitimate headers,
+                * and the user may expect to consult them later.
+                * So, leave them here (== overhead). */
+       }
+
+       obex_data_receive_finished(self);
+       self->substate = SUBSTATE_PREPARE_TX;
+       return obex_client_send_prepare_tx(self);
 }
 
 
@@ -274,15 +318,20 @@ int obex_client_send(obex_t *self, buf_t *msg, int rsp)
  */
 int obex_client(obex_t *self)
 {
-       int ret = -1;
-       buf_t *msg = obex_data_receive(self);
-       int rsp = msg_get_rsp(msg);
-
        DEBUG(4, "\n");
 
        switch (self->state) {
        case STATE_SEND:
-               ret = obex_client_send(self, msg, rsp);
+               switch (self->substate) {
+               case SUBSTATE_RECEIVE_RX:
+                       return obex_client_send(self);
+
+               case SUBSTATE_PREPARE_TX:
+                       return obex_client_send_prepare_tx(self);
+
+               case SUBSTATE_TRANSMIT_TX:
+                       return obex_client_send_transmit_tx(self);
+               }
                break;
 
        case STATE_REC:
@@ -300,10 +349,8 @@ int obex_client(obex_t *self)
 
        default:
                DEBUG(0, "Unknown state\n");
-               obex_deliver_event(self, OBEX_EV_PARSEERR, rsp, 0, TRUE);
-               return -1;
+               break;
        }
 
-       obex_data_receive_finished(self);
-       return ret;
+       return -1;
 }
diff --git a/lib/obex_client.h b/lib/obex_client.h
index d1ae8fd..6f0d0fa 100644
--- a/lib/obex_client.h
+++ b/lib/obex_client.h
@@ -23,9 +23,7 @@
 #define OBEX_CLIENT_H
 
 struct obex;
-struct databuffer;
 
 int obex_client(struct obex *self);
-int obex_client_send(obex_t *self, buf_t *msg, int rsp);
 
 #endif
diff --git a/lib/obex_main.c b/lib/obex_main.c
index 5337208..d3f0612 100644
--- a/lib/obex_main.c
+++ b/lib/obex_main.c
@@ -285,37 +285,35 @@ int obex_work(obex_t *self, int timeout)
         * as the client is not supposed to send any when we (as server) are
         * sending the response.
         * For request reception, this is handled above */
-       if (self->object &&
+       if (self->mode == MODE_SRV &&
+                       self->object &&
                        self->object->rsp_mode != OBEX_RSP_MODE_NORMAL &&
                        self->state == STATE_SEND &&
                        !(self->srm_flags & OBEX_SRM_FLAG_WAIT_LOCAL)) {
                /* Still, we need to do a zero-wait check for an ABORT
                 * and for connection errors. */
                ret = obex_transport_handle_input(self, 0);
-               if (ret == 0) { /* timeout: no error, no input */
-                       switch (self->mode) {
-                       case MODE_SRV:
-                               ret = obex_server_send(self, NULL, 
self->object->cmd, 0);
-                               break;
-
-                       case MODE_CLI:
-                               ret = obex_client_send(self, NULL, 
OBEX_RSP_CONTINUE);
-                               break;
-
-                       default:
-                               return -1;
-                       }
-               }
+               if (ret == 0) /* timeout: no error, no input */
+                       ret = obex_server_send(self, NULL, self->object->cmd, 
0);
                if (ret < 0)
                        return -1;
                else
                        return sizeof(obex_common_hdr_t);
+
+               ret = obex_transport_handle_input(self, timeout);
+               if (ret <= 0)
+                       return ret;
+
+       } else if (self->mode == MODE_CLI) {
+               if (self->substate == SUBSTATE_RECEIVE_RX) {
+                       ret = obex_transport_handle_input(self, timeout);
+                       if (ret <= 0)
+                               return ret;
+               }
+
        }
 
-       ret = obex_transport_handle_input(self, timeout);
-       if (ret == 1)
-               ret = obex_mode(self);
-       return ret;
+       return obex_mode(self);
 }
 
 /*
-- 
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