---
 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


------------------------------------------------------------------------------
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