diff --git a/device.go b/device.go index 4180b11..e70ac54 100644 --- a/device.go +++ b/device.go @@ -240,6 +240,18 @@ func (d *Device) GetStringDescriptor(descIndex int) (string, error) { return d.ctx.libusb.getStringDesc(d.handle, descIndex) } +// GetDescriptor returns a device descriptor with the given index number. +func (d *Device) GetDescriptor(descIndex int) ([]byte, error) { + if d.handle == nil { + return nil, fmt.Errorf("GetDescriptor(%d) called on %s after Close", descIndex, d) + } + // descriptor index value of 0 indicates no string descriptor. + if descIndex == 0 { + return nil, nil + } + return d.ctx.libusb.getDescriptor(d.handle, descIndex) +} + // Manufacturer returns the device's manufacturer name. // GetStringDescriptor's string conversion rules apply. func (d *Device) Manufacturer() (string, error) { diff --git a/libusb.go b/libusb.go index ddc0b2a..80e7bd6 100644 --- a/libusb.go +++ b/libusb.go @@ -150,6 +150,7 @@ type libusbIntf interface { getConfig(*libusbDevHandle) (uint8, error) setConfig(*libusbDevHandle, uint8) error getStringDesc(*libusbDevHandle, int) (string, error) + getDescriptor(*libusbDevHandle, int) ([]byte, error) setAutoDetach(*libusbDevHandle, int) error detachKernelDriver(*libusbDevHandle, uint8) error @@ -413,6 +414,22 @@ func (libusbImpl) getStringDesc(d *libusbDevHandle, index int) (string, error) { return string(buf[:errno]), nil } +func (libusbImpl) getDescriptor(d *libusbDevHandle, index int) ([]byte, error) { + // allocate 256-byte array limited the length of descriptor + buf := make([]byte, 256) + // get descriptor from libusb. if errno < 0 then there are any errors. + // if errno >= 0; it is a length of result descriptor + errno := C.libusb_get_descriptor( + (*C.libusb_device_handle)(d), + C.uint8_t(index), 0, + (*C.uchar)(unsafe.Pointer(&buf[0])), + 256) + if errno < 0 { + return nil, fmt.Errorf("failed to get descriptor %d: %s", index, fromErrNo(errno)) + } + return buf[:errno], nil +} + func (libusbImpl) setAutoDetach(d *libusbDevHandle, val int) error { err := fromErrNo(C.libusb_set_auto_detach_kernel_driver((*C.libusb_device_handle)(d), C.int(val))) if err != nil && err != ErrorNotSupported {