Skip to content

Commit

Permalink
improved based on suggestions from google#126 and updated to the now-…
Browse files Browse the repository at this point in the history
…recommended libusb context creation method
  • Loading branch information
kubaraczkowski-spectricity committed Jul 19, 2024
1 parent beb6261 commit b6f20af
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 38 deletions.
55 changes: 31 additions & 24 deletions libusb.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package gousb

import (
"encoding/binary"
"fmt"
"log"
"reflect"
Expand All @@ -32,7 +33,6 @@ struct libusb_transfer *gousb_alloc_transfer_and_buffer(int bufLen, int numIsoPa
void gousb_free_transfer_and_buffer(struct libusb_transfer *xfer);
int submit(struct libusb_transfer *xfer);
void gousb_set_debug(libusb_context *ctx, int lvl);
int gousb_disable_device_discovery(libusb_context *ctx);
*/
import "C"

Expand All @@ -41,12 +41,7 @@ type libusbDevice C.libusb_device
type libusbDevHandle C.libusb_device_handle
type libusbTransfer C.struct_libusb_transfer
type libusbEndpoint C.struct_libusb_endpoint_descriptor

type libusbOpt int

const (
LIBUSB_OPTION_NO_DEVICE_DISCOVERY libusbOpt = iota
)
type libusbLogLevel C.enum_libusb_log_level

func (ep libusbEndpoint) endpointDesc(dev *DeviceDesc) EndpointDesc {
ei := EndpointDesc{
Expand Down Expand Up @@ -140,7 +135,7 @@ func (ep libusbEndpoint) endpointDesc(dev *DeviceDesc) EndpointDesc {
// and occasionally on convenience data types (like TransferType or DeviceDesc).
type libusbIntf interface {
// context
init(flags ...libusbOpt) (*libusbContext, error)
init() (*libusbContext, error)
handleEvents(*libusbContext, <-chan struct{})
getDevices(*libusbContext) ([]*libusbDevice, error)
exit(*libusbContext) error
Expand All @@ -160,7 +155,7 @@ type libusbIntf interface {
getStringDesc(*libusbDevHandle, int) (string, error)
setAutoDetach(*libusbDevHandle, int) error
detachKernelDriver(*libusbDevHandle, uint8) error
getDevice(*libusbDevHandle) (*libusbDevice, error)
getDevice(*libusbDevHandle) *libusbDevice

// interface
claim(*libusbDevHandle, uint8) error
Expand All @@ -178,19 +173,35 @@ type libusbIntf interface {
}

// libusbImpl is an implementation of libusbIntf using real CGo-wrapped libusb.
type libusbImpl struct{}
type libusbImpl struct {
logLevel int
disableDiscovery bool
useUsbDK bool
}

func (libusbImpl) init(flags ...libusbOpt) (*libusbContext, error) {
func (impl libusbImpl) init() (*libusbContext, error) {
var ctx *C.libusb_context
if err := fromErrNo(C.libusb_init(&ctx)); err != nil {
return nil, err

var libusb_options [4]C.struct_libusb_init_option // fixed to 4 - there are maximum 4 options
n_options := 0
if impl.logLevel != C.LIBUSB_LOG_LEVEL_NONE {
libusb_options[n_options].option = C.LIBUSB_OPTION_LOG_LEVEL
b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, uint64(impl.logLevel))
copy(libusb_options[n_options].value[:], b)
n_options += 1
}
if impl.useUsbDK {
libusb_options[n_options].option = C.LIBUSB_OPTION_USE_USBDK
n_options += 1
}
if impl.disableDiscovery {
libusb_options[n_options].option = C.LIBUSB_OPTION_NO_DEVICE_DISCOVERY
n_options += 1
}

for _, flag := range flags {
switch flag {
case LIBUSB_OPTION_NO_DEVICE_DISCOVERY:
C.gousb_disable_device_discovery(ctx)
}
if err := fromErrNo(C.libusb_init_context(&ctx, &(libusb_options[0]), C.int(n_options))); err != nil {
return nil, err
}

return (*libusbContext)(ctx), nil
Expand Down Expand Up @@ -243,13 +254,9 @@ func (libusbImpl) wrapSysDevice(ctx *libusbContext, fd uintptr) (*libusbDevHandl
return (*libusbDevHandle)(handle), nil
}

func (libusbImpl) getDevice(d *libusbDevHandle) (*libusbDevice, error) {
func (libusbImpl) getDevice(d *libusbDevHandle) *libusbDevice {
device := C.libusb_get_device((*C.libusb_device_handle)(d))
if device == nil {
return nil, fmt.Errorf("libusb_get_device failed")
}

return (*libusbDevice)(device), nil
return (*libusbDevice)(device)
}

func (libusbImpl) exit(c *libusbContext) error {
Expand Down
3 changes: 0 additions & 3 deletions usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,3 @@ void gousb_set_debug(libusb_context *ctx, int lvl) {
#endif
}

int gousb_disable_device_discovery(libusb_context *ctx) {
return libusb_set_option(ctx, 2);
}
38 changes: 27 additions & 11 deletions usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ type Context struct {
devices map[*Device]bool
}

// LogLevel values match the levels of libusb
type LogLevel int

const (
LogLevelNone = 0
LogLevelError = 1
LogLevelWarning = 2
LogLevelInfo = 3
LogLevelDebug = 4
)

// 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
Expand Down Expand Up @@ -168,6 +179,20 @@ func NewContext() *Context {
return newContextWithImpl(libusbImpl{})
}

type ContextOptions struct {
LogLevel LogLevel
DisableDeviceDiscovery bool
UseUsbDK bool
}

func (o *ContextOptions) NewContext() *Context {
return newContextWithImpl(libusbImpl{
disableDiscovery: o.DisableDeviceDiscovery,
logLevel: int(o.LogLevel),
useUsbDK: o.UseUsbDK,
})
}

// 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.
Expand Down Expand Up @@ -213,21 +238,12 @@ func (c *Context) OpenDevices(opener func(desc *DeviceDesc) bool) ([]*Device, er
func (c *Context) OpenDeviceWithFileDescriptor(fd uintptr) (*Device, error) {
handle, err := c.libusb.wrapSysDevice(c.ctx, fd)
if err != nil {
return nil, err
return nil, fmt.Errorf("Error opening device from file descriptor: %d, %s", fd, err.Error())
}

dev, err := c.libusb.getDevice(handle)
if err != nil {
return nil, err
}
dev := c.libusb.getDevice(handle)

desc, err := c.libusb.getDeviceDesc(dev)
defer c.libusb.dereference(dev)
if err != nil {
return nil, err
}

handle, err = c.libusb.open(dev)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit b6f20af

Please sign in to comment.