├── libusb.go └── libusb_test.go /libusb.go: -------------------------------------------------------------------------------- 1 | package libusb 2 | 3 | /* 4 | #cgo LDFLAGS: -lusb 5 | #include 6 | */ 7 | import "C" 8 | import "unsafe" 9 | 10 | import "fmt" 11 | 12 | func Init() (int, int) { 13 | C.usb_init() 14 | 15 | bn := C.usb_find_busses() 16 | dn := C.usb_find_devices() 17 | 18 | return int(bn), int(dn) 19 | } 20 | 21 | type Info struct { 22 | Bus string 23 | Device string 24 | Vid int 25 | Pid int 26 | } 27 | 28 | func Enum() []Info { 29 | fmt.Printf("") 30 | 31 | bus := C.usb_get_busses() 32 | n := 0 33 | for ; bus != nil; bus = bus.next { 34 | for dev := bus.devices; dev != nil; dev = dev.next { 35 | n += 1 36 | } 37 | } 38 | infos := make([]Info, n) 39 | 40 | bus = C.usb_get_busses() 41 | n = 0 42 | 43 | for ; bus != nil; bus = bus.next { 44 | busname := C.GoString(&bus.dirname[0]) 45 | 46 | for dev := bus.devices; dev != nil; dev = dev.next { 47 | devname := C.GoString(&dev.filename[0]) 48 | 49 | var info Info 50 | info.Bus = busname 51 | info.Device = devname 52 | info.Vid = int(dev.descriptor.idVendor) 53 | info.Pid = int(dev.descriptor.idProduct) 54 | 55 | infos[n] = info 56 | n += 1 57 | } 58 | } 59 | return infos 60 | } 61 | 62 | type Device struct { 63 | *Info 64 | handle *C.usb_dev_handle 65 | descriptor C.struct_usb_device_descriptor 66 | Timeout int 67 | } 68 | 69 | type UsbError struct { 70 | ErrorDesc string 71 | } 72 | 73 | func (u UsbError) Error() string { 74 | return u.ErrorDesc 75 | } 76 | 77 | func OpenAllCallback(vid, pid int, callback func (*Device, error)) { 78 | for bus := C.usb_get_busses(); bus != nil; bus = bus.next { 79 | for dev := bus.devices; dev != nil; dev = dev.next { 80 | if int(dev.descriptor.idVendor) == vid && 81 | int(dev.descriptor.idProduct) == pid { 82 | h := C.usb_open(dev) 83 | if h == nil { 84 | callback(nil, UsbError{LastError()}) 85 | } else { 86 | rdev := &Device{ 87 | &Info{ 88 | C.GoString(&bus.dirname[0]), 89 | C.GoString(&dev.filename[0]), vid, pid}, 90 | h, dev.descriptor, 10000} 91 | callback(rdev, nil) 92 | } 93 | } 94 | } 95 | } 96 | } 97 | 98 | /// open usb device with info 99 | //func Open(info Info) (*Device) 100 | //{ 101 | // var rdev *Device = nil; 102 | // 103 | // for bus := C.usb_get_busses() ; bus != nil ; bus=bus.next 104 | // { 105 | // for dev := bus.devices ; dev!=nil ; dev = dev.next 106 | // { 107 | // if int(dev.descriptor.idVendor) == info.Vid && 108 | // int(dev.descriptor.idProduct) == info.Pid 109 | // { 110 | // h := C.usb_open(dev); 111 | // rdev = &Device{&info,h,dev.descriptor,10000}; 112 | // return rdev; 113 | // } 114 | // } 115 | // } 116 | // return rdev; 117 | //} 118 | /// open usb device with info 119 | func Open(vid, pid int) *Device { 120 | for bus := C.usb_get_busses(); bus != nil; bus = bus.next { 121 | for dev := bus.devices; dev != nil; dev = dev.next { 122 | if int(dev.descriptor.idVendor) == vid && 123 | int(dev.descriptor.idProduct) == pid { 124 | h := C.usb_open(dev) 125 | rdev := &Device{ 126 | &Info{ 127 | C.GoString(&bus.dirname[0]), 128 | C.GoString(&dev.filename[0]), vid, pid}, 129 | h, dev.descriptor, 10000} 130 | return rdev 131 | } 132 | } 133 | } 134 | return nil 135 | } 136 | 137 | func (dev *Device) Close() int { 138 | r := int(C.usb_close(dev.handle)) 139 | dev.handle = nil 140 | return r 141 | } 142 | 143 | func (dev *Device) String(key int) string { 144 | buf := make([]C.char, 256) 145 | 146 | C.usb_get_string_simple( 147 | dev.handle, 148 | C.int(key), 149 | &buf[0], 150 | C.size_t(len(buf))) 151 | 152 | return C.GoString(&buf[0]) 153 | 154 | } 155 | 156 | func (self *Device) Vendor() string { 157 | return self.String(int(self.descriptor.iManufacturer)) 158 | } 159 | func (self *Device) Product() string { 160 | return self.String(int(self.descriptor.iProduct)) 161 | } 162 | func LastError() string { 163 | return C.GoString(C.usb_strerror()) 164 | } 165 | func (*Device) LastError() string { 166 | return LastError() 167 | } 168 | 169 | func (self *Device) BulkWrite(ep int, dat []byte) int { 170 | return int(C.usb_bulk_write(self.handle, 171 | C.int(ep), 172 | (*C.char)(unsafe.Pointer(&dat[0])), 173 | C.int(len(dat)), 174 | C.int(self.Timeout))) 175 | } 176 | func (self *Device) BulkRead(ep int, dat []byte) int { 177 | return int(C.usb_bulk_read(self.handle, 178 | C.int(ep), 179 | (*C.char)(unsafe.Pointer(&dat[0])), 180 | C.int(len(dat)), 181 | C.int(self.Timeout))) 182 | } 183 | 184 | func (self *Device) InterruptWrite(ep int, dat []byte) int { 185 | return int(C.usb_interrupt_write(self.handle, 186 | C.int(ep), 187 | (*C.char)(unsafe.Pointer(&dat[0])), 188 | C.int(len(dat)), 189 | C.int(self.Timeout))) 190 | } 191 | 192 | func (self *Device) InterruptRead(ep int, dat []byte) int { 193 | return int(C.usb_interrupt_read(self.handle, 194 | C.int(ep), 195 | (*C.char)(unsafe.Pointer(&dat[0])), 196 | C.int(len(dat)), 197 | C.int(self.Timeout))) 198 | } 199 | 200 | func (self *Device) Configuration(conf int) int { 201 | return int(C.usb_set_configuration(self.handle, C.int(conf))) 202 | //return int( C.usb_set_configuration( (*C.uint)(123), C.int(conf)) ); 203 | } 204 | func (self *Device) Interface(ifc int) int { 205 | return int(C.usb_claim_interface(self.handle, C.int(ifc))) 206 | } 207 | 208 | const ( 209 | USB_TYPE_STANDARD = (0x00 << 5) 210 | USB_TYPE_CLASS = (0x01 << 5) 211 | USB_TYPE_VENDOR = (0x02 << 5) 212 | USB_TYPE_RESERVED = (0x03 << 5) 213 | ) 214 | 215 | func (self *Device) ControlMsg(reqtype int, req int, value int, index int, dat []byte) int { 216 | return int(C.usb_control_msg(self.handle, 217 | C.int(reqtype), 218 | C.int(req), 219 | C.int(value), 220 | C.int(index), 221 | (*C.char)(unsafe.Pointer(&dat[0])), 222 | C.int(len(dat)), 223 | C.int(self.Timeout))) 224 | } 225 | -------------------------------------------------------------------------------- /libusb_test.go: -------------------------------------------------------------------------------- 1 | package libusb 2 | 3 | import "fmt" 4 | import "os" 5 | import "testing" 6 | 7 | type method func() 8 | 9 | func enum() { 10 | 11 | Init() 12 | 13 | for i, info := range Enum() { 14 | fmt.Printf("======================================================\n") 15 | fmt.Printf(" %10d : BUS:%s DEVICE:%s VID:%04x PID:%04x\n", i, info.Bus, info.Device, info.Vid, info.Pid) 16 | dev := Open(info.Vid, info.Pid) 17 | if dev != nil { 18 | fmt.Printf(" Vendor : %s\n", dev.Vendor()) 19 | fmt.Printf(" Product : %s\n", dev.Product()) 20 | fmt.Printf(" Last Error : %s\n", dev.LastError()) 21 | dev.Close() 22 | } else { 23 | os.Exit(1) 24 | } 25 | } 26 | } 27 | 28 | func conf() { 29 | vid, pid := 0x04b4, 0x8613 30 | 31 | Init() 32 | 33 | device := Open(vid, pid) 34 | println("dev=", device) 35 | println("dev.bus=", device.Bus) 36 | println("dev.dev=", device.Device) 37 | println("dev.handle=", device.handle) 38 | fmt.Printf(" Last Error : %s\n", device.LastError()) 39 | 40 | var r int 41 | 42 | r = device.Configuration(1) 43 | println("Configuration=", r) 44 | fmt.Printf(" Last Error : %s\n", device.LastError()) 45 | 46 | device.Interface(0) 47 | println("Interface=", r) 48 | fmt.Printf(" Last Error : %s\n", device.LastError()) 49 | device.Close() 50 | } 51 | 52 | var methods = []method{ 53 | enum, 54 | //conf, 55 | } 56 | 57 | func TestAll(t *testing.T) { 58 | for i, method := range methods { 59 | println("==============================================") 60 | println("========= test ", i) 61 | println("==============================================") 62 | method() 63 | } 64 | } 65 | --------------------------------------------------------------------------------