diff options
author | Nikias Bassen | 2009-01-08 18:17:21 +0100 |
---|---|---|
committer | Jonathan Beck | 2009-01-08 18:17:21 +0100 |
commit | ef98ef7211bc6277e9a87349f0405957ab264936 (patch) | |
tree | 9b51d84d1d91f27734882cbc0f27c763721e6669 /src/iphone.c | |
parent | 5cde55426112a8cb79d809dae5f61e347c007212 (diff) | |
download | libimobiledevice-ef98ef7211bc6277e9a87349f0405957ab264936.tar.gz libimobiledevice-ef98ef7211bc6277e9a87349f0405957ab264936.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 @@ #include <stdlib.h> #include <string.h> +/** + * This function sets the configuration of the given device to 3 + * and claims the interface 1. If usb_set_configuration fails, it detaches + * the kernel driver that blocks the device, and retries configuration. + * + * @param phone which device to configure + */ +static void iphone_config_usb_device(iphone_device_t phone) +{ + int ret; + + log_debug_msg("setting configuration... "); + ret = usb_set_configuration(phone->device, 3); + if (ret != 0) { + log_debug_msg("Hm, usb_set_configuration returned %d: %s, trying to fix:\n", ret, strerror(-ret)); + log_debug_msg("-> detaching kernel driver... "); + ret = + usb_detach_kernel_driver_np(phone->device, + phone->__device->config->interface->altsetting->bInterfaceNumber); + if (ret != 0) { + log_debug_msg("usb_detach_kernel_driver_np returned %d: %s\n", ret, strerror(-ret)); + } else { + log_debug_msg("done.\n"); + log_debug_msg("setting configuration again... "); + ret = usb_set_configuration(phone->device, 3); + if (ret != 0) { + log_debug_msg("Error: usb_set_configuration returned %d: %s\n", ret, strerror(-ret)); + } else { + log_debug_msg("done.\n"); + } + } + } else { + log_debug_msg("done.\n"); + } + + log_debug_msg("claiming interface... "); + ret = usb_claim_interface(phone->device, 1); + if (ret != 0) { + log_debug_msg("Error: usb_claim_interface returned %d: %s\n", ret, strerror(-ret)); + } else { + log_debug_msg("done.\n"); + } +} /** * 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, if (dev->devnum == dev_n) { phone->__device = dev; phone->device = usb_open(phone->__device); - usb_set_configuration(phone->device, 3); - usb_claim_interface(phone->device, 1); + iphone_config_usb_device(phone); goto found; } @@ -115,9 +157,10 @@ static iphone_error_t iphone_get_specific_device(unsigned int bus_n, int dev_n, return IPHONE_E_SUCCESS; } else { // Bad header + log_debug_msg("get_iPhone(): Received a bad header/invalid version number.\n"); + log_debug_buffer((char *) version, sizeof(*version)); iphone_free_device(phone); free(version); - log_debug_msg("get_iPhone(): Received a bad header/invalid version number."); return IPHONE_E_BAD_HEADER; } @@ -173,13 +216,21 @@ iphone_error_t iphone_free_device(iphone_device_t device) if (!device) return IPHONE_E_INVALID_ARG; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; + int bytes; + unsigned char buf[512]; + + // read final package + bytes = usb_bulk_read(device->device, BULKIN, (void *) &buf, 512, 1000); + if (bytes > 0) { + log_debug_msg("iphone_free_device: final read returned\n"); + log_debug_buffer(buf, bytes); + } if (device->buffer) { free(device->buffer); } if (device->device) { usb_release_interface(device->device, 1); - usb_reset(device->device); usb_close(device->device); ret = IPHONE_E_SUCCESS; } |