Subversion Repositories freemyipod

Rev

Rev 694 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
693 user890104 1
#include <stdio.h>
2
 
3
#include <libusb-1.0/libusb.h>
4
 
5
#include "misc.h"
6
#include "usb.h"
7
 
8
libusb_context *usb_ctx = NULL;
9
libusb_device_handle *usb_handle = NULL;
10
 
11
int usb_init(void) {
12
	int res;
13
 
14
	printf("Initialising USB library... ");
15
 
16
	res = libusb_init(&usb_ctx);
17
 
18
	if (LIBUSB_SUCCESS != res) {
19
		return res;
20
	}
21
 
22
	printf("OK\n");
23
 
24
#ifdef DEBUG
25
	libusb_set_debug(usb_ctx, 3);
26
#endif
27
 
28
	return LIBUSB_SUCCESS;
29
}
30
 
31
int usb_find(unsigned char *reattach) {
32
	libusb_device **devs, *dev;
33
	ssize_t devs_cnt;
34
	int res, i;
35
	struct libusb_device_descriptor dev_desc;
36
	unsigned char found = 0;
37
	struct libusb_config_descriptor *cfg_desc;
38
	const struct libusb_interface *iface;
39
	const struct libusb_interface_descriptor *iface_desc;
40
 
41
	printf("Getting USB device list... ");
42
 
43
	devs_cnt = libusb_get_device_list(usb_ctx, &devs);
44
 
45
	if (devs_cnt < 0) {
46
		return devs_cnt;
47
	}
48
 
49
	printf("Found %d USB devices!\n", devs_cnt);
50
 
51
	for (i = 0; i < devs_cnt; ++i) {
52
		dev = devs[i];
53
 
54
		printf("Getting device descriptor of USB device %d...\n", i);
55
 
56
		res = libusb_get_device_descriptor(dev, &dev_desc);
57
 
58
		if (LIBUSB_SUCCESS != res) {
59
			fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
60
 
61
			continue;
62
		}
63
 
64
		printf("[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
65
			dev_desc.idProduct, libusb_get_bus_number(dev),
66
			libusb_get_device_address(dev), dev_desc.bcdUSB);
67
 
68
		if (0x05ac == dev_desc.idVendor && (
69
			/* DFU */
70
			0x1220 == dev_desc.idProduct || /* iPod Nano 2G */
71
			0x1223 == dev_desc.idProduct || /* iPod Classic 1G */
72
			0x1224 == dev_desc.idProduct || /* iPod Nano 3G */
73
			0x1225 == dev_desc.idProduct || /* iPod Nano 4G */
74
			0x1231 == dev_desc.idProduct || /* iPod Nano 5G */
75
			0x1232 == dev_desc.idProduct || /* iPod Nano 6G */
76
			0x1233 == dev_desc.idProduct || /* iPod Shuffle 4G */
77
			/* WTF */
78
			0x1240 == dev_desc.idProduct || /* iPod Nano 2G */
79
			0x1241 == dev_desc.idProduct || /* iPod Classic 1G */
80
			0x1242 == dev_desc.idProduct || /* iPod Nano 3G */
81
			0x1243 == dev_desc.idProduct || /* iPod Nano 4G */
82
			0x1245 == dev_desc.idProduct || /* iPod Classic 2G */
83
			0x1246 == dev_desc.idProduct || /* iPod Nano 5G */
84
			0x1247 == dev_desc.idProduct || /* iPod Classic 3G */
85
			0x1248 == dev_desc.idProduct    /* iPod Nano 6G */
86
		)) {
87
			printf("Found DFU USB device!\n");
88
 
89
			if (1 != dev_desc.bNumConfigurations) {
90
				fprintf(stderr, "Number of configs is different than 1, not the right device...\n");
91
 
92
				continue;
93
			}
94
 
95
			printf("Getting config descriptor 0 of device...\n");
96
 
97
			res = libusb_get_config_descriptor(dev, 0, &cfg_desc);
98
 
99
			if (LIBUSB_SUCCESS != res) {
100
				return res;
101
			}
102
 
103
			if (1 != cfg_desc->bNumInterfaces) {
104
				fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n");
105
 
106
				continue;
107
			}
108
 
109
			iface = &cfg_desc->interface[0];
110
 
111
			if (1 != iface->num_altsetting) {
112
				fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n");
113
 
114
				continue;
115
			}
116
 
117
			iface_desc = &iface->altsetting[0];
118
 
119
			if (0 != iface_desc->bNumEndpoints) {
120
				fprintf(stderr, "Wrong USB device, it should have no endpoints\n");
121
 
122
				continue;
123
			}
124
 
125
			found = 1;
126
		}
127
	}
128
 
129
	if (found) {
130
		res = usb_open(dev, reattach);
131
	}
132
	else {
133
		fprintf(stderr, "DFU USB device not found!\n");
134
 
135
		res = 1; // not found
136
	}
137
 
138
	printf("Freeing device list...\n");
139
 
140
	libusb_free_device_list(devs, 1);
141
 
142
	return res;
143
}
144
 
145
int usb_open(libusb_device *dev, unsigned char *reattach) {
146
	int res;
147
 
148
	printf("Opening USB device... ");
149
 
150
	res = libusb_open(dev, &usb_handle);
151
 
152
	if (LIBUSB_SUCCESS != res) {
153
		return res;
154
	}
155
 
156
	printf("OK\n");
157
 
158
	printf("Setting USB configuration 1... ");
159
 
160
	res = libusb_set_configuration(usb_handle, 1);
161
 
162
	if (LIBUSB_SUCCESS != res) {
163
		return res;
164
	}
165
 
166
	printf("OK\n");
167
 
168
	res = libusb_kernel_driver_active(usb_handle, 0);
169
 
170
	if (1 == res) {
171
		printf("Kernel driver active, detaching... ");
172
 
173
		*reattach = 1;
174
 
175
		res = libusb_detach_kernel_driver(usb_handle, 0);
176
 
177
		if (LIBUSB_SUCCESS == res) {
178
			printf("OK\n");
179
		}
180
	}
181
 
182
	if (LIBUSB_SUCCESS != res) {
183
		return res;
184
	}
185
 
186
	printf("Claiming interface 0... ");
187
 
188
	res = libusb_claim_interface(usb_handle, 0);
189
 
190
	if (LIBUSB_SUCCESS != res) {
191
		return res;
192
	}
193
 
194
	printf("OK\n");
195
 
196
	return LIBUSB_SUCCESS;
197
}
198
 
199
int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length) {
200
	int transferred;
201
	int res;
202
 
203
	res = libusb_bulk_transfer(usb_handle, endpoint, data, length, &transferred, 30000);
204
 
205
	if (LIBUSB_SUCCESS != res) {
206
		return res;
207
	}
208
 
209
	if ((unsigned int) transferred != length) {
210
		return 2; // incomplete
211
	}
212
 
213
	return LIBUSB_SUCCESS;
214
}
215
 
216
int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength) {
217
	int res;
218
 
219
	res = libusb_control_transfer(usb_handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, 30000);
220
 
221
	if (LIBUSB_SUCCESS != res) {
222
		return res;
223
	}
224
 
225
	return LIBUSB_SUCCESS;
226
}
227
 
228
int usb_close(const unsigned char reattach) {
229
	int res;
230
 
231
	printf("Releasing USB interface... ");
232
 
233
	res = libusb_release_interface(usb_handle, 0);
234
 
235
	if (LIBUSB_SUCCESS != res) {
236
		return res;
237
	}
238
 
239
	printf("OK\n");
240
 
241
	if (reattach) {
242
		printf("Reattaching kernel driver... ");
243
 
244
		res = libusb_attach_kernel_driver(usb_handle, 0);
245
 
246
		if (LIBUSB_SUCCESS == res) {
247
			printf("OK\n");
248
		}
249
		else {
250
			printf("\n");
251
			print_error(res);
252
 
253
			res = LIBUSB_SUCCESS;
254
		}
255
	}
256
 
257
	printf("Closing USB device handle...\n");
258
 
259
	libusb_close(usb_handle);
260
 
261
	return res;
262
}
263
 
264
void usb_exit(void) {
265
	printf("Deinitializing USB library...\n");
266
 
267
	libusb_exit(usb_ctx);
268
}