1 /* HM-CFG-USB libusb-driver 
   3  * Copyright (c) 2013 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 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 libusb_device_handle 
*hmcfgusb_find(int vid
, int pid
, char *serial
) { 
 103         libusb_device_handle 
*devh 
= NULL
; 
 104         libusb_device 
**list
; 
 109         cnt 
= libusb_get_device_list(NULL
, &list
); 
 111                 fprintf(stderr
, "Can't get USB device list: %d\n", (int)cnt
); 
 115         for (i 
= 0; i 
< cnt
; i
++){ 
 116                 struct libusb_device_descriptor desc
; 
 118                 err 
= libusb_get_device_descriptor(list
[i
], &desc
); 
 122                 if ((desc
.idVendor 
== vid
) && (desc
.idProduct 
== pid
)) { 
 123                         libusb_device 
*dev 
= list
[i
]; 
 125                         err 
= libusb_open(dev
, &devh
); 
 127                                 fprintf(stderr
, "Can't open device: %s\n", usb_strerror(err
)); 
 128                                 libusb_free_device_list(list
, 1); 
 133                                 if (desc
.iSerialNumber 
> 0) { 
 134                                         uint8_t devSerial
[256]; 
 135                                         err 
= libusb_get_string_descriptor_ascii(devh
, desc
.iSerialNumber
, devSerial
, sizeof(devSerial
)); 
 137                                                 fprintf(stderr
, "Can't read serial-number: %s\n", usb_strerror(err
)); 
 139                                                 libusb_free_device_list(list
, 1); 
 142                                         if (strcmp((char*)devSerial
, (char*)serial
)) { 
 152                         err 
= libusb_detach_kernel_driver(devh
, INTERFACE
); 
 153                         if ((err 
!= 0) && (err 
!= LIBUSB_ERROR_NOT_FOUND
)) { 
 154                                 fprintf(stderr
, "Can't detach kernel driver: %s\n", usb_strerror(err
)); 
 156                                 libusb_free_device_list(list
, 1); 
 160                         err 
= libusb_claim_interface(devh
, INTERFACE
); 
 162                                 fprintf(stderr
, "Can't claim interface: %s\n", usb_strerror(err
)); 
 164                                 libusb_free_device_list(list
, 1); 
 168                         libusb_free_device_list(list
, 0); 
 174         libusb_free_device_list(list
, 1); 
 178 int hmcfgusb_send_null_frame(struct hmcfgusb_dev 
*usbdev
, int silent
) 
 182         unsigned char out
[0x40]; 
 184         memset(out
, 0, sizeof(out
)); 
 186         err 
= libusb_interrupt_transfer(usbdev
->usb_devh
, EP_OUT
, out
, 0, &cnt
, USB_TIMEOUT
); 
 187         if (err 
&& (!silent
)) { 
 188                 fprintf(stderr
, "Can't send null frame: %s\n", usb_strerror(err
)); 
 195 int hmcfgusb_send(struct hmcfgusb_dev 
*usbdev
, unsigned char* send_data
, int len
, int done
) 
 199         struct timeval tv_start
, tv_end
; 
 203                 hexdump(send_data
, len
, "USB < "); 
 206         gettimeofday(&tv_start
, NULL
); 
 208         err 
= libusb_interrupt_transfer(usbdev
->usb_devh
, EP_OUT
, send_data
, len
, &cnt
, USB_TIMEOUT
); 
 210                 fprintf(stderr
, "Can't send data: %s\n", usb_strerror(err
)); 
 215                 if (!hmcfgusb_send_null_frame(usbdev
, 0)) { 
 220         gettimeofday(&tv_end
, NULL
); 
 221         msec 
= ((tv_end
.tv_sec
-tv_start
.tv_sec
)*1000)+((tv_end
.tv_usec
-tv_start
.tv_usec
)/1000); 
 224                 fprintf(stderr
, "usb-transfer took more than 100ms (%dms), this may lead to timing problems!\n", msec
); 
 226                 fprintf(stderr
, "usb-transfer took %dms!\n", msec
); 
 232 static struct libusb_transfer 
*hmcfgusb_prepare_int(libusb_device_handle 
*devh
, libusb_transfer_cb_fn cb
, void *data
, int in_size
) 
 234         unsigned char *data_buf
; 
 235         struct libusb_transfer 
*transfer
; 
 238         data_buf 
= malloc(in_size
); 
 240                 fprintf(stderr
, "Can't allocate memory for data-buffer!\n"); 
 244         transfer 
= libusb_alloc_transfer(0); 
 246                 fprintf(stderr
, "Can't allocate memory for usb-transfer!\n"); 
 251         libusb_fill_interrupt_transfer(transfer
, devh
, EP_IN
, 
 252                         data_buf
, in_size
, cb
, data
, USB_TIMEOUT
); 
 254         transfer
->flags 
= LIBUSB_TRANSFER_FREE_BUFFER
; 
 256         err 
= libusb_submit_transfer(transfer
); 
 258                 fprintf(stderr
, "Can't submit transfer: %s\n", usb_strerror(err
)); 
 259                 libusb_free_transfer(transfer
); 
 266 struct hmcfgusb_cb_data 
{ 
 267         struct hmcfgusb_dev 
*dev
; 
 272 static void LIBUSB_CALL 
hmcfgusb_interrupt(struct libusb_transfer 
*transfer
) 
 275         struct hmcfgusb_cb_data 
*cb_data
; 
 277         cb_data 
= transfer
->user_data
; 
 279         if (transfer
->status 
!= LIBUSB_TRANSFER_COMPLETED
) { 
 280                 if (transfer
->status 
!= LIBUSB_TRANSFER_TIMED_OUT
) { 
 281                         if (transfer
->status 
!= LIBUSB_TRANSFER_CANCELLED
) 
 282                                 fprintf(stderr
, "Interrupt transfer not completed: %s!\n", usb_strerror(transfer
->status
)); 
 288                 if (cb_data 
&& cb_data
->cb
) { 
 290                                 hexdump(transfer
->buffer
, transfer
->actual_length
, "USB > "); 
 292                         if (!cb_data
->cb(transfer
->buffer
, transfer
->actual_length
, cb_data
->data
)) { 
 297                         hexdump(transfer
->buffer
, transfer
->actual_length
, "> "); 
 301         err 
= libusb_submit_transfer(transfer
); 
 303                 fprintf(stderr
, "Can't re-submit transfer: %s\n", usb_strerror(err
)); 
 310         libusb_free_transfer(transfer
); 
 312                 if (cb_data
->dev 
&& cb_data
->dev
->transfer
) { 
 313                         cb_data
->dev
->transfer 
= NULL
; 
 319 struct hmcfgusb_dev 
*hmcfgusb_init(hmcfgusb_cb_fn cb
, void *data
, char *serial
) 
 321         libusb_device_handle 
*devh 
= NULL
; 
 322         const struct libusb_pollfd 
**usb_pfd 
= NULL
; 
 323         struct hmcfgusb_dev 
*dev 
= NULL
; 
 324         struct hmcfgusb_cb_data 
*cb_data 
= NULL
; 
 329         if (!libusb_initialized
) { 
 330                 err 
= libusb_init(NULL
); 
 332                         fprintf(stderr
, "Can't initialize libusb: %s\n", usb_strerror(err
)); 
 336         libusb_initialized 
= 1; 
 338         devh 
= hmcfgusb_find(ID_VENDOR
, ID_PRODUCT
, serial
); 
 340                 devh 
= hmcfgusb_find(ID_VENDOR
, ID_PRODUCT_BL
, serial
); 
 343                                 fprintf(stderr
, "Can't find/open HM-CFG-USB with serial %s!\n", serial
); 
 345                                 fprintf(stderr
, "Can't find/open HM-CFG-USB!\n"); 
 347 #ifdef NEED_LIBUSB_EXIT 
 355         dev 
= malloc(sizeof(struct hmcfgusb_dev
)); 
 357                 perror("Can't allocate memory for hmcfgusb_dev"); 
 359 #ifdef NEED_LIBUSB_EXIT 
 365         memset(dev
, 0, sizeof(struct hmcfgusb_dev
)); 
 366         dev
->usb_devh 
= devh
; 
 367         dev
->bootloader 
= bootloader
; 
 368         dev
->opened_at 
= time(NULL
); 
 370         cb_data 
= malloc(sizeof(struct hmcfgusb_cb_data
)); 
 372                 perror("Can't allocate memory for hmcfgusb_cb_data"); 
 375 #ifdef NEED_LIBUSB_EXIT 
 381         memset(cb_data
, 0, sizeof(struct hmcfgusb_cb_data
)); 
 385         cb_data
->data 
= data
; 
 387         dev
->transfer 
= hmcfgusb_prepare_int(devh
, hmcfgusb_interrupt
, cb_data
, ASYNC_SIZE
); 
 389         if (!dev
->transfer
) { 
 390                 fprintf(stderr
, "Can't prepare async device io!\n"); 
 394 #ifdef NEED_LIBUSB_EXIT 
 400         usb_pfd 
= libusb_get_pollfds(NULL
); 
 402                 fprintf(stderr
, "Can't get FDset from libusb!\n"); 
 403                 libusb_cancel_transfer(dev
->transfer
); 
 404                 libusb_handle_events(NULL
); 
 408 #ifdef NEED_LIBUSB_EXIT 
 415         for(i 
= 0; usb_pfd
[i
]; i
++) 
 418         dev
->pfd 
= malloc(dev
->n_usb_pfd 
* sizeof(struct pollfd
)); 
 420                 perror("Can't allocate memory for poll-fds"); 
 421                 libusb_cancel_transfer(dev
->transfer
); 
 422                 libusb_handle_events(NULL
); 
 426 #ifdef NEED_LIBUSB_EXIT 
 432         memset(dev
->pfd
, 0, dev
->n_usb_pfd 
* sizeof(struct pollfd
)); 
 434         for (i 
= 0; i 
< dev
->n_usb_pfd
; i
++) { 
 435                 dev
->pfd
[i
].fd 
= usb_pfd
[i
]->fd
; 
 436                 dev
->pfd
[i
].events 
= usb_pfd
[i
]->events
; 
 437                 dev
->pfd
[i
].revents 
= 0; 
 442         dev
->n_pfd 
= dev
->n_usb_pfd
; 
 449 int hmcfgusb_add_pfd(struct hmcfgusb_dev 
*dev
, int fd
, short events
) 
 452         dev
->pfd 
= realloc(dev
->pfd
, dev
->n_pfd 
* sizeof(struct pollfd
)); 
 454                 perror("Can't realloc poll-fds"); 
 458         dev
->pfd
[dev
->n_pfd
-1].fd 
= fd
; 
 459         dev
->pfd
[dev
->n_pfd
-1].events 
= events
; 
 460         dev
->pfd
[dev
->n_pfd
-1].revents 
= 0; 
 465 int hmcfgusb_poll(struct hmcfgusb_dev 
*dev
, int timeout
) 
 477         memset(&tv
, 0, sizeof(tv
)); 
 478         err 
= libusb_get_next_timeout(NULL
, &tv
); 
 480                 fprintf(stderr
, "libusb_get_next_timeout: %s\n", usb_strerror(err
)); 
 483         } else if (err 
== 0) { 
 484                 /* No pending timeout or a sane platform */ 
 486                 if ((tv
.tv_sec 
== 0) && (tv
.tv_usec 
== 0)) { 
 488                 } else if ((tv
.tv_sec 
* 1000) < timeout
) { 
 489                         timeout 
= tv
.tv_sec 
* 1000; 
 494                 for (i 
= 0; i 
< dev
->n_pfd
; i
++) { 
 495                         dev
->pfd
[i
].revents 
= 0; 
 498                 n 
= poll(dev
->pfd
, dev
->n_pfd
, timeout
); 
 507                         for (fd_n 
= 0; fd_n 
< dev
->n_pfd
; fd_n
++) { 
 508                                 if (dev
->pfd
[fd_n
].revents
) { 
 509                                         if (fd_n 
< dev
->n_usb_pfd
) { 
 514                                                 return dev
->pfd
[fd_n
].fd
; 
 522                 memset(&tv
, 0, sizeof(tv
)); 
 523                 err 
= libusb_handle_events_timeout_completed(NULL
, &tv
, NULL
); 
 525                         fprintf(stderr
, "libusb_handle_events_timeout_completed: %s\n", usb_strerror(err
)); 
 533                 fprintf(stderr
, "closing device-connection due to error %d\n", quit
); 
 543 void hmcfgusb_enter_bootloader(struct hmcfgusb_dev 
*dev
) 
 545         uint8_t out
[ASYNC_SIZE
]; 
 547         if (dev
->bootloader
) { 
 548                 fprintf(stderr
, "request for bootloader mode, but device already in bootloader!\n"); 
 552         memset(out
, 0, sizeof(out
)); 
 554         hmcfgusb_send(dev
, out
, sizeof(out
), 1); 
 559 void hmcfgusb_leave_bootloader(struct hmcfgusb_dev 
*dev
) 
 561         uint8_t out
[ASYNC_SIZE
]; 
 563         if (!dev
->bootloader
) { 
 564                 fprintf(stderr
, "request for leaving bootloader mode, but device already in normal mode!\n"); 
 568         memset(out
, 0, sizeof(out
)); 
 570         hmcfgusb_send(dev
, out
, sizeof(out
), 1); 
 575 void hmcfgusb_close(struct hmcfgusb_dev 
*dev
) 
 580                 libusb_cancel_transfer(dev
->transfer
); 
 581                 libusb_handle_events(NULL
); 
 584         err 
= libusb_release_interface(dev
->usb_devh
, INTERFACE
); 
 586                 fprintf(stderr
, "Can't release interface: %s\n", usb_strerror(err
)); 
 589         libusb_close(dev
->usb_devh
); 
 590 #ifdef NEED_LIBUSB_EXIT 
 597 void hmcfgusb_exit(void) 
 599         if (libusb_initialized
) { 
 601                 libusb_initialized 
= 0; 
 605 void hmcfgusb_set_debug(int d
)