---
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
[email protected]
http://lists.sourceforge.net/lists/listinfo/openobex-users