diff options
Diffstat (limited to 'libirecovery.c')
| -rw-r--r-- | libirecovery.c | 33 |
1 files changed, 27 insertions, 6 deletions
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) { | |||
| 338 | usb_descriptor.idProduct == kRecoveryMode2 || | 338 | usb_descriptor.idProduct == kRecoveryMode2 || |
| 339 | usb_descriptor.idProduct == kRecoveryMode3 || | 339 | usb_descriptor.idProduct == kRecoveryMode3 || |
| 340 | usb_descriptor.idProduct == kRecoveryMode4 || | 340 | usb_descriptor.idProduct == kRecoveryMode4 || |
| 341 | usb_descriptor.idProduct == kWTFMode || | ||
| 341 | usb_descriptor.idProduct == kDfuMode) { | 342 | usb_descriptor.idProduct == kDfuMode) { |
| 342 | 343 | ||
| 343 | debug("opening device %04x:%04x...\n", usb_descriptor.idVendor, usb_descriptor.idProduct); | 344 | 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) { | |||
| 369 | return error; | 370 | return error; |
| 370 | } | 371 | } |
| 371 | 372 | ||
| 372 | if (client->mode != kDfuMode) { | 373 | if ((client->mode != kDfuMode) && (client->mode != kWTFMode)) { |
| 373 | error = irecv_set_interface(client, 0, 0); | 374 | error = irecv_set_interface(client, 0, 0); |
| 374 | if (client->mode > kRecoveryMode2) { | 375 | if (client->mode > kRecoveryMode2) { |
| 375 | error = irecv_set_interface(client, 1, 1); | 376 | error = irecv_set_interface(client, 1, 1); |
| @@ -545,7 +546,7 @@ irecv_error_t irecv_close(irecv_client_t client) { | |||
| 545 | } | 546 | } |
| 546 | #ifndef WIN32 | 547 | #ifndef WIN32 |
| 547 | if (client->handle != NULL) { | 548 | if (client->handle != NULL) { |
| 548 | if (client->mode != kDfuMode) { | 549 | if ((client->mode != kDfuMode) && (client->mode != kWTFMode)) { |
| 549 | libusb_release_interface(client->handle, client->interface); | 550 | libusb_release_interface(client->handle, client->interface); |
| 550 | } | 551 | } |
| 551 | libusb_close(client->handle); | 552 | libusb_close(client->handle); |
| @@ -679,7 +680,7 @@ irecv_error_t irecv_get_status(irecv_client_t client, unsigned int* status) { | |||
| 679 | 680 | ||
| 680 | irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfuNotifyFinished) { | 681 | irecv_error_t irecv_send_buffer(irecv_client_t client, unsigned char* buffer, unsigned long length, int dfuNotifyFinished) { |
| 681 | irecv_error_t error = 0; | 682 | irecv_error_t error = 0; |
| 682 | int recovery_mode = (client->mode != kDfuMode); | 683 | int recovery_mode = ((client->mode != kDfuMode) && (client->mode != kWTFMode)); |
| 683 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 684 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; |
| 684 | 685 | ||
| 685 | int packet_size = recovery_mode ? 0x8000 : 0x800; | 686 | 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 | |||
| 729 | } | 730 | } |
| 730 | 731 | ||
| 731 | if (!recovery_mode && status != 5) { | 732 | if (!recovery_mode && status != 5) { |
| 732 | return IRECV_E_USB_UPLOAD; | 733 | int retry = 0; |
| 734 | while (retry < 20) { | ||
| 735 | irecv_get_status(client, &status); | ||
| 736 | if (status == 5) { | ||
| 737 | break; | ||
| 738 | } | ||
| 739 | sleep(1); | ||
| 740 | } | ||
| 741 | if (status != 5) { | ||
| 742 | return IRECV_E_USB_UPLOAD; | ||
| 743 | } | ||
| 733 | } | 744 | } |
| 734 | 745 | ||
| 735 | count += size; | 746 | count += size; |
| @@ -836,6 +847,16 @@ irecv_error_t irecv_getret(irecv_client_t client, unsigned int* value) { | |||
| 836 | irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { | 847 | irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { |
| 837 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 848 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; |
| 838 | 849 | ||
| 850 | if (client->mode == kWTFMode) { | ||
| 851 | char s_cpid[8] = {0,}; | ||
| 852 | strncpy(s_cpid, client->serial, 4); | ||
| 853 | if (sscanf(s_cpid, "%d", cpid) != 1) { | ||
| 854 | *cpid = 0; | ||
| 855 | return IRECV_E_UNKNOWN_ERROR; | ||
| 856 | } | ||
| 857 | return IRECV_E_SUCCESS; | ||
| 858 | } | ||
| 859 | |||
| 839 | char* cpid_string = strstr(client->serial, "CPID:"); | 860 | char* cpid_string = strstr(client->serial, "CPID:"); |
| 840 | if (cpid_string == NULL) { | 861 | if (cpid_string == NULL) { |
| 841 | *cpid = 0; | 862 | *cpid = 0; |
| @@ -1081,7 +1102,7 @@ int irecv_read_file(const char* filename, char** data, uint32_t* size) { | |||
| 1081 | 1102 | ||
| 1082 | irecv_error_t irecv_reset_counters(irecv_client_t client) { | 1103 | irecv_error_t irecv_reset_counters(irecv_client_t client) { |
| 1083 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1104 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; |
| 1084 | if (client->mode == kDfuMode) { | 1105 | if ((client->mode == kDfuMode) || (client->mode == kWTFMode)) { |
| 1085 | irecv_control_transfer(client, 0x21, 4, 0, 0, 0, 0, USB_TIMEOUT); | 1106 | irecv_control_transfer(client, 0x21, 4, 0, 0, 0, 0, USB_TIMEOUT); |
| 1086 | } | 1107 | } |
| 1087 | return IRECV_E_SUCCESS; | 1108 | return IRECV_E_SUCCESS; |
| @@ -1089,7 +1110,7 @@ irecv_error_t irecv_reset_counters(irecv_client_t client) { | |||
| 1089 | 1110 | ||
| 1090 | irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) { | 1111 | irecv_error_t irecv_recv_buffer(irecv_client_t client, char* buffer, unsigned long length) { |
| 1091 | irecv_error_t error = 0; | 1112 | irecv_error_t error = 0; |
| 1092 | int recovery_mode = (client->mode != kDfuMode); | 1113 | int recovery_mode = ((client->mode != kDfuMode) && (client->mode != kWTFMode)); |
| 1093 | 1114 | ||
| 1094 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; | 1115 | if (check_context(client) != IRECV_E_SUCCESS) return IRECV_E_NO_DEVICE; |
| 1095 | 1116 | ||
