1 /* HM-CFG-USB libusb-driver
3 * Copyright (c) 2013-16 Michael Gernoth <michael@gernoth.net>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
33 #include <libusb-1.0/libusb.h>
35 /* Workaround for old libusb-1.0 */
38 #define libusb_handle_events_timeout_completed(ctx, tv, x) libusb_handle_events_timeout(ctx, tv)
44 #define USB_TIMEOUT 10000
46 #define ID_VENDOR 0x1b1f
47 #define ID_PRODUCT 0xc00f
48 #define ID_PRODUCT_BL 0xc010
51 #define ASYNC_SIZE 0x0040
52 #define ASYNC_INTERVAL 32
61 static int libusb_initialized
= 0;
63 /* Not in all libusb-1.0 versions, so we have to roll our own :-( */
64 static const char* usb_strerror(int e
)
66 static char unknerr
[256];
72 return "Input/output error";
73 case LIBUSB_ERROR_INVALID_PARAM
:
74 return "Invalid parameter";
75 case LIBUSB_ERROR_ACCESS
:
76 return "Access denied (insufficient permissions)";
77 case LIBUSB_ERROR_NO_DEVICE
:
78 return "No such device (it may have been disconnected)";
79 case LIBUSB_ERROR_NOT_FOUND
:
80 return "Entity not found";
81 case LIBUSB_ERROR_BUSY
:
82 return "Resource busy";
83 case LIBUSB_ERROR_TIMEOUT
:
84 return "Operation timed out";
85 case LIBUSB_ERROR_OVERFLOW
:
87 case LIBUSB_ERROR_PIPE
:
89 case LIBUSB_ERROR_INTERRUPTED
:
90 return "System call interrupted (perhaps due to signal)";
91 case LIBUSB_ERROR_NO_MEM
:
92 return "Insufficient memory";
93 case LIBUSB_ERROR_NOT_SUPPORTED
:
94 return "Operation not supported or unimplemented on this platform";
95 case LIBUSB_ERROR_OTHER
:
98 snprintf(unknerr
, sizeof(unknerr
), "Unknown error code %d / 0x%02x", e
, e
);
102 static const char* usb_str_transfer_status(int e
)
104 static char unknerr
[256];
107 case LIBUSB_TRANSFER_COMPLETED
:
108 return "Transfer completed";
109 case LIBUSB_TRANSFER_ERROR
:
110 return "Transfer error";
111 case LIBUSB_TRANSFER_TIMED_OUT
:
112 return "Transfer timed out";
113 case LIBUSB_TRANSFER_CANCELLED
:
114 return "Transfer cancelled";
115 case LIBUSB_TRANSFER_STALL
:
116 return "For bulk/interrupt endpoints: endpoint stalled. For control endpoints: control request not supported.";
117 case LIBUSB_TRANSFER_NO_DEVICE
:
119 case LIBUSB_TRANSFER_OVERFLOW
:
120 return "Transfer overflow";
122 snprintf(unknerr
, sizeof(unknerr
), "Unknown transfer status %d / 0x%02x", e
, e
);
126 static libusb_device_handle
*hmcfgusb_find(int vid
, int pid
, char *serial
) {
127 libusb_device_handle
*devh
= NULL
;
128 libusb_device
**list
;
133 cnt
= libusb_get_device_list(NULL
, &list
);
135 fprintf(stderr
, "Can't get USB device list: %d\n", (int)cnt
);
139 for (i
= 0; i
< cnt
; i
++){
140 struct libusb_device_descriptor desc
;
142 err
= libusb_get_device_descriptor(list
[i
], &desc
);
146 if ((desc
.idVendor
== vid
) && (desc
.idProduct
== pid
)) {
147 libusb_device
*dev
= list
[i
];
149 err
= libusb_open(dev
, &devh
);
151 fprintf(stderr
, "Can't open device: %s\n", usb_strerror(err
));
152 libusb_free_device_list(list
, 1);
157 if (desc
.iSerialNumber
> 0) {
158 uint8_t devSerial
[256];
159 err
= libusb_get_string_descriptor_ascii(devh
, desc
.iSerialNumber
, devSerial
, sizeof(devSerial
));
161 fprintf(stderr
, "Can't read serial-number: %s\n", usb_strerror(err
));
163 libusb_free_device_list(list
, 1);
166 if (strcmp((char*)devSerial
, (char*)serial
)) {
176 err
= libusb_detach_kernel_driver(devh
, INTERFACE
);
177 if ((err
!= 0) && (err
!= LIBUSB_ERROR_NOT_FOUND
)) {
178 fprintf(stderr
, "Can't detach kernel driver: %s\n", usb_strerror(err
));
180 libusb_free_device_list(list
, 1);
184 err
= libusb_claim_interface(devh
, INTERFACE
);
186 fprintf(stderr
, "Can't claim interface: %s\n", usb_strerror(err
));
188 libusb_free_device_list(list
, 1);
192 libusb_free_device_list(list
, 0);
198 libusb_free_device_list(list
, 1);
202 int hmcfgusb_send_null_frame(struct hmcfgusb_dev
*usbdev
, int silent
)
206 unsigned char out
[0x40];
208 memset(out
, 0, sizeof(out
));
210 err
= libusb_interrupt_transfer(usbdev
->usb_devh
, EP_OUT
, out
, 0, &cnt
, USB_TIMEOUT
);
211 if (err
&& (!silent
)) {
212 fprintf(stderr
, "Can't send null frame: %s\n", usb_strerror(err
));
219 int hmcfgusb_send(struct hmcfgusb_dev
*usbdev
, unsigned char* send_data
, int len
, int done
)
223 struct timeval tv_start
, tv_end
;
227 hexdump(send_data
, len
, "USB < ");
230 gettimeofday(&tv_start
, NULL
);
232 err
= libusb_interrupt_transfer(usbdev
->usb_devh
, EP_OUT
, send_data
, len
, &cnt
, USB_TIMEOUT
);
234 fprintf(stderr
, "Can't send data: %s\n", usb_strerror(err
));
239 if (!hmcfgusb_send_null_frame(usbdev
, 0)) {
244 gettimeofday(&tv_end
, NULL
);
245 msec
= ((tv_end
.tv_sec
-tv_start
.tv_sec
)*1000)+((tv_end
.tv_usec
-tv_start
.tv_usec
)/1000);
248 fprintf(stderr
, "usb-transfer took more than 100ms (%dms), this may lead to timing problems!\n", msec
);
250 fprintf(stderr
, "usb-transfer took %dms!\n", msec
);
256 static struct libusb_transfer
*hmcfgusb_prepare_int(libusb_device_handle
*devh
, libusb_transfer_cb_fn cb
, void *data
, int in_size
)
258 unsigned char *data_buf
;
259 struct libusb_transfer
*transfer
;
262 data_buf
= malloc(in_size
);
264 fprintf(stderr
, "Can't allocate memory for data-buffer!\n");
268 transfer
= libusb_alloc_transfer(0);
270 fprintf(stderr
, "Can't allocate memory for usb-transfer!\n");
275 libusb_fill_interrupt_transfer(transfer
, devh
, EP_IN
,
276 data_buf
, in_size
, cb
, data
, USB_TIMEOUT
);
278 transfer
->flags
= LIBUSB_TRANSFER_FREE_BUFFER
;
280 err
= libusb_submit_transfer(transfer
);
282 fprintf(stderr
, "Can't submit transfer: %s\n", usb_strerror(err
));
283 libusb_free_transfer(transfer
);
290 struct hmcfgusb_cb_data
{
291 struct hmcfgusb_dev
*dev
;
296 static void LIBUSB_CALL
hmcfgusb_interrupt(struct libusb_transfer
*transfer
)
299 struct hmcfgusb_cb_data
*cb_data
;
301 cb_data
= transfer
->user_data
;
303 if (transfer
->status
!= LIBUSB_TRANSFER_COMPLETED
) {
304 if (transfer
->status
!= LIBUSB_TRANSFER_TIMED_OUT
) {
305 if (transfer
->status
!= LIBUSB_TRANSFER_CANCELLED
)
306 fprintf(stderr
, "Interrupt transfer not completed: %s!\n", usb_str_transfer_status(transfer
->status
));
312 if (cb_data
&& cb_data
->cb
) {
314 hexdump(transfer
->buffer
, transfer
->actual_length
, "USB > ");
316 if (!cb_data
->cb(transfer
->buffer
, transfer
->actual_length
, cb_data
->data
)) {
321 hexdump(transfer
->buffer
, transfer
->actual_length
, "> ");
325 err
= libusb_submit_transfer(transfer
);
327 fprintf(stderr
, "Can't re-submit transfer: %s\n", usb_strerror(err
));
334 libusb_free_transfer(transfer
);
336 if (cb_data
->dev
&& cb_data
->dev
->transfer
) {
337 cb_data
->dev
->transfer
= NULL
;
343 struct hmcfgusb_dev
*hmcfgusb_init(hmcfgusb_cb_fn cb
, void *data
, char *serial
)
345 libusb_device_handle
*devh
= NULL
;
346 const struct libusb_pollfd
**usb_pfd
= NULL
;
347 struct hmcfgusb_dev
*dev
= NULL
;
348 struct hmcfgusb_cb_data
*cb_data
= NULL
;
353 if (!libusb_initialized
) {
354 err
= libusb_init(NULL
);
356 fprintf(stderr
, "Can't initialize libusb: %s\n", usb_strerror(err
));
360 libusb_initialized
= 1;
362 devh
= hmcfgusb_find(ID_VENDOR
, ID_PRODUCT
, serial
);
364 devh
= hmcfgusb_find(ID_VENDOR
, ID_PRODUCT_BL
, serial
);
367 fprintf(stderr
, "Can't find/open HM-CFG-USB with serial %s!\n", serial
);
369 fprintf(stderr
, "Can't find/open HM-CFG-USB!\n");
371 #ifdef NEED_LIBUSB_EXIT
379 dev
= malloc(sizeof(struct hmcfgusb_dev
));
381 perror("Can't allocate memory for hmcfgusb_dev");
383 #ifdef NEED_LIBUSB_EXIT
389 memset(dev
, 0, sizeof(struct hmcfgusb_dev
));
390 dev
->usb_devh
= devh
;
391 dev
->bootloader
= bootloader
;
392 dev
->opened_at
= time(NULL
);
394 cb_data
= malloc(sizeof(struct hmcfgusb_cb_data
));
396 perror("Can't allocate memory for hmcfgusb_cb_data");
399 #ifdef NEED_LIBUSB_EXIT
405 memset(cb_data
, 0, sizeof(struct hmcfgusb_cb_data
));
409 cb_data
->data
= data
;
411 dev
->transfer
= hmcfgusb_prepare_int(devh
, hmcfgusb_interrupt
, cb_data
, ASYNC_SIZE
);
413 if (!dev
->transfer
) {
414 fprintf(stderr
, "Can't prepare async device io!\n");
418 #ifdef NEED_LIBUSB_EXIT
424 usb_pfd
= libusb_get_pollfds(NULL
);
426 fprintf(stderr
, "Can't get FDset from libusb!\n");
427 libusb_cancel_transfer(dev
->transfer
);
428 libusb_handle_events(NULL
);
432 #ifdef NEED_LIBUSB_EXIT
439 for(i
= 0; usb_pfd
[i
]; i
++)
442 dev
->pfd
= malloc(dev
->n_usb_pfd
* sizeof(struct pollfd
));
444 perror("Can't allocate memory for poll-fds");
445 libusb_cancel_transfer(dev
->transfer
);
446 libusb_handle_events(NULL
);
450 #ifdef NEED_LIBUSB_EXIT
456 memset(dev
->pfd
, 0, dev
->n_usb_pfd
* sizeof(struct pollfd
));
458 for (i
= 0; i
< dev
->n_usb_pfd
; i
++) {
459 dev
->pfd
[i
].fd
= usb_pfd
[i
]->fd
;
460 dev
->pfd
[i
].events
= usb_pfd
[i
]->events
;
461 dev
->pfd
[i
].revents
= 0;
466 dev
->n_pfd
= dev
->n_usb_pfd
;
473 int hmcfgusb_add_pfd(struct hmcfgusb_dev
*dev
, int fd
, short events
)
476 dev
->pfd
= realloc(dev
->pfd
, dev
->n_pfd
* sizeof(struct pollfd
));
478 perror("Can't realloc poll-fds");
482 dev
->pfd
[dev
->n_pfd
-1].fd
= fd
;
483 dev
->pfd
[dev
->n_pfd
-1].events
= events
;
484 dev
->pfd
[dev
->n_pfd
-1].revents
= 0;
489 int hmcfgusb_poll(struct hmcfgusb_dev
*dev
, int timeout
)
501 memset(&tv
, 0, sizeof(tv
));
502 err
= libusb_get_next_timeout(NULL
, &tv
);
504 fprintf(stderr
, "libusb_get_next_timeout: %s\n", usb_strerror(err
));
507 } else if (err
== 0) {
508 /* No pending timeout or a sane platform */
510 if ((tv
.tv_sec
== 0) && (tv
.tv_usec
== 0)) {
512 } else if ((tv
.tv_sec
* 1000) < timeout
) {
513 timeout
= tv
.tv_sec
* 1000;
518 for (i
= 0; i
< dev
->n_pfd
; i
++) {
519 dev
->pfd
[i
].revents
= 0;
522 n
= poll(dev
->pfd
, dev
->n_pfd
, timeout
);
531 for (fd_n
= 0; fd_n
< dev
->n_pfd
; fd_n
++) {
532 if (dev
->pfd
[fd_n
].revents
) {
533 if (fd_n
< dev
->n_usb_pfd
) {
538 return dev
->pfd
[fd_n
].fd
;
546 memset(&tv
, 0, sizeof(tv
));
547 err
= libusb_handle_events_timeout_completed(NULL
, &tv
, NULL
);
549 fprintf(stderr
, "libusb_handle_events_timeout_completed: %s\n", usb_strerror(err
));
557 fprintf(stderr
, "closing device-connection due to error %d\n", quit
);
567 void hmcfgusb_enter_bootloader(struct hmcfgusb_dev
*dev
)
569 uint8_t out
[ASYNC_SIZE
];
571 if (dev
->bootloader
) {
572 fprintf(stderr
, "request for bootloader mode, but device already in bootloader!\n");
576 memset(out
, 0, sizeof(out
));
578 hmcfgusb_send(dev
, out
, sizeof(out
), 1);
583 void hmcfgusb_leave_bootloader(struct hmcfgusb_dev
*dev
)
585 uint8_t out
[ASYNC_SIZE
];
587 if (!dev
->bootloader
) {
588 fprintf(stderr
, "request for leaving bootloader mode, but device already in normal mode!\n");
592 memset(out
, 0, sizeof(out
));
594 hmcfgusb_send(dev
, out
, sizeof(out
), 1);
599 void hmcfgusb_close(struct hmcfgusb_dev
*dev
)
604 libusb_cancel_transfer(dev
->transfer
);
605 libusb_handle_events(NULL
);
608 err
= libusb_release_interface(dev
->usb_devh
, INTERFACE
);
610 fprintf(stderr
, "Can't release interface: %s\n", usb_strerror(err
));
613 libusb_close(dev
->usb_devh
);
614 #ifdef NEED_LIBUSB_EXIT
621 void hmcfgusb_exit(void)
623 if (libusb_initialized
) {
625 libusb_initialized
= 0;
629 void hmcfgusb_set_debug(int d
)