diff options
author | Zach C | 2008-07-29 01:11:02 -0700 |
---|---|---|
committer | Matt Colyer | 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 @@ +/* iPhone.c + * Functions for creating and initializing iPhone structures + */ + +#include "usbmux.h" +#include "iphone.h" +#include <usb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* get_iPhone() + * + * Returns a structure with data on the first iPhone it finds. + * (Or NULL, on error) + */ +extern int debug; + +iPhone *get_iPhone() { + iPhone *phone = (iPhone*)malloc(sizeof(iPhone)); + usbmux_version_header *version = version_header(); + + // initialize the struct + phone->device = NULL; + phone->__device = NULL; + + // Initialize libusb. + usb_init(); + usb_find_busses(); + usb_find_devices(); + struct usb_bus *busses = usb_get_busses(), *bus; + struct usb_device *dev; + + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == 0x05ac && (dev->descriptor.idProduct == 0x1290 || dev->descriptor.idProduct == 0x1291)) { + phone->__device = dev; + phone->device = usb_open(phone->__device); + usb_reset(phone->device); + } + } + } + + phone->device = NULL; // :( sorry Daniel + phone->__device = NULL; // :( sorry Daniel + + for (bus = busses; bus; bus = bus->next) { // do it again as per libusb documentation + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.idVendor == 0x05ac && (dev->descriptor.idProduct == 0x1290 || dev->descriptor.idProduct == 0x1291)) { + phone->__device = dev; + phone->device = usb_open(phone->__device); + usb_set_configuration(phone->device, 3); + usb_claim_interface(phone->device, 1); + break; + } + } + if (phone->__device && phone->device) break; + } + + if (!phone->device || !phone->__device) { // nothing connected + free_iPhone(phone); + if (debug) printf("get_iPhone(): iPhone not found\n"); + return NULL; + } + + // Okay, initialize the phone now. + int bytes = 0; + bytes = usb_bulk_write(phone->device, BULKOUT, (char*)version, sizeof(*version), 800); + if (bytes < 20 && debug) { + printf("get_iPhone(): libusb did NOT send enough!\n"); + if (bytes < 0) { + printf("get_iPhone(): libusb gave me the error: %s\n", usb_strerror()); + } + } + bytes = usb_bulk_read(phone->device, BULKIN, (char*)version, sizeof(*version), 800); + if (bytes < 20) { + free_iPhone(phone); + if (debug) printf("get_iPhone(): Invalid version message -- header too short.\n"); + if (debug && bytes < 0) printf("get_iPhone(): libusb error message: %s\n", usb_strerror()); + return NULL; + } else { + if (ntohl(version->major) == 1 && ntohl(version->minor) == 0) { + // We're all ready to roll. + printf("get_iPhone() success\n"); + return phone; + } else { // BAD HEADER + free_iPhone(phone); + if (debug) printf("get_iPhone(): Received a bad header/invalid version number."); + return NULL; + } + } + + if (debug) printf("get_iPhone(): Unknown error.\n"); + return NULL; // if it got to this point it's gotta be bad +} + +/* free_iPhone(victim) + * This is a library-level function; deals directly with the iPhone to tear down relations, + * but otherwise is mostly internal. + * + * victim: a pointer to an iPhone structure + * Cleans up an iPhone structure, then frees the structure itself. + */ + +void free_iPhone(iPhone *victim) { + if (victim->buffer) free(victim->buffer); + if (victim->device) { + usb_release_interface(victim->device, 1); + usb_reset(victim->device); + usb_close(victim->device); + } + free(victim); +} + +/* send_to_phone(phone, data, datalen) + * This is a low-level (i.e. directly to phone) function. + * + * phone: the iPhone to send data to + * data: the data to send to the iPhone + * datalen: the length of the data + * + * Returns the number of bytes sent, or -1 on error or something. + */ +int send_to_phone(iPhone *phone, char *data, int datalen) { + if (!phone) return -1; + int bytes = 0; + // it may die here + if (debug) printf("dying here?\ndatalen = %i\ndata = %x\n", datalen, data); + + bytes = usb_bulk_write(phone->device, BULKOUT, data, datalen, 800); + if (debug) printf("noooo...?\n"); + if (bytes < datalen) { + return -1; + } else { + return bytes; + } + + return -1; +} + +/* recv_from_phone(phone, data, datalen): + * This function is a low-level (i.e. direct to iPhone) function. + * + * phone: the iPhone to receive data from + * data: where to put data read + * datalen: how much data to read in + * + * Returns: how many bytes were read in, or -1 on error. + */ +int recv_from_phone(iPhone *phone, char *data, int datalen) { + if (!phone) return -1; + int bytes = 0; + bytes = usb_bulk_read(phone->device, BULKIN, data, datalen, 3500); + return bytes; +} + |