view release on metacpan or search on metacpan
t/07-list_devices_if.t
t/08-get_busses.t
t/09-usb-bus.t
t/10-usb-device-accessors.t
t/11-usb-device-methods.t
t/12-constants.t
t/13-bus_find_device_if.t
t/14-bus_list_devices_if.t
t/15-usb_dev_configuration.t
t/16-usb_dev_interface.t
t/17-usb_dev_endpoint.t
t/18-usb_device-configurations.t
t/TestTools.pm
xt/boilerplate.t
xt/critic.t
xt/hasversion.t
xt/podcoverage.t
xt/pod.t
USB.pm
META.json Module JSON meta-data (added by MakeMaker)
lib/Device/USB.pm view on Meta::CPAN
This class method enables low-level debugging messages from the library
interface code.
=over 4
=item level
0 disables debugging, 1 enables some debug messages, and 2 enables verbose
debug messages
Any other values are forced to the nearest endpoint.
=back
=cut
sub debug_mode
{
my ($class, $level) = @_;
lib_debug_mode( $level );
lib/Device/USB.pm view on Meta::CPAN
=item libusb_get_string(void *dev, int index, int langid, char *buf, size_t buflen)
=item libusb_get_string_simple(void *dev, int index, char *buf, size_t buflen)
=item libusb_get_descriptor(void *dev, unsigned char type, unsigned char index, char *buf, int size)
=item libusb_get_descriptor_by_endpoint(void *dev, int ep, unsigned char type, unsigned char index, char *buf, int size)
=item libusb_bulk_write(void *dev, int ep, char *bytes, int size, int timeout)
=item libusb_bulk_read(void *dev, int ep, char *bytes, int size, int timeout)
=item libusb_interrupt_write(void *dev, int ep, char *bytes, int size, int timeout)
lib/Device/USB.pm view on Meta::CPAN
);
}
return usb_get_string_simple((usb_dev_handle *)dev, index, buf, buflen);
}
int libusb_get_descriptor(void *dev, unsigned char type, unsigned char index, char *buf, int size)
{
return usb_get_descriptor((usb_dev_handle *)dev, type, index, buf, size);
}
int libusb_get_descriptor_by_endpoint(void *dev, int ep, unsigned char type, unsigned char index, char *buf, int size)
{
return usb_get_descriptor_by_endpoint((usb_dev_handle *)dev, ep, type, index, buf, size);
}
int libusb_bulk_write(void *dev, int ep, char *bytes, int size, int timeout)
{
return usb_bulk_write((usb_dev_handle *)dev, ep, bytes, size, timeout);
}
int libusb_bulk_read(void *dev, int ep, char *bytes, int size, int timeout)
{
return usb_bulk_read((usb_dev_handle *)dev, ep, bytes, size, timeout);
lib/Device/USB.pm view on Meta::CPAN
hashStoreBcd( hash, "bcdDevice", dev->descriptor.bcdDevice );
hashStoreInt( hash, "iManufacturer", dev->descriptor.iManufacturer );
hashStoreInt( hash, "iProduct", dev->descriptor.iProduct );
hashStoreInt( hash, "iSerialNumber", dev->descriptor.iSerialNumber );
hashStoreInt( hash, "bNumConfigurations", dev->descriptor.bNumConfigurations );
return newRV_noinc( (SV*)hash );
}
/*
* Given a pointer to a usb_endpoint_descriptor struct, create a reference
* to a Device::USB::DevEndpoint object that represents it.
*/
static SV* build_endpoint( struct usb_endpoint_descriptor* endpt )
{
HV* hash = newHV();
hashStoreInt( hash, "bDescriptorType", endpt->bDescriptorType );
hashStoreInt( hash, "bEndpointAddress", endpt->bEndpointAddress );
hashStoreInt( hash, "bmAttributes", endpt->bmAttributes );
hashStoreInt( hash, "wMaxPacketSize", endpt->wMaxPacketSize );
hashStoreInt( hash, "bInterval", endpt->bInterval );
hashStoreInt( hash, "bRefresh", endpt->bRefresh );
hashStoreInt( hash, "bSynchAddress", endpt->bSynchAddress );
return sv_bless( newRV_noinc( (SV*)hash ),
gv_stashpv( "Device::USB::DevEndpoint", 1 )
);
}
/*
* Given a pointer to an array of usb_endpoint_descriptor structs, create a
* reference to a Perl array containing the same data.
*/
static SV* list_endpoints( struct usb_endpoint_descriptor* endpt, unsigned count )
{
AV* array = newAV();
unsigned i = 0;
for(i=0; i < count; ++i)
{
av_push( array, build_endpoint( endpt+i ) );
}
return newRV_noinc( (SV*)array );
}
/*
* Build the object that contains the interface descriptor.
*
* inter - the usb_interface_descriptor describing this interface.
lib/Device/USB.pm view on Meta::CPAN
HV* hash = newHV();
hashStoreInt( hash, "bDescriptorType", inter->bDescriptorType );
hashStoreInt( hash, "bInterfaceNumber", inter->bInterfaceNumber );
hashStoreInt( hash, "bAlternateSetting", inter->bAlternateSetting );
hashStoreInt( hash, "bNumEndpoints", inter->bNumEndpoints );
hashStoreInt( hash, "bInterfaceClass", inter->bInterfaceClass );
hashStoreInt( hash, "bInterfaceSubClass", inter->bInterfaceSubClass );
hashStoreInt( hash, "bInterfaceProtocol", inter->bInterfaceProtocol );
hashStoreInt( hash, "iInterface", inter->iInterface );
hashStoreSV( hash, "endpoints",
list_endpoints( inter->endpoint, inter->bNumEndpoints )
);
/* TODO: handle the 'extra' data */
return sv_bless( newRV_noinc( (SV*)hash ),
gv_stashpv( "Device::USB::DevInterface", 1 )
);
}
/*
* Given a pointer to an array of usb_interface structs, create a
lib/Device/USB/DevEndpoint.pm view on Meta::CPAN
require 5.006;
use warnings;
use strict;
use Carp;
=encoding utf8
=head1 Device::USB::DevEndpoint
This class encapsulates a USB Device endpoint and the methods that object
would support.
=head1 NAME
Device::USB::DevEndpoint - Access a device endpoint returned by libusb.
=head1 VERSION
Version 0.38
=cut
our $VERSION=0.38;
=head1 SYNOPSIS
Device::USB:DevEndpoint provides a Perl object for accessing an endpoint
of an interface of a USB device using the libusb library.
use Device::USB;
my $usb = Device::USB->new();
my $dev = $usb->find_device( $VENDOR, $PRODUCT );
printf "Device: %04X:%04X\n", $dev->idVendor(), $dev->idProduct();
$dev->open();
my $cfg = $dev->config()->[0];
my $inter = $cfg->interfaces()->[0]->[0];
my $ep = $inter->endpoints()->[0];
print "Endpoint:", $inter->bEndpointAddress(),
" name: ", $dev->get_string_simple($iter->iInterface()), "\n";
See USB specification for an explanation of the attributes of an
endpoint.
=head1 DESCRIPTION
This module defines a Perl object that represents the data associated with
a USB interface endpoint. The object provides read-only access to the
important data associated with the endpoint.
=head2 METHODS
There are several accessor methods that return data from the interface.
Each is named after the field that they return. These accessors include:
=cut
# I need to build a lot of accessors
sub _make_descr_accessor
lib/Device/USB/DevInterface.pm view on Meta::CPAN
my $usb = Device::USB->new();
my $dev = $usb->find_device( $VENDOR, $PRODUCT );
printf "Device: %04X:%04X\n", $dev->idVendor(), $dev->idProduct();
$dev->open();
my $cfg = $dev->config()->[0];
my $inter = $cfg->interfaces()->[0];
print "Interface:", $inter->bInterfaceNumber(),
" name: ", $dev->get_string_simple($iter->iInterface()),
": endpoint count: ", $inter->nNumEndpoints(), "\n";
See USB specification for an explanation of the attributes of an
interface.
=head1 DESCRIPTION
This module defines a Perl object that represents the data associated with
a USB device configuration's interface. The object provides read-only access
to the important data associated with the interface.
lib/Device/USB/DevInterface.pm view on Meta::CPAN
The 0-based number of this interface.
=item bAlternateSetting
Value used to select this alternate setting for the interface specified
in bInterfaceNumber.
=item bNumEndpoints
Number of endpoints (excluding endpoint 0) available on this interface.
If the value is 0, only the control interface is supported.
=item bInterfaceClass
Class code as specified by the USB-IF. A value of 0xff is a vendor-specific
interface class.
=item bInterfaceSubClass
Subclass code specified by the USB-IF. If bInterfaceClass is not 0xff,
lib/Device/USB/DevInterface.pm view on Meta::CPAN
=cut
_make_descr_accessor( 'bInterfaceNumber' );
_make_descr_accessor( 'bAlternateSetting' );
_make_descr_accessor( 'bNumEndpoints' );
_make_descr_accessor( 'bInterfaceClass' );
_make_descr_accessor( 'bInterfaceSubClass' );
_make_descr_accessor( 'bInterfaceProtocol' );
_make_descr_accessor( 'iInterface' );
=item endpoints
Returns a list of endpoint objects associated with this interface.
=cut
sub endpoints
{
my $self = shift;
return wantarray ? @{$self->{endpoints}} : $self->{endpoints};
}
=back
=head1 DIAGNOSTICS
This is an explanation of the diagnostic and error messages this module
can generate.
=head1 DEPENDENCIES
lib/Device/USB/Device.pm view on Meta::CPAN
{
my $self = shift;
my $alternate = shift;
$self->_assert_open();
return Device::USB::libusb_set_altinterface( $self->{handle}, $alternate );
}
=item clear_halt
Clears any halt status on the supplied endpoint.
=over 4
=item alternate
the integer specified bEndpointAddress descriptor field.
=back
returns 0 on success or <0 on error
lib/Device/USB/Device.pm view on Meta::CPAN
my $retlen = Device::USB::libusb_get_descriptor(
$self->{handle}, $type, $index, $buf, MAX_BUFFER_SIZE
);
return if $retlen < 0;
return substr( $buf, 0, $retlen );
}
=item get_descriptor_by_endpoint
Retrieve an endpoint-specific descriptor from the device
=over 4
=item ep
Endpoint to query.
=item type
The type of descriptor to retrieve.
lib/Device/USB/Device.pm view on Meta::CPAN
=back
TODO: This method needs major rewrite to be Perl-ish.
I need to provide a better way to specify the type (or at least document
which are available), and I need to return a Perl data structure, not
a buffer of binary data.
=cut
sub get_descriptor_by_endpoint
{
my $self = shift;
my $ep = shift;
my $type = shift;
my $index = shift;
$self->_assert_open();
my $buf = "\0" x MAX_BUFFER_SIZE;
my $retlen = Device::USB::libusb_get_descriptor_by_endpoint(
$self->{handle}, $ep, $type, $index, $buf, MAX_BUFFER_SIZE
);
return if $retlen < 0;
return substr( $buf, 0, $retlen );
}
=item bulk_read
Perform a bulk read request from the specified endpoint.
=over 4
=item ep
The number of the endpoint to read
=item bytes
Buffer into which to write the requested data.
=item size
Max size to read into the buffer.
=item timeout
lib/Device/USB/Device.pm view on Meta::CPAN
);
# stick back in the bytes parameter.
$_[1] = substr( $bytes, 0, $retlen );
return $retlen;
}
=item interrupt_read
Perform a interrupt read request from the specified endpoint.
=over 4
=item ep
The number of the endpoint to read
=item bytes
Buffer into which to write the requested data.
=item size
Max size to read into the buffer.
=item timeout
lib/Device/USB/Device.pm view on Meta::CPAN
);
# stick back in the bytes parameter.
$_[1] = substr( $bytes, 0, $retlen );
return $retlen;
}
=item bulk_write
Perform a bulk write request to the specified endpoint.
=over 4
=item ep
The number of the endpoint to write
=item bytes
Buffer from which to write the requested data.
=item timeout
Maximum time to wait (in milliseconds)
=back
lib/Device/USB/Device.pm view on Meta::CPAN
$self->_assert_open();
return Device::USB::libusb_bulk_write(
$self->{handle}, $ep, $bytes, length $bytes, $timeout
);
}
=item interrupt_write
Perform a interrupt write request to the specified endpoint.
=over 4
=item ep
The number of the endpoint to write
=item bytes
Buffer from which to write the requested data.
=item timeout
Maximum time to wait (in milliseconds)
=back
t/11-usb-device-methods.t view on Meta::CPAN
#
# Synthetics
can_ok( "Device::USB::Device",
qw/DESTROY manufacturer product serial_number/ );
# libusb methods
can_ok( "Device::USB::Device",
qw/open set_configuration set_altinterface clear_halt reset
claim_interface release_interface control_msg get_string
get_string_simple get_descriptor get_descriptor_by_endpoint
bulk_read interrupt_read bulk_write interrupt_write/ );
t/16-usb_dev_interface.t view on Meta::CPAN
}
else
{
fail( "Unable to create USB object." );
}
my @devices = $usb->list_devices();
isnt( scalar @devices, 0, "USB devices found" );
can_ok( "Device::USB::DevInterface",
qw/bInterfaceNumber endpoints bNumEndpoints
iInterface bInterfaceClass bInterfaceSubClass bInterfaceProtocol/
);
foreach my $dev (@devices)
{
my $filename = $dev->filename();
my $cfgno = 0;
foreach my $cfg ($dev->configurations())
{
foreach my $if (map { @{$_} } $cfg->interfaces())
{
my $ifno = $if->bInterfaceNumber();
isa_ok( $if, "Device::USB::DevInterface" );
like( $if->bInterfaceNumber(), qr/^\d+$/, "$filename:$cfgno:$ifno: Interface Number" );
like( $if->bAlternateSetting(), qr/^\d+$/, "$filename:$cfgno:$ifno: Alternate Setting" );
is( $if->bNumEndpoints(), scalar @{$if->endpoints()}, "$filename:$cfgno:$ifno: endpoint count" );
like( $if->bInterfaceClass(), qr/^\d+$/, "$filename:$cfgno:$ifno: Interface Class" );
like( $if->bInterfaceSubClass(), qr/^\d+$/, "$filename:$cfgno:$ifno: Interface Sub Class" );
like( $if->bInterfaceProtocol(), qr/^\d+$/, "$filename:$cfgno:$ifno: Interface Protocol" );
like( $if->iInterface(), qr/^\d+$/, "$filename:$cfgno:$ifno: Interface string index" );
}
++$cfgno;
}
}
t/17-usb_dev_endpoint.t view on Meta::CPAN
use Test::More;
use Device::USB;
use strict;
use warnings;
use constant TESTS_PER_ENDPOINT => 7;
my $usb = Device::USB->new();
if(defined $usb)
{
my $endpoint_count = 0;
foreach my $dev ($usb->list_devices())
{
foreach my $config ($dev->configurations())
{
my @interfaces = map {@{$_}} $config->interfaces();
$endpoint_count += $_->bNumEndpoints() foreach @interfaces;
}
}
if($endpoint_count)
{
plan tests => 2 + TESTS_PER_ENDPOINT * $endpoint_count;
}
else
{
plan skip_all => 'No devices found.';
}
}
else
{
fail( "Unable to create USB object." );
}
t/17-usb_dev_endpoint.t view on Meta::CPAN
foreach my $dev (@devices)
{
my $filename = $dev->filename();
my $cfgno = 0;
foreach my $cfg ($dev->configurations())
{
foreach my $if (map { @{$_} } $cfg->interfaces())
{
my $ifno = $if->bInterfaceNumber();
foreach my $ep ($if->endpoints())
{
my $descr = "$filename:$cfgno:$ifno:".$ep->bEndpointAddress();
isa_ok( $ep, "Device::USB::DevEndpoint" );
like( $ep->bEndpointAddress(), qr/^\d+$/, "$descr: Endpoint Address" );
like( $ep->bmAttributes(), qr/^\d+$/, "$descr: Attributes" );
like( $ep->wMaxPacketSize(), qr/^\d+$/, "$descr: Max Packet Size" );
like( $ep->bInterval(), qr/^\d+$/, "$descr: Interval" );
like( $ep->bRefresh(), qr/^\d+$/, "$descr: Refresh" );
like( $ep->bSynchAddress(), qr/^\d+$/, "$descr: Synch Address" );
}