diff options
| author | 2008-07-29 01:11:02 -0700 | |
|---|---|---|
| committer | 2008-07-29 01:11:02 -0700 | |
| commit | e2ff1128351d75eafd5426af7f96f9719c1af3e6 (patch) | |
| tree | c1c460b4de78cd5645d6d12e83d2646f56f30363 /iphone.c | |
| download | libimobiledevice-e2ff1128351d75eafd5426af7f96f9719c1af3e6.tar.gz libimobiledevice-e2ff1128351d75eafd5426af7f96f9719c1af3e6.tar.bz2 | |
First released version, 0.089.
Diffstat (limited to 'iphone.c')
| -rw-r--r-- | iphone.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/iphone.c b/iphone.c new file mode 100644 index 0000000..4ddb571 --- /dev/null +++ b/iphone.c | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | /* iPhone.c | ||
| 2 | * Functions for creating and initializing iPhone structures | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include "usbmux.h" | ||
| 6 | #include "iphone.h" | ||
| 7 | #include <usb.h> | ||
| 8 | #include <stdio.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | #include <string.h> | ||
| 11 | |||
| 12 | /* get_iPhone() | ||
| 13 | * | ||
| 14 | * Returns a structure with data on the first iPhone it finds. | ||
| 15 | * (Or NULL, on error) | ||
| 16 | */ | ||
| 17 | extern int debug; | ||
| 18 | |||
| 19 | iPhone *get_iPhone() { | ||
| 20 | iPhone *phone = (iPhone*)malloc(sizeof(iPhone)); | ||
| 21 | usbmux_version_header *version = version_header(); | ||
| 22 | |||
| 23 | // initialize the struct | ||
| 24 | phone->device = NULL; | ||
| 25 | phone->__device = NULL; | ||
| 26 | |||
| 27 | // Initialize libusb. | ||
| 28 | usb_init(); | ||
| 29 | usb_find_busses(); | ||
| 30 | usb_find_devices(); | ||
| 31 | struct usb_bus *busses = usb_get_busses(), *bus; | ||
| 32 | struct usb_device *dev; | ||
| 33 | |||
| 34 | for (bus = busses; bus; bus = bus->next) { | ||
| 35 | for (dev = bus->devices; dev; dev = dev->next) { | ||
| 36 | if (dev->descriptor.idVendor == 0x05ac && (dev->descriptor.idProduct == 0x1290 || dev->descriptor.idProduct == 0x1291)) { | ||
| 37 | phone->__device = dev; | ||
| 38 | phone->device = usb_open(phone->__device); | ||
| 39 | usb_reset(phone->device); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | phone->device = NULL; // :( sorry Daniel | ||
| 45 | phone->__device = NULL; // :( sorry Daniel | ||
| 46 | |||
| 47 | for (bus = busses; bus; bus = bus->next) { // do it again as per libusb documentation | ||
| 48 | for (dev = bus->devices; dev; dev = dev->next) { | ||
| 49 | if (dev->descriptor.idVendor == 0x05ac && (dev->descriptor.idProduct == 0x1290 || dev->descriptor.idProduct == 0x1291)) { | ||
| 50 | phone->__device = dev; | ||
| 51 | phone->device = usb_open(phone->__device); | ||
| 52 | usb_set_configuration(phone->device, 3); | ||
| 53 | usb_claim_interface(phone->device, 1); | ||
| 54 | break; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | if (phone->__device && phone->device) break; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (!phone->device || !phone->__device) { // nothing connected | ||
| 61 | free_iPhone(phone); | ||
| 62 | if (debug) printf("get_iPhone(): iPhone not found\n"); | ||
| 63 | return NULL; | ||
| 64 | } | ||
| 65 | |||
| 66 | // Okay, initialize the phone now. | ||
| 67 | int bytes = 0; | ||
| 68 | bytes = usb_bulk_write(phone->device, BULKOUT, (char*)version, sizeof(*version), 800); | ||
| 69 | if (bytes < 20 && debug) { | ||
| 70 | printf("get_iPhone(): libusb did NOT send enough!\n"); | ||
| 71 | if (bytes < 0) { | ||
| 72 | printf("get_iPhone(): libusb gave me the error: %s\n", usb_strerror()); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | bytes = usb_bulk_read(phone->device, BULKIN, (char*)version, sizeof(*version), 800); | ||
| 76 | if (bytes < 20) { | ||
| 77 | free_iPhone(phone); | ||
| 78 | if (debug) printf("get_iPhone(): Invalid version message -- header too short.\n"); | ||
| 79 | if (debug && bytes < 0) printf("get_iPhone(): libusb error message: %s\n", usb_strerror()); | ||
| 80 | return NULL; | ||
| 81 | } else { | ||
| 82 | if (ntohl(version->major) == 1 && ntohl(version->minor) == 0) { | ||
| 83 | // We're all ready to roll. | ||
| 84 | printf("get_iPhone() success\n"); | ||
| 85 | return phone; | ||
| 86 | } else { // BAD HEADER | ||
| 87 | free_iPhone(phone); | ||
| 88 | if (debug) printf("get_iPhone(): Received a bad header/invalid version number."); | ||
| 89 | return NULL; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | if (debug) printf("get_iPhone(): Unknown error.\n"); | ||
| 94 | return NULL; // if it got to this point it's gotta be bad | ||
| 95 | } | ||
| 96 | |||
| 97 | /* free_iPhone(victim) | ||
| 98 | * This is a library-level function; deals directly with the iPhone to tear down relations, | ||
| 99 | * but otherwise is mostly internal. | ||
| 100 | * | ||
| 101 | * victim: a pointer to an iPhone structure | ||
| 102 | * Cleans up an iPhone structure, then frees the structure itself. | ||
| 103 | */ | ||
| 104 | |||
| 105 | void free_iPhone(iPhone *victim) { | ||
| 106 | if (victim->buffer) free(victim->buffer); | ||
| 107 | if (victim->device) { | ||
| 108 | usb_release_interface(victim->device, 1); | ||
| 109 | usb_reset(victim->device); | ||
| 110 | usb_close(victim->device); | ||
| 111 | } | ||
| 112 | free(victim); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* send_to_phone(phone, data, datalen) | ||
| 116 | * This is a low-level (i.e. directly to phone) function. | ||
| 117 | * | ||
| 118 | * phone: the iPhone to send data to | ||
| 119 | * data: the data to send to the iPhone | ||
| 120 | * datalen: the length of the data | ||
| 121 | * | ||
| 122 | * Returns the number of bytes sent, or -1 on error or something. | ||
| 123 | */ | ||
| 124 | int send_to_phone(iPhone *phone, char *data, int datalen) { | ||
| 125 | if (!phone) return -1; | ||
| 126 | int bytes = 0; | ||
| 127 | // it may die here | ||
| 128 | if (debug) printf("dying here?\ndatalen = %i\ndata = %x\n", datalen, data); | ||
| 129 | |||
| 130 | bytes = usb_bulk_write(phone->device, BULKOUT, data, datalen, 800); | ||
| 131 | if (debug) printf("noooo...?\n"); | ||
| 132 | if (bytes < datalen) { | ||
| 133 | return -1; | ||
| 134 | } else { | ||
| 135 | return bytes; | ||
| 136 | } | ||
| 137 | |||
| 138 | return -1; | ||
| 139 | } | ||
| 140 | |||
| 141 | /* recv_from_phone(phone, data, datalen): | ||
| 142 | * This function is a low-level (i.e. direct to iPhone) function. | ||
| 143 | * | ||
| 144 | * phone: the iPhone to receive data from | ||
| 145 | * data: where to put data read | ||
| 146 | * datalen: how much data to read in | ||
| 147 | * | ||
| 148 | * Returns: how many bytes were read in, or -1 on error. | ||
| 149 | */ | ||
| 150 | int recv_from_phone(iPhone *phone, char *data, int datalen) { | ||
| 151 | if (!phone) return -1; | ||
| 152 | int bytes = 0; | ||
| 153 | bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, 3500); | ||
| 154 | return bytes; | ||
| 155 | } | ||
| 156 | |||
