Subversion Repositories freemyipod

Rev

Rev 694 | Rev 864 | 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
 
799 user890104 76
    printf("Found %Zd USB devices!\n", devs_cnt);
694 user890104 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;
799 user890104 161
            break;
694 user890104 162
        }
163
    }
164
 
165
    if (found)
166
    {
167
        res = usb_open(dev, reattach);
168
    }
169
    else
170
    {
171
        fprintf(stderr, "DFU USB device not found!\n");
172
 
173
        res = 1; // not found
174
    }
175
 
176
    printf("Freeing device list...\n");
177
 
178
    libusb_free_device_list(devs, 1);
179
 
180
    return res;
181
}
182
 
183
int usb_open(libusb_device *dev, unsigned char *reattach)
184
{
185
    int res;
186
 
187
    printf("Opening USB device... ");
188
 
189
    res = libusb_open(dev, &usb_handle);
190
 
191
    if (LIBUSB_SUCCESS != res)
192
    {
193
        return res;
194
    }
195
 
196
    printf("OK\n");
197
 
198
    printf("Setting USB configuration 1... ");
199
 
200
    res = libusb_set_configuration(usb_handle, 1);
201
 
202
    if (LIBUSB_SUCCESS != res)
203
    {
204
        return res;
205
    }
206
 
207
    printf("OK\n");
208
 
209
    res = libusb_kernel_driver_active(usb_handle, 0);
210
 
211
    if (1 == res)
212
    {
213
        printf("Kernel driver active, detaching... ");
214
 
215
        *reattach = 1;
216
 
217
        res = libusb_detach_kernel_driver(usb_handle, 0);
218
 
219
        if (LIBUSB_SUCCESS == res)
220
        {
221
            printf("OK\n");
222
        }
223
    }
224
 
225
    if (LIBUSB_SUCCESS != res)
226
    {
227
        return res;
228
    }
229
 
230
    printf("Claiming interface 0... ");
231
 
232
    res = libusb_claim_interface(usb_handle, 0);
233
 
234
    if (LIBUSB_SUCCESS != res)
235
    {
236
        return res;
237
    }
238
 
239
    printf("OK\n");
240
 
241
    return LIBUSB_SUCCESS;
242
}
243
 
244
int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length)
245
{
246
    int transferred;
247
    int res;
248
 
249
    res = libusb_bulk_transfer(usb_handle, endpoint, data, length, &transferred, 30000);
250
 
251
    if (LIBUSB_SUCCESS != res)
252
    {
253
        return res;
254
    }
255
 
256
    if ((unsigned int) transferred != length)
257
    {
258
        return 2; // incomplete
259
    }
260
 
261
    return LIBUSB_SUCCESS;
262
}
263
 
264
int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength)
265
{
266
    int res;
267
 
268
    res = libusb_control_transfer(usb_handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, 30000);
269
 
270
    if (LIBUSB_SUCCESS != res)
271
    {
272
        return res;
273
    }
274
 
275
    return LIBUSB_SUCCESS;
276
}
277
 
278
int usb_close(const unsigned char reattach)
279
{
280
    int res;
281
 
282
    printf("Releasing USB interface... ");
283
 
284
    res = libusb_release_interface(usb_handle, 0);
285
 
286
    if (LIBUSB_SUCCESS != res)
287
    {
288
        return res;
289
    }
290
 
291
    printf("OK\n");
292
 
293
    if (reattach)
294
    {
295
        printf("Reattaching kernel driver... ");
296
 
297
        res = libusb_attach_kernel_driver(usb_handle, 0);
298
 
299
        if (LIBUSB_SUCCESS == res)
300
        {
301
            printf("OK\n");
302
        }
303
        else
304
        {
305
            printf("\n");
306
            print_error(res);
307
 
308
            res = LIBUSB_SUCCESS;
309
        }
310
    }
311
 
312
    printf("Closing USB device handle...\n");
313
 
314
    libusb_close(usb_handle);
315
 
316
    return res;
317
}
318
 
319
void usb_exit(void)
320
{
321
    printf("Deinitializing USB library...\n");
322
 
323
    libusb_exit(usb_ctx);
324
}