There are now three steps for sending an object: a prepare step where a new TX message is written to the TX buffer, a transmit step where the object is transmitted and the decision step on wether the whole object is finished. The goal is to allow sending incomplete message buffers on non-blocking sockets. --- lib/obex_main.c | 30 +++++++--- lib/obex_main.h | 4 +- lib/obex_object.c | 154 +++++++++++++++++++++++++++++++++++++---------------- lib/obex_object.h | 5 ++ 4 files changed, 136 insertions(+), 57 deletions(-)
diff --git a/lib/obex_main.c b/lib/obex_main.c index 1d39cd8..884c9e3 100644 --- a/lib/obex_main.c +++ b/lib/obex_main.c @@ -210,23 +210,20 @@ void obex_response_request(obex_t *self, uint8_t opcode) obex_return_if_fail(self != NULL); msg = buf_reuse(self->tx_msg); - - obex_data_request(self, msg, opcode | OBEX_FINAL); + obex_data_request_prepare(self, msg, opcode | OBEX_FINAL); + obex_data_request(self, msg); } /* - * Function obex_data_request (self, opcode, cmd) + * Function obex_data_request_prepare (self, opcode, cmd) * - * Send response or command code along with optional headers/data. + * Prepare response or command code along with optional headers/data + * to send. * */ -int obex_data_request(obex_t *self, buf_t *msg, int opcode) +void obex_data_request_prepare(obex_t *self, buf_t *msg, int opcode) { obex_common_hdr_t *hdr; - int status; - - obex_return_val_if_fail(self != NULL, -1); - obex_return_val_if_fail(msg != NULL, -1); /* Insert common header */ hdr = buf_reserve_begin(msg, sizeof(*hdr)); @@ -235,6 +232,21 @@ int obex_data_request(obex_t *self, buf_t *msg, int opcode) hdr->len = htons((uint16_t) msg->data_size); DUMPBUFFER(1, "Tx", msg); +} + +/* + * Function obex_data_request (self, opcode) + * + * Send message. + * + */ +int obex_data_request(obex_t *self, buf_t *msg) +{ + int status; + + obex_return_val_if_fail(self != NULL, -1); + obex_return_val_if_fail(msg != NULL, -1); + DEBUG(1, "len = %lu bytes\n", (unsigned long) msg->data_size); do { diff --git a/lib/obex_main.h b/lib/obex_main.h index 3c3098c..53d2768 100644 --- a/lib/obex_main.h +++ b/lib/obex_main.h @@ -71,7 +71,9 @@ int obex_get_buffer_status(buf_t *msg); int obex_data_indication(struct obex *self); void obex_response_request(struct obex *self, uint8_t opcode); -int obex_data_request(struct obex *self, struct databuffer *msg, int opcode); +void obex_data_request_prepare(struct obex *self, struct databuffer *msg, + int opcode); +int obex_data_request(struct obex *self, struct databuffer *msg); int obex_cancelrequest(struct obex *self, int nice); char *obex_response_to_string(int rsp); diff --git a/lib/obex_object.c b/lib/obex_object.c index 3fcd10a..f888a2d 100644 --- a/lib/obex_object.c +++ b/lib/obex_object.c @@ -446,30 +446,54 @@ static unsigned int obex_object_send_srm_flags (uint8_t flag) } } +static int obex_object_get_real_opcode(obex_object_t *object, + int allowfinalcmd, int forcefinalbit) +{ + int real_opcode = object->opcode; + + /* Decide which command to use, and if to use final-bit */ + DEBUG(4, "allowfinalcmd: %d forcefinalbit:%d\n", allowfinalcmd, + forcefinalbit); + + /* Have more headers (or body) to send? */ + if (!slist_is_empty(object->tx_headerq)) { + /* In server, final bit is always set. + * In client, final bit is set only when we finish sending. */ + if (forcefinalbit) + real_opcode |= OBEX_FINAL; + + } else { + /* Have no more headers to send */ + if (allowfinalcmd != FALSE) { + /* Allowed to send final command (== end data we are + * sending) */ + real_opcode = object->lastopcode; + } + + real_opcode |= OBEX_FINAL; + } + + return real_opcode; +} + /* - * Function obex_object_send() + * Function obex_object_prepare_send() * - * Send away all headers attached to an object. Returns: - * 1 on sucessfully done - * 0 on progress made - * < 0 on error + * Prepare to send away all headers attached to an object. + * Returns: + * 1 when a message was created + * 0 when no message was created + * -1 on error */ -int obex_object_send(obex_t *self, obex_object_t *object, - int allowfinalcmd, int forcefinalbit) +int obex_object_prepare_send(obex_t *self, obex_object_t *object, + int allowfinalcmd, int forcefinalbit) { buf_t *txmsg; - int actual, real_opcode, finished = 0, addmore = TRUE; + int actual, real_opcode, addmore = TRUE; uint16_t tx_left; unsigned int srm_flags = 0; - DEBUG(4, "allowfinalcmd: %d forcefinalbit:%d\n", allowfinalcmd, - forcefinalbit); - - /* Return finished if aborted */ - if (object->abort) - return 1; - - /* Don't do anything of object is suspended */ + /* Don't do anything if object is suspended */ if (object->suspend) return 0; @@ -539,8 +563,8 @@ int obex_object_send(obex_t *self, obex_object_t *object, object->suspend = 1; if (h->hi == OBEX_HDR_SRM_FLAGS) - srm_flags = - obex_object_send_srm_flags(h->buf->data[0]); + srm_flags = obex_object_send_srm_flags( + h->buf->data[0]); /* Remove from tx-queue */ object->tx_headerq = @@ -570,46 +594,82 @@ int obex_object_send(obex_t *self, obex_object_t *object, addmore = FALSE; } - /* Decide which command to use, and if to use final-bit */ - if (object->tx_headerq) { - /* Have more headers (or body) to send */ - real_opcode = object->opcode; + real_opcode = obex_object_get_real_opcode(self->object, allowfinalcmd, + forcefinalbit); + DEBUG(4, "Generating packet with opcode %d\n", real_opcode); + obex_data_request_prepare(self, self->tx_msg, real_opcode); - /* In server, final bit is always set. - * In client, final bit is set only when we finish sending. */ - if (forcefinalbit) - real_opcode |= OBEX_FINAL; + self->srm_flags &= ~OBEX_SRM_FLAG_WAIT_REMOTE; + self->srm_flags |= srm_flags; - finished = 0; - } else { - /* Have no more headers to send */ - if (allowfinalcmd == FALSE) { - /* Not allowed to send final command (== server, - * receiving incomming request) */ - real_opcode = object->opcode; + return 1; +} - } else { - /* Allowed to send final command (== end data we are - * sending) */ - real_opcode = object->lastopcode; - } +int obex_object_finished(obex_t *self, obex_object_t *object, int allowfinalcmd) +{ + int finished = 0; - real_opcode |= OBEX_FINAL; + if (object->abort) + return 1; + + if (object->suspend) + return 0; + + if (slist_is_empty(object->tx_headerq)) finished = !!allowfinalcmd; + + return finished; +} + +int obex_object_send_transmit(obex_t *self, obex_object_t *object) +{ + int ret; + + if (!buf_empty(self->tx_msg)) { + ret = obex_data_request(self, self->tx_msg); + if (ret < 0) { + DEBUG(4, "Send error\n"); + return -1; + } } - DEBUG(4, "Sending package with opcode %d\n", real_opcode); - actual = obex_data_request(self, txmsg, real_opcode); + return buf_empty(self->tx_msg); +} - if (actual < 0) { - DEBUG(4, "Send error\n"); - return -1; +/* + * Function obex_object_send() + * + * Send away an object packet. + * Returns: + * 1 complete + * 0 incomplete but no error + * -1 error + */ +int obex_object_send(obex_t *self, obex_object_t *object, int allowfinalcmd, + int forcefinalbit) +{ + int ret; + + /* Return finished if aborted */ + if (object->abort) { + (void)buf_reuse(self->tx_msg); + return 1; } - self->srm_flags &= ~OBEX_SRM_FLAG_WAIT_REMOTE; - self->srm_flags |= srm_flags; + if (buf_empty(self->tx_msg)) { + ret = obex_object_prepare_send(self, object, allowfinalcmd, + forcefinalbit); + if (ret == -1) { + DEBUG(4, "Packet prepare error\n"); + return -1; + } else if (ret == 0) + return 0; + } - return finished; + ret = obex_object_send_transmit(self, object); + if (ret == 1) + ret = obex_object_finished(self, object, allowfinalcmd); + return ret; } /* diff --git a/lib/obex_object.h b/lib/obex_object.h index fd2904a..eef3458 100644 --- a/lib/obex_object.h +++ b/lib/obex_object.h @@ -96,6 +96,11 @@ int obex_object_getnextheader(struct obex *self, struct obex_object *object, uin int obex_object_reparseheaders(struct obex *self, struct obex_object *object); void obex_object_setcmd(struct obex_object *object, uint8_t cmd); int obex_object_setrsp(struct obex_object *object, uint8_t rsp, uint8_t lastrsp); +int obex_object_prepare_send(obex_t *self, obex_object_t *object, + int allowfinalcmd, int forcefinalbit); +int obex_object_finished(obex_t *self, obex_object_t *object, + int allowfinalcmd); +int obex_object_send_transmit(obex_t *self, obex_object_t *object); int obex_object_send(struct obex *self, struct obex_object *object, int allowfinalcmd, int forcefinalbit); -- 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