Subversion Repositories freemyipod

Rev

Rev 693 | Rev 799 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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