?? obex_object.c
字號(hào):
many as possible into the tx-msg */ while(addmore == TRUE && object->tx_headerq != NULL) { h = object->tx_headerq->data; if(h->stream) { /* This is a streaming body */ actual = send_stream(self, h, txmsg, tx_left); if(actual < 0 ) return -1; tx_left -= actual; if (object->suspend) addmore = FALSE; } else if(h->hi == OBEX_HDR_BODY) { /* The body may be fragmented over several packets. */ tx_left -= send_body(object, h, txmsg, tx_left); } else if(h->length <= tx_left) { /* There is room for more data in tx msg */ DEBUG(4, "Adding non-body header\n"); g_netbuf_put_data(txmsg, h->buf->data, h->length); tx_left -= h->length; /* Remove from tx-queue */ object->tx_headerq = slist_remove(object->tx_headerq, h); g_netbuf_free(h->buf); free(h); } else if(h->length > self->mtu_tx) { /* Header is bigger than MTU. This should not happen, because OBEX_ObjectAddHeader() rejects headers bigger than the MTU */ DEBUG(0, "ERROR! header to big for MTU\n"); return -1; } else { /* This header won't fit. */ addmore = FALSE; } if(tx_left == 0) addmore = FALSE; }; /* Decide which command to use, and if to use final-bit */ if(object->tx_headerq) { /* Have more headers (or body) to send */ /* In server, final bit is always set. * In client, final bit is set only when we finish sending. * Jean II */ if(forcefinalbit) real_opcode = object->opcode | OBEX_FINAL; else real_opcode = object->opcode; finished = 0; } else if(allowfinalcmd == FALSE) { /* Have no yet any headers to send, but not allowed to send * final command (== server, receiving incomming request) */ real_opcode = object->opcode | OBEX_FINAL; finished = 0; } else { /* Have no more headers to send, and allowed to send final * command (== end data we are sending) */ real_opcode = object->lastopcode | OBEX_FINAL; finished = 1; } DEBUG(4, "Sending package with opcode %d\n", real_opcode); actual = obex_data_request(self, txmsg, real_opcode); if(actual < 0) { DEBUG(4, "Send error\n"); return actual; } else { return finished; }}/* * Function obex_object_getnextheader() * * Return the next header in the rx-queue * */int obex_object_getnextheader(obex_t *self, obex_object_t *object, uint8_t *hi, obex_headerdata_t *hv, uint32_t *hv_size){ uint32_t *bq4; struct obex_header_element *h; DEBUG(4, "\n"); /* No more headers */ if(object->rx_headerq == NULL) return 0; /* New headers are appended at the end of the list while receiving, so we pull them from the front. Since we cannot free the mem used just yet just put the header in another list so we can free it when the object is deleted. */ h = object->rx_headerq->data; object->rx_headerq = slist_remove(object->rx_headerq, h); object->rx_headerq_rm = slist_append(object->rx_headerq_rm, h); *hi = h->hi; *hv_size= h->length; switch (h->hi & OBEX_HI_MASK) { case OBEX_BYTE_STREAM: hv->bs = &h->buf->data[0]; break; case OBEX_UNICODE: hv->bs = &h->buf->data[0]; break; case OBEX_INT: bq4 = (uint32_t*) h->buf->data; hv->bq4 = ntohl(*bq4); break; case OBEX_BYTE: hv->bq1 = h->buf->data[0]; break; } return 1;}/* * Function obex_object_reparseheader() * * Allow the user to re-parse the headers in the rx-queue * */int obex_object_reparseheaders(obex_t *self, obex_object_t *object){ DEBUG(4, "\n"); /* Check that there is no more active headers */ if(object->rx_headerq != NULL) return 0; /* Put the old headers back in the active list */ object->rx_headerq = object->rx_headerq_rm; object->rx_headerq_rm = NULL; /* Success */ return 1;}/* * Function obex_object_receive_stream() * * Handle receiving of body-stream * */static void obex_object_receive_stream(obex_t *self, uint8_t hi, uint8_t *source, unsigned int len){ obex_object_t *object = self->object; DEBUG(4, "\n"); /* Spare the app this empty nonlast body-hdr */ if(hi == OBEX_HDR_BODY && len == 0) { return; } object->s_buf = source; object->s_len = len; if (object->abort) { DEBUG(3, "Ignoring incomming data because request was aborted\n"); return; } /* Notify app that data has arrived */ obex_deliver_event(self, OBEX_EV_STREAMAVAIL, 0, 0, FALSE); /* If send send EOS to app */ if(hi == OBEX_HDR_BODY_END && len != 0) { object->s_buf = source; object->s_len = 0; obex_deliver_event(self, OBEX_EV_STREAMAVAIL, 0, 0, FALSE); }}/* * Function obex_object_receive_body() * * Handle receiving of body * */static int obex_object_receive_body(obex_object_t *object, GNetBuf *msg, uint8_t hi, uint8_t *source, unsigned int len){ struct obex_header_element *element; DEBUG(4, "This is a body-header. Len=%d\n", len); if(len > msg->len) { DEBUG(1, "Header %d to big. HSize=%d Buffer=%d\n", hi, len, msg->len); return -1; } if(!object->rx_body) { int alloclen = OBEX_OBJECT_ALLOCATIONTRESHOLD + len; if(object->hinted_body_len) alloclen = object->hinted_body_len; DEBUG(4, "Allocating new body-buffer. Len=%d\n", alloclen); if(! (object->rx_body = g_netbuf_new(alloclen))) return -1; } /* Reallocate body-netbuf if needed */ if(g_netbuf_tailroom(object->rx_body) < (int)len) { DEBUG(4, "Buffer too small. Go realloc\n"); if(! (object->rx_body = g_netbuf_realloc(object->rx_body, object->rx_body->truesize + OBEX_OBJECT_ALLOCATIONTRESHOLD + len) ) ) { DEBUG(1, "Can't realloc rx_body\n"); return -1; // FIXME: Handle this in a nice way... } } g_netbuf_put_data(object->rx_body, source, len); if(hi == OBEX_HDR_BODY_END) { DEBUG(4, "Body receive done\n"); if( (element = malloc(sizeof(struct obex_header_element)) ) ) { memset(element, 0, sizeof(struct obex_header_element)); element->length = object->rx_body->len; element->hi = OBEX_HDR_BODY; element->buf = object->rx_body; /* Add element to rx-list */ object->rx_headerq = slist_append(object->rx_headerq, element); } else { g_netbuf_free(object->rx_body); } object->rx_body = NULL; } else { DEBUG(4, "Normal body fragment...\n"); } return 1;}/* * Function obex_object_receive() * * Add any incoming headers to headerqueue. * */int obex_object_receive(obex_t *self, GNetBuf *msg){ obex_object_t *object; struct obex_header_element *element; uint8_t *source = NULL; unsigned int len, hlen; uint8_t hi; int err = 0; union { struct obex_unicode_hdr *unicode; struct obex_byte_stream_hdr *bstream; struct obex_uint_hdr *uint; } h; DEBUG(4, "\n"); object = self->object; /* Remove command from buffer */ g_netbuf_pull(msg, sizeof(struct obex_common_hdr)); /* Copy any non-header data (like in CONNECT and SETPATH) */ if(object->headeroffset) { object->rx_nonhdr_data = g_netbuf_new(object->headeroffset); if(!object->rx_nonhdr_data) return -1; g_netbuf_put_data(object->rx_nonhdr_data, msg->data, object->headeroffset); DEBUG(4, "Command has %d bytes non-headerdata\n", object->rx_nonhdr_data->len); g_netbuf_pull(msg, object->headeroffset); object->headeroffset = 0; } while ((msg->len > 0) && (!err)) { hi = msg->data[0]; DEBUG(4, "Header: %02x\n", hi); switch (hi & OBEX_HI_MASK) { case OBEX_UNICODE: h.unicode = (struct obex_unicode_hdr *) msg->data; source = &msg->data[3]; hlen = ntohs(h.unicode->hl); len = hlen - 3; break; case OBEX_BYTE_STREAM: h.bstream = (struct obex_byte_stream_hdr *) msg->data; source = &msg->data[3]; hlen = ntohs(h.bstream->hl); len = hlen - 3; if(hi == OBEX_HDR_BODY || hi == OBEX_HDR_BODY_END) { /* The body-header need special treatment */ if(object->s_srv) { obex_object_receive_stream(self, hi, source, len); } else { if(obex_object_receive_body(object, msg, hi, source, len) < 0) err = -1; } /* We have already handled this data! */ source = NULL; } break; case OBEX_BYTE: source = &msg->data[1]; len = 1; hlen = 2; break; case OBEX_INT: source = &msg->data[1]; len = 4; hlen = 5; break; default: DEBUG(1, "Badly formed header received\n"); source = NULL; hlen = 0; len = 0; err = -1; break; } /* Make sure that the msg is big enough for header */ if(len > msg->len) { DEBUG(1, "Header %d to big. HSize=%d Buffer=%d\n", hi, len, msg->len); source = NULL; err = -1; } if(source) { /* The length MAY be useful when receiving body. */ if(hi == OBEX_HDR_LENGTH) { h.uint = (struct obex_uint_hdr *) msg->data; object->hinted_body_len = ntohl(h.uint->hv); DEBUG(4, "Hinted body len is %d\n", object->hinted_body_len); } if( (element = malloc(sizeof(struct obex_header_element)) ) ) { memset(element, 0, sizeof(struct obex_header_element)); element->length = len; element->hi = hi; // If we get an emtpy we have to deal with it... // This might not be an optimal way, but it works. if(len == 0) { DEBUG(4, "Got empty header. Allocating dummy buffer anyway\n"); element->buf = g_netbuf_new(1); } else { element->buf = g_netbuf_new(len); if(element->buf) { DEBUG(4, "Copying %d bytes\n", len); g_netbuf_put_data(element->buf, source, len); } } if(element->buf) { /* Add element to rx-list */ object->rx_headerq = slist_append(object->rx_headerq, element); } else { DEBUG(1, "Cannot allocate memory\n"); free(element); err = -1; } } else { DEBUG(1, "Cannot allocate memory\n"); err = -1; } } if(err) return err; DEBUG(4, "Pulling %d bytes\n", hlen); g_netbuf_pull(msg, hlen); } return 1;}/* * Function obex_object_readstream() * * App wants to read stream fragment. * */int obex_object_readstream(obex_t *self, obex_object_t *object, const uint8_t **buf){ DEBUG(4, "\n"); /* Enable streaming */ if(buf == NULL) { DEBUG(4, "Streaming is enabled!\n"); object->s_srv = TRUE; return 0; } DEBUG(4, "s_len = %d\n", object->s_len); *buf = object->s_buf; return object->s_len;}int obex_object_suspend(obex_object_t *object){ object->suspend = 1; return 0;}int obex_object_resume(obex_t *self, obex_object_t *object){ if (!object->suspend) return 0; object->suspend = 0; if (!object->continue_received) return 0; if (obex_object_send(self, object, TRUE, FALSE) < 0) obex_deliver_event(self, OBEX_EV_LINKERR, object->opcode, 0, TRUE); else obex_deliver_event(self, OBEX_EV_PROGRESS, object->opcode, 0, FALSE); object->continue_received = 0; return 0;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -