diff options
| -rw-r--r-- | include/libirecovery.h | 1 | ||||
| -rw-r--r-- | src/irecovery.c | 24 | ||||
| -rw-r--r-- | src/libirecovery.c | 100 | 
3 files changed, 103 insertions, 22 deletions
| diff --git a/include/libirecovery.h b/include/libirecovery.h index 822d0e1..65abf04 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -58,6 +58,7 @@ struct irecv_device {  };  irecv_device_t* irecv_init(); +const char* irecv_strerror(irecv_error_t error);  irecv_error_t irecv_open(irecv_device_t* device);  irecv_error_t irecv_exit(irecv_device_t* device);  irecv_error_t irecv_reset(irecv_device_t* device); diff --git a/src/irecovery.c b/src/irecovery.c index 8ffe86b..7133606 100644 --- a/src/irecovery.c +++ b/src/irecovery.c @@ -30,7 +30,7 @@ enum {  };  static unsigned int quit = 0; -static unsigned int debug = 0; +static unsigned int verbose = 0;  void print_shell_usage() {  	printf("Usage:\n"); @@ -50,7 +50,7 @@ void parse_command(irecv_device_t* device, unsigned char* command, unsigned int  	} else  	if(!strcmp(command, "/upload")) { -		char* filename = strtok(0, " "); +		char* filename = strtok(NULL, " ");  		if(filename != NULL) {  			irecv_send_file(device, filename);  		} @@ -87,10 +87,16 @@ void init_shell(irecv_device_t* device) {  	irecv_set_sender(device, &send_callback);  	irecv_set_receiver(device, &recv_callback);  	while(!quit) { -		irecv_update(device); +		if(irecv_update(device) != IRECV_SUCCESS) { +			break; +		} +		  		char* cmd = readline("> ");  		if(cmd && *cmd) { -			irecv_send_command(device, cmd); +			if(irecv_send_command(device, cmd) != IRECV_SUCCESS) { +				quit = 1; +			} +			  			append_command_to_history(cmd);  			free(cmd);  		} @@ -100,8 +106,8 @@ void init_shell(irecv_device_t* device) {  void print_usage() {  	printf("iRecovery - iDevice Recovery Utility\n");  	printf("Usage: ./irecovery [args]\n"); +	printf("\t-v\t\tStart irecovery in verbose mode.\n");  	printf("\t-c <cmd>\tSend command to device.\n"); -	printf("\t-d\t\tStart irecovery in debug mode.\n");  	printf("\t-f <file>\tSend file to device.\n");  	printf("\t-h\t\tShow this help.\n");  	printf("\t-r\t\tReset device.\n"); @@ -114,10 +120,10 @@ int main(int argc, char** argv) {  	int action = 0;  	char* argument = NULL;  	if(argc == 1) print_usage(); -	while ((opt = getopt(argc, argv, "dhrsc:f:")) > 0) { +	while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) {  		switch (opt) { -		case 'd': -			debug = 1; +		case 'v': +			verbose += 1;  			break;  		case 'h': @@ -153,7 +159,7 @@ int main(int argc, char** argv) {  		fprintf(stderr, "Unable to initialize libirecovery\n");  		return -1;  	} -	if(debug) irecv_set_debug(device, 1); +	if(verbose) irecv_set_debug(device, verbose);  	if(irecv_open(device) < 0) {  		fprintf(stderr, "Unable to open device\n"); diff --git a/src/libirecovery.c b/src/libirecovery.c index 21cdfcf..bcea61c 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -27,6 +27,21 @@  #define BUFFER_SIZE 0x1000  #define debug(...) if(device->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_device_t* device, unsigned char* data, int size); +int irecv_default_receiver(irecv_device_t* device, unsigned char* data, int size); +  irecv_device_t* irecv_init() {  	struct libusb_context* usb_context = NULL; @@ -36,8 +51,10 @@ irecv_device_t* irecv_init() {  		return NULL;  	}  	memset(device, '\0', sizeof(irecv_device_t)); -	device->context = usb_context; +	irecv_set_receiver(device, &irecv_default_receiver); +	irecv_set_sender(device, &irecv_default_sender); +	device->context = usb_context;  	return device;  } @@ -112,8 +129,10 @@ irecv_error_t irecv_set_interface(irecv_device_t* device, int interface, int alt  		return IRECV_ERROR_USB_INTERFACE;  	} -	if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) { -		return IRECV_ERROR_USB_INTERFACE; +	if(alt_interface > 0) { +		if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) { +			return IRECV_ERROR_USB_INTERFACE; +		}  	}  	device->interface = interface; @@ -170,6 +189,7 @@ irecv_error_t irecv_set_debug(irecv_device_t* device, int level) {  	libusb_set_debug(device->context, level);  	device->debug = level; +	return IRECV_SUCCESS;  }  irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { @@ -177,23 +197,21 @@ irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command)  		return IRECV_ERROR_NO_DEVICE;  	} -	ssize_t length = strlen(command); +	unsigned int length = strlen(command);  	if(length >= 0x100) { -		return IRECV_ERROR_INVALID_INPUT; +		length = 0xFF;  	}  	if(device->send_callback != NULL) {  		// Call our user defined callback first, this must return a number of bytes to send  		//   or zero to abort send.  		length = device->send_callback(device, command, length); -		if(length > 0) { -			int ret = libusb_control_transfer(device->handle, 0x40, 0, 0, 0, (unsigned char*) command, length+1, 100); -			if(ret < 0) { -				return IRECV_ERROR_UNKNOWN; -			} -		}  	} +	if(length > 0) { +		libusb_control_transfer(device->handle, 0x40, 0, 0, 0, command, length+1, 100); +	} +	  	return IRECV_SUCCESS;  } @@ -299,8 +317,10 @@ irecv_error_t irecv_update(irecv_device_t* device) {  	int bytes = 0;  	while(libusb_bulk_transfer(device->handle, 0x81, buffer, BUFFER_SIZE, &bytes, 100) == 0) {  		if(bytes > 0) { -			if(device->receive_callback(device, buffer, bytes) != bytes) { -				return IRECV_ERROR_UNKNOWN; +			if(device->receive_callback != NULL) { +				if(device->receive_callback(device, buffer, bytes) != bytes) { +					return IRECV_ERROR_UNKNOWN; +				}  			}  		} else break;  	} @@ -308,6 +328,18 @@ irecv_error_t irecv_update(irecv_device_t* device) {  	return IRECV_SUCCESS;  } +int irecv_default_sender(irecv_device_t* device, unsigned char* data, int size) { +	return size; +} + +int irecv_default_receiver(irecv_device_t* device, unsigned char* data, int size) { +	int i = 0; +	for(i = 0; i < size; i++) { +		printf("%c", data[i]); +	} +	return size; +} +  irecv_error_t irecv_set_receiver(irecv_device_t* device, irecv_receive_callback callback) {  	if(device == NULL) {  		return IRECV_ERROR_NO_DEVICE;  @@ -325,3 +357,45 @@ irecv_error_t irecv_set_sender(irecv_device_t* device, irecv_send_callback callb  	device->send_callback = callback;  	return IRECV_SUCCESS;  } + +const char* irecv_strerror(irecv_error_t error) { +	switch(error) { +	case IRECV_SUCCESS: +		return irecv_error_success; +		 +	case IRECV_ERROR_NO_DEVICE: +		return irecv_error_no_device; +		 +	case IRECV_ERROR_OUT_OF_MEMORY: +		return irecv_error_out_of_memory; +		 +	case IRECV_ERROR_UNABLE_TO_CONNECT: +		return irecv_error_unable_to_connect; +		 +	case IRECV_ERROR_INVALID_INPUT: +		return irecv_error_invalid_input; +		 +	case IRECV_ERROR_UNKNOWN: +		return irecv_error_unknown; +		 +	case IRECV_ERROR_FILE_NOT_FOUND: +		return irecv_error_file_not_found; +		 +	case IRECV_ERROR_USB_UPLOAD: +		return irecv_error_usb_upload; +		 +	case IRECV_ERROR_USB_STATUS: +		return irecv_error_usb_status; +		 +	case IRECV_ERROR_USB_INTERFACE: +		return irecv_error_usb_interface; +		 +	case IRECV_ERROR_USB_CONFIGURATION: +		return irecv_error_usb_configuration; +		 +	default: +		return irecv_error_unknown; +	} +	 +	return NULL; +} | 
