File: ipod-usb.c

package info (click to toggle)
libgpod 0.8.2-7
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 5,532 kB
  • sloc: ansic: 26,876; sh: 11,215; cs: 1,399; python: 1,251; makefile: 472; cpp: 296; xml: 100
file content (112 lines) | stat: -rw-r--r-- 3,009 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <libusb.h>
#include <glib.h>

static int send_command (libusb_device_handle *handle, const guint value, const guint index, guchar *data, gsize len)
{
    return libusb_control_transfer (handle, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x40, value, index, data, len, 0);
}

static libusb_device_handle *open_handle (libusb_context *ctx, const guint bus_number, const guint device_address)
{
    libusb_device **list;
    libusb_device *dev;
    libusb_device_handle *handle;
    unsigned int i;

    int success;
    int device_count;

    device_count = libusb_get_device_list (ctx, &list);
    if (device_count < 0) {
        g_print ("Couldn't get device list\n");
        return NULL;
    }

    dev = NULL;
    for (i = 0; i < device_count; i++) {
        if (libusb_get_bus_number (list[i]) != bus_number) {
            continue;
        }
        if (libusb_get_device_address (list[i]) != device_address) {
            continue;
        }
        dev = list[i];
        break;
    }

    if (dev == NULL) {
        libusb_free_device_list (list, 1);
        g_print ("Couldn't find iPod\n");
        return NULL;
    }

    success = libusb_open (dev, &handle);
    libusb_free_device_list (list, 1);
    if (success < 0) {
        g_print ("Couldn't open usb device: %d\n", success);
        return NULL;
    }

    return handle;
}


static gchar *get_sysinfo_extended (libusb_device_handle *handle)
{
    GString *sysinfo_extended;
    guchar data[0x1000];
    unsigned int i; 

    sysinfo_extended = g_string_sized_new (0x8000);

    for (i = 0; i < 0xffff; i++) {
        int bytes_read;
        bytes_read = send_command (handle, 0x02, i, data, sizeof (data));
        if (bytes_read < 0) {
            g_print ("error reading: %d (i = %d)\n", bytes_read, i);
            return NULL;
        }
        g_string_append_len (sysinfo_extended, (gchar*)data, bytes_read);
        if (bytes_read != sizeof (data)) {
            /* assume short reads mean "end of file" */
            break;
        }
    }
    /*hexdump ((guchar *)sysinfo_extended->str, sysinfo_extended->len);*/

    if (sysinfo_extended->len == 0) {
        /* Nothing could be read from USB */
        g_string_free(sysinfo_extended, TRUE);
        return NULL;
    }

    return g_string_free (sysinfo_extended, FALSE);
}

G_GNUC_INTERNAL char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address);
G_GNUC_INTERNAL char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address)
{
    int success;
    libusb_context *ctx;
    libusb_device_handle *handle;
    gchar *sysinfo_extended;

    success = libusb_init (&ctx);
    if (success < 0) {
        return NULL;

    }

    handle = open_handle (ctx, bus_number, device_address);
    if (handle == NULL) {
        libusb_exit (ctx);
        return NULL;
    }

    sysinfo_extended = get_sysinfo_extended (handle);

    libusb_close (handle);
    libusb_exit (ctx);

    return sysinfo_extended;
}