diff options
| author | 2010-05-17 18:40:58 -0400 | |
|---|---|---|
| committer | 2010-05-17 18:40:58 -0400 | |
| commit | cf12a431935f814b6f0b98fe43915c48fde2fcf0 (patch) | |
| tree | 8b2b2acdbbec86fecf7cc1901282bb8d6ae3a18d | |
| parent | 34fc43b128e475fda4e9834689e3649eba82c4c9 (diff) | |
| download | libirecovery-cf12a431935f814b6f0b98fe43915c48fde2fcf0.tar.gz libirecovery-cf12a431935f814b6f0b98fe43915c48fde2fcf0.tar.bz2 | |
Implemented irecv_getenv() and added a number of bug fixes
| -rw-r--r-- | include/libirecovery.h | 4 | ||||
| -rw-r--r-- | src/irecovery.c | 79 | ||||
| -rw-r--r-- | src/libirecovery.c | 79 | 
3 files changed, 129 insertions, 33 deletions
| diff --git a/include/libirecovery.h b/include/libirecovery.h index 65abf04..680448f 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -63,8 +63,10 @@ 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);  irecv_error_t irecv_close(irecv_device_t* device); -irecv_error_t irecv_update(irecv_device_t* device); +irecv_error_t irecv_receive(irecv_device_t* device);  irecv_error_t irecv_set_debug(irecv_device_t* device, int level); +irecv_error_t irecv_getenv(irecv_device_t* device, unsigned char** var); +irecv_error_t irecv_send(irecv_device_t* device, unsigned char* command);  irecv_error_t irecv_send_file(irecv_device_t* device, const char* filename);  irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command);  irecv_error_t irecv_set_configuration(irecv_device_t* device, int configuration); diff --git a/src/irecovery.c b/src/irecovery.c index 7133606..1c4957e 100644 --- a/src/irecovery.c +++ b/src/irecovery.c @@ -23,7 +23,8 @@  #include <readline/readline.h>  #include <readline/history.h> -#define FILE_HISTORY_PATH "~/.irecovery/history" +#define FILE_HISTORY_PATH ".irecovery" +#define debug(...) if(verbose) fprintf(stderr, __VA_ARGS__)  enum {  	kResetDevice, kStartShell, kSendCommand, kSendFile @@ -40,21 +41,29 @@ void print_shell_usage() {  }  void parse_command(irecv_device_t* device, unsigned char* command, unsigned int size) { -	char* cmd = strtok(command, " "); -	if(!strcmp(command, "/exit")) { +	char* cmd = strtok(strdup(command), " "); +	debug("Executing %s %s\n", cmd, command); +	if(!strcmp(cmd, "/exit")) {  		quit = 1;  	} else -	if(!strcmp(command, "/help")) { +	if(!strcmp(cmd, "/help")) {  		print_shell_usage();  	} else + +	if(!strcmp(cmd, "/reconnect")) { +		irecv_close(device); +		irecv_open(device); +	} else -	if(!strcmp(command, "/upload")) { +	if(!strcmp(cmd, "/upload")) {  		char* filename = strtok(NULL, " "); +		debug("Sending %s\n", filename);  		if(filename != NULL) {  			irecv_send_file(device, filename);  		}  	} +	free(cmd);  }  int recv_callback(irecv_device_t* device, unsigned char* data, int size) { @@ -66,10 +75,41 @@ int recv_callback(irecv_device_t* device, unsigned char* data, int size) {  }  int send_callback(irecv_device_t* device, unsigned char* command, int size) { +	irecv_error_t error = 0;  	if(command[0] == '/') {  		parse_command(device, command, size);  		return 0;  	} + +	if(strstr(command, "getenv") != NULL) { +		unsigned char* value = NULL; +		error = irecv_send_command(device, command); +		if(error != IRECV_SUCCESS) { +			debug("%s\n", irecv_strerror(error)); +			return error; +		} + +		error = irecv_getenv(device, &value); +		if(error != IRECV_SUCCESS) { +			debug("%s\n", irecv_strerror(error)); +			return error; +		} + +		printf("%s\n", value); +		free(value); +		return 0; +	} + +	if(!strcmp(command, "reboot")) { +		error = irecv_send_command(device, command); +		if(error != IRECV_SUCCESS) { +			debug("%s\n", irecv_strerror(error)); +			return error; +		} +		quit = 1; +		return 0; +	} +  	return size;  } @@ -83,17 +123,21 @@ void append_command_to_history(char* cmd) {  }  void init_shell(irecv_device_t* device) { +	irecv_error_t error = 0;  	load_command_history();  	irecv_set_sender(device, &send_callback);  	irecv_set_receiver(device, &recv_callback);  	while(!quit) { -		if(irecv_update(device) != IRECV_SUCCESS) { +		error = irecv_receive(device); +		if(error != IRECV_SUCCESS) { +			debug("%s\n", irecv_strerror(error));  			break;  		}  		char* cmd = readline("> ");  		if(cmd && *cmd) { -			if(irecv_send_command(device, cmd) != IRECV_SUCCESS) { +			error = irecv_send(device, cmd); +			if(error != IRECV_SUCCESS) {  				quit = 1;  			} @@ -119,6 +163,7 @@ int main(int argc, char** argv) {  	int opt = 0;  	int action = 0;  	char* argument = NULL; +	irecv_error_t error = 0;  	if(argc == 1) print_usage();  	while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) {  		switch (opt) { @@ -161,9 +206,17 @@ int main(int argc, char** argv) {  	}  	if(verbose) irecv_set_debug(device, verbose); -	if(irecv_open(device) < 0) { -		fprintf(stderr, "Unable to open device\n"); -		return -1; +	int i = 0; +	for(i = 0; i <= 5; i++) { +		debug("Attempting to connect... "); +		if(i == 5) { +			irecv_exit(device); +			return -1; +		} + +		if(irecv_open(device) < 0) sleep(1); +		else break; +		debug("failed\n");  	}  	switch(action) { @@ -172,11 +225,13 @@ int main(int argc, char** argv) {  		break;  	case kSendFile: -		irecv_send_file(device, argument); +		error = irecv_send_file(device, argument); +		debug("%s\n", irecv_strerror(error));  		break;  	case kSendCommand: -		irecv_send_command(device, argument); +		error = irecv_send_command(device, argument); +		debug("%s\n", irecv_strerror(error));  		break;  	case kStartShell: diff --git a/src/libirecovery.c b/src/libirecovery.c index bcea61c..b8eb224 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -52,8 +52,8 @@ irecv_device_t* irecv_init() {  	}  	memset(device, '\0', sizeof(irecv_device_t)); -	irecv_set_receiver(device, &irecv_default_receiver); -	irecv_set_sender(device, &irecv_default_sender); +	//irecv_set_receiver(device, &irecv_default_receiver); +	//irecv_set_sender(device, &irecv_default_sender);  	device->context = usb_context;  	return device;  } @@ -124,15 +124,13 @@ irecv_error_t irecv_set_interface(irecv_device_t* device, int interface, int alt  	if(device == NULL || device->handle == NULL) {  		return IRECV_ERROR_NO_DEVICE;   	} -	 +  	if (libusb_claim_interface(device->handle, 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; -		} +	if(libusb_set_interface_alt_setting(device->handle, interface, alt_interface) < 0) { +		return IRECV_ERROR_USB_INTERFACE;  	}  	device->interface = interface; @@ -192,7 +190,7 @@ irecv_error_t irecv_set_debug(irecv_device_t* device, int level) {  	return IRECV_SUCCESS;  } -irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { +irecv_error_t irecv_send(irecv_device_t* device, unsigned char* command) {  	if(device == NULL || device->handle == NULL) {  		return IRECV_ERROR_NO_DEVICE;  	} @@ -209,6 +207,23 @@ irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command)  	}  	if(length > 0) { +		irecv_send_command(device, command); +	} + +	return IRECV_SUCCESS; +} + +irecv_error_t irecv_send_command(irecv_device_t* device, unsigned char* command) { +	if(device == NULL || device->handle == NULL) { +		return IRECV_ERROR_NO_DEVICE; +	} + +	unsigned int length = strlen(command); +	if(length >= 0x100) { +		length = 0xFF; +	} + +	if(length > 0) {  		libusb_control_transfer(device->handle, 0x40, 0, 0, 0, command, length+1, 100);  	} @@ -243,7 +258,9 @@ irecv_error_t irecv_send_file(irecv_device_t* device, const char* filename) {  		return IRECV_ERROR_UNKNOWN;  	} -	return irecv_send_buffer(device, buffer, length); +	irecv_error_t error = irecv_send_buffer(device, buffer, length); +	free(buffer); +	return error;  }  irecv_error_t irecv_get_status(irecv_device_t* device, unsigned int* status) { @@ -254,11 +271,12 @@ irecv_error_t irecv_get_status(irecv_device_t* device, unsigned int* status) {  	unsigned char buffer[6];  	memset(buffer, '\0', 6); -	if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, buffer, 6, 500) != 6) { +	if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, buffer, 6, 1000) != 6) {  		*status = 0;  		return IRECV_ERROR_USB_STATUS;  	} +	debug("status: %d\n", (unsigned int) buffer[4]);  	*status = (unsigned int) buffer[4];  	return IRECV_SUCCESS;  } @@ -268,46 +286,52 @@ irecv_error_t irecv_send_buffer(irecv_device_t* device, unsigned char* buffer, u  	if(device == NULL || device->handle == NULL) {  		return IRECV_ERROR_NO_DEVICE;   	} -	 +  	int last = length % 0x800;  	int packets = length / 0x800;  	if (last != 0) {  		packets++; -	} else { -		last = 0x800;  	}  	int i = 0;  	unsigned int status = 0;  	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); +		int bytes = libusb_control_transfer(device->handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 1000);  		if (bytes != size) { -			free(buffer);  			return IRECV_ERROR_USB_UPLOAD;  		} +		debug("Sent %d bytes\n", bytes); +  		error = irecv_get_status(device, &status); -		if (error != IRECV_SUCCESS || status != 5) { -			free(buffer); +		if (error != IRECV_SUCCESS) {  			return error;  		} + +		if(status != 5) { +			return IRECV_ERROR_USB_STATUS; +		} +  	} +	//char command[0x100]; +	//memset(command, '\0', 0x100); +	//snprintf(command, 0x100, "setenv filesize %d", length);  	libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000);  	for (i = 0; i < 3; i++) {  		error = irecv_get_status(device, &status);  		if(error != IRECV_SUCCESS) { -			free(buffer);  			return error;  		}  	} -	free(buffer); +	//irecv_send_command(device, command); +  	return IRECV_SUCCESS;  } -irecv_error_t irecv_update(irecv_device_t* device) { +irecv_error_t irecv_receive(irecv_device_t* device) {  	unsigned char buffer[BUFFER_SIZE];  	memset(buffer, '\0', BUFFER_SIZE);  	if(device == NULL || device->handle == NULL) { @@ -358,6 +382,21 @@ irecv_error_t irecv_set_sender(irecv_device_t* device, irecv_send_callback callb  	return IRECV_SUCCESS;  } +irecv_error_t irecv_getenv(irecv_device_t* device, unsigned char** var) { +	unsigned char* value = (unsigned char*) malloc(0x200); +	if(value == NULL) { +		return IRECV_ERROR_OUT_OF_MEMORY; +	} + +	int ret =  libusb_control_transfer(device->handle, 0xC0, 0, 0, 0, value, 0x200, 500); +	if(ret < 0) { +		return IRECV_ERROR_UNKNOWN; +	} + +	*var = value; +	return IRECV_SUCCESS; +} +  const char* irecv_strerror(irecv_error_t error) {  	switch(error) {  	case IRECV_SUCCESS: | 
