Example #1
0
irecv_error_t irecv_recv_buffer(irecv_client_t client, char *buffer,
				unsigned long length)
{
	int recovery_mode = (client->mode != kDfuMode);
	int packet_size, last, packets;
	int i = 0;
	int bytes = 0;
	unsigned long count = 0;

	if (check_context(client) != IRECV_E_SUCCESS)
		return IRECV_E_NO_DEVICE;

	packet_size = recovery_mode ? 0x2000 : 0x800;
	last = length % packet_size;
	packets = length / packet_size;
	if (last != 0) {
		packets++;
	} else {
		last = packet_size;
	}

	for (i = 0; i < packets; i++) {
		unsigned short size = (i + 1) < packets ? packet_size : last;
		bytes =
		    irecv_control_transfer(client, 0xA1, 2, 0, 0,
					   (unsigned char *)&buffer[i *
								    packet_size],
					   size, 1000);

		if (bytes != size) {
			return IRECV_E_USB_UPLOAD;
		}

		count += size;
		if (client->progress_callback != NULL) {
			irecv_event_t event;
			event.progress =
			    ((double)count / (double)length) * 100.0;
			event.type = IRECV_PROGRESS;
			event.data = "Downloading";
			event.size = count;
			client->progress_callback(client, &event);
		} else {
			DPRINT("Sent: %d bytes - %lu of %lu\n", bytes, count,
			       length);
		}
	}

	return IRECV_E_SUCCESS;
}
Example #2
0
irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfuNotifyFinished) {
	irecv_error_t error = 0;
	int recovery_mode = (client->mode != kDfuMode);
	if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE;

	int packet_size = 0x800;
	int last = length % packet_size;
	int packets = length / packet_size;
	if (last != 0) {
		packets++;
	} else {
		last = packet_size;
	}

	/* initiate transfer */
	if (recovery_mode) {
		error = irecv_control_transfer(client, 0x41, 0, 0, 0, NULL, 0, 1000);
	} else {
		error = irecv_control_transfer(client, 0x21, 4, 0, 0, NULL, 0, 1000);
	}
	if (error != IRECV_E_SUCCESS) {
		return error;
	}

	int i = 0;
	double progress = 0;
	unsigned long count = 0;
	unsigned int status = 0;
	int bytes = 0;
	for (i = 0; i < packets; i++) {
		int size = (i + 1) < packets ? packet_size : last;

		/* Use bulk transfer for recovery mode and control transfer for DFU and WTF mode */
		if (recovery_mode) {
			error = irecv_bulk_transfer(client, 0x04, &buffer[i * packet_size], size, &bytes, 1000);
		} else {
			bytes = irecv_control_transfer(client, 0x21, 1, 0, 0, &buffer[i * packet_size], size, 1000);
		}

		if (bytes != size) {
			return IRECV_E_USB_UPLOAD;
		}

		if (!recovery_mode) {
			error = irecv_get_status(client, &status);
		}

		if (error != IRECV_E_SUCCESS) {
			return error;
		}

		if (!recovery_mode && status != 5) {
			return IRECV_E_USB_UPLOAD;
		}

		count += size;
		if(client->progress_callback != NULL) {
			irecv_event_t event;
			event.progress = ((double) count/ (double) length) * 100.0;
			event.type = IRECV_PROGRESS;
			event.data = "Uploading";
			event.size = count;
			client->progress_callback(client, &event);
		} else {
			debug("Sent: %d bytes - %lu of %lu\n", bytes, count, length);
		}
	}

	if (dfuNotifyFinished && !recovery_mode) {
		irecv_control_transfer(client, 0x21, 1, 0, 0, (unsigned char*) buffer, 0, 1000);

		for (i = 0; i < 3; i++) {
			error = irecv_get_status(client, &status);
			if (error != IRECV_E_SUCCESS) {
				return error;
			}
		}
		irecv_reset(client);
	}

	return IRECV_E_SUCCESS;
}