diff options
| -rw-r--r-- | include/libirecovery.h | 1 | ||||
| -rw-r--r-- | libirecovery.c | 33 | 
2 files changed, 28 insertions, 6 deletions
diff --git a/include/libirecovery.h b/include/libirecovery.h index eb07266..3422f9d 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -90,6 +90,7 @@ enum {  	kRecoveryMode2 = 0x1281,  	kRecoveryMode3 = 0x1282,  	kRecoveryMode4 = 0x1283, +	kWTFMode = 0x1222,  	kDfuMode = 0x1227  }; diff --git a/libirecovery.c b/libirecovery.c index ffabd84..71de46d 100644 --- a/libirecovery.c +++ b/libirecovery.c @@ -338,6 +338,7 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {  				usb_descriptor.idProduct == kRecoveryMode2 ||  				usb_descriptor.idProduct == kRecoveryMode3 ||  				usb_descriptor.idProduct == kRecoveryMode4 || +				usb_descriptor.idProduct == kWTFMode ||  				usb_descriptor.idProduct == kDfuMode) {  				debug("opening device %04x:%04x...\n", usb_descriptor.idVendor, usb_descriptor.idProduct); @@ -369,7 +370,7 @@ irecv_error_t irecv_open(irecv_client_t* pclient) {  					return error;  				} -				if (client->mode != kDfuMode) { +				if ((client->mode != kDfuMode) && (client->mode != kWTFMode)) {  					error = irecv_set_interface(client, 0, 0);  					if (client->mode > kRecoveryMode2) {  						error = irecv_set_interface(client, 1, 1); @@ -545,7 +546,7 @@ irecv_error_t irecv_close(irecv_client_t client) {  		}  #ifndef WIN32  		if (client->handle != NULL) { -			if (client->mode != kDfuMode) { +			if ((client->mode != kDfuMode) && (client->mode != kWTFMode)) {  				libusb_release_interface(client->handle, client->interface);  			}  			libusb_close(client->handle); @@ -679,7 +680,7 @@ irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) {  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); +	int recovery_mode = ((client->mode != kDfuMode) && (client->mode != kWTFMode));  	if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE;  	int packet_size = recovery_mode ? 0x8000 : 0x800; @@ -729,7 +730,17 @@ irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, un  		}  		if (!recovery_mode && status != 5) { -			return IRECV_E_USB_UPLOAD; +			int retry = 0; +			while (retry < 20) { +				irecv_get_status(client, &status); +				if (status == 5) { +					break; +				} +				sleep(1); +			} +			if (status != 5) { +				return IRECV_E_USB_UPLOAD; +			}  		}  		count += size; @@ -836,6 +847,16 @@ irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) {  irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) {  	if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; +	if (client->mode == kWTFMode) { +		char s_cpid[8] = {0,}; +		strncpy(s_cpid, client->serial, 4); +		if (sscanf(s_cpid, "%d", cpid) != 1) { +			*cpid = 0; +			return IRECV_E_UNKNOWN_ERROR; +		} +		return IRECV_E_SUCCESS; +	} +  	char* cpid_string = strstr(client->serial, "CPID:");  	if (cpid_string == NULL) {  		*cpid = 0; @@ -1081,7 +1102,7 @@ int irecv_read_file(const char* filename, char** data, uint32_t* size) {  irecv_error_t irecv_reset_counters(irecv_client_t client) {  	if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; -	if (client->mode == kDfuMode) { +	if ((client->mode == kDfuMode) || (client->mode == kWTFMode)) {  		irecv_control_transfer(client, 0x21, 4, 0, 0, 0, 0, USB_TIMEOUT);  	}  	return IRECV_E_SUCCESS; @@ -1089,7 +1110,7 @@ irecv_error_t irecv_reset_counters(irecv_client_t client) {  irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) {  	irecv_error_t error = 0; -	int recovery_mode = (client->mode != kDfuMode); +	int recovery_mode = ((client->mode != kDfuMode) && (client->mode != kWTFMode));  	if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE;  | 
