The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

USB::LibUSB - Perl interface to the libusb-1.0 API.

SYNOPSIS

 use USB::LibUSB;

 #
 # simple program to list all devices on the USB
 #
 
 my $ctx = USB::LibUSB->init();
 my @devices = $ctx->get_device_list();
 
 for my $dev (@devices) {
     my $bus_number = $dev->get_bus_number();
     my $device_address = $dev->get_device_address();
     my $desc = $dev->get_device_descriptor();
     my $idVendor = $desc->{idVendor};
     my $idProduct = $desc->{idProduct};
     
     printf("Bus %03d Device %03d: ID %04x:%04x\n", $bus_number,
            $device_address, $idVendor, $idProduct);
 }
    
 #
 # Synchronous bulk transfers
 #

 my $ctx = USB::LibUSB->init();
 my $handle = $ctx->open_device_with_vid_pid(0x1111, 0x2222);

 $handle->set_auto_detach_kernel_driver(1); # Linux only

 # We want to use interface 0
 $handle->claim_interface(0);

 $handle->bulk_transfer_write($endpoint, $data, $timeout);
 my $data = $handle->bulk_transfer_read($endpoint, $length, $timeout);
 

DESCRIPTION

This module provides a Perl interface to the libusb-1.0 API. It provides access to most basic libusb functionality including read-out of device descriptors and synchronous device I/O.

The design of the module is basically a two-tier system:

USB::LibUSB::XS

Raw XS interface, stay as close at possible to the libusb API. Not intended to be used directly.

USB::LibUSB

Based on USB::LibUSB::XS, adds convenient error handling and additional high-level functionality (e.g. device discovery with vid, pid and serial number). Easy to build more functionality without knowing about XS.

INSTALLATION

Prerequisites

Linux/UNIX

This requires libusb (>= 1.0.17) development files and pkg-config installed.

On Debian like Linux:

 $ apt-get install libusb-1.0-0-dev pkg-config

On Cygwin you need the pkg-config, libusb1.0-devel and libcrypt-devel packages.

Windows

On Windows you have to manually download the libusb binaries from http://libusb.info and extract them somewhere.

Assuming that the location of the extracted libusb folder is C:\Users\simon\libusb-1.0, you need to set the USB_LIBUSB_INCLUDE and USB_LIBUSB_LIB environment variables as follows:

 > SET USB_LIBUSB_INCLUDE=-IC:\Users\simon\libusb-1.0\include\libusb-1.0
 > SET USB_LIBUSB_LIB=-lC:\Users\simon\libusb-1.0\MinGW64\dll\libusb-1.0.dll.a

You will also need to add

 C:\Users\simon\libusb-1.0\MinGW64\dll

to the Path environment variable.

For StrawberryPerl, version 5.26 or newer is required (see https://rt.cpan.org/Public/Bug/Display.html?id=121219).

Driver Installation

On Windows you need an additional driver to use a device with libusb. See the Windows section in the libusb wiki.

Building USB::LibUSB

The rest of the installation can be done by a CPAN client like cpanm:

 $ cpanm USB::LibUSB

 

METHODS/FUNCTIONS

Library initialization/deinitialization

set_debug

 $ctx->set_debug(LIBUSB_LOG_LEVEL_DEBUG);

init

 my $ctx = USB::LibUSB->init();

exit

 $ctx->exit();

last_retval

 my $retval = $ctx->last_retval();

Get return value of last called libusb function.

Device handling and enumeration

get_device_list

 my @device_list = $ctx->get_device_list();

Returned elements are USB::LibUSB::Device objects.

get_bus_number

 my $bus_number = $dev->get_bus_number();

get_port_number

 my $port_number = $dev->get_port_number();

get_port_numbers

 my @port_numbers = $dev->get_port_numbers();

get_parent

 my $parent_dev = $dev->get_parent();

get_device_address

 my $address = $dev->get_device_address();

get_device_speed

 my $speed = $dev->get_device_speed();

get_max_packet_size

 my $size = $dev->get_max_packet_size($endpoint);

get_max_iso_packet_size

 my $size = $dev->get_max_iso_packet_size($endpoint);

ref_device

 $dev->ref_device();

unref_device

 $dev->unref_device();

open

 my $handle = $dev->open();

Return a USB::LibUSB::Device::Handle object.

open_device_with_vid_pid

 my $handle = $ctx->open_device_with_vid_pid(0x1111, 0x2222);

Return a USB::LibUSB::Device::Handle object. If the vid:pid combination is not unique, return the first device which is found.

open_device_with_vid_pid_unique

 my $handle = $ctx->open_device_with_vid_pid_unique(0x1111, 0x2222);

Like open_device_with_vid_pid, but croak in case of multiple devices with this vid:pid combination.

open_device_with_vid_pid_serial

 my $handle = $ctx->open_device_with_vid_pid_serial(0x0957, 0x0607, "MY47000419");

Like open_device_with_vid_pid, but also requires a serial number.

close

 $handle->close();

get_device

 my $dev = $handle->get_device();

get_configuration

 my $config = $handle->get_configuration();

set_configuration

 $handle->set_configuration($config);

claim_interface

 $handle->claim_interface($interface_number);

release_interface

 $handle->release_interface($interface_number);

set_interface_alt_setting

 $handle->set_interface_alt_setting($interface_number, $alternate_setting);

clear_halt

 $handle->clear_halt($endpoint);

reset_device

 $handle->reset_device();

kernel_driver_active

 my $is_active = $handle->kernelt_driver_active($interface_number);

detach_kernel_driver

 $handle->detach_kernel_driver($interface_number);

attach_kernel_driver

 $handle->attach_kernel_driver($interface_number);

set_auto_detach_kernel_driver

 $handle->set_auto_detach_kernel_driver($enable);

Throws exception on Windows and Darwin.

Miscellaneous

libusb_has_capability

 my $has_cap = libusb_has_capability($capability);

libusb_error_name

 my $error_name = libusb_error_name($error_code);

libusb_get_version

 my $version_hash = libusb_get_version();

Return hashref $version_hash with the following keys:

major
minor
micro
nano
rc

libusb_setlocale

 my $rv = libusb_setlocale($locale);

libusb_strerror

 my $strerror = libusb_strerror($error_code);

USB descriptors

All descriptors are returned as hash references.

get_device_descriptor

 my $desc = $dev->get_device_descriptor();

Return hashref $desc with the following keys

bLength
bDescriptorType
bcdUSB
bDeviceClass
bDeviceSubClass
bDeviceProtocol
bMaxPacketSize0
idVendor
idProduct
bcdDevice
iManufacturer
iProduct
iSerialNumber
bNumConfigurations

All keys hold a scalar value.

get_active_config_descriptor

 my $config = $dev->get_active_config_descriptor();

Return hashref $config with the following keys:

bLength
bDescriptorType
wTotalLength
bNumInterfaces
bConfigurationValue
iConfiguration
bmAttributes
MaxPower
interface
extra

With the exception of interface, all values are scalars. interface holds an arrayref of bNumInterfaces interface descriptors. Each interface consists of an array of alternate settings. These are hashrefs with the following keys:

bLength
bDescriptorType
bInterfaceNumber
bAlternateSetting
bNumEndpoints
bInterfaceClass
bInterfaceSubClass
bInterfaceProtocol
iInterface
endpoint
extra

With the exception of endpoint, all values are scalars. endpoint holds an arrayref of endpoint descriptors. These are hashrefs with the following keys:

bLength
bDescriptorType
bEndpointAddress
bmAttributes
wMaxPacketSize
bInterval
bRefresh
bSynchAddress
extra

All values are scalars. If the endpoint supports USB 3.0 SuperSpeed, the hashref will contain an additional key superspeed which holds a SuperSpeed Endpoint Companion descriptor with the following keys:

bLength
bDescriptorType
bMaxBurst
bmAttributes
wBytesPerInterval

Example

Dump $config with YAML::XS:

 use YAML::XS;
 print Dump($config);
 

For a Linux Foundation 3.0 root hub:

 ---
 MaxPower: 0
 bConfigurationValue: 1
 bDescriptorType: 2
 bLength: 9
 bNumInterfaces: 1
 bmAttributes: 224
 extra: ~
 iConfiguration: 0
 interface:
 - - bAlternateSetting: 0
     bDescriptorType: 4
     bInterfaceClass: 9
     bInterfaceNumber: 0
     bInterfaceProtocol: 0
     bInterfaceSubClass: 0
     bLength: 9
     bNumEndpoints: 1
     endpoint:
     - bDescriptorType: 5
       bEndpointAddress: 129
       bInterval: 12
       bLength: 7
       bRefresh: 0
       bSynchAddress: 0
       bmAttributes: 3
       extra: "\x060\0\0\x02\0"
       ss_endpoint_companion:
         bDescriptorType: 48
         bLength: 6
         bMaxBurst: 0
         bmAttributes: 0
         wBytesPerInterval: 2
       wMaxPacketSize: 4
     extra: ~
     iInterface: 0
 wTotalLength: 31
 

get_config_descriptor

 my $config = $dev->get_config_descriptor($config_index);

Return config descriptor as hashref.

get_config_descriptor_by_value

 my $config = $dev->get_config_descriptor_by_value($bConfigurationValue);

Return config descriptor as hashref.

get_bos_descriptor

 my $bos = $handle->get_bos_descriptor();

Return BOS descriptor as hashref with the following keys:

bLength
bDescriptorType
wTotalLength
bNumDeviceCaps
dev_capability

dev_capability holds an arrayref of BOS Device Capability descriptors. They have the following keys:

bLength
bDescriptorType
bDevCapabilityType
dev_capability_data

Additional parsing of the capability data is performed if bDevCapabilityType has one of the following values:

LIBUSB_BT_USB_2_0_EXTENSION

The hashref will contain a key usb_2_0_extension.

LIBUSB_BT_SS_USB_DEVICE_CAPABILITY

The hashref will contain a key ss_usb_device_capability.

LIBUSB_BT_CONTAINER_ID

The hashref will contain a key container_id.

Example

Dump $bos with YAML::XS:

 use YAML::XS;
 print Dump($bos);
 

For a Linux Foundation 3.0 root hub:

 bDescriptorType: 15
 bLength: 5
 bNumDeviceCaps: 1
 dev_capability:
 - bDescriptorType: 16
   bDevCapabilityType: 3
   bLength: 10
   dev_capability_data: "\x02\b\0\x03\0\0\0"
   ss_usb_device_capability:
     bDescriptorType: 16
     bDevCapabilityType: 3
     bFunctionalitySupport: 3
     bLength: 10
     bU1DevExitLat: 0
     bU2DevExitLat: 0
     bmAttributes: 2
     wSpeedSupported: 8
 wTotalLength: 15

get_string_descriptor_ascii

 my $data = $handle->get_string_descriptor_ascii($desc_index, $length);

get_descriptor

 my $data = $handle->get_descriptor($desc_type, $desc_index, $length);

get_string_descriptor

 my $data = $handle->get_string_descriptor($desc_index, $langid, $length);

 

Device hotplug event notification

To be implemented.

Asynchronous device I/O

To be implemented.

Polling and timing

To be implemented.

Synchronous device I/O

control_transfer_write

 $handle->control_transfer_write($bmRequestType, $bRequest, $wValue, $wIndex, $data, $timeout);

control_transfer_read

 my $data = $handle->control_transfer_read($bmRequestType, $bRequest, $wValue, $wIndex, $length, $timeout);
 

bulk_tranfer_write

 my $transferred = $handle->bulk_transfer_write($endpoint, $data, $timeout);
 

bulk_transfer_read

 my $data = $handle->bulk_transfer_read($endpoint, $length, $timeout);
 

interrupt_transfer_write

 my $transferred = $handle->interrupt_transfer_write($endpoint, $data, $timeout);

interrupt_transfer_read

 my $data = $handle->interrupt_transfer_read($endpoint, $length, $timeout);

REPORTING BUGS

Please report bugs at https://github.com/lab-measurement/USB-LibUSB/issues.

CONTACT

Feel free to contact us at the #labmeasurement channel on Freenode IRC.

AUTHOR

Simon Reinhardt, <simon.reinhardt@physik.uni-r.de>

COPYRIGHT AND LICENSE

Copyright (C) 2017 by Simon Reinhardt

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.24.0 or, at your option, any later version of Perl 5 you may have available.