From 1755936932ccfbc03ab045b29b386eafcab1599e Mon Sep 17 00:00:00 2001 From: Sebastian Zagrodzki Date: Wed, 8 Feb 2017 22:30:03 +0100 Subject: [PATCH] Change how device is addressed, add alternative --bus/--addr flags. Print all diagnostics to the log (stderr). Capture the data from the specified endpoint and print it to stdout. --- rawread/main.go | 112 ++++++++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 42 deletions(-) diff --git a/rawread/main.go b/rawread/main.go index 8a2efac..55ab813 100644 --- a/rawread/main.go +++ b/rawread/main.go @@ -20,18 +20,23 @@ import ( "flag" "fmt" "log" + "os" "github.com/kylelemons/gousb/usb" "github.com/kylelemons/gousb/usbid" ) var ( - device = flag.String("device", "vend:prod", "Device to which to connect") - config = flag.Int("config", 1, "Endpoint to which to connect") - iface = flag.Int("interface", 0, "Endpoint to which to connect") - setup = flag.Int("setup", 0, "Endpoint to which to connect") - endpoint = flag.Int("endpoint", 1, "Endpoint to which to connect") + vid = flag.Uint("vid", 0, "VID of the device to which to connect. Exclusive with bus/addr flags.") + pid = flag.Uint("pid", 0, "PID of the device to which to connect. Exclusive with bus/addr flags.") + bus = flag.Uint("bus", 0, "Bus number for the device to which to connect. Exclusive with vid/pid flags.") + addr = flag.Uint("addr", 0, "Address of the device to which to connect. Exclusive with vid/pid flags.") + config = flag.Uint("config", 1, "Endpoint to which to connect") + iface = flag.Uint("interface", 0, "Endpoint to which to connect") + setup = flag.Uint("setup", 0, "Endpoint to which to connect") + endpoint = flag.Uint("endpoint", 1, "Endpoint to which to connect") debug = flag.Int("debug", 3, "Debug level for libusb") + size = flag.Uint("read_size", 1024, "Maximum number of bytes of data to read. Collected will be printed to STDOUT.") ) func main() { @@ -43,40 +48,29 @@ func main() { ctx.Debug(*debug) - log.Printf("Scanning for device %q...", *device) + var devName string + switch { + case *vid == 0 && *pid == 0 && *bus == 0 && *addr == 0: + log.Fatal("You need to specify the device, either through --vid/--pid flags or through --bus/--addr flags.") + case (*vid > 0 || *pid > 0) && (*bus > 0 || *addr > 0): + log.Fatal("You can't use --vid/--pid flags at the same time as --bus/--addr.") + case *vid > 0 || *pid > 0: + devName = fmt.Sprintf("VID:PID %04x:%04x", *vid, *pid) + default: + devName = fmt.Sprintf("bus:addr %d:%d", *bus, *addr) + } + log.Printf("Scanning for device %q...", devName) // ListDevices is used to find the devices to open. devs, err := ctx.ListDevices(func(desc *usb.Descriptor) bool { - if fmt.Sprintf("%s:%s", desc.Vendor, desc.Product) != *device { - return false + switch { + case usb.ID(*vid) == desc.Vendor && usb.ID(*pid) == desc.Product: + return true + case uint8(*bus) == desc.Bus && uint8(*addr) == desc.Address: + return true } - - // The usbid package can be used to print out human readable information. - fmt.Printf(" Protocol: %s\n", usbid.Classify(desc)) - - // The configurations can be examined from the Descriptor, though they can only - // be set once the device is opened. All configuration references must be closed, - // to free up the memory in libusb. - for _, cfg := range desc.Configs { - // This loop just uses more of the built-in and usbid pretty printing to list - // the USB devices. - fmt.Printf(" %s:\n", cfg) - for _, alt := range cfg.Interfaces { - fmt.Printf(" --------------\n") - for _, iface := range alt.Setups { - fmt.Printf(" %s\n", iface) - fmt.Printf(" %s\n", usbid.Classify(iface)) - for _, end := range iface.Endpoints { - fmt.Printf(" %s\n", end) - } - } - } - fmt.Printf(" --------------\n") - } - - return true + return false }) - // All Devices returned from ListDevices must be closed. defer func() { for _, d := range devs { @@ -84,22 +78,56 @@ func main() { } }() - // ListDevices can occaionally fail, so be sure to check its return value. + // ListDevices can occasionally fail, so be sure to check its return value. if err != nil { - log.Fatalf("list: %s", err) + log.Printf("Warning: ListDevices: %s.", err) } - - if len(devs) == 0 { - log.Fatalf("no devices found") + switch { + case len(devs) == 0: + log.Fatal("No matching devices found.") + case len(devs) > 1: + log.Printf("Warning: multiple devices found. Using bus %d, addr %d.", devs[0].Bus, devs[0].Address) + for _, d := range devs[1:] { + d.Close() + } + devs = devs[:1] } - dev := devs[0] + // The usbid package can be used to print out human readable information. + log.Printf(" Protocol: %s\n", usbid.Classify(dev.Descriptor)) + + // The configurations can be examined from the Descriptor, though they can only + // be set once the device is opened. All configuration references must be closed, + // to free up the memory in libusb. + for _, cfg := range dev.Configs { + // This loop just uses more of the built-in and usbid pretty printing to list + // the USB devices. + log.Printf(" %s:\n", cfg) + for _, alt := range cfg.Interfaces { + log.Printf(" --------------\n") + for _, iface := range alt.Setups { + log.Printf(" %s\n", iface) + log.Printf(" %s\n", usbid.Classify(iface)) + for _, end := range iface.Endpoints { + log.Printf(" %s\n", end) + } + } + } + log.Printf(" --------------\n") + } + log.Printf("Connecting to endpoint...") - log.Printf("- %#v", dev.Descriptor) ep, err := dev.OpenEndpoint(uint8(*config), uint8(*iface), uint8(*setup), uint8(*endpoint)|uint8(usb.ENDPOINT_DIR_IN)) if err != nil { log.Fatalf("open: %s", err) } - _ = ep + + buf := make([]byte, *size) + num, err := ep.Read(buf) + if err != nil { + log.Fatalf("Reading from device failed: %v", err) + } + log.Printf("Read %d bytes of data", num) + os.Stdout.Write(buf[:num]) }