1(define nullptr #f)2(define ifs '(0 1)) ;; TODO34(define-record-type <usb-endpoint>5 (%make-usb-endpoint usb-device addr)6 usb-endpoint?78 (usb-device usb-endpoint-device)9 (addr usb-endpoint-addr))1011(define (make-usb-endpoint vid pid addr)12 (define (make-usb-device vid pid)13 (libusb-open nullptr vid pid))1415 (let ((device (make-usb-device vid pid)))16 (if (not device)17 (error "make-usb-device failed")18 (begin19 (libusb-auto-detach device 1)20 (%make-usb-endpoint device addr)))))2122(define (close-usb-endpoint endpoint)23 (libusb-close (usb-endpoint-device endpoint)))2425(define (call-with-usb-endpoint endpoint proc)26 (define dev (usb-endpoint-device endpoint))27 (define (conf-if state)28 (let ((proc (cond29 ((eq? state 'claim) libusb-claim)30 ((eq? state 'release) libusb-release)31 (else (abort "unknown interface state")))))32 (for-each33 (lambda (i)34 (when (not (zero? (proc dev i)))35 (error "interface state change failed"))) ifs)))3637 (let ((r (call-with-current-continuation38 (lambda (k)39 (with-exception-handler40 (lambda (x)41 (conf-if 'release))42 (lambda ()43 (conf-if 'claim)44 (proc endpoint)))))))45 (if (condition? r)46 (signal r)47 (conf-if 'release))))4849;; TODO: Swap arguments50(define (endpoint-transfer data endpoint)51 (let-location ((t int))52 (if (not (zero?53 (libusb-irq-transfer54 (usb-endpoint-device endpoint)55 (usb-endpoint-addr endpoint)56 data57 (u8vector-length data)58 (location t)59 0)))60 (error "libusb-irq-transfer failed")61 t)))