summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2010-05-20 13:10:26 +0200
committerGravatar Martin Szulecki2010-05-20 13:10:26 +0200
commitfdbdb9f9e964528d08038e51cd57f9545cef294a (patch)
tree9f8b43a2d95121973d48c2c23c26d732168069cb /src
parentcf12a431935f814b6f0b98fe43915c48fde2fcf0 (diff)
downloadlibirecovery-fdbdb9f9e964528d08038e51cd57f9545cef294a.tar.gz
libirecovery-fdbdb9f9e964528d08038e51cd57f9545cef294a.tar.bz2
Improve irecv_open()'s device selection logic and allow opening by uuid
Previous code did attempt to open anything with an Apple vendor id. Now it also verifies if the USB device is within a mode we know and also allows targeting a specific device by it's UUID.
Diffstat (limited to 'src')
-rw-r--r--src/irecovery.c24
-rw-r--r--src/libirecovery.c77
2 files changed, 73 insertions, 28 deletions
diff --git a/src/irecovery.c b/src/irecovery.c
index 1c4957e..56b0453 100644
--- a/src/irecovery.c
+++ b/src/irecovery.c
@@ -52,8 +52,10 @@ void parse_command(irecv_device_t* device, unsigned char* command, unsigned int
52 } else 52 } else
53 53
54 if(!strcmp(cmd, "/reconnect")) { 54 if(!strcmp(cmd, "/reconnect")) {
55 char* uuid = strdup(device->uuid);
55 irecv_close(device); 56 irecv_close(device);
56 irecv_open(device); 57 irecv_open(device, uuid);
58 free(uuid);
57 } else 59 } else
58 60
59 if(!strcmp(cmd, "/upload")) { 61 if(!strcmp(cmd, "/upload")) {
@@ -151,6 +153,7 @@ void print_usage() {
151 printf("iRecovery - iDevice Recovery Utility\n"); 153 printf("iRecovery - iDevice Recovery Utility\n");
152 printf("Usage: ./irecovery [args]\n"); 154 printf("Usage: ./irecovery [args]\n");
153 printf("\t-v\t\tStart irecovery in verbose mode.\n"); 155 printf("\t-v\t\tStart irecovery in verbose mode.\n");
156 printf("\t-u <uuid>\ttarget specific device by its 40-digit device UUID\n");
154 printf("\t-c <cmd>\tSend command to device.\n"); 157 printf("\t-c <cmd>\tSend command to device.\n");
155 printf("\t-f <file>\tSend file to device.\n"); 158 printf("\t-f <file>\tSend file to device.\n");
156 printf("\t-h\t\tShow this help.\n"); 159 printf("\t-h\t\tShow this help.\n");
@@ -163,9 +166,10 @@ int main(int argc, char** argv) {
163 int opt = 0; 166 int opt = 0;
164 int action = 0; 167 int action = 0;
165 char* argument = NULL; 168 char* argument = NULL;
169 char *uuid = NULL;
166 irecv_error_t error = 0; 170 irecv_error_t error = 0;
167 if(argc == 1) print_usage(); 171 if(argc == 1) print_usage();
168 while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) { 172 while ((opt = getopt(argc, argv, "vhru:sc:f:")) > 0) {
169 switch (opt) { 173 switch (opt) {
170 case 'v': 174 case 'v':
171 verbose += 1; 175 verbose += 1;
@@ -179,6 +183,10 @@ int main(int argc, char** argv) {
179 action = kResetDevice; 183 action = kResetDevice;
180 break; 184 break;
181 185
186 case 'u':
187 uuid = optarg;
188 break;
189
182 case 's': 190 case 's':
183 action = kStartShell; 191 action = kStartShell;
184 break; 192 break;
@@ -195,7 +203,7 @@ int main(int argc, char** argv) {
195 203
196 default: 204 default:
197 fprintf(stderr, "Unknown argument\n"); 205 fprintf(stderr, "Unknown argument\n");
198 break; 206 return -1;
199 } 207 }
200 } 208 }
201 209
@@ -209,14 +217,16 @@ int main(int argc, char** argv) {
209 int i = 0; 217 int i = 0;
210 for(i = 0; i <= 5; i++) { 218 for(i = 0; i <= 5; i++) {
211 debug("Attempting to connect... "); 219 debug("Attempting to connect... ");
220
221 if(irecv_open(device, uuid) < 0) sleep(1);
222 else break;
223
224 debug("failed. No recovery device found.\n");
225
212 if(i == 5) { 226 if(i == 5) {
213 irecv_exit(device); 227 irecv_exit(device);
214 return -1; 228 return -1;
215 } 229 }
216
217 if(irecv_open(device) < 0) sleep(1);
218 else break;
219 debug("failed\n");
220 } 230 }
221 231
222 switch(action) { 232 switch(action) {
diff --git a/src/libirecovery.c b/src/libirecovery.c
index b8eb224..18097ee 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -58,9 +58,10 @@ irecv_device_t* irecv_init() {
58 return device; 58 return device;
59} 59}
60 60
61irecv_error_t irecv_open(irecv_device_t* device) { 61irecv_error_t irecv_open(irecv_device_t* device, const char *uuid) {
62 int i = 0; 62 int i = 0;
63 int usb_device_count = 0; 63 int usb_device_count = 0;
64 char serial[256];
64 struct libusb_device* usb_device = NULL; 65 struct libusb_device* usb_device = NULL;
65 struct libusb_device** usb_device_list = NULL; 66 struct libusb_device** usb_device_list = NULL;
66 struct libusb_device_handle* usb_handle = NULL; 67 struct libusb_device_handle* usb_handle = NULL;
@@ -75,28 +76,58 @@ irecv_error_t irecv_open(irecv_device_t* device) {
75 for (i = 0; i < usb_device_count; i++) { 76 for (i = 0; i < usb_device_count; i++) {
76 usb_device = usb_device_list[i]; 77 usb_device = usb_device_list[i];
77 libusb_get_device_descriptor(usb_device, &usb_descriptor); 78 libusb_get_device_descriptor(usb_device, &usb_descriptor);
78 if (usb_descriptor.idVendor == kAppleId) { 79 if (usb_descriptor.idVendor == APPLE_VENDOR_ID) {
80 /* verify this device is in a mode we understand */
81 if (usb_descriptor.idProduct == kRecoveryMode1 ||
82 usb_descriptor.idProduct == kRecoveryMode2 ||
83 usb_descriptor.idProduct == kRecoveryMode3 ||
84 usb_descriptor.idProduct == kRecoveryMode4 ||
85 usb_descriptor.idProduct == kDfuMode) {
86
87 libusb_open(usb_device, &usb_handle);
88 if (usb_handle == NULL) {
89 libusb_free_device_list(usb_device_list, 1);
90 return IRECV_ERROR_UNABLE_TO_CONNECT;
91 }
92
93 /* get serial number */
94 if (libusb_get_string_descriptor_ascii (usb_handle, usb_descriptor.iSerialNumber, serial, sizeof(serial)) < 0) {
95 libusb_free_device_list(usb_device_list, 1);
96 libusb_close(usb_handle);
97 return IRECV_ERROR_UNABLE_TO_CONNECT;
98 }
99
100 /* match uuid if required */
101 if (uuid != NULL) {
102 if (strcmp(uuid, serial)) {
103 libusb_close(usb_handle);
104 continue;
105 }
106 }
79 107
80 libusb_open(usb_device, &usb_handle); 108 /* identified a valid recovery device */
81 if (usb_handle == NULL) {
82 libusb_free_device_list(usb_device_list, 1); 109 libusb_free_device_list(usb_device_list, 1);
83 return IRECV_ERROR_UNABLE_TO_CONNECT; 110
84 } 111 device->handle = usb_handle;
85 libusb_free_device_list(usb_device_list, 1); 112 device->uuid = strdup(serial);
86 113 device->mode = (irecv_mode_t) usb_descriptor.idProduct;
87 device->handle = usb_handle; 114
88 device->mode = (irecv_mode_t) usb_descriptor.idProduct; 115 debug("opening UUID \"%s\"... ", device->uuid);
89 error = irecv_set_configuration(device, 1); 116
90 if(error != IRECV_SUCCESS) { 117 error = irecv_set_configuration(device, 1);
91 return error; 118 if(error != IRECV_SUCCESS) {
92 } 119 debug("setting configuration... ");
93 120 return error;
94 error = irecv_set_interface(device, 1, 1); 121 }
95 if(error != IRECV_SUCCESS) { 122
96 return error; 123 error = irecv_set_interface(device, 1, 1);
124 if(error != IRECV_SUCCESS) {
125 debug("setting interface... ");
126 return error;
127 }
128
129 return IRECV_SUCCESS;
97 } 130 }
98
99 return IRECV_SUCCESS;
100 } 131 }
101 } 132 }
102 133
@@ -158,7 +189,11 @@ irecv_error_t irecv_close(irecv_device_t* device) {
158 libusb_close(device->handle); 189 libusb_close(device->handle);
159 device->handle = NULL; 190 device->handle = NULL;
160 } 191 }
161 192
193 if(device->uuid != NULL) {
194 free(device->uuid);
195 }
196
162 return IRECV_SUCCESS; 197 return IRECV_SUCCESS;
163} 198}
164 199