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