/* * Function obex_insert_connectframe () * * Add the data needed to send/reply to a connect * */ int obex_insert_connectframe(obex_t *self, obex_object_t *object) { obex_connect_hdr_t *conn_hdr; DEBUG(4, "\n"); object->tx_nonhdr_data = buf_new(4); if (!object->tx_nonhdr_data) return -1; conn_hdr = (obex_connect_hdr_t *) buf_reserve_end(object->tx_nonhdr_data, 4); conn_hdr->version = OBEX_VERSION; conn_hdr->flags = 0x00; /* Flags */ conn_hdr->mtu = htons(self->mtu_rx); /* Max packet size */ return 0; }
static int obex_bulk_read(obex_t *self, buf_t *msg) { int retval, actual_length; int expected_length; char * buffer; DEBUG(self, 4, "Read from endpoint %d\n", self->read_endpoint_address); do { buffer = buf_reserve_end(msg, self->mtu_rx); retval = libusb_bulk_transfer(self->usb_dev, self->read_endpoint_address, buffer, self->mtu_rx, &actual_length, 1245); buf_remove_end(msg, self->mtu_rx - actual_length); expected_length = ntohs(*((uint16_t*)(msg->data + 1))); } while (expected_length != msg->data_size && actual_length > 0); if (retval == 0) retval = msg->data_size; return retval; }
/* * Function send_body(object, header, txmsg, tx_left) * * Fragment and send the body * */ static int send_body(obex_object_t *object, struct obex_header_element *h, buf_t *txmsg, unsigned int tx_left) { struct obex_byte_stream_hdr *body_txh; unsigned int actual; body_txh = (struct obex_byte_stream_hdr*) buf_reserve_end(txmsg, sizeof(struct obex_byte_stream_hdr)); if (!h->body_touched) { /* This is the first time we try to send this header obex_object_addheaders has added a struct_byte_stream_hdr before the actual body-data. We shall send this in every fragment so we just remove it for now.*/ buf_remove_begin(h->buf, sizeof(struct obex_byte_stream_hdr) ); h->body_touched = TRUE; } if (tx_left < ( h->buf->data_size + sizeof(struct obex_byte_stream_hdr) ) ) { DEBUG(4, "Add BODY header\n"); body_txh->hi = OBEX_HDR_BODY; body_txh->hl = htons((uint16_t)tx_left); buf_insert_end(txmsg, h->buf->data, tx_left - sizeof(struct obex_byte_stream_hdr) ); buf_remove_begin(h->buf, tx_left - sizeof(struct obex_byte_stream_hdr) ); /* We have completely filled the tx-buffer */ actual = tx_left; } else { DEBUG(4, "Add BODY_END header\n"); body_txh->hi = OBEX_HDR_BODY_END; body_txh->hl = htons((uint16_t) (h->buf->data_size + sizeof(struct obex_byte_stream_hdr))); buf_insert_end(txmsg, h->buf->data, h->buf->data_size); actual = h->buf->data_size; object->tx_headerq = slist_remove(object->tx_headerq, h); buf_free(h->buf); free(h); } return actual; }
static int obex_verify_seq(obex_t *self, uint8_t seq) { int retval, actual_length = 0, count = 0; char * buffer; buffer = buf_reserve_end(self->rx_msg, self->mtu_rx); do { retval = libusb_bulk_transfer(self->usb_dev, self->read_endpoint_address, buffer, self->mtu_rx, &actual_length, 1245); if (retval < 0) break; count++; } while (count < 100 && actual_length == 0); buf_remove_end(self->rx_msg, self->mtu_rx - actual_length); if (retval < 0 || actual_length == 0) { DEBUG(self, 4, "Error reading seq number (%d)\n", retval); return 0; } if ((uint8_t)buffer[0] != seq) { DEBUG(self, 4, "Sequence mismatch %u != %u\n", (uint8_t)buffer[0], seq); return 0; } buf_remove_begin(self->rx_msg, 1); return 1; }
/* * Function obex_transport_read () * * Do the reading * */ int obex_transport_read(obex_t *self, int max, uint8_t *buf, int buflen) { int actual = -1; buf_t *msg = self->rx_msg; #if defined(HAVE_USB) && defined(HAVE_USB1) int usberror; #endif DEBUG(4, "Request to read max %d bytes\n", max); switch (self->trans.type) { #ifdef HAVE_IRDA case OBEX_TRANS_IRDA: #endif /*HAVE_IRDA*/ #ifdef HAVE_BLUETOOTH case OBEX_TRANS_BLUETOOTH: #endif /*HAVE_BLUETOOTH*/ case OBEX_TRANS_INET: actual = recv(self->fd, buf_reserve_end(msg, max), max, 0); if (actual > 0) buf_remove_end(msg, max - actual); break; case OBEX_TRANS_FD: #ifdef _WIN32 actual = _read(self->fd, buf_reserve_end(msg, max), max); #else actual = read(self->fd, buf_reserve_end(msg, max), max); #endif if (actual > 0) buf_remove_end(msg, max - actual); break; #ifdef HAVE_USB case OBEX_TRANS_USB: if (self->trans.connected != TRUE) break; DEBUG(4, "Endpoint %d\n", self->trans.self.usb.data_endpoint_read); #ifdef HAVE_USB1 usberror = libusb_bulk_transfer(self->trans.self.usb.dev, self->trans.self.usb.data_endpoint_read, buf_reserve_end(msg, self->mtu_rx), self->mtu_rx, &actual, USB_OBEX_TIMEOUT); if (usberror) actual = usberror; #else actual = usb_bulk_read(self->trans.self.usb.dev, self->trans.self.usb.data_endpoint_read, buf_reserve_end(msg, self->mtu_rx), self->mtu_rx, USB_OBEX_TIMEOUT); #endif buf_remove_end(msg, self->mtu_rx - actual); break; #endif /*HAVE_USB*/ case OBEX_TRANS_CUSTOM: if (buflen > max) { memcpy(buf_reserve_end(msg, max), buf, max); actual = max; } else { memcpy(buf_reserve_end(msg, buflen), buf, buflen); actual = buflen; } break; default: DEBUG(4, "Transport not implemented!\n"); break; } return actual; }
/* * Function send_stream(object, header, txmsg, tx_left) * * Send a streaming header. * */ static int send_stream(obex_t *self, struct obex_header_element *h, buf_t *txmsg, unsigned int tx_left) { obex_object_t *object; struct obex_byte_stream_hdr *body_txh; int actual; /* Number of bytes sent in this fragment */ DEBUG(4, "\n"); object = self->object; /* Fill in length and header type later, but reserve space for it */ body_txh = (struct obex_byte_stream_hdr*) buf_reserve_end(txmsg, sizeof(struct obex_byte_stream_hdr) ); tx_left -= sizeof(struct obex_byte_stream_hdr); actual = sizeof(struct obex_byte_stream_hdr); do { if (object->s_len == 0) { /* Ask app for more data if no more */ object->s_offset = 0; object->s_buf = NULL; obex_deliver_event(self, OBEX_EV_STREAMEMPTY, 0, 0, FALSE); DEBUG(4, "s_len=%d, s_stop = %d\n", object->s_len, object->s_stop); /* End of stream ?*/ if (object->s_stop) break; /* User suspended and didn't provide any new data */ if (object->suspend && object->s_buf == NULL) break; /* Error ?*/ if (object->s_buf == NULL) { DEBUG(1, "Unexpected end-of-stream\n"); return -1; } } if (tx_left < object->s_len) { /* There is more data left in buffer than tx_left */ DEBUG(4, "More data than tx_left. Buffer will not be empty\n"); buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, tx_left); object->s_len -= tx_left; object->s_offset += tx_left; actual += tx_left; tx_left = 0; } else { /* There less data in buffer than tx_left */ DEBUG(4, "Less data that tx_left. Buffer will be empty\n"); buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, object->s_len); tx_left -= object->s_len; object->s_offset += object->s_len; actual += object->s_len; object->s_len = 0; if (object->suspend) tx_left = 0; } } while (tx_left > 0); DEBUG(4, "txmsg full or no more stream-data. actual = %d\n", actual); body_txh->hi = OBEX_HDR_BODY; if (object->s_stop && object->s_len == 0) { /* We are done. Remove header from tx-queue */ object->tx_headerq = slist_remove(object->tx_headerq, h); body_txh->hi = OBEX_HDR_BODY_END; buf_free(h->buf); free(h); } body_txh->hl = htons((uint16_t)actual); return actual; }