diff options
| author | 2010-05-13 15:10:40 -0400 | |
|---|---|---|
| committer | 2010-05-13 15:10:40 -0400 | |
| commit | a814b04770dc83774cd705d2fc8993f24e504a01 (patch) | |
| tree | 3354669aab557d16eea95373538152c311142ca4 | |
| parent | 520c99d33e18009660f30bd38b31a2f1cd432fe6 (diff) | |
| download | libirecovery-a814b04770dc83774cd705d2fc8993f24e504a01.tar.gz libirecovery-a814b04770dc83774cd705d2fc8993f24e504a01.tar.bz2 | |
Implemented irecv_get_status() to return current iphone usb "state".
Implemented irecv_send_buffer() to upload a buffer to the device load address.
Implemented irecv_send_file() to read a file into memory and pass the buffer into irecv_send_buffer()
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | include/libirecovery.h | 7 | ||||
| -rw-r--r-- | src/irecovery.c | 15 | ||||
| -rw-r--r-- | src/libirecovery.c | 150 | 
4 files changed, 166 insertions, 8 deletions
| @@ -1,4 +1,4 @@ -all: +all: static  	@echo "Please choose either macosx, linux, or windows"  static: diff --git a/include/libirecovery.h b/include/libirecovery.h index b489011..801ad88 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -24,6 +24,9 @@  #define IRECV_ERROR_UNABLE_TO_CONNECT  -3  #define IRECV_ERROR_INVALID_INPUT      -4  #define IRECV_ERROR_UNKNOWN            -5 +#define IRECV_ERROR_FILE_NOT_FOUND     -6 +#define IRECV_ERROR_USB_UPLOAD         -7 +#define IRECV_ERROR_USB_STATUS         -8  enum {  	kAppleId       = 0x05AC, @@ -44,5 +47,5 @@ int irecv_exit(irecv_device* device);  int irecv_init(irecv_device** device);  int irecv_reset(irecv_device* device);  int irecv_close(irecv_device* device); -int irecv_command(irecv_device* device, const char* command); - +int irecv_send_file(irecv_device* device, const char* filename); +int irecv_send_command(irecv_device* device, const char* command); diff --git a/src/irecovery.c b/src/irecovery.c index 51320a5..3091319 100644 --- a/src/irecovery.c +++ b/src/irecovery.c @@ -22,7 +22,7 @@  #include <libirecovery.h>  enum { -	kResetDevice, kSendCommand +	kResetDevice, kSendCommand, kSendFile  };  void print_usage() { @@ -51,8 +51,13 @@ int main(int argc, char** argv) {  			break;  		case 'c': -			argument = optarg;  			action = kSendCommand; +			argument = optarg; +			break; + +		case 'f': +			action = kSendFile; +			argument = optarg;  			break;  		default: @@ -77,8 +82,12 @@ int main(int argc, char** argv) {  		irecv_reset(device);  		break; +	case kSendFile: +		irecv_send_file(device, argument); +		break; +  	case kSendCommand: -		irecv_command(device, argument); +		irecv_send_command(device, argument);  		break;  	default: diff --git a/src/libirecovery.c b/src/libirecovery.c index 85967ec..e3d6eb6 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -120,7 +120,7 @@ void irecv_set_debug(int level) {  	irecv_debug = level;  } -int irecv_command(irecv_device* device, const char* command) { +int irecv_send_command(irecv_device* device, const char* command) {  	if(device == NULL || device->handle == NULL) {  		return IRECV_ERROR_NO_DEVICE;  	} @@ -138,6 +138,152 @@ int irecv_command(irecv_device* device, const char* command) {  	return IRECV_SUCCESS;  } -int irecv_upload(irecv_device* device, const char* filename) { +int irecv_send_file(irecv_device* device, const char* filename) { +	FILE* file = fopen(filename, "rb"); +	if (file == NULL) { +		return IRECV_ERROR_FILE_NOT_FOUND; +	} + +	fseek(file, 0, SEEK_END); +	int length = ftell(file); +	fseek(file, 0, SEEK_SET); + +	unsigned char* buffer = (unsigned char*) malloc(length); +	if (buffer == NULL) { +		fclose(file); +		return IRECV_ERROR_OUT_OF_MEMORY; +	} + +	int bytes = fread(buffer, 1, length, file); +	fclose(file); + +	if(bytes != length) { +		free(buffer); +		return IRECV_ERROR_UNKNOWN; +	} + +	return irecv_send_buffer(device, buffer, length); +} + +unsigned int irecv_get_status(irecv_device* device) { +	unsigned char status[6]; +	memset(status, '\0', 6); +	if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, status, 6, 500) != 6) { +		return IRECV_ERROR_USB_STATUS; +	} +	return (unsigned int) status[4]; +} + +int irecv_send_buffer(irecv_device* device, unsigned char* buffer, int length) { +	int packets = length / 0x800; +	if (length % 0x800) { +		packets++; +	} + +	int last = length % 0x800; +	if (!last) { +		last = 0x800; +	} + +	int i = 0; +	char status[6]; +	for (i = 0; i < packets; i++) { +		int size = i + 1 < packets ? 0x800 : last; +		int bytes = libusb_control_transfer(device->handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 500); +		if (bytes != size) { +			free(buffer); +			return IRECV_ERROR_USB_UPLOAD; +		} + +		if (irecv_get_status(device) != 5) { +			free(buffer); +			return IRECV_ERROR_USB_STATUS; +		} +	} + +	libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000); +	for (i = 6; i <= 8; i++) { +		if (irecv_get_status(device) != i) { +			free(buffer); +			return IRECV_ERROR_USB_STATUS; +		} +	} + +	free(buffer);  	return IRECV_SUCCESS;  } + +/* +int send_file(struct libusb_device_handle *handle, const char* filename, int loadOffset) { +	FILE* file = fopen(filename, "rb"); +	if (file == NULL) { +		printf("send_file: File %s not found.\n", filename); +		return -1; +	} + +	fseek(file, 0, SEEK_END); +	int len = ftell(file); +	fseek(file, 0, SEEK_SET); + +	char* buffer = malloc(len + loadOffset); +	if (buffer == NULL) { +		printf("send_file: Error allocating memory!\n"); +		fclose(file); +		return -1; +	} + +	fread(&buffer[loadOffset], 1, len, file); +	fclose(file); + +	len += loadOffset; + +	int packets = len / 0x800; +	if (len % 0x800) { +		packets++; +	} + +	int last = len % 0x800; +	if (!last) { +		last = 0x800; +	} + +	int i = 0; +	char response[6]; +	for (i = 0; i < packets; i++) { +		int size = i + 1 < packets ? 0x800 : last; + +		if (!libusb_control_transfer(handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 1000)) { +			printf("send_file: Error sending packet!\n"); +			return -1; +		} + +		if (libusb_control_transfer(handle, 0xA1, 3, 0, 0, response, 6, 1000) != 6) { +			printf("send_file: Error receiving status!\n"); +			return -1; + +		} else { +			if (response[4] != 5) { +				printf("send_file: Status error!\n"); +				return -1; +			} +		} +	} + +	libusb_control_transfer(handle, 0x21, 1, i, 0, buffer, 0, 1000); +	for (i = 6; i <= 8; i++) { +		if (libusb_control_transfer(handle, 0xA1, 3, 0, 0, response, 6, 1000) != 6) { +			printf("send_file: Error receiving status!\n"); +			return -1; + +		} else { +			if (response[4] != i) { +				printf("send_file: Status error!\n"); +				return -1; +			} +		} +	} + +	free(buffer); +	return 0; +} +*/ | 
