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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb.h>
#include <stdint.h>

void put32le(uint8_t *buf, uint32_t i)
{
    *buf++ = i & 0xff;
    *buf++ = (i >> 8) & 0xff;
    *buf++ = (i >> 16) & 0xff;
    *buf++ = (i >> 24) & 0xff;
}

void put32be(uint8_t *buf, uint32_t i)
{
    *buf++ = (i >> 24) & 0xff;
    *buf++ = (i >> 16) & 0xff;
    *buf++ = (i >> 8) & 0xff;
    *buf++ = i & 0xff;
}

int main(int argc, char **argv)
{
    int ret;
    uint8_t msg[0x20];
    uint8_t *p;
    FILE *f;

    if(argc != 2)
    {
        printf("usage: %s <file>\n", argv[0]);
        return 1;
    }
    f = fopen(argv[1], "r");
    if(f == NULL)
    {
        perror("cannot open file");
        return 1;
    }
    fseek(f, 0, SEEK_END);
    size_t size = ftell(f);
    fseek(f, 0, SEEK_SET);
    fclose(f);

    libusb_device_handle *dev;

    libusb_init(NULL);

    libusb_set_debug(NULL, 3);

    dev = libusb_open_device_with_vid_pid(NULL, 0x066F, 0x3780);
    if(dev == NULL)
    {
        printf("Cannot open device\n");
        return 1;
    }

    libusb_detach_kernel_driver(dev, 0);
    libusb_detach_kernel_driver(dev, 4);

    libusb_claim_interface (dev, 0);
    libusb_claim_interface (dev, 4);

    if (!dev)
    {
        printf("No dev\n");
        exit(1);
    }

    memset(msg, 0, 0x20);

    p = msg;

    *p++ = 0x01; // Init upload command
    *p++ = 'B'; // Signature
    *p++ = 'L';
    *p++ = 'T';
    *p++ = 'C';
    put32le(p, 0x1); // I guess version or sub-command
    p += 4;
    put32le(p, size); // Payload size

    // The second command starts at 0x20

    p = &msg[0x10];

    *p++ = 0x02; // Start upload
    put32be(p, size); // Payload size, again

    ret = libusb_control_transfer(dev, 
        LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE, 
        0x0000009, 0x0000201, 0x0000000, msg, 0x0000020, 5*1000);

    printf("ret %i\n", ret);

    return 0;
}