/
io.go
109 lines (98 loc) · 2.06 KB
/
io.go
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
99
100
101
102
103
104
105
106
107
108
109
package usb
// #cgo CFLAGS: -I/usr/include/libusb-1.0
// #cgo LDFLAGS: -lusb-1.0
// #include <libusb.h>
// #include <malloc.h>
import "C"
import (
"io"
"syscall"
"unsafe"
)
type Endpoint interface {
GetDescriptor() EndpointDescriptor
Readable() bool
Writable() bool
io.Reader
io.Writer
}
/*
type EndpointReader interface {
Endpoint
io.Reader
}
type EndpointWriter interface {
Endpoint
io.Writer
}
*/
type EndpointHandle struct {
handle *DeviceHandle
descriptor *EndpointDescriptor
readable bool
ep byte // endpoint number
transfer func(ep *EndpointHandle, p []byte, for_read bool) (n int, err error)
}
func (ep *EndpointHandle) Write(p []byte) (n int, err error) {
if ep.readable {
return 0, syscall.EBADF
}
n, err = ep.transfer(ep, p, false)
if err == nil && n < len(p) {
err = syscall.EAGAIN
}
return
}
func (ep *EndpointHandle) Read(p []byte) (n int, err error) {
if !ep.readable {
return 0, syscall.EBADF
}
return ep.transfer(ep, p, true)
}
func (ep *EndpointHandle) Readable() bool {
return ep.readable
}
func (ep *EndpointHandle) Writable() bool {
return !ep.readable
}
func (ep *EndpointHandle) GetDescriptor() EndpointDescriptor {
return *ep.descriptor
}
type TwoWayStream struct {
R io.Reader
W io.Writer
}
func (s TwoWayStream) Read(p []byte) (n int, err error) {
return s.R.Read(p)
}
func (s TwoWayStream) Write(p []byte) (n int, err error) {
return s.W.Write(p)
}
func interruptTransfer(ep *EndpointHandle, p []byte, _ bool) (n int, err error) {
var transferred C.int
err0 := returnUsbError(C.libusb_interrupt_transfer(
ep.handle.handle,
C.uchar(ep.ep),
(*C.uchar)(unsafe.Pointer(&p[0])),
C.int(len(p)),
&transferred,
0))
if err0 != nil {
err = err0
}
return int(transferred), err
}
func bulkTransfer(ep *EndpointHandle, p []byte, _ bool) (n int, err error) {
var transferred C.int
err0 := returnUsbError(C.libusb_bulk_transfer(
ep.handle.handle,
C.uchar(ep.ep),
(*C.uchar)(unsafe.Pointer(&p[0])),
C.int(len(p)),
&transferred,
0))
if err0 != nil {
err = err0
}
return int(transferred), err
}