From 86c8e27edff1a1a879bc3760728ac552b25c0d8a Mon Sep 17 00:00:00 2001 From: Sebastian Zagrodzki Date: Sat, 6 May 2017 02:30:16 +0200 Subject: [PATCH] moar comments. Add a done callback to DefaultInterface return values. --- config.go | 2 ++ device.go | 22 ++++++++++++++++------ endpoint.go | 3 +++ interface.go | 3 +++ usb_test.go | 4 ++-- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/config.go b/config.go index 830a612..d357a6b 100644 --- a/config.go +++ b/config.go @@ -43,6 +43,8 @@ func (c ConfigInfo) String() string { // Config represents a USB device set to use a particular configuration. // Only one Config of a particular device can be used at any one time. +// To access device endpoints, claim an interface and it's alternate +// setting number through a call to Interface(). type Config struct { Info ConfigInfo diff --git a/device.go b/device.go index 077d226..57780b2 100644 --- a/device.go +++ b/device.go @@ -51,6 +51,10 @@ func (d *Descriptor) String() string { } // Device represents an opened USB device. +// Device allows sending USB control commands through the Command() method. +// For data transfers select a device configuration through a call to +// Config(). +// A Device must be Close()d after use. type Device struct { handle *libusbDevHandle @@ -108,6 +112,7 @@ func (d *Device) ActiveConfigNum() (int, error) { // USB supports only one active config per device at a time. Config claims the // device before setting the desired config and keeps it locked until Close is // called. +// A claimed config needs to be Close()d after use. func (d *Device) Config(cfgNum int) (*Config, error) { if d.handle == nil { return nil, fmt.Errorf("Config(%d) called on %s after Close", cfgNum, d) @@ -133,20 +138,25 @@ func (d *Device) Config(cfgNum int) (*Config, error) { // DefaultInterface opens interface #0 with alternate setting #0 of the currently active // config. It's intended as a shortcut for devices that have the simplest // interface of a single config, interface and alternate setting. -func (d *Device) DefaultInterface() (*Interface, error) { +// The done func should be called to release the claimed interface and config. +func (d *Device) DefaultInterface() (intf *Interface, done func(), err error) { cfgNum, err := d.ActiveConfigNum() if err != nil { - return nil, fmt.Errorf("failed to get active config number of device %s: %v", d, err) + return nil, nil, fmt.Errorf("failed to get active config number of device %s: %v", d, err) } cfg, err := d.Config(cfgNum) if err != nil { - return nil, fmt.Errorf("failed to claim config %d of device %s: %v", cfgNum, d, err) + return nil, nil, fmt.Errorf("failed to claim config %d of device %s: %v", cfgNum, d, err) } - intf, err := cfg.Interface(0, 0) + i, err := cfg.Interface(0, 0) if err != nil { - return nil, fmt.Errorf("failed to select interface #%d alternate setting %d of config %d of device %s: %v", 0, 0, cfgNum, d, err) + cfg.Close() + return nil, nil, fmt.Errorf("failed to select interface #%d alternate setting %d of config %d of device %s: %v", 0, 0, cfgNum, d, err) } - return intf, nil + return i, func() { + intf.Close() + cfg.Close() + }, nil } // Control sends a control request to the device. diff --git a/endpoint.go b/endpoint.go index 67f32f6..53e50b6 100644 --- a/endpoint.go +++ b/endpoint.go @@ -105,6 +105,9 @@ func (e *endpoint) transfer(buf []byte) (int, error) { } // InEndpoint represents an IN endpoint open for transfer. +// InEndpoint implements the io.Reader interface. +// For high-throughput transfers, consider creating a bufffered read stream +// through InEndpoint.ReadStream. type InEndpoint struct { *endpoint } diff --git a/interface.go b/interface.go index 11b4ec2..726e0cc 100644 --- a/interface.go +++ b/interface.go @@ -69,6 +69,9 @@ func (a InterfaceSetting) String() string { return fmt.Sprintf("Interface %d alternate setting %d (available endpoints: %v)", a.Number, a.Alternate, a.sortedEndpointIds()) } +// Interface is a representation of a claimed interface with a particular setting. +// To access device endpoints use InEndpoint() and OutEndpoint() methods. +// The interface should be Close()d after use. type Interface struct { Setting InterfaceSetting diff --git a/usb_test.go b/usb_test.go index 0ebeb4c..ab126b5 100644 --- a/usb_test.go +++ b/usb_test.go @@ -110,11 +110,11 @@ func Example_simple() { // Claim the default interface using a convenience function. // The default interface is always #0 alt #0 in the currently active // config. - intf, err := dev.DefaultInterface() + intf, done, err := dev.DefaultInterface() if err != nil { log.Fatalf("%s.DefaultInterface(): %v", dev, err) } - defer intf.Close() + defer done() // Open an OUT endpoint. ep, err := intf.OutEndpoint(7)