Subversion Repositories freemyipod

Rev

Rev 693 | Rev 799 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 693 Rev 694
Line 1... Line 1...
1
#include <stdio.h>
1
//
2
 
2
//
3
#include <libusb-1.0/libusb.h>
3
//    Copyright 2011 user890104
4
 
4
//
5
#include "misc.h"
5
//
6
#include "usb.h"
6
//    This file is part of ipoddfu.
7
 
7
//
8
libusb_context *usb_ctx = NULL;
8
//    ipoddfu is free software: you can redistribute it and/or
9
libusb_device_handle *usb_handle = NULL;
9
//    modify it under the terms of the GNU General Public License as
10
 
10
//    published by the Free Software Foundation, either version 2 of the
11
int usb_init(void) {
11
//    License, or (at your option) any later version.
12
	int res;
12
//
13
	
13
//    ipoddfu is distributed in the hope that it will be useful,
14
	printf("Initialising USB library... ");
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
	
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
	res = libusb_init(&usb_ctx);
16
//    See the GNU General Public License for more details.
17
	
17
//
18
	if (LIBUSB_SUCCESS != res) {
18
//    You should have received a copy of the GNU General Public License along
19
		return res;
19
//    with ipoddfu.  If not, see <http://www.gnu.org/licenses/>.
20
	}
20
//
21
	
21
//
22
	printf("OK\n");
22
 
23
	
23
 
24
#ifdef DEBUG
24
#include <stdio.h>
25
	libusb_set_debug(usb_ctx, 3);
25
 
26
#endif
26
#include <libusb-1.0/libusb.h>
27
 
27
 
28
	return LIBUSB_SUCCESS;
28
#include "misc.h"
29
}
29
#include "usb.h"
30
 
30
 
31
int usb_find(unsigned char *reattach) {
31
libusb_context *usb_ctx = NULL;
32
	libusb_device **devs, *dev;
32
libusb_device_handle *usb_handle = NULL;
33
	ssize_t devs_cnt;
33
 
34
	int res, i;
34
int usb_init(void)
35
	struct libusb_device_descriptor dev_desc;
35
{
36
	unsigned char found = 0;
36
    int res;
37
	struct libusb_config_descriptor *cfg_desc;
37
    
38
	const struct libusb_interface *iface;
38
    printf("Initialising USB library... ");
39
	const struct libusb_interface_descriptor *iface_desc;
39
    
40
	
40
    res = libusb_init(&usb_ctx);
41
	printf("Getting USB device list... ");
41
    
42
	
42
    if (LIBUSB_SUCCESS != res)
43
	devs_cnt = libusb_get_device_list(usb_ctx, &devs);
43
    {
44
		
44
        return res;
45
	if (devs_cnt < 0) {
45
    }
46
		return devs_cnt;
46
    
47
	}
47
    printf("OK\n");
48
	
48
    
49
	printf("Found %d USB devices!\n", devs_cnt);
49
#ifdef DEBUG
50
			
50
    libusb_set_debug(usb_ctx, 3);
51
	for (i = 0; i < devs_cnt; ++i) {
51
#endif
52
		dev = devs[i];
52
 
53
		
53
    return LIBUSB_SUCCESS;
54
		printf("Getting device descriptor of USB device %d...\n", i);
54
}
55
 
55
 
56
		res = libusb_get_device_descriptor(dev, &dev_desc);
56
int usb_find(unsigned char *reattach)
57
 
57
{
58
		if (LIBUSB_SUCCESS != res) {
58
    libusb_device **devs, *dev;
59
			fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
59
    ssize_t devs_cnt;
60
			
60
    int res, i;
61
			continue;
61
    struct libusb_device_descriptor dev_desc;
62
		}
62
    unsigned char found = 0;
63
		
63
    struct libusb_config_descriptor *cfg_desc;
64
		printf("[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
64
    const struct libusb_interface *iface;
65
			dev_desc.idProduct, libusb_get_bus_number(dev),
65
    const struct libusb_interface_descriptor *iface_desc;
66
			libusb_get_device_address(dev), dev_desc.bcdUSB);
66
    
67
 
67
    printf("Getting USB device list... ");
68
		if (0x05ac == dev_desc.idVendor && (
68
    
69
			/* DFU */
69
    devs_cnt = libusb_get_device_list(usb_ctx, &devs);
70
			0x1220 == dev_desc.idProduct || /* iPod Nano 2G */
70
        
71
			0x1223 == dev_desc.idProduct || /* iPod Classic 1G */
71
    if (devs_cnt < 0)
72
			0x1224 == dev_desc.idProduct || /* iPod Nano 3G */
72
    {
73
			0x1225 == dev_desc.idProduct || /* iPod Nano 4G */
73
        return devs_cnt;
74
			0x1231 == dev_desc.idProduct || /* iPod Nano 5G */
74
    }
75
			0x1232 == dev_desc.idProduct || /* iPod Nano 6G */
75
    
76
			0x1233 == dev_desc.idProduct || /* iPod Shuffle 4G */
76
    printf("Found %d USB devices!\n", (int) devs_cnt);
77
			/* WTF */
77
            
78
			0x1240 == dev_desc.idProduct || /* iPod Nano 2G */
78
    for (i = 0; i < devs_cnt; ++i)
79
			0x1241 == dev_desc.idProduct || /* iPod Classic 1G */
79
    {
80
			0x1242 == dev_desc.idProduct || /* iPod Nano 3G */
80
        dev = devs[i];
81
			0x1243 == dev_desc.idProduct || /* iPod Nano 4G */
81
        
82
			0x1245 == dev_desc.idProduct || /* iPod Classic 2G */
82
        printf("Getting device descriptor of USB device %d...\n", i);
83
			0x1246 == dev_desc.idProduct || /* iPod Nano 5G */
83
 
84
			0x1247 == dev_desc.idProduct || /* iPod Classic 3G */
84
        res = libusb_get_device_descriptor(dev, &dev_desc);
85
			0x1248 == dev_desc.idProduct    /* iPod Nano 6G */
85
 
86
		)) {
86
        if (LIBUSB_SUCCESS != res)
87
			printf("Found DFU USB device!\n");
87
        {
88
			
88
            fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
89
			if (1 != dev_desc.bNumConfigurations) {
89
            
90
				fprintf(stderr, "Number of configs is different than 1, not the right device...\n");
90
            continue;
91
				
91
        }
92
				continue;
92
        
93
			}
93
        printf("[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
94
			
94
            dev_desc.idProduct, libusb_get_bus_number(dev),
95
			printf("Getting config descriptor 0 of device...\n");
95
            libusb_get_device_address(dev), dev_desc.bcdUSB);
96
 
96
 
97
			res = libusb_get_config_descriptor(dev, 0, &cfg_desc);
97
        if (0x05ac == dev_desc.idVendor && (
98
 
98
            // DFU
99
			if (LIBUSB_SUCCESS != res) {
99
            0x1220 == dev_desc.idProduct || // iPod Nano 2G
100
				return res;
100
            0x1223 == dev_desc.idProduct || // iPod Classic 1G
101
			}
101
            0x1224 == dev_desc.idProduct || // iPod Nano 3G
102
			
102
            0x1225 == dev_desc.idProduct || // iPod Nano 4G
103
			if (1 != cfg_desc->bNumInterfaces) {
103
            0x1231 == dev_desc.idProduct || // iPod Nano 5G
104
				fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n");
104
            0x1232 == dev_desc.idProduct || // iPod Nano 6G
105
				
105
            0x1233 == dev_desc.idProduct || // iPod Shuffle 4G
106
				continue;
106
            // WTF
107
			}
107
            0x1240 == dev_desc.idProduct || // iPod Nano 2G
108
			
108
            0x1241 == dev_desc.idProduct || // iPod Classic 1G
109
			iface = &cfg_desc->interface[0];
109
            0x1242 == dev_desc.idProduct || // iPod Nano 3G
110
 
110
            0x1243 == dev_desc.idProduct || // iPod Nano 4G
111
			if (1 != iface->num_altsetting) {
111
            0x1245 == dev_desc.idProduct || // iPod Classic 2G
112
				fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n");
112
            0x1246 == dev_desc.idProduct || // iPod Nano 5G
113
				
113
            0x1247 == dev_desc.idProduct || // iPod Classic 3G
114
				continue;
114
            0x1248 == dev_desc.idProduct    // iPod Nano 6G
115
			}
115
        ))
116
			
116
        {
117
			iface_desc = &iface->altsetting[0];
117
            printf("Found DFU USB device!\n");
118
			
118
            
119
			if (0 != iface_desc->bNumEndpoints) {
119
            if (1 != dev_desc.bNumConfigurations)
120
				fprintf(stderr, "Wrong USB device, it should have no endpoints\n");
120
            {
121
				
121
                fprintf(stderr, "Number of configs is different than 1, not the right device...\n");
122
				continue;
122
                
123
			}
123
                continue;
124
			
124
            }
125
			found = 1;
125
            
126
		}
126
            printf("Getting config descriptor 0 of device...\n");
127
	}
127
 
128
 
128
            res = libusb_get_config_descriptor(dev, 0, &cfg_desc);
129
	if (found) {
129
 
130
		res = usb_open(dev, reattach);
130
            if (LIBUSB_SUCCESS != res)
131
	}
131
            {
132
	else {
132
                return res;
133
		fprintf(stderr, "DFU USB device not found!\n");
133
            }
134
		
134
            
135
		res = 1; // not found
135
            if (1 != cfg_desc->bNumInterfaces)
136
	}
136
            {
137
	
137
                fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n");
138
	printf("Freeing device list...\n");
138
                
139
 
139
                continue;
140
	libusb_free_device_list(devs, 1);
140
            }
141
 
141
            
142
	return res;
142
            iface = &cfg_desc->interface[0];
143
}
143
 
144
 
144
            if (1 != iface->num_altsetting)
145
int usb_open(libusb_device *dev, unsigned char *reattach) {
145
            {
146
	int res;
146
                fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n");
147
	
147
                
148
	printf("Opening USB device... ");
148
                continue;
149
 
149
            }
150
	res = libusb_open(dev, &usb_handle);
150
            
151
 
151
            iface_desc = &iface->altsetting[0];
152
	if (LIBUSB_SUCCESS != res) {
152
            
153
		return res;
153
            if (0 != iface_desc->bNumEndpoints)
154
	}
154
            {
155
	
155
                fprintf(stderr, "Wrong USB device, it should have no endpoints\n");
156
	printf("OK\n");
156
                
157
 
157
                continue;
158
	printf("Setting USB configuration 1... ");
158
            }
159
 
159
            
160
	res = libusb_set_configuration(usb_handle, 1);
160
            found = 1;
161
 
161
        }
162
	if (LIBUSB_SUCCESS != res) {
162
    }
163
		return res;
163
 
164
	}
164
    if (found)
165
	
165
    {
166
	printf("OK\n");
166
        res = usb_open(dev, reattach);
167
 
167
    }
168
	res = libusb_kernel_driver_active(usb_handle, 0);
168
    else
169
 
169
    {
170
	if (1 == res) {
170
        fprintf(stderr, "DFU USB device not found!\n");
171
		printf("Kernel driver active, detaching... ");
171
        
172
		
172
        res = 1; // not found
173
		*reattach = 1;
173
    }
174
 
174
    
175
		res = libusb_detach_kernel_driver(usb_handle, 0);
175
    printf("Freeing device list...\n");
176
		
176
 
177
		if (LIBUSB_SUCCESS == res) {
177
    libusb_free_device_list(devs, 1);
178
			printf("OK\n");
178
 
179
		}
179
    return res;
180
	}
180
}
181
 
181
 
182
	if (LIBUSB_SUCCESS != res) {
182
int usb_open(libusb_device *dev, unsigned char *reattach)
183
		return res;
183
{
184
	}
184
    int res;
185
	
185
    
186
	printf("Claiming interface 0... ");
186
    printf("Opening USB device... ");
187
 
187
 
188
	res = libusb_claim_interface(usb_handle, 0);
188
    res = libusb_open(dev, &usb_handle);
189
 
189
 
190
	if (LIBUSB_SUCCESS != res) {
190
    if (LIBUSB_SUCCESS != res)
191
		return res;
191
    {
192
	}
192
        return res;
193
	
193
    }
194
	printf("OK\n");
194
    
195
	
195
    printf("OK\n");
196
	return LIBUSB_SUCCESS;
196
 
197
}
197
    printf("Setting USB configuration 1... ");
198
 
198
 
199
int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length) {
199
    res = libusb_set_configuration(usb_handle, 1);
200
	int transferred;
200
 
201
	int res;
201
    if (LIBUSB_SUCCESS != res)
202
	
202
    {
203
	res = libusb_bulk_transfer(usb_handle, endpoint, data, length, &transferred, 30000);
203
        return res;
204
	
204
    }
205
	if (LIBUSB_SUCCESS != res) {
205
    
206
		return res;
206
    printf("OK\n");
207
	}
207
 
208
	
208
    res = libusb_kernel_driver_active(usb_handle, 0);
209
	if ((unsigned int) transferred != length) {
209
 
210
		return 2; // incomplete
210
    if (1 == res)
211
	}
211
    {
212
	
212
        printf("Kernel driver active, detaching... ");
213
	return LIBUSB_SUCCESS;
213
        
214
}
214
        *reattach = 1;
215
 
215
 
216
int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength) {
216
        res = libusb_detach_kernel_driver(usb_handle, 0);
217
	int res;
217
        
218
	
218
        if (LIBUSB_SUCCESS == res)
219
	res = libusb_control_transfer(usb_handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, 30000);
219
        {
220
	
220
            printf("OK\n");
221
	if (LIBUSB_SUCCESS != res) {
221
        }
222
		return res;
222
    }
223
	}
223
 
224
	
224
    if (LIBUSB_SUCCESS != res)
225
	return LIBUSB_SUCCESS;
225
    {
226
}
226
        return res;
227
 
227
    }
228
int usb_close(const unsigned char reattach) {
228
    
229
	int res;
229
    printf("Claiming interface 0... ");
230
	
230
 
231
	printf("Releasing USB interface... ");
231
    res = libusb_claim_interface(usb_handle, 0);
232
	
232
 
233
	res = libusb_release_interface(usb_handle, 0);
233
    if (LIBUSB_SUCCESS != res)
234
	
234
    {
235
	if (LIBUSB_SUCCESS != res) {
235
        return res;
236
		return res;
236
    }
237
	}
237
    
238
	
238
    printf("OK\n");
239
	printf("OK\n");
239
    
240
	
240
    return LIBUSB_SUCCESS;
241
	if (reattach) {
241
}
242
		printf("Reattaching kernel driver... ");
242
 
243
		
243
int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length)
244
		res = libusb_attach_kernel_driver(usb_handle, 0);
244
{
245
		
245
    int transferred;
246
		if (LIBUSB_SUCCESS == res) {
246
    int res;
247
			printf("OK\n");
247
    
248
		}
248
    res = libusb_bulk_transfer(usb_handle, endpoint, data, length, &transferred, 30000);
249
		else {
249
    
250
			printf("\n");
250
    if (LIBUSB_SUCCESS != res)
251
			print_error(res);
251
    {
252
			
252
        return res;
253
			res = LIBUSB_SUCCESS;
253
    }
254
		}
254
    
255
	}
255
    if ((unsigned int) transferred != length)
256
	
256
    {
257
	printf("Closing USB device handle...\n");
257
        return 2; // incomplete
258
	
258
    }
259
	libusb_close(usb_handle);
259
    
260
	
260
    return LIBUSB_SUCCESS;
261
	return res;
261
}
262
}
262
 
263
 
263
int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength)
264
void usb_exit(void) {
264
{
265
	printf("Deinitializing USB library...\n");
265
    int res;
266
 
266
    
267
	libusb_exit(usb_ctx);
267
    res = libusb_control_transfer(usb_handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, 30000);
268
}
268
    
-
 
269
    if (LIBUSB_SUCCESS != res)
-
 
270
    {
-
 
271
        return res;
-
 
272
    }
-
 
273
    
-
 
274
    return LIBUSB_SUCCESS;
-
 
275
}
-
 
276
 
-
 
277
int usb_close(const unsigned char reattach)
-
 
278
{
-
 
279
    int res;
-
 
280
    
-
 
281
    printf("Releasing USB interface... ");
-
 
282
    
-
 
283
    res = libusb_release_interface(usb_handle, 0);
-
 
284
    
-
 
285
    if (LIBUSB_SUCCESS != res)
-
 
286
    {
-
 
287
        return res;
-
 
288
    }
-
 
289
    
-
 
290
    printf("OK\n");
-
 
291
    
-
 
292
    if (reattach)
-
 
293
    {
-
 
294
        printf("Reattaching kernel driver... ");
-
 
295
        
-
 
296
        res = libusb_attach_kernel_driver(usb_handle, 0);
-
 
297
        
-
 
298
        if (LIBUSB_SUCCESS == res)
-
 
299
        {
-
 
300
            printf("OK\n");
-
 
301
        }
-
 
302
        else
-
 
303
        {
-
 
304
            printf("\n");
-
 
305
            print_error(res);
-
 
306
            
-
 
307
            res = LIBUSB_SUCCESS;
-
 
308
        }
-
 
309
    }
-
 
310
    
-
 
311
    printf("Closing USB device handle...\n");
-
 
312
    
-
 
313
    libusb_close(usb_handle);
-
 
314
    
-
 
315
    return res;
-
 
316
}
-
 
317
 
-
 
318
void usb_exit(void)
-
 
319
{
-
 
320
    printf("Deinitializing USB library...\n");
-
 
321
 
-
 
322
    libusb_exit(usb_ctx);
-
 
323
}