/*
 * 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;
}
Example #2
0
/*
 * does fragmented write
 */
static int do_write(int fd, buf_t *msg, unsigned int mtu,
		            ssize_t (*write_func)(int, const void *, size_t))
{
	int actual = -1;
	int size;

	/* Send and fragment if necessary  */
	while (msg->data_size) {
		if (msg->data_size > mtu)
			size = mtu;
		else
			size = msg->data_size;
		DEBUG(1, "sending %d bytes\n", size);

		actual = write_func(fd, msg->data, size);
		if (actual <= 0)
			return actual;

		/* Hide sent data */
		buf_remove_begin(msg, actual);
	}

	return actual;
}
Example #3
0
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_object_receive()
 *
 *    Add any incoming headers to headerqueue.
 *
 */
int obex_object_receive(obex_t *self, buf_t *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 */
	buf_remove_begin(msg, sizeof(struct obex_common_hdr));

	/* Copy any non-header data (like in CONNECT and SETPATH) */
	if (object->headeroffset) {
		object->rx_nonhdr_data = buf_new(object->headeroffset);
		if (!object->rx_nonhdr_data)
			return -1;
		buf_insert_end(object->rx_nonhdr_data, msg->data, object->headeroffset);
		DEBUG(4, "Command has %d bytes non-headerdata\n", object->rx_nonhdr_data->data_size);
		buf_remove_begin(msg, object->headeroffset);
		object->headeroffset = 0;
	}

	while ((msg->data_size > 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->data_size) {
			DEBUG(1, "Header %d to big. HSize=%d Buffer=%d\n",
					hi, len, msg->data_size);
			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 = buf_new(1);
				} else {
					element->buf = buf_new(len);
					if (element->buf) {
						DEBUG(4, "Copying %d bytes\n", len);
						buf_insert_end(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);
		buf_remove_begin(msg, hlen);
	}

	return 1;
}