Device-USB
view release on metacpan or search on metacpan
lib/Device/USB.pm view on Meta::CPAN
=item *
CLASS_MASS_STORAGE
=item *
CLASS_HUB
=item *
CLASS_DATA
=item *
CLASS_VENDOR_SPEC
=back
=head2 FUNCTIONS
=over 4
=cut
#
# Internal-only, one-time init function.
my $init_ref;
$init_ref = sub
{
libusb_init();
$init_ref = sub {};
};
=item new
Create a new Device::USB object for accessing the library.
=cut
sub new
{
my $class = shift;
$init_ref->();
return bless {}, $class;
}
=item debug_mode
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 );
return;
}
=item find_busses
Returns the number of changes since previous call to the function: the
number of busses added or removed.
=cut
sub find_busses
{
my $self = shift;
return libusb_find_busses();
}
=item find_devices
Returns the number of changes since previous call to the function: the
number of devices added or removed. Should be called after find_busses.
=cut
sub find_devices
{
my $self = shift;
return libusb_find_devices();
}
=item find_device
Find a particular USB device based on the vendor and product ids. If more
than one device has the same product id from the same vendor, the first one
found is returned.
=over 4
=item vendor
the vendor id
=item product
product id for that vendor
=back
returns a device reference or undef if none was found.
lib/Device/USB.pm view on Meta::CPAN
=over 4
=item DeviceUSBDebugLevel()
=item libusb_init()
=item libusb_find_busses()
=item libusb_find_devices()
=item libusb_get_busses()
=item libusb_open(void *dev)
=item libusb_close(void *dev)
=item libusb_set_configuration(void *dev, int configuration)
=item libusb_set_altinterface(void *dev, int alternate)
=item libusb_clear_halt(void *dev, unsigned int ep)
=item libusb_reset(void *dev)
=item libusb_get_driver_np(void *dev, int interface, char *name, unsigned int namelen)
=item libusb_detach_kernel_driver_np(void *dev, int interface)
=item libusb_claim_interface(void *dev, int interface)
=item libusb_release_interface(void *dev, int interface)
=item libusb_control_msg(void *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout)
=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)
=item libusb_interrupt_read(void *dev, int ep, char *bytes, int size, int timeout)
=item lib_get_usb_busses()
Return the complete list of information after finding busses and devices.
Before calling this function, remember to call find_busses and find_devices.
returns a reference to an array of busses.
=item lib_list_busses()
Return the complete list of information after finding busses and devices.
By using this function, you do not need to do the find_* calls yourself.
returns a reference to an array of busses.
=item lib_find_usb_device( int vendor, int product )
Find a particular device
vendor - the vendor id
product - product id for that vendor
returns a pointer to the device if it is found, NULL otherwise.
=item lib_debug_mode( int unsafe_level )
Set debugging level: 0: off, 1: some messages, 2: verbose
Values outside range are forced into range.
=back
=head1 DIAGNOSTICS
This is an explanation of the diagnostic and error messages this module
can generate.
=head1 DEPENDENCIES
This module depends on the Carp, Inline and Inline::C modules, as well as
the strict and warnings pragmas. Obviously, libusb must be available since
that is the entire reason for the module's existence.
=head1 AUTHOR
G. Wade Johnson (gwadej at cpan dot org)
lib/Device/USB.pm view on Meta::CPAN
printf( "libusb_control_msg( %#04x, %#04x, %#04x, %#04x, %p, %d, %d )\n",
requesttype, request, value, index, bytes, size, timeout
);
/* maybe need to add support for printing the bytes string. */
}
retval = usb_control_msg((usb_dev_handle *)dev, requesttype, request, value, index, bytes, size, timeout);
if(DeviceUSBDebugLevel())
{
printf( "\t => %d\n",retval );
}
/* quiet compiler warnings. */
(void)i;
(void)ax;
(void)items;
/*
* For some reason, I could not get this string transferred back to the Perl side
* through a direct copy like in get_simple_string. So, I resorted to returning
* it on the stack and doing the fixup on the Perl side.
*/
Inline_Stack_Reset;
Inline_Stack_Push(sv_2mortal(newSViv(retval)));
if(retval > 0)
{
Inline_Stack_Push(sv_2mortal(newSVpv(bytes, retval)));
}
else
{
Inline_Stack_Push(sv_2mortal(newSVpv(bytes, 0)));
}
Inline_Stack_Done;
}
int libusb_get_string(void *dev, int index, int langid, char *buf, size_t buflen)
{
if(DeviceUSBDebugLevel())
{
printf( "libusb_get_string( %d, %d, %p, %lu )\n",
index, langid, buf, (unsigned long)buflen
);
}
return usb_get_string((usb_dev_handle *)dev, index, langid, buf, buflen);
}
int libusb_get_string_simple(void *dev, int index, char *buf, size_t buflen)
{
if(DeviceUSBDebugLevel())
{
printf( "libusb_get_string_simple( %d, %p, %lu )\n",
index, buf, (unsigned long)buflen
);
}
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);
}
int libusb_interrupt_write(void *dev, int ep, char *bytes, int size, int timeout)
{
return usb_interrupt_write((usb_dev_handle *)dev, ep, bytes, size, timeout);
}
int libusb_interrupt_read(void *dev, int ep, char *bytes, int size, int timeout)
{
return usb_interrupt_read((usb_dev_handle *)dev, ep, bytes, size, timeout);
}
/* ------------------------------------------------------------
* Provide Perl-ish interface for accessing busses and devices.
*/
/*
* Utility function to store BCD encoded number as an appropriate string
* in a hash under the supplied key.
*/
static void hashStoreBcd( HV *hash, const char *key, long value )
{
int major = (value >> 8) & 0xff;
int minor = (value >> 4) & 0xf;
int subminor = value & 0xf;
// should not be able to exceed 6.
char buffer[10] = "";
sprintf( buffer, "%d.%d%d", major, minor, subminor );
(void) hv_store( hash, key, strlen( key ), newSVpv( buffer, strlen( buffer ) ), 0 );
}
/*
* Utility function to store an integer value in a hash under the supplied key.
*/
static void hashStoreInt( HV *hash, const char *key, long value )
{
(void) hv_store( hash, key, strlen( key ), newSViv( value ), 0 );
}
/*
* Utility function to store a C-style string in a hash under the supplied key.
*/
static void hashStoreString( HV *hash, const char *key, const char *value )
{
(void) hv_store( hash, key, strlen( key ), newSVpv( value, strlen( value ) ), 0 );
}
/*
* Utility function to store an SV in a hash under the supplied key.
*/
static void hashStoreSV( HV *hash, const char *key, SV *value )
{
(void) hv_store( hash, key, strlen( key ), value, 0 );
}
/*
* Given a pointer to an array of usb_device, create a hash
* reference containing the descriptor information.
*/
static SV* build_descriptor(struct usb_device *dev)
{
HV* hash = newHV();
hashStoreInt( hash, "bDescriptorType", dev->descriptor.bDescriptorType );
hashStoreBcd( hash, "bcdUSB", dev->descriptor.bcdUSB );
hashStoreInt( hash, "bDeviceClass", dev->descriptor.bDeviceClass );
hashStoreInt( hash, "bDeviceSubClass", dev->descriptor.bDeviceSubClass );
hashStoreInt( hash, "bDeviceProtocol", dev->descriptor.bDeviceProtocol );
hashStoreInt( hash, "bMaxPacketSize0", dev->descriptor.bMaxPacketSize0 );
hashStoreInt( hash, "idVendor", dev->descriptor.idVendor );
hashStoreInt( hash, "idProduct", dev->descriptor.idProduct );
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.
*
* returns the appropriate pointer to a reference.
*/
static SV* build_interface( struct usb_interface_descriptor* inter )
{
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
* reference to a Perl array containing the same data.
*/
static SV* list_interfaces( struct usb_interface* ints, unsigned count )
{
AV* array = newAV();
unsigned i = 0;
for(i=0; i < count; ++i)
{
AV* inters = newAV();
unsigned j = 0;
for(j=0; j < ints[i].num_altsetting; ++j)
{
av_push( inters, build_interface( (ints[i].altsetting+j) ) );
}
av_push( array, newRV_noinc( (SV*)inters ) );
}
return newRV_noinc( (SV*)array );
}
/*
* Given a pointer to a usb_config_descriptor struct, create a Perl
* object that contains the same data.
*/
static SV* build_configuration( struct usb_config_descriptor *cfg )
{
HV* hash = newHV();
hashStoreInt( hash, "bDescriptorType", cfg->bDescriptorType );
hashStoreInt( hash, "wTotalLength", cfg->wTotalLength );
hashStoreInt( hash, "bNumInterfaces", cfg->bNumInterfaces );
hashStoreInt( hash, "bConfigurationValue", cfg->bConfigurationValue );
hashStoreInt( hash, "iConfiguration", cfg->iConfiguration );
hashStoreInt( hash, "bmAttributes", cfg->bmAttributes );
hashStoreInt( hash, "MaxPower", cfg->MaxPower*2 );
hashStoreSV( hash, "interfaces",
list_interfaces( cfg->interface, cfg->bNumInterfaces )
);
return sv_bless( newRV_noinc( (SV*)hash ),
gv_stashpv( "Device::USB::DevConfig", 1 )
);
}
/*
* Given a pointer to an array of usb_config_descriptor structs, create a
* reference to a Perl array containing the same data.
*/
static SV* list_configurations(struct usb_config_descriptor *cfg, unsigned count )
{
( run in 1.259 second using v1.01-cache-2.11-cpan-524268b4103 )