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.
This commit is contained in:
112
rawread/main.go
112
rawread/main.go
@@ -20,18 +20,23 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/kylelemons/gousb/usb"
|
"github.com/kylelemons/gousb/usb"
|
||||||
"github.com/kylelemons/gousb/usbid"
|
"github.com/kylelemons/gousb/usbid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
device = flag.String("device", "vend:prod", "Device to which to connect")
|
vid = flag.Uint("vid", 0, "VID of the device to which to connect. Exclusive with bus/addr flags.")
|
||||||
config = flag.Int("config", 1, "Endpoint to which to connect")
|
pid = flag.Uint("pid", 0, "PID of the device to which to connect. Exclusive with bus/addr flags.")
|
||||||
iface = flag.Int("interface", 0, "Endpoint to which to connect")
|
bus = flag.Uint("bus", 0, "Bus number for the device to which to connect. Exclusive with vid/pid flags.")
|
||||||
setup = flag.Int("setup", 0, "Endpoint to which to connect")
|
addr = flag.Uint("addr", 0, "Address of the device to which to connect. Exclusive with vid/pid flags.")
|
||||||
endpoint = flag.Int("endpoint", 1, "Endpoint to which to connect")
|
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")
|
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() {
|
func main() {
|
||||||
@@ -43,40 +48,29 @@ func main() {
|
|||||||
|
|
||||||
ctx.Debug(*debug)
|
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.
|
// ListDevices is used to find the devices to open.
|
||||||
devs, err := ctx.ListDevices(func(desc *usb.Descriptor) bool {
|
devs, err := ctx.ListDevices(func(desc *usb.Descriptor) bool {
|
||||||
if fmt.Sprintf("%s:%s", desc.Vendor, desc.Product) != *device {
|
switch {
|
||||||
return false
|
case usb.ID(*vid) == desc.Vendor && usb.ID(*pid) == desc.Product:
|
||||||
|
return true
|
||||||
|
case uint8(*bus) == desc.Bus && uint8(*addr) == desc.Address:
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
// 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
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// All Devices returned from ListDevices must be closed.
|
// All Devices returned from ListDevices must be closed.
|
||||||
defer func() {
|
defer func() {
|
||||||
for _, d := range devs {
|
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 {
|
if err != nil {
|
||||||
log.Fatalf("list: %s", err)
|
log.Printf("Warning: ListDevices: %s.", err)
|
||||||
}
|
}
|
||||||
|
switch {
|
||||||
if len(devs) == 0 {
|
case len(devs) == 0:
|
||||||
log.Fatalf("no devices found")
|
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]
|
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("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))
|
ep, err := dev.OpenEndpoint(uint8(*config), uint8(*iface), uint8(*setup), uint8(*endpoint)|uint8(usb.ENDPOINT_DIR_IN))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("open: %s", err)
|
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])
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user