diff --git a/demo.go b/demo.go index 229faaf..a86d23c 100644 --- a/demo.go +++ b/demo.go @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . +//go:build none // +build none package main @@ -71,6 +72,7 @@ func main() { fmt.Printf(" Vendor ID: %#04x\n", raw.VendorID) fmt.Printf(" Product ID: %#04x\n", raw.ProductID) fmt.Printf(" Interface: %d\n", raw.Interface) + fmt.Printf(" Serial: %s\n", raw.Serial) fmt.Println(strings.Repeat("-", 128)) } } diff --git a/raw_enabled.go b/raw_enabled.go index 54c02eb..021f61a 100644 --- a/raw_enabled.go +++ b/raw_enabled.go @@ -56,7 +56,7 @@ func enumerateRaw(vendorID uint16, productID uint16) ([]DeviceInfo, error) { // to every matched device so they may selectively be opened on request. func enumerateRawWithRef(vendorID uint16, productID uint16) ([]DeviceInfo, error) { // Ensure we have a libusb context to interact through. The enumerate call is - // protexted by a mutex outside, so it's fine to do the below check and init. + // protected by a mutex outside, so it's fine to do the below check and init. if C.ctx == nil { if err := fromRawErrno(C.libusb_init((**C.libusb_context)(&C.ctx))); err != nil { return nil, fmt.Errorf("failed to initialize libusb: %v", err) @@ -129,10 +129,6 @@ func enumerateRawWithRef(vendorID uint16, productID uint16) ([]DeviceInfo, error } var reader, writer *uint8 for _, end := range ends { - // Skip any non-interrupt endpoints - if end.bmAttributes != C.LIBUSB_TRANSFER_TYPE_INTERRUPT { - continue - } if end.bEndpointAddress&C.LIBUSB_ENDPOINT_IN == C.LIBUSB_ENDPOINT_IN { reader = new(uint8) *reader = uint8(end.bEndpointAddress) @@ -146,17 +142,38 @@ func enumerateRawWithRef(vendorID uint16, productID uint16) ([]DeviceInfo, error // Enumeration matched, bump the device refcount to avoid cleaning it up C.libusb_ref_device(dev) + // Open the device to get ascii serial number + var handle *C.libusb_device_handle + if err := fromRawErrno(C.libusb_open(dev, &handle)); err != nil { + continue + } + defer C.libusb_close(handle) + var serialString string + if desc.iSerialNumber > 0 { + serial := make([]byte, 256) + ret := C.libusb_get_string_descriptor_ascii(handle, C.uint8_t(desc.iSerialNumber), (*C.uint8_t)(&serial[0]), C.int(len(serial))) + if ret < 0 { + continue + } + // Convert to string + serialString = string(serial[:ret]) + } + port := uint8(C.libusb_get_port_number(dev)) - infos = append(infos, DeviceInfo{ + + deviceInfo := DeviceInfo{ Path: fmt.Sprintf("%04x:%04x:%02d", uint16(desc.idVendor), uint16(desc.idProduct), port), VendorID: uint16(desc.idVendor), ProductID: uint16(desc.idProduct), Interface: ifacenum, + Serial: serialString, rawDevice: dev, rawPort: &port, rawReader: reader, rawWriter: writer, - }) + } + + infos = append(infos, deviceInfo) } } }