summaryrefslogtreecommitdiffstats
path: root/iphone.c
diff options
context:
space:
mode:
authorGravatar Zach C2008-07-29 01:11:02 -0700
committerGravatar Matt Colyer2008-07-29 01:11:02 -0700
commite2ff1128351d75eafd5426af7f96f9719c1af3e6 (patch)
treec1c460b4de78cd5645d6d12e83d2646f56f30363 /iphone.c
downloadlibimobiledevice-e2ff1128351d75eafd5426af7f96f9719c1af3e6.tar.gz
libimobiledevice-e2ff1128351d75eafd5426af7f96f9719c1af3e6.tar.bz2
First released version, 0.089.
Diffstat (limited to 'iphone.c')
-rw-r--r--iphone.c156
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 */
17extern int debug;
18
19iPhone *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
105void 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 */
124int 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 */
150int 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