---
 lib/obex_main.c   |   44 +---------
 lib/obex_server.c |  259 +++++++++++++++++++++++++++++++++++++---------------
 lib/obex_server.h |    2 -
 3 files changed, 187 insertions(+), 118 deletions(-)

diff --git a/lib/obex_main.c b/lib/obex_main.c
index d3f0612..bc55661 100644
--- a/lib/obex_main.c
+++ b/lib/obex_main.c
@@ -281,36 +281,12 @@ int obex_work(obex_t *self, int timeout)
 {
        int ret;
 
-       /* Waiting for an incoming packet will not work for single response mode
-        * 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->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 */
-                       ret = obex_server_send(self, NULL, self->object->cmd, 
0);
-               if (ret < 0)
-                       return -1;
-               else
-                       return sizeof(obex_common_hdr_t);
-
+       if (self->state == STATE_IDLE ||
+           self->substate == SUBSTATE_RECEIVE_RX)
+       {
                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;
-               }
-
        }
 
        return obex_mode(self);
@@ -417,20 +393,6 @@ int obex_data_indication(obex_t *self)
 buf_t* obex_data_receive(obex_t *self)
 {
        buf_t *msg = self->rx_msg;
-       obex_common_hdr_t *hdr = (obex_common_hdr_t *)msg->data;
-       uint8_t opcode = hdr->opcode & ~OBEX_FINAL;
-
-       if (self->mode == MODE_SRV) {
-               /* Single response mode makes it possible for the client to send
-                * the next request (e.g. PUT) while still receiving the last
-                * multi-packet response. So we must not consume any request
-                * except ABORT. */
-               if (self->object &&
-                               self->object->rsp_mode != OBEX_RSP_MODE_NORMAL 
&&
-                               self->state == STATE_SEND &&
-                               !(opcode == OBEX_CMD_ABORT || opcode == 
self->object->cmd))
-                       return NULL;
-       }
 
        if (!obex_get_buffer_status(msg))
                return NULL;
diff --git a/lib/obex_server.c b/lib/obex_server.c
index 401a98d..351d710 100644
--- a/lib/obex_server.c
+++ b/lib/obex_server.c
@@ -36,20 +36,103 @@
 
 static __inline int msg_get_cmd(const buf_t *msg)
 {
-       return ((obex_common_hdr_t *) msg->data)->opcode & ~OBEX_FINAL;
+       if (msg)
+               return ((obex_common_hdr_t *) msg->data)->opcode & ~OBEX_FINAL;
+       else
+               return 0;
 }
 
 static __inline uint16_t msg_get_len(const buf_t *msg)
 {
-       return ntohs(((obex_common_hdr_t *) msg->data)->len);
+       if (msg)
+               return ntohs(((obex_common_hdr_t *) msg->data)->len);
+       else
+               return 0;
+}
+
+static __inline int msg_get_final(const buf_t *msg)
+{
+       if (msg)
+               return ((obex_common_hdr_t *) msg->data)->opcode & OBEX_FINAL;
+       else
+               return 0;
+}
+
+static int obex_server_send_transmit_tx(obex_t *self)
+{
+       int ret;
+       int cmd = self->object->cmd;
+
+       DEBUG(4, "STATE: SEND/TRANSMIT_TX\n");
+
+       ret = obex_object_send_transmit(self, self->object);
+       if (ret == -1) {
+               /* Error sending response */
+               obex_deliver_event(self, OBEX_EV_LINKERR, cmd, 0, TRUE);
+               self->state = STATE_IDLE;
+
+       } else if (ret == 1) {
+               /* Made some progress */
+               obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
+               if (obex_object_finished(self, self->object, TRUE)) {
+                       self->state = STATE_IDLE;
+                       /* Response sent and object finished! */
+                       if (cmd == OBEX_CMD_DISCONNECT) {
+                               DEBUG(2, "CMD_DISCONNECT done. Resetting 
MTU!\n");
+                               self->mtu_tx = OBEX_MINIMUM_MTU;
+                               self->rsp_mode = OBEX_RSP_MODE_NORMAL;
+                               self->srm_flags = 0;
+                       }
+                       obex_deliver_event(self, OBEX_EV_REQDONE, cmd, 0, TRUE);
+
+               } else if (self->object->rsp_mode == OBEX_RSP_MODE_SINGLE &&
+                          !(self->srm_flags & OBEX_SRM_FLAG_WAIT_LOCAL)) {
+                       self->substate = SUBSTATE_PREPARE_TX;
+
+               } else
+                       self->substate = SUBSTATE_RECEIVE_RX;
+       }
+
+       return ret;
 }
 
-int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len)
+static int obex_server_send_prepare_tx(obex_t *self)
 {
        int ret;
 
-       /* Send back response */
-       DEBUG(4, "STATE_SEND\n");
+       DEBUG(4, "STATE: SEND/PREPARE_TX\n");
+
+       /* As a server, the final bit is always SET, and the "real final" packet
+        * is distinguished by being SUCCESS instead of CONTINUE.
+        * So, force the final bit here. */
+       ret = obex_object_prepare_send(self, self->object, TRUE, TRUE);
+       if (ret == 1) {
+               self->substate = SUBSTATE_TRANSMIT_TX;
+               return obex_server_send_transmit_tx(self);
+
+       } else
+               return ret;
+}
+
+static int obex_server_send(obex_t *self)
+{
+       int ret;
+       buf_t *msg = obex_data_receive(self);
+       int cmd = msg_get_cmd(msg);
+       uint16_t len = msg_get_len(msg);
+
+       DEBUG(4, "STATE: SEND/RECEIVE_RX\n");
+
+       /* Single response mode makes it possible for the client to send
+        * the next request (e.g. PUT) while still receiving the last
+        * multi-packet response. So we must not consume any request
+        * except ABORT. */
+       if (self->object &&
+           self->object->rsp_mode == OBEX_RSP_MODE_SINGLE &&
+           !(cmd == OBEX_CMD_ABORT || cmd == self->object->cmd)) {
+               self->substate = SUBSTATE_PREPARE_TX;
+               return obex_server_send_prepare_tx(self);
+       }
 
        /* Abort? */
        if (cmd == OBEX_CMD_ABORT) {
@@ -104,47 +187,68 @@ int obex_server_send(obex_t *self, buf_t *msg, int cmd, 
uint16_t len)
                 * consult them later. So, leave them here (== overhead). */
        }
 
-       /* As a server, the final bit is always SET, and the "real final" packet
-        * is distinguish by beeing SUCCESS instead of CONTINUE.
-        * So, force the final bit here. */
-       self->object->continue_received = 1;
+       obex_data_receive_finished(self);
+       self->substate = SUBSTATE_PREPARE_TX;
+       return obex_server_send_prepare_tx(self);
+}
 
-       if (self->object->suspend)
-               return 0;
+static int obex_server_recv_transmit_tx(obex_t *self)
+{
+       int ret = 0;
+       int cmd = self->object->cmd;
 
-       ret = obex_object_send(self, self->object, TRUE, TRUE);
-       if (ret == 0) {
-               /* Made some progress */
-               obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
-               self->object->first_packet_sent = 1;
-               self->object->continue_received = 0;
-       } else if (ret < 0) {
-               /* Error sending response */
+       DEBUG(4, "STATE: RECV/TRANSMIT_TX\n");
+
+       ret = obex_object_send_transmit(self, self->object);
+       if (ret == -1) {
                obex_deliver_event(self, OBEX_EV_LINKERR, cmd, 0, TRUE);
-               return -1;
-       } else {
-               /* Response sent! */
-               if (cmd == OBEX_CMD_DISCONNECT) {
-                       DEBUG(2, "CMD_DISCONNECT done. Resetting MTU!\n");
-                       self->mtu_tx = OBEX_MINIMUM_MTU;
-                       self->rsp_mode = OBEX_RSP_MODE_NORMAL;
-                       self->srm_flags = 0;
-               }
                self->state = STATE_IDLE;
-               obex_deliver_event(self, OBEX_EV_REQDONE, cmd, 0, TRUE);
+
+       } else if (ret == 1) {
+               obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
+               self->substate = SUBSTATE_RECEIVE_RX;
        }
 
-       return 0;
+       return ret;
+}
+
+static int obex_server_recv_prepare_tx(obex_t *self)
+{
+       DEBUG(4, "STATE: RECV/PREPARE_TX\n");
+
+       if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL ||
+           (self->object->rsp_mode == OBEX_RSP_MODE_SINGLE &&
+            self->srm_flags & OBEX_SRM_FLAG_WAIT_REMOTE))
+       {
+               int ret = obex_object_prepare_send(self, self->object,
+                                                  FALSE, TRUE);
+               if (ret == 1) {
+                       self->substate = SUBSTATE_TRANSMIT_TX;
+                       return obex_server_recv_transmit_tx(self);
+
+               } else
+                       return ret;
+
+       } else {
+               self->substate = SUBSTATE_RECEIVE_RX;
+               return 0;
+       }
 }
 
-static int obex_server_recv(obex_t *self, buf_t *msg, int first, int final,
-                                                       int cmd, uint16_t len)
+static int obex_server_recv(obex_t *self, int first)
 {
        int deny = 0;
        uint64_t filter;
+       buf_t *msg = obex_data_receive(self);
+       int cmd;
+       int final;
 
-       DEBUG(4, "STATE_REC\n");
-       /* In progress of receiving a request */
+       DEBUG(4, "STATE: RECV/RECEIVE_RX\n");
+
+       if (msg == NULL)
+               return 0;
+       cmd = msg_get_cmd(msg);
+       final = msg_get_final(msg);
 
        /* Abort? */
        if (cmd == OBEX_CMD_ABORT) {
@@ -217,23 +321,12 @@ static int obex_server_recv(obex_t *self, buf_t *msg, int 
first, int final,
                break;
        }
 
+       obex_data_receive_finished(self);
        if (!final) {
-               obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
-               if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL ||
-                               (self->srm_flags & OBEX_SRM_FLAG_WAIT_REMOTE)) {
-                       int ret = obex_object_send(self, self->object, FALSE,
-                                                                       TRUE);
-                       if (ret < 0) {
-                               obex_deliver_event(self, OBEX_EV_LINKERR,
-                                                               cmd, 0, TRUE);
-                               return -1;
-                       }
-               }
-
-               return 0;
-       }
+               self->substate = SUBSTATE_PREPARE_TX;
+               return obex_server_recv_prepare_tx(self);
 
-       if (!self->object->first_packet_sent) {
+       } else {
                /* Tell the app that a whole request has
                 * arrived. While this event is delivered the
                 * app should append the headers that should be
@@ -245,19 +338,24 @@ static int obex_server_recv(obex_t *self, buf_t *msg, int 
first, int final,
                /* More connect-magic woodoo stuff */
                if (cmd == OBEX_CMD_CONNECT)
                        obex_insert_connectframe(self, self->object);
-               /* Otherwise sanitycheck later will fail */
-               len = 3;
-       }
 
-       self->state = STATE_SEND;
-       return obex_server_send(self, msg, cmd, len);
+               self->state = STATE_SEND;
+               self->substate = SUBSTATE_PREPARE_TX;
+               return obex_server_send_prepare_tx(self);
+       }
 }
 
-static int obex_server_idle(obex_t *self, buf_t *msg, int final,
-                                                       int cmd, uint16_t len)
+static int obex_server_idle(obex_t *self)
 {
+       buf_t *msg = obex_data_receive(self);
+       int cmd;
+
        /* Nothing has been recieved yet, so this is probably a new request */
-       DEBUG(4, "STATE_IDLE\n");
+       DEBUG(4, "STATE: IDLE\n");
+
+       if (msg == NULL)
+               return 0;
+       cmd = msg_get_cmd(msg);
 
        if (self->object) {
                /* What shall we do here? I don't know!*/
@@ -304,15 +402,19 @@ static int obex_server_idle(obex_t *self, buf_t *msg, int 
final,
                break;
        }
 
+       /* Check the response from the REQHINT event */
        switch ((self->object->opcode & ~OBEX_FINAL) & 0xF0) {
        case OBEX_RSP_CONTINUE:
        case OBEX_RSP_SUCCESS:
                self->state = STATE_REC;
-               return obex_server_recv(self, msg, 1, final, cmd, len);
+               self->substate = SUBSTATE_RECEIVE_RX;
+               return obex_server_recv(self, 1);
 
        default:
+               obex_data_receive_finished(self);
                self->state = STATE_SEND;
-               return obex_server_send(self, msg, cmd, 3);
+               self->substate = SUBSTATE_PREPARE_TX;
+               return obex_server_send_prepare_tx(self);
        }
 }
 
@@ -324,35 +426,42 @@ static int obex_server_idle(obex_t *self, buf_t *msg, int 
final,
  */
 int obex_server(obex_t *self)
 {
-       int ret = -1;
-       buf_t *msg = obex_data_receive(self);
-       obex_common_hdr_t *hdr = (obex_common_hdr_t *)msg->data;
-       int cmd = msg_get_cmd(msg);
-       uint16_t len = msg_get_len(msg);
-       int final = hdr->opcode & OBEX_FINAL; /* Extract final bit */
-
        DEBUG(4, "\n");
 
        switch (self->state) {
        case STATE_IDLE:
-               ret = obex_server_idle(self, msg, final, cmd, len);
-               break;
+               return obex_server_idle(self);
 
        case STATE_REC:
-               ret = obex_server_recv(self, msg, 0, final, cmd, len);
+               switch (self->substate) {
+               case SUBSTATE_RECEIVE_RX:
+                       return obex_server_recv(self, 0);
+
+               case SUBSTATE_PREPARE_TX:
+                       return obex_server_recv_prepare_tx(self);
+
+               case SUBSTATE_TRANSMIT_TX:
+                       return obex_server_recv_transmit_tx(self);
+               }
                break;
 
        case STATE_SEND:
-               ret = obex_server_send(self, msg, cmd, len);
+               switch (self->substate) {
+               case SUBSTATE_RECEIVE_RX:
+                       return obex_server_send(self);
+
+               case SUBSTATE_PREPARE_TX:
+                       return obex_server_send_prepare_tx(self);
+
+               case SUBSTATE_TRANSMIT_TX:
+                       return obex_server_send_transmit_tx(self);
+               }
                break;
 
        default:
                DEBUG(0, "Unknown state\n");
-               obex_response_request(self, OBEX_RSP_BAD_REQUEST);
-               obex_deliver_event(self, OBEX_EV_PARSEERR, cmd, 0, TRUE);
-               return -1;
+               break;
        }
 
-       obex_data_receive_finished(self);
-       return ret;
+       return -1;
 }
diff --git a/lib/obex_server.h b/lib/obex_server.h
index 2d4bc18..fc9f115 100644
--- a/lib/obex_server.h
+++ b/lib/obex_server.h
@@ -23,9 +23,7 @@
 #define OBEX_SERVER_H
 
 struct obex;
-struct databuffer;
 
 int obex_server(struct obex *self);
-int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len);
 
 #endif
-- 
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