]> git.zerfleddert.de Git - fs20pcs/blob - fs20pcs.c
2a4ec377fae0f3b7362d2c7692d4c54f87da8398
[fs20pcs] / fs20pcs.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <libusb-1.0/libusb.h>
7
8 #define USB_TIMEOUT 10000
9
10 #define ID_VENDOR 0x18ef
11 #define ID_PRODUCT 0xe015
12
13 /* Not in all libusb-1.0 versions, so we have to roll our own :-( */
14 static char * usb_strerror(int e)
15 {
16 static char unknerr[256];
17
18 switch (e) {
19 case LIBUSB_SUCCESS:
20 return "Success";
21 case LIBUSB_ERROR_IO:
22 return "Input/output error";
23 case LIBUSB_ERROR_INVALID_PARAM:
24 return "Invalid parameter";
25 case LIBUSB_ERROR_ACCESS:
26 return "Access denied (insufficient permissions)";
27 case LIBUSB_ERROR_NO_DEVICE:
28 return "No such device (it may have been disconnected)";
29 case LIBUSB_ERROR_NOT_FOUND:
30 return "Entity not found";
31 case LIBUSB_ERROR_BUSY:
32 return "Resource busy";
33 case LIBUSB_ERROR_TIMEOUT:
34 return "Operation timed out";
35 case LIBUSB_ERROR_OVERFLOW:
36 return "Overflow";
37 case LIBUSB_ERROR_PIPE:
38 return "Pipe error";
39 case LIBUSB_ERROR_INTERRUPTED:
40 return "System call interrupted (perhaps due to signal)";
41 case LIBUSB_ERROR_NO_MEM:
42 return "Insufficient memory";
43 case LIBUSB_ERROR_NOT_SUPPORTED:
44 return "Operation not supported or unimplemented on this platform";
45 case LIBUSB_ERROR_OTHER:
46 return "Other error";
47 };
48 snprintf(unknerr, sizeof(unknerr), "Unknown error code %d / 0x%02x", e, e);
49 return unknerr;
50 }
51
52 libusb_device_handle *fs20pcs_find() {
53 libusb_device_handle *devh = NULL;
54 libusb_device **list;
55 ssize_t cnt;
56 ssize_t i;
57 int err;
58
59 cnt = libusb_get_device_list(NULL, &list);
60 if (cnt < 0) {
61 fprintf(stderr, "Can't get USB device list: %d\n", (int)cnt);
62 return NULL;
63 }
64
65 for (i = 0; i < cnt; i++){
66 struct libusb_device_descriptor desc;
67
68 err = libusb_get_device_descriptor(list[i], &desc);
69 if (err)
70 continue;
71
72 if ((desc.idVendor == ID_VENDOR) && (desc.idProduct == ID_PRODUCT)) {
73 libusb_device *dev = list[i];
74
75 err = libusb_open(dev, &devh);
76 if (err) {
77 fprintf(stderr, "Can't open device: %s\n", usb_strerror(err));
78 return NULL;
79 }
80
81 err = libusb_detach_kernel_driver(devh, 0);
82 if ((err != 0) && (err != LIBUSB_ERROR_NOT_FOUND)) {
83 fprintf(stderr, "Can't detach kernel driver: %s\n", usb_strerror(err));
84 return NULL;
85 }
86
87 err = libusb_claim_interface(devh, 0);
88 if ((err != 0)) {
89 fprintf(stderr, "Can't claim interface: %s\n", usb_strerror(err));
90 return NULL;
91 }
92
93 return devh;
94 }
95
96 }
97
98 return NULL;
99 }
100
101 int fs20pcs_send(libusb_device_handle *devh, unsigned char* send_data)
102 {
103 unsigned char recv_data[5] = {0x00, 0x00, 0x00, 0x00, 0x00};
104 int err;
105 int cnt;
106 int i;
107 int ret;
108
109 err = libusb_interrupt_transfer(devh, 0x01, send_data, 11, &cnt, 5000);
110 if (err) {
111 fprintf(stderr, "Can't send data: %s\n", usb_strerror(err));
112 return 0;
113 }
114
115 err = libusb_interrupt_transfer(devh, 0x81, recv_data, sizeof(recv_data), &cnt, 5000);
116 if (err) {
117 fprintf(stderr, "Can't receive data: %s\n", usb_strerror(err));
118 return 0;
119 }
120
121 if ((recv_data[0] != 0x02) ||
122 (recv_data[1] != 0x03) ||
123 (recv_data[2] != 0xa0)) {
124 fprintf(stderr, "Unexpected response: ");
125 for (i = 0; i < cnt; i++) {
126 fprintf(stderr, "0x%02x ", recv_data[i]);
127 }
128 fprintf(stderr, "\n");
129
130 return 0;
131 }
132
133 ret = 1;
134
135 switch(recv_data[3]) {
136 case 0x00:
137 printf("Success");
138 break;
139 case 0x01:
140 printf("Firmware V%d.%d", ((recv_data[4] & 0xf0) >> 4) & 0x0f, recv_data[4] & 0x0f);
141 break;
142 case 0x02:
143 printf("Unknown command");
144 ret = 0;
145 break;
146 case 0x03:
147 printf("Wrong length");
148 ret = 0;
149 break;
150 case 0x04:
151 printf("Aborted sending long press");
152 break;
153 case 0x05:
154 printf("Nothing to stop");
155 break;
156 default:
157 printf("Unknown response: 0x%02x 0x%02x", recv_data[3], recv_data[4]);
158 ret = 0;
159 break;
160 }
161
162 printf("\n");
163
164 return ret;
165 }
166
167 int main(int argc, char **argv)
168 {
169 unsigned char send_data[11];
170 libusb_device_handle *devh = NULL;
171 int err;
172 int i;
173
174 if ((argc < 2) || (argc > 12)) {
175 fprintf(stderr, "Invalid number of parameters!\n");
176 return EXIT_FAILURE;
177 }
178
179 memset(send_data, 0, sizeof(send_data));
180 for (i = 0; i < argc - 1; i++) {
181 send_data[i] = strtoul(argv[i+1], NULL, 16);
182 }
183
184 err = libusb_init(NULL);
185 if (err != 0) {
186 fprintf(stderr, "Can't initialize libusb: %s\n", usb_strerror(err));
187 return EXIT_FAILURE;
188 }
189
190 devh = fs20pcs_find();
191 if (!devh) {
192 fprintf(stderr, "Can't find/open fs20pcs!\n");
193 return EXIT_FAILURE;
194 }
195
196 if (fs20pcs_send(devh, send_data) == 0) {
197 fprintf(stderr, "Can't communicate with fs20pcs!\n");
198 return EXIT_FAILURE;
199 }
200
201 libusb_close(NULL);
202
203 return EXIT_SUCCESS;
204 }
Impressum, Datenschutz