gousb

package module
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2024 License: Apache-2.0 Imports: 16 Imported by: 268

README

Introduction

Build Status GoDoc Coverage Status

The gousb package is an attempt at wrapping the libusb library into a Go-like binding.

Supported platforms include:

  • linux
  • darwin
  • windows

This is the release 2.0 of the package github.com/kylelemons/gousb. Its API is not backwards-compatible with version 1.0. As of 2017-07-13 the 2.0 API is considered stable and 1.0 is deprecated.

Documentation

The documentation can be viewed via local godoc or via the excellent godoc.org:

Installation

Dependencies

You must first install libusb-1.0. This is pretty straightforward on linux and darwin. The cgo package should be able to find it if you install it in the default manner or use your distribution's package manager. How to tell cgo how to find one installed in a non-default place is beyond the scope of this README.

Note: If you are installing this on darwin, you will probably need to run fixlibusb_darwin.sh /usr/local/lib/libusb-1.0/libusb.h because of an LLVM incompatibility. It shouldn't break C programs, though I haven't tried it in anger.

Example: lsusb

The gousb project provides a simple but useful example: lsusb. This binary will list the USB devices connected to your system and various interesting tidbits about them, their configurations, endpoints, etc. To install it, run the following command:

go get -v github.com/google/gousb/lsusb

gousb

If you installed the lsusb example, both libraries below are already installed.

Installing the primary gousb package is really easy:

go get -v github.com/google/gousb

There is also a usbid package that will not be installed by default by this command, but which provides useful information including the human-readable vendor and product codes for detected hardware. It's not installed by default and not linked into the gousb package by default because it adds ~400kb to the resulting binary. If you want both, they can be installed thus:

go get -v github.com/google/gousb{,/usbid}

Notes for installation on Windows

You'll need:

Make sure the libusb-1.0.pc pkg-config file from libusb was installed and that the result of the pkg-config --cflags libusb-1.0 command shows the correct include path for installed libusb.

After that you can continue with instructions for lsusb/gousb above.

Contributing

Contributing to this project will require signing the Google CLA. This is the same agreement that is required for contributing to Go itself, so if you have already filled it out for that, you needn't fill it out again.

Documentation

Overview

Package gousb provides an low-level interface to attached USB devices.

A Short Tutorial

A Context manages all resources necessary for communicating with USB devices. Through the Context users can iterate over available USB devices.

The USB standard defines a mechanism of discovering USB device functionality through descriptors. After the device is attached and initialized by the host stack, it's possible to retrieve its descriptor (the device descriptor). It contains elements such as product and vendor IDs, bus number and device number (address) on the bus.

In gousb, the Device struct represents a USB device. The Device struct’s Desc field contains all known information about the device.

Among other information in the device descriptor is a list of configuration descriptors, accessible through Device.Desc.Configs.

The USB standard allows one physical USB device to switch between different sets of behaviors, or working modes, by selecting one of the offered configs (each device has at least one). This allows the same device to sometimes present itself as e.g. a 3G modem, and sometimes as a flash drive with the drivers for that 3G modem. Configs are mutually exclusive, each device can have only one active config at a time. Switching the active config performs a light-weight device reset. Each config in the device descriptor has a unique identification number.

In gousb a device config needs to be selected through Device.Config(num). It returns a Config struct that represents the device in this particular configuration. The configuration descriptor is accessible through Config.Desc.

A config descriptor determines the list of available USB interfaces on the device. Each interface is a virtual device within the physical USB device and its active config. There can be many interfaces active concurrently. Interfaces are enumerated sequentially starting from zero.

Additionally, each interface comes with a number of alternate settings for the interface, which are somewhat similar to device configs, but on the interface level. Each interface can have only a single alternate setting active at any time. Alternate settings are enumerated sequentially starting from zero.

In gousb an interface and its alternate setting can be selected through Config.Interface(num, altNum). The Interface struct is the representation of the claimed interface with a particular alternate setting. The descriptor of the interface is available through Interface.Setting.

An interface with a particular alternate setting defines up to 30 data endpoints, each identified by a unique address. The endpoint address is a combination of endpoint number (1..15) and endpoint directionality (IN/OUT). IN endpoints have addresses 0x81..0x8f, while OUT endpoints 0x01..0x0f.

An endpoint can be considered similar to a UDP/IP port, except the data transfers are unidirectional.

Endpoints are represented by the Endpoint struct, and all defined endpoints can be obtained through the Endpoints field of the Interface.Setting.

Each endpoint descriptor (EndpointDesc) defined in the interface's endpoint map includes information about the type of the endpoint:

- endpoint address

- endpoint number

- direction: IN (device-to-host) or OUT (host-to-device)

- transfer type: USB standard defines a few distinct data transfer types:

--- bulk - high throughput, but no guaranteed bandwidth and no latency guarantees,

--- isochronous - medium throughput, guaranteed bandwidth, some latency guarantees,

--- interrupt - low throughput, high latency guarantees.

The endpoint descriptor determines the type of the transfer that will be used.

- maximum packet size: maximum number of bytes that can be sent or received by the device in a single USB transaction. and a few other less frequently used pieces of endpoint information.

An IN Endpoint can be opened for reading through Interface.InEndpoint(epNum), while an OUT Endpoint can be opened for writing through Interface.OutEndpoint(epNum).

An InEndpoint implements the io.Reader interface, an OutEndpoint implements the io.Writer interface. Both Reads and Writes will accept larger slices of data than the endpoint's maximum packet size, the transfer will be split into smaller USB transactions as needed. But using Read/Write size equal to an integer multiple of maximum packet size helps with improving the transfer performance.

Apart from 15 possible data endpoints, each USB device also has a control endpoint. The control endpoint is present regardless of the current device config, claimed interfaces and their alternate settings. It makes a lot of sense, as the control endpoint is actually used, among others, to issue commands to switch the active config or select an alternate setting for an interface.

Control commands are also often used to control the behavior of the device. There is no single standard for control commands though, and many devices implement their custom control command schema.

Control commands can be issued through Device.Control().

See Also

For more information about USB protocol and handling USB devices, see the excellent "USB in a nutshell" guide: http://www.beyondlogic.org/usbnutshell/

Example (Complex)

This example demostrates the full API for accessing endpoints. It opens a device with a known VID/PID, switches the device to configuration #2, in that configuration it opens (claims) interface #3 with alternate setting #0. Within that interface setting it opens an IN endpoint number 6 and an OUT endpoint number 5, then starts copying data between them,

package main

import (
	"fmt"
	"log"

	"github.com/google/gousb"
)

func main() {
	// Initialize a new Context.
	ctx := gousb.NewContext()
	defer ctx.Close()

	// Iterate through available Devices, finding all that match a known VID/PID.
	vid, pid := gousb.ID(0x04f2), gousb.ID(0xb531)
	devs, err := ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool {
		// this function is called for every device present.
		// Returning true means the device should be opened.
		return desc.Vendor == vid && desc.Product == pid
	})
	// All returned devices are now open and will need to be closed.
	for _, d := range devs {
		defer d.Close()
	}
	if err != nil {
		log.Fatalf("OpenDevices(): %v", err)
	}
	if len(devs) == 0 {
		log.Fatalf("no devices found matching VID %s and PID %s", vid, pid)
	}

	// Pick the first device found.
	dev := devs[0]

	// Switch the configuration to #2.
	cfg, err := dev.Config(2)
	if err != nil {
		log.Fatalf("%s.Config(2): %v", dev, err)
	}
	defer cfg.Close()

	// In the config #2, claim interface #3 with alt setting #0.
	intf, err := cfg.Interface(3, 0)
	if err != nil {
		log.Fatalf("%s.Interface(3, 0): %v", cfg, err)
	}
	defer intf.Close()

	// In this interface open endpoint #6 for reading.
	epIn, err := intf.InEndpoint(6)
	if err != nil {
		log.Fatalf("%s.InEndpoint(6): %v", intf, err)
	}

	// And in the same interface open endpoint #5 for writing.
	epOut, err := intf.OutEndpoint(5)
	if err != nil {
		log.Fatalf("%s.OutEndpoint(5): %v", intf, err)
	}

	// Buffer large enough for 10 USB packets from endpoint 6.
	buf := make([]byte, 10*epIn.Desc.MaxPacketSize)
	total := 0
	// Repeat the read/write cycle 10 times.
	for i := 0; i < 10; i++ {
		// readBytes might be smaller than the buffer size. readBytes might be greater than zero even if err is not nil.
		readBytes, err := epIn.Read(buf)
		if err != nil {
			fmt.Println("Read returned an error:", err)
		}
		if readBytes == 0 {
			log.Fatalf("IN endpoint 6 returned 0 bytes of data.")
		}
		// writeBytes might be smaller than the buffer size if an error occurred. writeBytes might be greater than zero even if err is not nil.
		writeBytes, err := epOut.Write(buf[:readBytes])
		if err != nil {
			fmt.Println("Write returned an error:", err)
		}
		if writeBytes != readBytes {
			log.Fatalf("IN endpoint 5 received only %d bytes of data out of %d sent", writeBytes, readBytes)
		}
		total += writeBytes
	}
	fmt.Printf("Total number of bytes copied: %d\n", total)
}
Output:

Example (Simple)

This examples demonstrates the use of a few convenience functions that can be used in simple situations and with simple devices. It opens a device with a given VID/PID, claims the default interface (use the same config as currently active, interface 0, alternate setting 0) and tries to write 5 bytes of data to endpoint number 7.

package main

import (
	"fmt"
	"log"

	"github.com/google/gousb"
)

func main() {
	// Initialize a new Context.
	ctx := gousb.NewContext()
	defer ctx.Close()

	// Open any device with a given VID/PID using a convenience function.
	dev, err := ctx.OpenDeviceWithVIDPID(0x046d, 0xc526)
	if err != nil {
		log.Fatalf("Could not open a device: %v", err)
	}
	defer dev.Close()

	// Claim the default interface using a convenience function.
	// The default interface is always #0 alt #0 in the currently active
	// config.
	intf, done, err := dev.DefaultInterface()
	if err != nil {
		log.Fatalf("%s.DefaultInterface(): %v", dev, err)
	}
	defer done()

	// Open an OUT endpoint.
	ep, err := intf.OutEndpoint(7)
	if err != nil {
		log.Fatalf("%s.OutEndpoint(7): %v", intf, err)
	}

	// Generate some data to write.
	data := make([]byte, 5)
	for i := range data {
		data[i] = byte(i)
	}

	// Write data to the USB device.
	numBytes, err := ep.Write(data)
	if numBytes != 5 {
		log.Fatalf("%s.Write([5]): only %d bytes written, returned error is %v", ep, numBytes, err)
	}
	fmt.Println("5 bytes successfully sent to the endpoint")
}
Output:

Index

Examples

Constants

View Source
const (
	ControlIn  = C.LIBUSB_ENDPOINT_IN
	ControlOut = C.LIBUSB_ENDPOINT_OUT

	// "Standard" is explicitly omitted, as functionality of standard requests
	// is exposed through higher level operations of gousb.
	ControlClass  = C.LIBUSB_REQUEST_TYPE_CLASS
	ControlVendor = C.LIBUSB_REQUEST_TYPE_VENDOR

	ControlDevice    = C.LIBUSB_RECIPIENT_DEVICE
	ControlInterface = C.LIBUSB_RECIPIENT_INTERFACE
	ControlEndpoint  = C.LIBUSB_RECIPIENT_ENDPOINT
	ControlOther     = C.LIBUSB_RECIPIENT_OTHER
)

Control request type bit fields as defined in the USB spec. All values are of uint8 type. These constants can be used with Device.Control() method to specify the type and destination of the control request, e.g. `dev.Control(ControlOut|ControlVendor|ControlDevice, ...)`.

Variables

This section is empty.

Functions

This section is empty.

Types

type BCD

type BCD uint16

BCD is a binary-coded decimal version number. Its first 8 bits represent the major version number, its last 8 bits represent the minor version number. Major and minor are composed of 4+4 bits, where each 4 bits represents a decimal digit. Example: BCD(0x1234) means major 12 (decimal) and minor 34 (decimal).

func Version

func Version(major, minor uint8) BCD

Version returns a BCD version number with given major/minor.

func (BCD) Major

func (s BCD) Major() uint8

Major is the major number of the BCD.

func (BCD) Minor

func (s BCD) Minor() uint8

Minor is the minor number of the BCD.

func (BCD) String

func (s BCD) String() string

String returns a dotted representation of the BCD (major.minor).

type Class

type Class uint8

Class represents a USB-IF (Implementers Forum) class or subclass code.

const (
	ClassPerInterface       Class = 0x00
	ClassAudio              Class = 0x01
	ClassComm               Class = 0x02
	ClassHID                Class = 0x03
	ClassPhysical           Class = 0x05
	ClassImage              Class = 0x06
	ClassPTP                Class = ClassImage // legacy name for image
	ClassPrinter            Class = 0x07
	ClassMassStorage        Class = 0x08
	ClassHub                Class = 0x09
	ClassData               Class = 0x0a
	ClassSmartCard          Class = 0x0b
	ClassContentSecurity    Class = 0x0d
	ClassVideo              Class = 0x0e
	ClassPersonalHealthcare Class = 0x0f
	ClassAudioVideo         Class = 0x10
	ClassBillboard          Class = 0x11
	ClassUSBTypeCBridge     Class = 0x12
	ClassDiagnosticDevice   Class = 0xdc
	ClassWireless           Class = 0xe0
	ClassMiscellaneous      Class = 0xef
	ClassApplication        Class = 0xfe
	ClassVendorSpec         Class = 0xff
)

Standard classes defined by USB spec, see https://www.usb.org/defined-class-codes

func (Class) String

func (c Class) String() string

type Config

type Config struct {
	Desc ConfigDesc
	// contains filtered or unexported fields
}

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().

func (*Config) Close

func (c *Config) Close() error

Close releases the underlying device, allowing the caller to switch the device to a different configuration.

func (*Config) Interface

func (c *Config) Interface(num, alt int) (*Interface, error)

Interface claims and returns an interface on a USB device. num specifies the number of an interface to claim, and alt specifies the alternate setting number for that interface.

func (*Config) String

func (c *Config) String() string

String returns the human-readable description of the configuration.

type ConfigDesc

type ConfigDesc struct {
	// Number is the configuration number.
	Number int
	// SelfPowered is true if the device is powered externally, i.e. not
	// drawing power from the USB bus.
	SelfPowered bool
	// RemoteWakeup is true if the device supports remote wakeup, i.e.
	// an external signal that will wake up a suspended USB device. An example
	// might be a keyboard that can wake up through a keypress after
	// the host put it in suspend mode. Note that gousb does not support
	// device power management, RemoteWakeup only refers to the reported device
	// capability.
	RemoteWakeup bool
	// MaxPower is the maximum current the device draws from the USB bus
	// in this configuration.
	MaxPower Milliamperes
	// Interfaces has a list of USB interfaces available in this configuration.
	Interfaces []InterfaceDesc
	// contains filtered or unexported fields
}

ConfigDesc contains the information about a USB device configuration, extracted from the device descriptor.

func (ConfigDesc) String

func (c ConfigDesc) String() string

String returns the human-readable description of the configuration descriptor.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context manages all resources related to USB device handling.

func NewContext

func NewContext() *Context

NewContext returns a new Context instance.

func (*Context) Close

func (c *Context) Close() error

Close releases the Context and all associated resources.

func (*Context) Debug

func (c *Context) Debug(level int)

Debug changes the debug level. Level 0 means no debug, higher levels will print out more debugging information. TODO(sebek): in the next major release, replace int levels with Go-typed constants.

func (*Context) OpenDeviceWithVIDPID

func (c *Context) OpenDeviceWithVIDPID(vid, pid ID) (*Device, error)

OpenDeviceWithVIDPID opens Device from specific VendorId and ProductId. If none is found, it returns nil and nil error. If there are multiple devices with the same VID/PID, it will return one of them, picked arbitrarily. If there were any errors during device list traversal, it is possible it will return a non-nil device and non-nil error. A Device.Close() must be called to release the device if the returned device wasn't nil.

func (*Context) OpenDevices

func (c *Context) OpenDevices(opener func(desc *DeviceDesc) bool) ([]*Device, error)

OpenDevices calls opener with each enumerated device. If the opener returns true, the device is opened and a Device is returned if the operation succeeds. Every Device returned (whether an error is also returned or not) must be closed. If there are any errors enumerating the devices, the final one is returned along with any successfully opened devices.

type DescriptorType

type DescriptorType uint8

DescriptorType identifies the type of a USB descriptor.

const (
	DescriptorTypeDevice    DescriptorType = C.LIBUSB_DT_DEVICE
	DescriptorTypeConfig    DescriptorType = C.LIBUSB_DT_CONFIG
	DescriptorTypeString    DescriptorType = C.LIBUSB_DT_STRING
	DescriptorTypeInterface DescriptorType = C.LIBUSB_DT_INTERFACE
	DescriptorTypeEndpoint  DescriptorType = C.LIBUSB_DT_ENDPOINT
	DescriptorTypeHID       DescriptorType = C.LIBUSB_DT_HID
	DescriptorTypeReport    DescriptorType = C.LIBUSB_DT_REPORT
	DescriptorTypePhysical  DescriptorType = C.LIBUSB_DT_PHYSICAL
	DescriptorTypeHub       DescriptorType = C.LIBUSB_DT_HUB
)

Descriptor types defined by the USB spec.

func (DescriptorType) String

func (dt DescriptorType) String() string

type Device

type Device struct {

	// Embed the device information for easy access
	Desc *DeviceDesc
	// Timeout for control commands
	ControlTimeout time.Duration
	// contains filtered or unexported fields
}

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.

func (*Device) ActiveConfigNum

func (d *Device) ActiveConfigNum() (int, error)

ActiveConfigNum returns the config id of the active configuration. The value corresponds to the ConfigInfo.Config field of one of the ConfigInfos of this Device.

func (*Device) Close

func (d *Device) Close() error

Close closes the device.

func (*Device) Config

func (d *Device) Config(cfgNum int) (*Config, error)

Config returns a USB device set to use a particular config. The cfgNum provided is the config id (not the index) of the configuration to set, which corresponds to the ConfigInfo.Config field. 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 (*Device) ConfigDescription

func (d *Device) ConfigDescription(cfg int) (string, error)

ConfigDescription returns the description of the selected device configuration. GetStringDescriptor's string conversion rules apply.

func (*Device) Control

func (d *Device) Control(rType, request uint8, val, idx uint16, data []byte) (int, error)

Control sends a control request to the device.

func (*Device) DefaultInterface

func (d *Device) DefaultInterface() (intf *Interface, done func(), err 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. The done func should be called to release the claimed interface and config.

func (*Device) GetStringDescriptor

func (d *Device) GetStringDescriptor(descIndex int) (string, error)

GetStringDescriptor returns a device string descriptor with the given index number. The first supported language is always used and the returned descriptor string is converted to ASCII (non-ASCII characters are replaced with "?").

func (*Device) InterfaceDescription

func (d *Device) InterfaceDescription(cfgNum, intfNum, altNum int) (string, error)

InterfaceDescription returns the description of the selected interface and its alternate setting in a selected configuration. GetStringDescriptor's string conversion rules apply.

func (*Device) Manufacturer

func (d *Device) Manufacturer() (string, error)

Manufacturer returns the device's manufacturer name. GetStringDescriptor's string conversion rules apply.

func (*Device) Product

func (d *Device) Product() (string, error)

Product returns the device's product name. GetStringDescriptor's string conversion rules apply.

func (*Device) Reset

func (d *Device) Reset() error

Reset performs a USB port reset to reinitialize a device.

func (*Device) SerialNumber

func (d *Device) SerialNumber() (string, error)

SerialNumber returns the device's serial number. GetStringDescriptor's string conversion rules apply.

func (*Device) SetAutoDetach

func (d *Device) SetAutoDetach(autodetach bool) error

SetAutoDetach enables/disables automatic kernel driver detachment. When autodetach is enabled gousb 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 (*Device) String

func (d *Device) String() string

String represents a human readable representation of the device.

type DeviceDesc

type DeviceDesc struct {
	// The bus on which the device was detected
	Bus int
	// The address of the device on the bus
	Address int
	// The negotiated operating speed for the device
	Speed Speed
	// The pyhsical port on the parent hub on which the device is connected.
	// Ports are numbered from 1, excepting root hub devices which are always 0.
	Port int
	// Physical path of connected parent ports, starting at the root hub device.
	// A path length of 0 represents a root hub device,
	// a path length of 1 represents a device directly connected to a root hub,
	// a path length of 2 or more are connected to intermediate hub devices.
	// e.g. [1,2,3] represents a device connected to port 3 of a hub connected
	// to port 2 of a hub connected to port 1 of a root hub.
	Path []int

	// Version information
	Spec   BCD // USB Specification Release Number
	Device BCD // The device version

	// Product information
	Vendor  ID // The Vendor identifer
	Product ID // The Product identifier

	// Protocol information
	Class                Class    // The class of this device
	SubClass             Class    // The sub-class (within the class) of this device
	Protocol             Protocol // The protocol (within the sub-class) of this device
	MaxControlPacketSize int      // Maximum size of the control transfer

	// Configuration information
	Configs map[int]ConfigDesc
	// contains filtered or unexported fields
}

DeviceDesc is a representation of a USB device descriptor.

func (*DeviceDesc) String

func (d *DeviceDesc) String() string

String returns a human-readable version of the device descriptor.

type EndpointAddress

type EndpointAddress uint8

EndpointAddress is a unique identifier for the endpoint, combining the endpoint number and direction.

func (EndpointAddress) String

func (a EndpointAddress) String() string

String implements the Stringer interface.

type EndpointDesc

type EndpointDesc struct {
	// Address is the unique identifier of the endpoint within the interface.
	Address EndpointAddress
	// Number represents the endpoint number. Note that the endpoint number is different from the
	// address field in the descriptor - address 0x82 means endpoint number 2,
	// with endpoint direction IN.
	// The device can have up to two endpoints with the same number but with
	// different directions.
	Number int
	// Direction defines whether the data is flowing IN or OUT from the host perspective.
	Direction EndpointDirection
	// MaxPacketSize is the maximum USB packet size for a single frame/microframe.
	MaxPacketSize int
	// TransferType defines the endpoint type - bulk, interrupt, isochronous.
	TransferType TransferType
	// PollInterval is the maximum time between transfers for interrupt and isochronous transfer,
	// or the NAK interval for a control transfer. See endpoint descriptor bInterval documentation
	// in the USB spec for details.
	PollInterval time.Duration
	// IsoSyncType is the isochronous endpoint synchronization type, as defined by USB spec.
	IsoSyncType IsoSyncType
	// UsageType is the isochronous or interrupt endpoint usage type, as defined by USB spec.
	UsageType UsageType
}

EndpointDesc contains the information about an interface endpoint, extracted from the descriptor.

func (EndpointDesc) String

func (e EndpointDesc) String() string

String returns the human-readable description of the endpoint.

type EndpointDirection

type EndpointDirection bool

EndpointDirection defines the direction of data flow - IN (device to host) or OUT (host to device).

const (

	// EndpointDirectionIn marks data flowing from device to host.
	EndpointDirectionIn EndpointDirection = true
	// EndpointDirectionOut marks data flowing from host to device.
	EndpointDirectionOut EndpointDirection = false
)

func (EndpointDirection) String

func (ed EndpointDirection) String() string

type Error

type Error C.int

Error is an error code from a USB operation. See the list of Error constants below.

const (
	Success           Error = C.LIBUSB_SUCCESS
	ErrorIO           Error = C.LIBUSB_ERROR_IO
	ErrorInvalidParam Error = C.LIBUSB_ERROR_INVALID_PARAM
	ErrorAccess       Error = C.LIBUSB_ERROR_ACCESS
	ErrorNoDevice     Error = C.LIBUSB_ERROR_NO_DEVICE
	ErrorNotFound     Error = C.LIBUSB_ERROR_NOT_FOUND
	ErrorBusy         Error = C.LIBUSB_ERROR_BUSY
	ErrorTimeout      Error = C.LIBUSB_ERROR_TIMEOUT
	// ErrorOverflow indicates that the device tried to send more data than was
	// requested and that could fit in the packet buffer.
	ErrorOverflow     Error = C.LIBUSB_ERROR_OVERFLOW
	ErrorPipe         Error = C.LIBUSB_ERROR_PIPE
	ErrorInterrupted  Error = C.LIBUSB_ERROR_INTERRUPTED
	ErrorNoMem        Error = C.LIBUSB_ERROR_NO_MEM
	ErrorNotSupported Error = C.LIBUSB_ERROR_NOT_SUPPORTED
	ErrorOther        Error = C.LIBUSB_ERROR_OTHER
)

Defined result codes.

func (Error) Error

func (e Error) Error() string

Error implements the error interface.

type ID

type ID uint16

ID represents a vendor or product ID.

func (ID) String

func (id ID) String() string

String returns a hexadecimal ID.

type InEndpoint

type InEndpoint struct {
	// contains filtered or unexported fields
}

InEndpoint represents an IN endpoint open for transfer. InEndpoint implements the io.Reader interface. For high-throughput transfers, consider creating a buffered read stream through InEndpoint.ReadStream.

func (*InEndpoint) NewStream

func (e *InEndpoint) NewStream(size, count int) (*ReadStream, error)

NewStream prepares a new read stream that will keep reading data from the endpoint until closed or until an error or timeout is encountered. Size defines a buffer size for a single read transaction and count defines how many transactions should be active at any time. By keeping multiple transfers active at the same time, a Stream reduces the latency between subsequent transfers and increases reading throughput. Similarly to InEndpoint.Read, the size of the buffer should be a multiple of EndpointDesc.MaxPacketSize to avoid overflows, see documentation in InEndpoint.Read for more details.

func (*InEndpoint) Read

func (e *InEndpoint) Read(buf []byte) (int, error)

Read reads data from an IN endpoint. Read returns number of bytes obtained from the endpoint. Read may return non-zero length even if the returned error is not nil (partial read). It's recommended to use buffer sizes that are multiples of EndpointDesc.MaxPacketSize to avoid overflows. When a USB device receives a read request, it doesn't know the size of the buffer and may send too much data in one packet to fit in the buffer. If that happens, Read will return an error signaling an overflow. See http://libusb.sourceforge.net/api-1.0/libusb_packetoverflow.html for more details.

func (*InEndpoint) ReadContext

func (e *InEndpoint) ReadContext(ctx context.Context, buf []byte) (int, error)

ReadContext reads data from an IN endpoint. ReadContext returns number of bytes obtained from the endpoint. ReadContext may return non-zero length even if the returned error is not nil (partial read). The passed context can be used to control the cancellation of the read. If the context is cancelled, ReadContext will cancel the underlying transfers, resulting in TransferCancelled error. It's recommended to use buffer sizes that are multiples of EndpointDesc.MaxPacketSize to avoid overflows. When a USB device receives a read request, it doesn't know the size of the buffer and may send too much data in one packet to fit in the buffer. If that happens, Read will return an error signaling an overflow. See http://libusb.sourceforge.net/api-1.0/libusb_packetoverflow.html for more details.

func (InEndpoint) String

func (e InEndpoint) String() string

String returns a human-readable description of the endpoint.

type Interface

type Interface struct {
	Setting InterfaceSetting
	// contains filtered or unexported fields
}

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.

func (*Interface) Close

func (i *Interface) Close()

Close releases the interface.

func (*Interface) InEndpoint

func (i *Interface) InEndpoint(epNum int) (*InEndpoint, error)

InEndpoint prepares an IN endpoint for transfer.

func (*Interface) OutEndpoint

func (i *Interface) OutEndpoint(epNum int) (*OutEndpoint, error)

OutEndpoint prepares an OUT endpoint for transfer.

func (*Interface) String

func (i *Interface) String() string

type InterfaceDesc

type InterfaceDesc struct {
	// Number is the number of this interface.
	Number int
	// AltSettings is a list of alternate settings supported by the interface.
	AltSettings []InterfaceSetting
}

InterfaceDesc contains information about a USB interface, extracted from the descriptor.

func (InterfaceDesc) String

func (i InterfaceDesc) String() string

String returns a human-readable description of the interface descriptor and its alternate settings.

type InterfaceSetting

type InterfaceSetting struct {
	// Number is the number of this interface, the same as in InterfaceDesc.
	Number int
	// Alternate is the number of this alternate setting.
	Alternate int
	// Class is the USB-IF (Implementers Forum) class code, as defined by the USB spec.
	Class Class
	// SubClass is the USB-IF (Implementers Forum) subclass code, as defined by the USB spec.
	SubClass Class
	// Protocol is USB protocol code, as defined by the USB spe.c
	Protocol Protocol
	// Endpoints enumerates the endpoints available on this interface with
	// this alternate setting.
	Endpoints map[EndpointAddress]EndpointDesc
	// contains filtered or unexported fields
}

InterfaceSetting contains information about a USB interface with a particular alternate setting, extracted from the descriptor.

func (InterfaceSetting) String

func (a InterfaceSetting) String() string

String returns a human-readable description of the particular alternate setting of an interface.

type IsoSyncType

type IsoSyncType uint8

IsoSyncType defines the isochronous transfer synchronization type.

const (
	IsoSyncTypeNone     IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_NONE << 2
	IsoSyncTypeAsync    IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ASYNC << 2
	IsoSyncTypeAdaptive IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_ADAPTIVE << 2
	IsoSyncTypeSync     IsoSyncType = C.LIBUSB_ISO_SYNC_TYPE_SYNC << 2
)

Synchronization types defined by the USB spec.

func (IsoSyncType) String

func (ist IsoSyncType) String() string

String returns a human-readable description of the synchronization type.

type Milliamperes

type Milliamperes uint

Milliamperes is a unit of electric current consumption.

type OutEndpoint

type OutEndpoint struct {
	// contains filtered or unexported fields
}

OutEndpoint represents an OUT endpoint open for transfer.

func (*OutEndpoint) NewStream

func (e *OutEndpoint) NewStream(size, count int) (*WriteStream, error)

NewStream prepares a new write stream that will write data in the background. Size defines a buffer size for a single write transaction and count defines how many transactions may be active at any time. By buffering the writes, a Stream reduces the latency between subsequent transfers and increases writing throughput.

func (OutEndpoint) String

func (e OutEndpoint) String() string

String returns a human-readable description of the endpoint.

func (*OutEndpoint) Write

func (e *OutEndpoint) Write(buf []byte) (int, error)

Write writes data to an OUT endpoint. Write returns number of bytes comitted to the endpoint. Write may return non-zero length even if the returned error is not nil (partial write).

func (*OutEndpoint) WriteContext

func (e *OutEndpoint) WriteContext(ctx context.Context, buf []byte) (int, error)

WriteContext writes data to an OUT endpoint. WriteContext returns number of bytes comitted to the endpoint. WriteContext may return non-zero length even if the returned error is not nil (partial write). The passed context can be used to control the cancellation of the write. If the context is cancelled, WriteContext will cancel the underlying transfers, resulting in TransferCancelled error.

type Protocol

type Protocol uint8

Protocol is the interface class protocol, qualified by the values of interface class and subclass.

func (Protocol) String

func (p Protocol) String() string

type ReadStream

type ReadStream struct {
	// contains filtered or unexported fields
}

ReadStream is a buffer that tries to prefetch data from the IN endpoint, reducing the latency between subsequent Read()s. ReadStream keeps prefetching data until Close() is called or until an error is encountered. After Close(), the buffer might still have data left from transfers that were initiated before Close. Read()ing from the ReadStream will keep returning available data. When no more data is left, io.EOF is returned.

func (*ReadStream) Close

func (r *ReadStream) Close() error

Close signals that the transfer should stop. After Close is called, subsequent Read()s will return data from all transfers that were already in progress before returning an io.EOF error, unless another error was encountered earlier. Close cannot be called concurrently with Read.

func (*ReadStream) Read

func (r *ReadStream) Read(p []byte) (int, error)

Read reads data from the transfer stream. The data will come from at most a single transfer, so the returned number might be smaller than the length of p. After a non-nil error is returned, all subsequent attempts to read will return io.ErrClosedPipe. Read cannot be called concurrently with other Read, ReadContext or Close.

func (*ReadStream) ReadContext

func (r *ReadStream) ReadContext(ctx context.Context, p []byte) (int, error)

ReadContext reads data from the transfer stream. The data will come from at most a single transfer, so the returned number might be smaller than the length of p. After a non-nil error is returned, all subsequent attempts to read will return io.ErrClosedPipe. ReadContext cannot be called concurrently with other Read, ReadContext or Close. The context passed controls the cancellation of this particular read operation within the stream. The semantics is identical to Endpoint.ReadContext.

type Speed

type Speed int

Speed identifies the speed of the device.

const (
	SpeedUnknown Speed = C.LIBUSB_SPEED_UNKNOWN
	SpeedLow     Speed = C.LIBUSB_SPEED_LOW
	SpeedFull    Speed = C.LIBUSB_SPEED_FULL
	SpeedHigh    Speed = C.LIBUSB_SPEED_HIGH
	SpeedSuper   Speed = C.LIBUSB_SPEED_SUPER
)

Device speeds as defined in the USB spec.

func (Speed) String

func (s Speed) String() string

String returns a human-readable name of the device speed.

type TransferStatus

type TransferStatus uint8

TransferStatus contains information about the result of a transfer.

Defined Transfer status values.

func (TransferStatus) Error

func (ts TransferStatus) Error() string

Error implements the error interface.

func (TransferStatus) String

func (ts TransferStatus) String() string

String returns a human-readable transfer status.

type TransferType

type TransferType uint8

TransferType defines the endpoint transfer type.

const (
	TransferTypeControl     TransferType = C.LIBUSB_TRANSFER_TYPE_CONTROL
	TransferTypeIsochronous TransferType = C.LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
	TransferTypeBulk        TransferType = C.LIBUSB_TRANSFER_TYPE_BULK
	TransferTypeInterrupt   TransferType = C.LIBUSB_TRANSFER_TYPE_INTERRUPT
)

Transfer types defined by the USB spec.

func (TransferType) String

func (tt TransferType) String() string

String returns a human-readable name of the endpoint transfer type.

type UsageType

type UsageType uint8

UsageType defines the transfer usage type for isochronous and interrupt transfers.

const (
	// Note: USB3.0 defines usage type for both isochronous and interrupt
	// endpoints, with the same constants representing different usage types.
	// UsageType constants do not correspond to bmAttribute values.
	UsageTypeUndefined UsageType = iota
	IsoUsageTypeData
	IsoUsageTypeFeedback
	IsoUsageTypeImplicit
	InterruptUsageTypePeriodic
	InterruptUsageTypeNotification
)

Usage types for iso and interrupt transfers, defined by the USB spec.

func (UsageType) String

func (ut UsageType) String() string

type WriteStream

type WriteStream struct {
	// contains filtered or unexported fields
}

WriteStream is a buffer that will send data asynchronously, reducing the latency between subsequent Write()s.

func (*WriteStream) Close

func (w *WriteStream) Close() error

Close signals end of data to write. Close blocks until all transfers that were sent are finished. The error returned by Close is the first error encountered during writing the entire stream (if any). Close returning nil indicates all transfers completed successfully. After Close, the total number of bytes successfully written can be retrieved using Written(). Close may not be called concurrently with Write, Close or Written.

func (*WriteStream) CloseContext

func (w *WriteStream) CloseContext(ctx context.Context) error

CloseContext signals end of data to write. CloseContext blocks until all transfers that were sent are finished or until the context is canceled. The error returned by CloseContext is the first error encountered during writing the entire stream (if any). CloseContext returning nil indicates all transfers completed successfully. After CloseContext, the total number of bytes successfully written can be retrieved using Written(). CloseContext may not be called concurrently with Write, WriteContext, Close, CloseContext or Written.

func (*WriteStream) Write

func (w *WriteStream) Write(p []byte) (int, error)

Write sends the data to the endpoint. Write returning a nil error doesn't mean that data was written to the device, only that it was written to the buffer. Only a call to Close() that returns nil error guarantees that all transfers have succeeded. If the slice passed to Write does not align exactly with the transfer buffer size (as declared in a call to NewStream), the last USB transfer of this Write will be sent with less data than the full buffer. After a non-nil error is returned, all subsequent attempts to write will return io.ErrClosedPipe. If Write encounters an error when preparing the transfer, the stream will still try to complete any pending transfers. The total number of bytes successfully written can be retrieved through a Written() call after Close() has returned. Write cannot be called concurrently with another Write, Written or Close.

func (*WriteStream) WriteContext

func (w *WriteStream) WriteContext(ctx context.Context, p []byte) (int, error)

WriteContext sends the data to the endpoint. Write returning a nil error doesn't mean that data was written to the device, only that it was written to the buffer. Only a call to Close() that returns nil error guarantees that all transfers have succeeded. If the slice passed to WriteContext does not align exactly with the transfer buffer size (as declared in a call to NewStream), the last USB transfer of this Write will be sent with less data than the full buffer. After a non-nil error is returned, all subsequent attempts to write will return io.ErrClosedPipe. If WriteContext encounters an error when preparing the transfer, the stream will still try to complete any pending transfers. The total number of bytes successfully written can be retrieved through a Written() call after Close() has returned. WriteContext cannot be called concurrently with another Write, WriteContext, Written, Close or CloseContext.

func (*WriteStream) Written

func (w *WriteStream) Written() int

Written returns the number of bytes successfully written by the stream. Written may be called only after Close() or CloseContext() has been called and returned.

Directories

Path Synopsis
lsusb lists attached USB devices.
lsusb lists attached USB devices.
rawread attempts to read from the specified USB device.
rawread attempts to read from the specified USB device.
Package usbid provides human-readable text output for the usb package.
Package usbid provides human-readable text output for the usb package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL