From 500caaeda74dd9c660279036293f4b2997cf0b03 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 9 Sep 2017 09:42:37 +0200 Subject: Add vendor --- vendor/github.com/kylelemons/gousb/usb/device.go | 196 +++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 vendor/github.com/kylelemons/gousb/usb/device.go (limited to 'vendor/github.com/kylelemons/gousb/usb/device.go') diff --git a/vendor/github.com/kylelemons/gousb/usb/device.go b/vendor/github.com/kylelemons/gousb/usb/device.go new file mode 100644 index 0000000..bc22287 --- /dev/null +++ b/vendor/github.com/kylelemons/gousb/usb/device.go @@ -0,0 +1,196 @@ +// Copyright 2013 Google Inc. All rights reserved. +// Copyright 2016 the gousb Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package usb + +import ( + "fmt" + "sync" + "time" +) + +var DefaultReadTimeout = 1 * time.Second +var DefaultWriteTimeout = 1 * time.Second +var DefaultControlTimeout = 250 * time.Millisecond //5 * time.Second + +type Device struct { + handle *libusbDevHandle + + // Embed the device information for easy access + *Descriptor + + // Timeouts + ReadTimeout time.Duration + WriteTimeout time.Duration + ControlTimeout time.Duration + + // Claimed interfaces + lock *sync.Mutex + claimed map[uint8]int +} + +func newDevice(handle *libusbDevHandle, desc *Descriptor) *Device { + ifaces := 0 + d := &Device{ + handle: handle, + Descriptor: desc, + ReadTimeout: DefaultReadTimeout, + WriteTimeout: DefaultWriteTimeout, + ControlTimeout: DefaultControlTimeout, + lock: new(sync.Mutex), + claimed: make(map[uint8]int, ifaces), + } + + return d +} + +func (d *Device) Reset() error { + return libusb.reset(d.handle) +} + +func (d *Device) Control(rType, request uint8, val, idx uint16, data []byte) (int, error) { + return libusb.control(d.handle, d.ControlTimeout, rType, request, val, idx, data) +} + +// ActiveConfig returns the config id (not the index) of the active configuration. +// This corresponds to the ConfigInfo.Config field. +func (d *Device) ActiveConfig() (uint8, error) { + return libusb.getConfig(d.handle) +} + +// SetConfig attempts to change the active configuration. +// The cfg provided is the config id (not the index) of the configuration to set, +// which corresponds to the ConfigInfo.Config field. +func (d *Device) SetConfig(cfg uint8) error { + return libusb.setConfig(d.handle, cfg) +} + +// Close the device. +func (d *Device) Close() error { + if d.handle == nil { + return fmt.Errorf("usb: double close on device") + } + d.lock.Lock() + defer d.lock.Unlock() + for iface := range d.claimed { + libusb.release(d.handle, iface) + } + libusb.close(d.handle) + d.handle = nil + return nil +} + +func (d *Device) OpenEndpoint(cfgNum, ifNum, setNum, epNum uint8) (Endpoint, error) { + var cfg *ConfigInfo + for _, c := range d.Configs { + if c.Config == cfgNum { + debug.Printf("found conf: %#v\n", c) + cfg = &c + break + } + } + if cfg == nil { + return nil, fmt.Errorf("usb: unknown configuration %02x", cfgNum) + } + + var intf *InterfaceInfo + for _, i := range cfg.Interfaces { + if i.Number == ifNum { + debug.Printf("found iface: %#v\n", i) + intf = &i + break + } + } + if intf == nil { + return nil, fmt.Errorf("usb: unknown interface %02x", ifNum) + } + + var setAlternate bool + var ifs *InterfaceSetup + for i, s := range intf.Setups { + if s.Alternate == setNum { + setAlternate = i != 0 + debug.Printf("found setup: %#v [default: %v]\n", s, !setAlternate) + ifs = &s + break + } + } + if ifs == nil { + return nil, fmt.Errorf("usb: unknown setup %02x", setNum) + } + + var ep *EndpointInfo + for _, e := range ifs.Endpoints { + if e.Address == epNum { + debug.Printf("found ep %02x in %#v\n", epNum, *ifs) + ep = &e + break + } + } + if ep == nil { + return nil, fmt.Errorf("usb: unknown endpoint %02x", epNum) + } + + end := newEndpoint(d.handle, *ifs, *ep, d.ReadTimeout, d.WriteTimeout) + + // Set the configuration + activeConf, err := libusb.getConfig(d.handle) + if err != nil { + return nil, fmt.Errorf("usb: getcfg: %s", err) + } + if activeConf != cfgNum { + if err := libusb.setConfig(d.handle, cfgNum); err != nil { + return nil, fmt.Errorf("usb: setcfg: %s", err) + } + } + + // Claim the interface + if err := libusb.claim(d.handle, ifNum); err != nil { + return nil, fmt.Errorf("usb: claim: %s", err) + } + + // Increment the claim count + d.lock.Lock() + d.claimed[ifNum]++ + d.lock.Unlock() // unlock immediately because the next calls may block + + // Choose the alternate + if setAlternate { + if err := libusb.setAlt(d.handle, ifNum, setNum); err != nil { + return nil, fmt.Errorf("usb: setalt: %s", err) + } + } + + return end, nil +} + +func (d *Device) GetStringDescriptor(desc_index int) (string, error) { + return libusb.getStringDesc(d.handle, desc_index) +} + +// SetAutoDetach enables/disables libusb's automatic kernel driver detachment. +// When autodetach is enabled libusb will automatically detach the kernel driver +// on the interface and reattach it when releasing the interface. +// Automatic kernel driver detachment is disabled on newly opened device handles by default. +func (d *Device) SetAutoDetach(autodetach bool) error { + var autodetachInt int + switch autodetach { + case true: + autodetachInt = 1 + case false: + autodetachInt = 0 + } + return libusb.setAutoDetach(d.handle, autodetachInt) +} -- cgit v1.2.3