diff options
| author | 2009-01-08 18:17:21 +0100 | |
|---|---|---|
| committer | 2009-01-09 20:18:38 -0800 | |
| commit | 89ad220b093b73e229207ca2da0ad568d81f69e3 (patch) | |
| tree | babb6c465ad3fd021068f7a86d55845590d06bad /src/iphone.c | |
| parent | cae85d48c44a9cf9b947a91aef6fbf7309398c4a (diff) | |
| download | libimobiledevice-89ad220b093b73e229207ca2da0ad568d81f69e3.tar.gz libimobiledevice-89ad220b093b73e229207ca2da0ad568d81f69e3.tar.bz2 | |
Perform proper goodby on lockdown shutdown.
Diffstat (limited to 'src/iphone.c')
| -rw-r--r-- | src/iphone.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/src/iphone.c b/src/iphone.c index 32d27f6..1f68180 100644 --- a/src/iphone.c +++ b/src/iphone.c | |||
| @@ -28,6 +28,49 @@ | |||
| 28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
| 29 | #include <string.h> | 29 | #include <string.h> |
| 30 | 30 | ||
| 31 | /** | ||
| 32 | * This function sets the configuration of the given device to 3 | ||
| 33 | * and claims the interface 1. If usb_set_configuration fails, it detaches | ||
| 34 | * the kernel driver that blocks the device, and retries configuration. | ||
| 35 | * | ||
| 36 | * @param phone which device to configure | ||
| 37 | */ | ||
| 38 | static void iphone_config_usb_device(iphone_device_t phone) | ||
| 39 | { | ||
| 40 | int ret; | ||
| 41 | |||
| 42 | log_debug_msg("setting configuration... "); | ||
| 43 | ret = usb_set_configuration(phone->device, 3); | ||
| 44 | if (ret != 0) { | ||
| 45 | log_debug_msg("Hm, usb_set_configuration returned %d: %s, trying to fix:\n", ret, strerror(-ret)); | ||
| 46 | log_debug_msg("-> detaching kernel driver... "); | ||
| 47 | ret = | ||
| 48 | usb_detach_kernel_driver_np(phone->device, | ||
| 49 | phone->__device->config->interface->altsetting->bInterfaceNumber); | ||
| 50 | if (ret != 0) { | ||
| 51 | log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n", ret, strerror(-ret)); | ||
| 52 | } else { | ||
| 53 | log_debug_msg("done.\n"); | ||
| 54 | log_debug_msg("setting configuration again... "); | ||
| 55 | ret = usb_set_configuration(phone->device, 3); | ||
| 56 | if (ret != 0) { | ||
| 57 | log_debug_msg("Error: usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); | ||
| 58 | } else { | ||
| 59 | log_debug_msg("done.\n"); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } else { | ||
| 63 | log_debug_msg("done.\n"); | ||
| 64 | } | ||
| 65 | |||
| 66 | log_debug_msg("claiming interface... "); | ||
| 67 | ret = usb_claim_interface(phone->device, 1); | ||
| 68 | if (ret != 0) { | ||
| 69 | log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret, strerror(-ret)); | ||
| 70 | } else { | ||
| 71 | log_debug_msg("done.\n"); | ||
| 72 | } | ||
| 73 | } | ||
| 31 | 74 | ||
| 32 | /** | 75 | /** |
| 33 | * Given a USB bus and device number, returns a device handle to the iPhone on | 76 | * Given a USB bus and device number, returns a device handle to the iPhone on |
| @@ -73,8 +116,7 @@ static iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, | |||
| 73 | if (dev->devnum == dev_n) { | 116 | if (dev->devnum == dev_n) { |
| 74 | phone->__device = dev; | 117 | phone->__device = dev; |
| 75 | phone->device = usb_open(phone->__device); | 118 | phone->device = usb_open(phone->__device); |
| 76 | usb_set_configuration(phone->device, 3); | 119 | iphone_config_usb_device(phone); |
| 77 | usb_claim_interface(phone->device, 1); | ||
| 78 | goto found; | 120 | goto found; |
| 79 | } | 121 | } |
| 80 | 122 | ||
| @@ -115,9 +157,10 @@ static iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, | |||
| 115 | return IPHONE_E_SUCCESS; | 157 | return IPHONE_E_SUCCESS; |
| 116 | } else { | 158 | } else { |
| 117 | // Bad header | 159 | // Bad header |
| 160 | log_debug_msg("get_iPhone(): Received a bad header/invalid version number.\n"); | ||
| 161 | log_debug_buffer((char *) version, sizeof(*version)); | ||
| 118 | iphone_free_device(phone); | 162 | iphone_free_device(phone); |
| 119 | free(version); | 163 | free(version); |
| 120 | log_debug_msg("get_iPhone(): Received a bad header/invalid version number."); | ||
| 121 | return IPHONE_E_BAD_HEADER; | 164 | return IPHONE_E_BAD_HEADER; |
| 122 | } | 165 | } |
| 123 | 166 | ||
| @@ -173,13 +216,21 @@ iphone_error_t iphone_free_device(iphone_device_t device) | |||
| 173 | if (!device) | 216 | if (!device) |
| 174 | return IPHONE_E_INVALID_ARG; | 217 | return IPHONE_E_INVALID_ARG; |
| 175 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 218 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 219 | int bytes; | ||
| 220 | unsigned char buf[512]; | ||
| 221 | |||
| 222 | // read final package | ||
| 223 | bytes = usb_bulk_read(device->device, BULKIN, (void *) &buf, 512, 1000); | ||
| 224 | if (bytes > 0) { | ||
| 225 | log_debug_msg("iphone_free_device: final read returned\n"); | ||
| 226 | log_debug_buffer(buf, bytes); | ||
| 227 | } | ||
| 176 | 228 | ||
| 177 | if (device->buffer) { | 229 | if (device->buffer) { |
| 178 | free(device->buffer); | 230 | free(device->buffer); |
| 179 | } | 231 | } |
| 180 | if (device->device) { | 232 | if (device->device) { |
| 181 | usb_release_interface(device->device, 1); | 233 | usb_release_interface(device->device, 1); |
| 182 | usb_reset(device->device); | ||
| 183 | usb_close(device->device); | 234 | usb_close(device->device); |
| 184 | ret = IPHONE_E_SUCCESS; | 235 | ret = IPHONE_E_SUCCESS; |
| 185 | } | 236 | } |
