summaryrefslogtreecommitdiffstats
path: root/src/libirecovery.c
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/libirecovery.c
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/libirecovery.c')
-rw-r--r--src/libirecovery.c77
1 files changed, 56 insertions, 21 deletions
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