Module: USB

Defined in:
lib/usb.rb,
ext/usb/usb.c

Overview

USB module is a binding for libusb.

It needs appropriate privilege to access USB. For example, the process should be an member of plugdev group on Debin GNU/Linux (etch).

Example

  1. list up USB devices

require 'usb'
require 'pp'
pp USB.devices
#=>
[#<USB::Device 001/001 0000:0000 Linux 2.6.17-2-486 uhci_hcd UHCI Host Controller 0000:00:1d.0 (Full speed Hub)>,
 #<USB::Device 002/001 0000:0000 Linux 2.6.17-2-486 uhci_hcd UHCI Host Controller 0000:00:1d.1 (Full speed Hub)>,
 #<USB::Device 003/001 0000:0000 Linux 2.6.17-2-486 uhci_hcd UHCI Host Controller 0000:00:1d.2 (Full speed Hub)>,
 #<USB::Device 004/001 0000:0000 Linux 2.6.17-2-486 ehci_hcd EHCI Host Controller 0000:00:1d.7 (Hi-speed Hub with single TT)>]
  1. find a device by bus id and device id

# find the device "004/001" in the above list.
dev = USB.find_bus(4).find_device(1)
p dev
#=>
#<USB::Device 004/001 0000:0000 Linux 2.6.17-2-486 ehci_hcd EHCI Host Controller 0000:00:1d.7 (Hi-speed Hub with single TT)>
  1. open a device

dev.open {|handle| p handle }
#=>
#<USB::DevHandle:0xa7d94688>

USB overview

  • A host has busses.

  • A bus has devices.

  • A device has configurations.

  • A configuration has interfaces.

  • A interface has settings.

  • A setting has endpoints.

Defined Under Namespace

Classes: Bus, Configuration, DevHandle, Device, Endpoint, Interface, Setting

Constant Summary collapse

VERSION =
'0.3.0'
CLASS_CODES =
[
  [0x01, nil, nil, "Audio"],
  [0x02, nil, nil, "Comm"],
  [0x03, nil, nil, "HID"],
  [0x05, nil, nil, "Physical"],
  [0x06, 0x01, 0x01, "StillImaging"],
  [0x06, nil, nil, "Image"],
  [0x07, nil, nil, "Printer"],
  [0x08, 0x01, nil, "MassStorage RBC Bluk-Only"],
  [0x08, 0x02, 0x50, "MassStorage ATAPI Bluk-Only"],
  [0x08, 0x03, 0x50, "MassStorage QIC-157 Bluk-Only"],
  [0x08, 0x04, nil, "MassStorage UFI"],
  [0x08, 0x05, 0x50, "MassStorage SFF-8070i Bluk-Only"],
  [0x08, 0x06, 0x50, "MassStorage SCSI Bluk-Only"],
  [0x08, nil, nil, "MassStorage"],
  [0x09, 0x00, 0x00, "Full speed Hub"],
  [0x09, 0x00, 0x01, "Hi-speed Hub with single TT"],
  [0x09, 0x00, 0x02, "Hi-speed Hub with multiple TTs"],
  [0x09, nil, nil, "Hub"],
  [0x0a, nil, nil, "CDC"],
  [0x0b, nil, nil, "SmartCard"],
  [0x0d, 0x00, 0x00, "ContentSecurity"],
  [0x0e, nil, nil, "Video"],
  [0xdc, 0x01, 0x01, "Diagnostic USB2"],
  [0xdc, nil, nil, "Diagnostic"],
  [0xe0, 0x01, 0x01, "Bluetooth"],
  [0xe0, 0x01, 0x02, "UWB"],
  [0xe0, 0x01, 0x03, "RemoteNDIS"],
  [0xe0, 0x02, 0x01, "Host Wire Adapter Control/Data"],
  [0xe0, 0x02, 0x02, "Device Wire Adapter Control/Data"],
  [0xe0, 0x02, 0x03, "Device Wire Adapter Isochronous"],
  [0xe0, nil, nil, "Wireless Controller"],
  [0xef, 0x01, 0x01, "Active Sync"],
  [0xef, 0x01, 0x02, "Palm Sync"],
  [0xef, 0x02, 0x01, "Interface Association Descriptor"],
  [0xef, 0x02, 0x02, "Wire Adapter Multifunction Peripheral"],
  [0xef, 0x03, 0x01, "Cable Based Association Framework"],
  [0xef, nil, nil, "Miscellaneous"],
  [0xfe, 0x01, 0x01, "Device Firmware Upgrade"],
  [0xfe, 0x02, 0x00, "IRDA Bridge"],
  [0xfe, 0x03, 0x00, "USB Test and Measurement"],
  [0xfe, 0x03, 0x01, "USB Test and Measurement (USBTMC USB488)"],
  [0xfe, nil, nil, "Application Specific"],
  [0xff, nil, nil, "Vendor specific"],
]
CLASS_CODES_HASH1 =
{}
CLASS_CODES_HASH2 =
{}
CLASS_CODES_HASH3 =
{}

Class Method Summary collapse

Class Method Details

.bussesObject



66
67
68
69
70
71
72
73
74
# File 'lib/usb.rb', line 66

def USB.busses
  result = []
  bus = USB.first_bus
  while bus
    result << bus
    bus = bus.next
  end
  result.sort_by {|b| b.dirname }
end

.configurationsObject



77
# File 'lib/usb.rb', line 77

def USB.configurations() USB.devices.map {|d| d.configurations }.flatten end

.dev_string(base_class, sub_class, protocol) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
# File 'lib/usb.rb', line 216

def USB.dev_string(base_class, sub_class, protocol)
  if desc = CLASS_CODES_HASH3[[base_class, sub_class, protocol]]
    desc
  elsif desc = CLASS_CODES_HASH2[[base_class, sub_class]]
    desc + " (%02x)" % [protocol]
  elsif desc = CLASS_CODES_HASH1[base_class]
    desc + " (%02x,%02x)" % [sub_class, protocol]
  else
    "Unkonwn(%02x,%02x,%02x)" % [base_class, sub_class, protocol]
  end
end

.devicesObject



76
# File 'lib/usb.rb', line 76

def USB.devices() USB.busses.map {|b| b.devices }.flatten end

.each_device_by_class(devclass, subclass = nil, protocol = nil) ⇒ Object

searches devices by USB device class, subclass and protocol.

# find hubs.
USB.each_device_by_class(USB::USB_CLASS_HUB) {|d| p d }'

# find Full speed Hubs
USB.each_device_by_class(USB::USB_CLASS_HUB, 0, 0) {|d| p d }'

# find Hi-speed Hubs with single TT
USB.each_device_by_class(USB::USB_CLASS_HUB, 0, 1) {|d| p d }'

# find Hi-speed Hubs with multiple TT
USB.each_device_by_class(USB::USB_CLASS_HUB, 0, 2) {|d| p d }'


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/usb.rb', line 105

def USB.each_device_by_class(devclass, subclass=nil, protocol=nil)
  USB.devices.each {|dev|
    if dev.bDeviceClass == USB::USB_CLASS_PER_INTERFACE
      found = dev.settings.any? {|s|
                s.bInterfaceClass == devclass &&
                (!subclass || s.bInterfaceSubClass == subclass) &&
                (!protocol || s.bInterfaceProtocol == protocol) }
    else
      found = dev.bDeviceClass == devclass &&
              (!subclass || dev.bDeviceSubClass == subclass) &&
              (!protocol || dev.bDeviceProtocol == protocol)
    end
    yield dev if found
  }
  nil
end

.endpointsObject



80
# File 'lib/usb.rb', line 80

def USB.endpoints() USB.settings.map {|d| d.endpoints }.flatten end

.find_bus(n) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/usb.rb', line 82

def USB.find_bus(n)
  bus = USB.first_bus
  while bus
    return bus if n == bus.dirname.to_i
    bus = bus.next
  end
  return nil
end

.find_bussesObject

USB.find_busses



118
119
120
121
122
123
124
125
126
127
128
# File 'ext/usb/usb.c', line 118

static VALUE
rusb_find_busses(VALUE cUSB)
{
  st_foreach(bus_objects, revoke_data_i, 0);
  st_foreach(device_objects, revoke_data_i, 0);
  st_foreach(config_descriptor_objects, revoke_data_i, 0);
  st_foreach(interface_objects, revoke_data_i, 0);
  st_foreach(interface_descriptor_objects, revoke_data_i, 0);
  st_foreach(endpoint_descriptor_objects, revoke_data_i, 0);
  return INT2NUM(usb_find_busses());
}

.find_devicesObject

USB.find_devices



131
132
133
134
135
# File 'ext/usb/usb.c', line 131

static VALUE
rusb_find_devices(VALUE cUSB)
{
  return INT2NUM(usb_find_devices());
}

.first_busObject

USB.first_bus



138
139
140
141
142
143
# File 'ext/usb/usb.c', line 138

static VALUE
rusb_first_bus(VALUE cUSB)
{
  struct usb_bus *bus = usb_get_busses();
  return rusb_bus_make(bus, Qnil);
}

.interfacesObject



78
# File 'lib/usb.rb', line 78

def USB.interfaces() USB.configurations.map {|d| d.interfaces }.flatten end

.settingsObject



79
# File 'lib/usb.rb', line 79

def USB.settings() USB.interfaces.map {|d| d.settings }.flatten end