Am Dienstag 09 November 2010, 09:45:19 schrieb Hendrik Sattler:
> Zitat von "hui li" <nami.li1...@gmail.com>:
> > Thans a lot for your mail. The obex15 spec says "SRM shall be used for
> > all multi-response operatons(PUT and GET) for the duration of the SRM
> > mode". I don`t know why you think SRM only valid in PUT request and
> > GET response in my branch. I handled both server and client side
> > during SRM.
> >
> > For SRM PUT request ,client keeps sending request containing body to
> >
> > server without server response ,and server only responses at the
> > first request, the last put request or abort request. For SRM GET
> > request, server keeps sending responses containing body to client
> > without client other request ,and client only send first SRM GET
> > request or abort request.
> > My brach simply assumes only client can request SRM enble firstly, if
> > server receives SRM header, it responses SRM enable. On a put or get
> > operation, server does not request SRM in its head initiatively.
> >
> > I will study your queue without threading later.
>
> I will publish it (not done, yet). The idea is to make
> OBEX_HandleInput() not call obex_transport_handle_input() but a new
> function obex_work() instead which call one of the new function
> obex_(client|server)_work(). In those, it is easy to see in which
> state a response will not come and a packet has to be sent without it.
> Omitting more than one response(server) or additional requests(client)
> is easily done inline.
> I will post a proposal patch this evening so everybody can comment. It
> will leave handling of all OBEX SRM headers to the application so it
> can decide if it trusts the transport enough to enable it.
Here it is. Note that the write()/send() functions still fail too easily.
That's needs to be solved, I'll do that the next days.
What's in it:
- allows to handle SRM mode
- removes STATE_IDLE which was only used in MODE_CLI (now handled by
STATE_SEND)
- changes rx_msg buffer management so that a message stream is handled
correctly
You can test it easily with any application by initialising self->rsp_mode to
OBEX_RSP_MODE_SINGLE instead of OBEX_RSP_MODE_NORMAL.
HS
diff --git a/include/openobex/obex.h b/include/openobex/obex.h
index 954a411..f948113 100644
--- a/include/openobex/obex.h
+++ b/include/openobex/obex.h
@@ -96,6 +96,9 @@ OPENOBEX_SYMBOL(obex_object_t *) OBEX_ObjectNew(obex_t *self, uint8_t cmd);
OPENOBEX_SYMBOL(int) OBEX_ObjectDelete(obex_t *self, obex_object_t *object);
OPENOBEX_SYMBOL(int) OBEX_ObjectGetSpace(obex_t *self, obex_object_t *object, unsigned int flags);
+OPENOBEX_SYMBOL(void) OBEX_SetReponseMode(obex_t *self,
+ enum obex_rsp_mode rsp_mode);
+
OPENOBEX_SYMBOL(int) OBEX_ObjectAddHeader(obex_t *self, obex_object_t *object,
uint8_t hi, obex_headerdata_t hv, uint32_t hv_size,
unsigned int flags);
diff --git a/include/openobex/obex_const.h b/include/openobex/obex_const.h
index f019ccb..b8335ec 100644
--- a/include/openobex/obex_const.h
+++ b/include/openobex/obex_const.h
@@ -292,6 +292,11 @@ typedef union {
#define OBEX_RSP_DATABASE_FULL 0x60
#define OBEX_RSP_DATABASE_LOCKED 0x61
+enum obex_rsp_mode {
+ OBEX_RSP_MODE_NORMAL = 0, /**< normal response mode */
+ OBEX_RSP_MODE_SINGLE = 1, /**< single response mode (SRM) */
+};
+
/* Min, Max and default transport MTU */
#define OBEX_DEFAULT_MTU 1024
#define OBEX_MINIMUM_MTU 255
diff --git a/lib/defines.h b/lib/defines.h
index d8e75c9..39cfb35 100644
--- a/lib/defines.h
+++ b/lib/defines.h
@@ -25,7 +25,6 @@ enum obex_mode {
enum obex_state {
STATE_IDLE,
- STATE_START,
STATE_SEND,
STATE_REC,
};
diff --git a/lib/obex.c b/lib/obex.c
index ff030a6..609fcfb 100644
--- a/lib/obex.c
+++ b/lib/obex.c
@@ -107,6 +107,7 @@ obex_t * CALLAPI OBEX_Init(int transport, obex_event_t eventcb,
self->init_flags = flags;
self->mode = MODE_SRV;
self->state = STATE_IDLE;
+ self->rsp_mode = OBEX_RSP_MODE_NORMAL;
/* Safe values.
* Both self->mtu_rx and self->mtu_tx_max can be increased by app
@@ -509,9 +510,10 @@ int CALLAPI OBEX_Request(obex_t *self, obex_object_t *object)
obex_return_val_if_fail(object != NULL, -1);
+ object->rsp_mode = self->rsp_mode;
self->object = object;
self->mode = MODE_CLI;
- self->state = STATE_START;
+ self->state = STATE_SEND;
return obex_client(self, NULL, 0);
}
@@ -623,6 +625,32 @@ int CALLAPI OBEX_ObjectGetSpace(obex_t *self, obex_object_t *object,
}
/**
+ Set the OBEX response mode.
+ \param self OBEX context
+ \param rsp_mode see OBEX_RSP_MODE_*
+
+ If you want any mode other than default (#OBEX_RSP_MODE_NORMAL), you
+ have to call this function. If you want it to affect the current object,
+ you need to call it at the first #OBEX_EV_PROGRESS (as client) or
+ at the #OBEX_EV_REQHINT or #OBEX_EV_REQCHECK events (as server).
+ */
+LIB_SYMBOL
+void CALLAPI OBEX_SetReponseMode(obex_t *self, enum obex_rsp_mode rsp_mode)
+{
+ switch (rsp_mode) {
+ case OBEX_RSP_MODE_NORMAL:
+ case OBEX_RSP_MODE_SINGLE:
+ self->rsp_mode = rsp_mode;
+ if (self->object)
+ self->object->rsp_mode = rsp_mode;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
Attach a header to an object.
\param self OBEX handle
\param object OBEX object
diff --git a/lib/obex_client.c b/lib/obex_client.c
index 43e7800..9b082cc 100644
--- a/lib/obex_client.c
+++ b/lib/obex_client.c
@@ -43,7 +43,10 @@ static __inline int msg_get_rsp(const buf_t *msg)
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 int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
@@ -61,7 +64,7 @@ static int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
self->mode = MODE_SRV;
self->state = STATE_IDLE;
obex_deliver_event(self, OBEX_EV_PARSEERR,
- self->object->opcode, 0, TRUE);
+ self->object->opcode, rsp, TRUE);
return -1;
}
self->object->headeroffset=4;
@@ -71,6 +74,7 @@ static int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
/* So does CMD_DISCONNECT */
DEBUG(2, "CMD_DISCONNECT done. Resetting MTU!\n");
self->mtu_tx = OBEX_MINIMUM_MTU;
+ self->rsp_mode = OBEX_RSP_MODE_NORMAL;
break;
}
@@ -80,7 +84,7 @@ static int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
self->mode = MODE_SRV;
self->state = STATE_IDLE;
obex_deliver_event(self, OBEX_EV_PARSEERR,
- self->object->opcode, 0, TRUE);
+ self->object->opcode, rsp, TRUE);
return -1;
}
@@ -100,11 +104,17 @@ static int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
return 0;
}
- ret = obex_object_send(self, self->object, TRUE, FALSE);
- if (ret < 0)
- obex_deliver_event(self, OBEX_EV_LINKERR, self->object->opcode, 0, TRUE);
- else
- obex_deliver_event(self, OBEX_EV_PROGRESS, self->object->opcode, 0, FALSE);
+ if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL) {
+ ret = obex_object_send(self, self->object, TRUE, FALSE);
+ if (ret < 0) {
+ obex_deliver_event(self, OBEX_EV_LINKERR,
+ self->object->opcode, rsp,
+ TRUE);
+ }
+ }
+ if (ret >= 0)
+ obex_deliver_event(self, OBEX_EV_PROGRESS,
+ self->object->opcode, rsp, FALSE);
if (self->object)
self->object->continue_received = 0;
@@ -133,96 +143,85 @@ static int obex_client_recv(obex_t *self, buf_t *msg, int rsp)
return 0;
}
-static int obex_client_start(obex_t *self, buf_t *msg, int rsp)
+int obex_client_send(obex_t *self, buf_t *msg, int rsp)
{
int ret;
- /* Nothing has been sent yet */
- DEBUG(4, "STATE_START\n");
+ /* In progress of sending request */
+ DEBUG(4, "STATE_SEND\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;
- if (!self->object) {
- DEBUG(4, "Got unexpected data from the server\n");
- obex_deliver_event(self, OBEX_EV_PARSEERR, rsp, 0, TRUE);
- return -1;
+ 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) {
+ DEBUG(1, "STATE_SEND. Didn't excpect data from peer "
+ "(%u)\n", msg_get_len(msg));
+ DUMPBUFFER(4, "unexpected data", msg);
+ /* 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). */
+ if (self->object->opcode == OBEX_CMD_CONNECT ||
+ obex_object_receive(self, msg) < 0) {
+ self->mode = MODE_SRV;
+ self->state = STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_PARSEERR,
+ self->object->opcode, 0, TRUE);
+ return -1;
+ }
+ obex_deliver_event(self, OBEX_EV_UNEXPECTED,
+ self->object->opcode, 0, FALSE);
+ /* 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);
if (ret < 0) {
/* Error while sending */
- self->mode = MODE_SRV;
- self->state = STATE_IDLE;
obex_deliver_event(self, OBEX_EV_LINKERR,
self->object->opcode, 0, TRUE);
- return 0;
+ self->mode = MODE_SRV;
+ self->state = STATE_IDLE;
+ return -1;
+
}
self->object->first_packet_sent = 1;
-
obex_deliver_event(self, OBEX_EV_PROGRESS, self->object->opcode,
- 0, FALSE);
-
- self->state = STATE_REC;
-
+ 0, FALSE);
+ if (ret > 0) {
+ self->state = STATE_REC;
+ }
return 0;
}
-static int obex_client_send(obex_t *self, buf_t *msg, int rsp)
-{
- /* In progress of sending request */
- DEBUG(4, "STATE_SEND\n");
-
- /* Any errors from peer? Win2k will send RSP_SUCCESS after
- * every fragment sent so we have to accept that too.*/
- if (rsp != OBEX_RSP_SUCCESS && rsp != OBEX_RSP_CONTINUE) {
- 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) {
- DEBUG(1, "STATE_SEND. Didn't excpect data from peer (%u)\n",
- msg_get_len(msg));
- DUMPBUFFER(4, "unexpected data", msg);
- /* At this point, we are in the middle of sending
- * our request to the server, and it is already
- * sending us some data ! This break the whole
- * Request/Response model of HTTP !
- * 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 header, 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).
- * Don't send any additional event to the app to not
- * break compatibility and because app can just check
- * this condition itself...
- * No headeroffset needed because 'connect' is
- * single packet (or we deny it).
- * Jean II */
- if (self->object->opcode == OBEX_CMD_CONNECT ||
- obex_object_receive(self, msg) < 0) {
- self->mode = MODE_SRV;
- self->state = STATE_IDLE;
- obex_deliver_event(self, OBEX_EV_PARSEERR,
- self->object->opcode, 0, TRUE);
- return -1;
- }
- obex_deliver_event(self, OBEX_EV_UNEXPECTED,
- self->object->opcode, 0, FALSE);
- /* 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). Jean II */
- }
-
- return obex_client_start(self, msg, rsp);
-}
/*
* Function obex_client ()
@@ -240,9 +239,6 @@ int obex_client(obex_t *self, buf_t *msg, int final)
case STATE_SEND:
return obex_client_send(self, msg, rsp);
- case STATE_START:
- return obex_client_start(self, msg, rsp);
-
case STATE_REC:
return obex_client_recv(self, msg, rsp);
@@ -252,14 +248,3 @@ int obex_client(obex_t *self, buf_t *msg, int final)
return -1;
}
}
-
-/*
- * Function obex_client_work (self, timeout)
- *
- * Do some work on the current transferred object.
- *
- */
-int obex_client_work(obex_t *self, int timeout)
-{
- return obex_transport_handle_input(self, timeout);
-}
diff --git a/lib/obex_client.h b/lib/obex_client.h
index 8b2cff3..bed3593 100644
--- a/lib/obex_client.h
+++ b/lib/obex_client.h
@@ -26,6 +26,6 @@ struct obex;
struct databuffer;
int obex_client(struct obex *self, struct databuffer *msg, int final);
-int obex_client_work(obex_t *self, int timeout);
+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 700b3c3..ccde817 100644
--- a/lib/obex_main.c
+++ b/lib/obex_main.c
@@ -231,16 +231,36 @@ int obex_data_request(obex_t *self, buf_t *msg, int opcode)
*/
int obex_work(obex_t *self, int timeout)
{
- switch (self->mode) {
- case MODE_SRV:
- return obex_server_work(self, timeout);
-
- case MODE_CLI:
- return obex_client_work(self, timeout);
+ /* 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->object &&
+ self->object->rsp_mode != OBEX_RSP_MODE_NORMAL &&
+ self->state == STATE_SEND)
+ {
+ int ret;
+
+ /* 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:
+ obex_server_send(self, NULL, self->object->cmd, 0);
+
+ case MODE_CLI:
+ obex_client_send(self, NULL, OBEX_RSP_CONTINUE);
+
+ default:
+ return -1;
+ }
+ }
+ return 1;
- default:
- return -1;
}
+
+ return obex_transport_handle_input(self, timeout);
}
/*
@@ -340,7 +360,11 @@ int obex_data_indication(obex_t *self)
ret = obex_server(self, msg, final);
else
ret = obex_client(self, msg, final);
- buf_reuse(msg);
+
+ DEBUG(4, "Pulling %u bytes\n", size);
+ buf_remove_begin(msg, size);
+ if (msg->data_size == 0)
+ buf_reuse(msg);
/* Check parse errors */
if(ret < 0)
diff --git a/lib/obex_main.h b/lib/obex_main.h
index 9666e25..7d7b1f7 100644
--- a/lib/obex_main.h
+++ b/lib/obex_main.h
@@ -42,6 +42,7 @@ struct obex {
enum obex_state state;
enum obex_mode mode;
+ enum obex_rsp_mode rsp_mode; /* OBEX_RSP_MODE_* */
unsigned int init_flags;
diff --git a/lib/obex_object.c b/lib/obex_object.c
index 5713f5c..3469663 100644
--- a/lib/obex_object.c
+++ b/lib/obex_object.c
@@ -750,9 +750,6 @@ int obex_object_receive_nonhdr_data(obex_t *self, buf_t *msg)
DEBUG(4, "\n");
- /* Remove command from buffer */
- buf_remove_begin(msg, sizeof(struct obex_common_hdr));
-
if (object->headeroffset == 0)
return 0;
@@ -765,8 +762,6 @@ int obex_object_receive_nonhdr_data(obex_t *self, buf_t *msg)
object->headeroffset);
DEBUG(4, "Command has %lu bytes non-headerdata\n",
(unsigned long) object->rx_nonhdr_data->data_size);
- buf_remove_begin(msg, object->headeroffset);
- object->headeroffset = 0;
return 0;
}
@@ -941,8 +936,6 @@ int obex_object_receive(obex_t *self, buf_t *msg)
if (hlen < 0)
return hlen;
- DEBUG(4, "Pulling %lu bytes\n", (unsigned long)msg->data_size);
- buf_remove_begin(msg, msg->data_size);
return 0;
}
@@ -955,14 +948,16 @@ int obex_object_receive(obex_t *self, buf_t *msg)
*/
int obex_object_receive_headers(obex_t *self, buf_t *msg, uint64_t filter)
{
- uint16_t offset = 0;
+ struct obex_common_hdr *hdr = (obex_common_hdr_t *)msg->data;
+ uint16_t offset = sizeof(*hdr) + self->object->headeroffset;
int consumed = 0;
const uint64_t body_filter = (1 << OBEX_HDR_ID_BODY |
1 << OBEX_HDR_ID_BODY_END);
+ uint16_t msglen = ntohs(hdr->len);
DEBUG(4, "\n");
- while (offset < msg->data_size) {
+ while (offset < msglen) {
uint8_t hi = msg->data[offset];
uint8_t *source = NULL;
unsigned int len = 0;
@@ -976,10 +971,10 @@ int obex_object_receive_headers(obex_t *self, buf_t *msg, uint64_t filter)
&len, &hlen);
/* Make sure that the msg is big enough for header */
- if (len > (msg->data_size - offset)) {
- DEBUG(1, "Header %d to big. HSize=%d Buffer=%lu\n",
+ if (len > (unsigned int)(msglen - offset)) {
+ DEBUG(1, "Header %d too big. HSize=%d Buffer=%lu\n",
hi, len,
- (unsigned long) msg->data_size - offset);
+ (unsigned long) msglen - offset);
source = NULL;
err = -1;
}
diff --git a/lib/obex_server.c b/lib/obex_server.c
index 1f1ce74..9340117 100644
--- a/lib/obex_server.c
+++ b/lib/obex_server.c
@@ -44,7 +44,7 @@ static __inline uint16_t msg_get_len(const buf_t *msg)
return ntohs(((obex_common_hdr_t *)msg->data)->len);
}
-static int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len)
+int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len)
{
int ret;
@@ -130,6 +130,7 @@ static int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len)
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->state = STATE_IDLE;
obex_deliver_event(self, OBEX_EV_REQDONE, cmd, 0, TRUE);
@@ -232,42 +233,39 @@ static int obex_server_recv(obex_t *self, buf_t *msg, int final,
return -1;
}
}
- DEBUG(4, "Pulling %lu bytes\n", (unsigned long)msg->data_size);
- buf_remove_begin(msg, msg->data_size);
if (!final) {
- /* As a server, the final bit is always SET- Jean II */
- 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;
-
- } else {
- obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
- return 0; /* Stay in this state if not final */
+ obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);
+ if (self->object->rsp_mode == OBEX_RSP_MODE_NORMAL) {
+ 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;
} else {
if (!self->object->first_packet_sent) {
- DEBUG(4, "We got a request!\n");
- /* More connect-magic woodoo stuff */
- if (cmd == OBEX_CMD_CONNECT)
- obex_insert_connectframe(self, self->object);
-
/* Tell the app that a whole request has
* arrived. While this event is delivered the
* app should append the headers that should be
* in the response */
- if (!deny)
+ if (!deny) {
+ DEBUG(4, "We got a request!\n");
obex_deliver_event(self, OBEX_EV_REQ, cmd,
0, FALSE);
- self->state = STATE_SEND;
-
+ }
+ /* More connect-magic woodoo stuff */
+ if (cmd == OBEX_CMD_CONNECT)
+ obex_insert_connectframe(self, self->object);
/* Otherwise sanitycheck later will fail */
- return obex_server_send(self, msg, cmd, 3);
-
- } else
- return obex_server_send(self, msg, cmd, len);
+ len = 3;
+ }
+ self->state = STATE_SEND;
+ return obex_server_send(self, msg, cmd, len);
}
}
@@ -292,6 +290,7 @@ static int obex_server_idle(obex_t *self, buf_t *msg, int final,
}
/* Remember the initial command of the request.*/
self->object->cmd = cmd;
+ self->object->rsp_mode = self->rsp_mode;
/* If ABORT command is done while we are not handling another command,
* we don't need to send a request hint to the application */
@@ -355,14 +354,3 @@ int obex_server(obex_t *self, buf_t *msg, int final)
return -1;
}
}
-
-/*
- * Function obex_server_work (self, timeout)
- *
- * Do some work on the current transferred object.
- *
- */
-int obex_server_work(obex_t *self, int timeout)
-{
- return obex_transport_handle_input(self, timeout);
-}
diff --git a/lib/obex_server.h b/lib/obex_server.h
index e41f29a..3906e6f 100644
--- a/lib/obex_server.h
+++ b/lib/obex_server.h
@@ -26,6 +26,6 @@ struct obex;
struct databuffer;
int obex_server(struct obex *self, struct databuffer *msg, int final);
-int obex_server_work(obex_t *self, int timeout);
+int obex_server_send(obex_t *self, buf_t *msg, int cmd, uint16_t len);
#endif
diff --git a/lib/obex_transport.c b/lib/obex_transport.c
index 060e12b..be4be74 100644
--- a/lib/obex_transport.c
+++ b/lib/obex_transport.c
@@ -238,7 +238,13 @@ int obex_transport_standard_handle_input(obex_t *self)
*/
int obex_transport_handle_input(obex_t *self, int timeout)
{
+ DEBUG(4, "\n");
self->trans.timeout = timeout;
+ if (self->rx_msg->data_size) {
+ DEBUG(4, "data already in buffer\n");
+ return obex_data_indication(self);
+ }
+
if (self->trans.ops.handle_input)
return self->trans.ops.handle_input(self);
else
------------------------------------------------------------------------------
The Next 800 Companies to Lead America's Growth: New Video Whitepaper
David G. Thomson, author of the best-selling book "Blueprint to a
Billion" shares his insights and actions to help propel your
business during the next growth cycle. Listen Now!
http://p.sf.net/sfu/SAP-dev2dev
_______________________________________________
Openobex-users mailing list
Openobex-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/openobex-users