diff options
| author | 2010-05-23 17:20:50 -0400 | |
|---|---|---|
| committer | 2010-05-23 17:20:50 -0400 | |
| commit | 53142922b14fe36f950eb28d3b42683ddedb7669 (patch) | |
| tree | 936df7c71a646d310e97c5378b217c2b86a9757a | |
| parent | 442363a01ef44e84eda3e22c71dd2de424f5121e (diff) | |
| download | libirecovery-53142922b14fe36f950eb28d3b42683ddedb7669.tar.gz libirecovery-53142922b14fe36f950eb28d3b42683ddedb7669.tar.bz2 | |
Quite a few bug fixes, updated to be used with the latest version of idevicerestore. Still quite a few issues to be ironed out though.
| -rw-r--r-- | include/libirecovery.h | 35 | ||||
| -rw-r--r-- | src/libirecovery.c | 115 | 
2 files changed, 82 insertions, 68 deletions
| diff --git a/include/libirecovery.h b/include/libirecovery.h index 9d30497..9848655 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -18,29 +18,29 @@  #include <libusb-1.0/libusb.h> -typedef enum { -	IRECV_E_SUCCESS =             0, -	IRECV_E_NO_DEVICE =          -1, -	IRECV_E_OUT_OF_MEMORY =      -2, -	IRECV_E_UNABLE_TO_CONNECT =  -3, -	IRECV_E_INVALID_INPUT =      -4, -	IRECV_E_UNKNOWN =            -5, -	IRECV_E_FILE_NOT_FOUND =     -6, -	IRECV_E_USB_UPLOAD =         -7, -	IRECV_E_USB_STATUS =         -8, -	IRECV_E_USB_INTERFACE =      -9, -	IRECV_E_USB_CONFIGURATION =  -10 -} irecv_error_t; -  #define APPLE_VENDOR_ID 0x05AC -typedef enum { +enum {  	kRecoveryMode1 = 0x1280,  	kRecoveryMode2 = 0x1281,  	kRecoveryMode3 = 0x1282,  	kRecoveryMode4 = 0x1283,  	kDfuMode       = 0x1227 -} irecv_mode_t; +}; + +typedef enum { +	IRECV_E_SUCCESS =              0, +	IRECV_E_NO_DEVICE =           -1, +	IRECV_E_OUT_OF_MEMORY =       -2, +	IRECV_E_UNABLE_TO_CONNECT =   -3, +	IRECV_E_INVALID_INPUT =       -4, +	IRECV_E_FILE_NOT_FOUND =      -5, +	IRECV_E_USB_UPLOAD =          -6, +	IRECV_E_USB_STATUS =          -7, +	IRECV_E_USB_INTERFACE =       -8, +	IRECV_E_USB_CONFIGURATION =   -9, +	IRECV_E_UNKNOWN_ERROR =     -255 +} irecv_error_t;  struct irecv_client;  typedef struct irecv_client* irecv_client_t; @@ -53,8 +53,7 @@ struct irecv_client {  	int config;  	int interface;  	int alt_interface; -	char *uuid; -	irecv_mode_t mode; +	unsigned short mode;  	libusb_context* context;  	libusb_device_handle* handle;  	irecv_send_callback send_callback; diff --git a/src/libirecovery.c b/src/libirecovery.c index a2ec9c9..131032c 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -27,18 +27,6 @@  #define BUFFER_SIZE 0x1000  #define debug(...) if(client->debug) fprintf(stderr, __VA_ARGS__) -const char* irecv_error_invalid_input     = "Invalid input"; -const char* irecv_error_unknown           = "Unknown error"; -const char* irecv_error_file_not_found    = "Unable to find file"; -const char* irecv_error_usb_status        = "Invalid device status"; -const char* irecv_error_no_device         = "Unable to find device"; -const char* irecv_error_out_of_memory     = "Unable to allocate memory"; -const char* irecv_error_unable_to_connect = "Unable to connect to device"; -const char* irecv_error_usb_interface     = "Unable to set device interface"; -const char* irecv_error_success           = "Command completed successfully"; -const char* irecv_error_usb_upload        = "Unable to upload data to device"; -const char* irecv_error_usb_configuration = "Unable to set device configuration"; -  int irecv_default_sender(irecv_client_t client, unsigned char* data, int size);  int irecv_default_receiver(irecv_client_t client, unsigned char* data, int size); @@ -85,22 +73,17 @@ irecv_error_t irecv_open(irecv_client_t* pclient, const char* uuid) {  					return IRECV_E_OUT_OF_MEMORY;  				}  				memset(client, '\0', sizeof(irecv_client_t)); +				client->interface = -1;  				client->handle = usb_handle;  				client->context = usb_context; -				client->mode = (irecv_mode_t) usb_descriptor.idProduct; +				client->mode = usb_descriptor.idProduct;  				error = irecv_set_configuration(client, 1);  				if(error != IRECV_E_SUCCESS) {  					return error;  				} -				error = irecv_set_interface(client, 1, 1); -				if(error != IRECV_E_SUCCESS) { -					return error; -				} -  				*pclient = client; -				printf("done");  				return IRECV_E_SUCCESS;  			}  		} @@ -133,9 +116,11 @@ irecv_error_t irecv_set_interface(irecv_client_t client, int interface, int alt_  		return IRECV_E_NO_DEVICE;  	} -	debug("Setting to interface %d:%d", interface, alt_interface); -	libusb_reset_device(client->handle); +	if(client->interface == interface) { +		return IRECV_E_SUCCESS; +	} +	debug("Setting to interface %d:%d", interface, alt_interface);  	if (libusb_claim_interface(client->handle, interface) < 0) {  		return IRECV_E_USB_INTERFACE;  	} @@ -150,7 +135,7 @@ irecv_error_t irecv_set_interface(irecv_client_t client, int interface, int alt_  }  irecv_error_t irecv_reset(irecv_client_t client) { -	if (client == NULL || client->handle != NULL) { +	if (client == NULL || client->handle == NULL) {  		return IRECV_E_NO_DEVICE;  	} @@ -161,7 +146,9 @@ irecv_error_t irecv_reset(irecv_client_t client) {  irecv_error_t irecv_close(irecv_client_t client) {  	if (client != NULL) {  		if (client->handle != NULL) { -			libusb_release_interface(client->handle, 1); +			if(client->interface >= 0) { +				libusb_release_interface(client->handle, client->interface); +			}  			libusb_close(client->handle);  			client->handle = NULL;  		} @@ -171,10 +158,6 @@ irecv_error_t irecv_close(irecv_client_t client) {  			client->context = NULL;  		} -		if(client->uuid != NULL) { -			free(client->uuid); -		} -  		free(client);  		client = NULL;  	} @@ -220,6 +203,11 @@ irecv_error_t irecv_send_command(irecv_client_t client, unsigned char* command)  		return IRECV_E_NO_DEVICE;  	} +	irecv_error_t error = irecv_set_interface(client, 1, 1); +	if(error != IRECV_E_SUCCESS) { +		return error; +	} +  	unsigned int length = strlen(command);  	if(length >= 0x100) {  		length = 0xFF; @@ -257,7 +245,7 @@ irecv_error_t irecv_send_file(irecv_client_t client, const char* filename) {  	if(bytes != length) {  		free(buffer); -		return IRECV_E_UNKNOWN; +		return IRECV_E_UNKNOWN_ERROR;  	}  	irecv_error_t error = irecv_send_buffer(client, buffer, length); @@ -271,6 +259,11 @@ irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) {  		return IRECV_E_NO_DEVICE;  	} +	irecv_error_t error = irecv_set_interface(client, 1, 1); +	if(error != IRECV_E_SUCCESS) { +		return error; +	} +  	unsigned char buffer[6];  	memset(buffer, '\0', 6);  	if(libusb_control_transfer(client->handle, 0xA1, 3, 0, 0, buffer, 6, 1000) != 6) { @@ -289,6 +282,11 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un  		return IRECV_E_NO_DEVICE;  	} +	error = irecv_set_interface(client, 1, 1); +	if(error != IRECV_E_SUCCESS) { +		return error; +	} +  	int last = length % 0x800;  	int packets = length / 0x800;  	if (last != 0) { @@ -312,7 +310,7 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un  		}  		if(status != 5) { -			return IRECV_E_USB_STATUS; +			return IRECV_E_USB_UPLOAD;  		}  	} @@ -335,12 +333,17 @@ irecv_error_t irecv_receive(irecv_client_t client) {  		return IRECV_E_NO_DEVICE;  	} +	irecv_error_t error = irecv_set_interface(client, 1, 1); +	if(error != IRECV_E_SUCCESS) { +		return error; +	} +  	int bytes = 0;  	while(libusb_bulk_transfer(client->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) {  		if(bytes > 0) {  			if(client->receive_callback != NULL) {  				if(client->receive_callback(client, buffer, bytes) != bytes) { -					return IRECV_E_UNKNOWN; +					return IRECV_E_UNKNOWN_ERROR;  				}  			}  		} else break; @@ -380,14 +383,23 @@ irecv_error_t irecv_set_sender(irecv_client_t client, irecv_send_callback callba  }  irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var) { -	unsigned char* value = (unsigned char*) malloc(0x200); +	if(client == NULL || client->handle == NULL) { +		return IRECV_E_NO_DEVICE; +	} + +	irecv_error_t error = irecv_set_interface(client, 1, 1); +	if(error != IRECV_E_SUCCESS) { +		return error; +	} + +	unsigned char* value = (unsigned char*) malloc(256);  	if(value == NULL) {  		return IRECV_E_OUT_OF_MEMORY;  	} -	int ret =  libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, value, 0x200, 500); +	int ret =  libusb_control_transfer(client->handle, 0xC0, 0, 0, 0, value, 256, 500);  	if(ret < 0) { -		return IRECV_E_UNKNOWN; +		return IRECV_E_UNKNOWN_ERROR;  	}  	*var = value; @@ -398,56 +410,59 @@ irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var) {  irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) {  	char info[256];  	memset(info, '\0', 256); -	libusb_get_string_descriptor_ascii(client->handle, 3, info, 0x100); -	debug("%s\n", info); + +	if(client == NULL || client->handle == NULL) { +		return IRECV_E_NO_DEVICE; +	} + +	libusb_get_string_descriptor_ascii(client->handle, 3, info, 255); +	printf("%d: %s\n", strlen(info), info);  	unsigned char* ecid_string = strstr(info, "ECID:");  	if(ecid_string == NULL) {  		*ecid = 0; -		return IRECV_E_UNKNOWN; +		return IRECV_E_UNKNOWN_ERROR;  	}  	sscanf(ecid_string, "ECID:%qX", ecid); +	irecv_reset(client);  	return IRECV_E_SUCCESS;  }  const char* irecv_strerror(irecv_error_t error) {  	switch(error) {  	case IRECV_E_SUCCESS: -		return irecv_error_success; +		return "Command completed successfully";  	case IRECV_E_NO_DEVICE: -		return irecv_error_no_device; +		return "Unable to find device";  	case IRECV_E_OUT_OF_MEMORY: -		return irecv_error_out_of_memory; +		return "Out of memory";  	case IRECV_E_UNABLE_TO_CONNECT: -		return irecv_error_unable_to_connect; +		return "Unable to connect to device";  	case IRECV_E_INVALID_INPUT: -		return irecv_error_invalid_input; -		 -	case IRECV_E_UNKNOWN: -		return irecv_error_unknown; +		return "Invalid input";  	case IRECV_E_FILE_NOT_FOUND: -		return irecv_error_file_not_found; +		return "File not found";  	case IRECV_E_USB_UPLOAD: -		return irecv_error_usb_upload; +		return "Unable to upload data to device";  	case IRECV_E_USB_STATUS: -		return irecv_error_usb_status; +		return "Unable to get device status";  	case IRECV_E_USB_INTERFACE: -		return irecv_error_usb_interface; +		return "Unable to set device interface";  	case IRECV_E_USB_CONFIGURATION: -		return irecv_error_usb_configuration; +		return "Unable to set device configuration";  	default: -		return irecv_error_unknown; +		return "Unknown error";  	}  	return NULL; | 
