Use Class for classes in usbid.

This commit is contained in:
Sebastian Zagrodzki
2017-04-09 18:29:16 +02:00
parent af00028b97
commit d3428d9b35
7 changed files with 36 additions and 23 deletions

View File

@@ -218,4 +218,14 @@ func (s DeviceSpeed) String() string {
return deviceSpeedDescription[s] return deviceSpeedDescription[s]
} }
const (
// SelfPoweredMask is the bitmask for "self powered" field of configuration
// descriptor bmAttributes.
SelfPoweredMask = 0x40
// RemoteWakeupMask is the bitmask for "supports remote wakeup" field of
// configuration descriptor bmAttributes.
RemoteWakeupMask = 0x20
)
// Milliamperes is a unit of electric current consumption.
type Milliamperes uint type Milliamperes uint

View File

@@ -29,8 +29,8 @@ type Descriptor struct {
Product ID // The Product identifier Product ID // The Product identifier
// Protocol information // Protocol information
Class uint8 // The class of this device Class Class // The class of this device
SubClass uint8 // The sub-class (within the class) of this device SubClass Class // The sub-class (within the class) of this device
Protocol uint8 // The protocol (within the sub-class) of this device Protocol uint8 // The protocol (within the sub-class) of this device
// Configuration information // Configuration information

View File

@@ -214,8 +214,10 @@ func (libusbImpl) getDeviceDesc(d *libusbDevice) (*Descriptor, error) {
} }
c := ConfigInfo{ c := ConfigInfo{
Config: uint8(cfg.bConfigurationValue), Config: uint8(cfg.bConfigurationValue),
Attributes: uint8(cfg.bmAttributes), SelfPowered: (cfg.bmAttributes & SelfPoweredMask) != 0,
MaxPower: uint8(cfg.MaxPower), RemoteWakeup: (cfg.bmAttributes & RemoteWakeupMask) != 0,
// TODO(sebek): at GenX speeds MaxPower is expressed in units of 8mA, not 2mA.
MaxPower: 2 * Milliamperes(cfg.MaxPower),
} }
var ifaces []C.struct_libusb_interface var ifaces []C.struct_libusb_interface
@@ -274,8 +276,8 @@ func (libusbImpl) getDeviceDesc(d *libusbDevice) (*Descriptor, error) {
Device: BCD(desc.bcdDevice), Device: BCD(desc.bcdDevice),
Vendor: ID(desc.idVendor), Vendor: ID(desc.idVendor),
Product: ID(desc.idProduct), Product: ID(desc.idProduct),
Class: uint8(desc.bDeviceClass), Class: Class(desc.bDeviceClass),
SubClass: uint8(desc.bDeviceSubClass), SubClass: Class(desc.bDeviceSubClass),
Protocol: uint8(desc.bDeviceProtocol), Protocol: uint8(desc.bDeviceProtocol),
Configs: cfgs, Configs: cfgs,
}, nil }, nil

View File

@@ -56,12 +56,15 @@ func Describe(val interface{}) string {
// - *usb.Descriptor "Class (SubClass) Protocol" // - *usb.Descriptor "Class (SubClass) Protocol"
// - usb.InterfaceSetup "IfClass (IfSubClass) IfProtocol" // - usb.InterfaceSetup "IfClass (IfSubClass) IfProtocol"
func Classify(val interface{}) string { func Classify(val interface{}) string {
var class, sub, proto uint8 var (
class, sub usb.Class
proto uint8
)
switch val := val.(type) { switch val := val.(type) {
case *usb.Descriptor: case *usb.Descriptor:
class, sub, proto = val.Class, val.SubClass, val.Protocol class, sub, proto = val.Class, val.SubClass, val.Protocol
case usb.InterfaceSetup: case usb.InterfaceSetup:
class, sub, proto = val.IfClass, val.IfSubClass, val.IfProtocol class, sub, proto = usb.Class(val.IfClass), usb.Class(val.IfSubClass), val.IfProtocol
default: default:
return fmt.Sprintf("Unknown (%T)", val) return fmt.Sprintf("Unknown (%T)", val)
} }

View File

@@ -34,7 +34,7 @@ var (
Vendors map[usb.ID]*Vendor Vendors map[usb.ID]*Vendor
// Classes stores the class, subclass and protocol mappings. // Classes stores the class, subclass and protocol mappings.
Classes map[uint8]*Class Classes map[usb.Class]*Class
) )
// LoadFromURL replaces the built-in vendor and class mappings with ones loaded // LoadFromURL replaces the built-in vendor and class mappings with ones loaded

View File

@@ -52,7 +52,7 @@ func (p Product) String() string {
// A Class contains the name of the class and mappings for each subclass. // A Class contains the name of the class and mappings for each subclass.
type Class struct { type Class struct {
Name string Name string
SubClass map[uint8]*SubClass SubClass map[usb.Class]*SubClass
} }
// String returns the name of the class. // String returns the name of the class.
@@ -75,9 +75,9 @@ func (s SubClass) String() string {
// should not be necessary, as a set of mappings is already embedded in the library. // should not be necessary, as a set of mappings is already embedded in the library.
// If a new or specialized file is obtained, this can be used to retrieve the mappings, // If a new or specialized file is obtained, this can be used to retrieve the mappings,
// which can be stored in the global Vendors and Classes map. // which can be stored in the global Vendors and Classes map.
func ParseIDs(r io.Reader) (map[usb.ID]*Vendor, map[uint8]*Class, error) { func ParseIDs(r io.Reader) (map[usb.ID]*Vendor, map[usb.Class]*Class, error) {
vendors := make(map[usb.ID]*Vendor, 2800) vendors := make(map[usb.ID]*Vendor, 2800)
classes := make(map[uint8]*Class) // TODO(kevlar): count classes := make(map[usb.Class]*Class) // TODO(kevlar): count
split := func(s string) (kind string, level int, id uint64, name string, err error) { split := func(s string) (kind string, level int, id uint64, name string, err error) {
pieces := strings.SplitN(s, " ", 2) pieces := strings.SplitN(s, " ", 2)
@@ -159,15 +159,13 @@ func ParseIDs(r io.Reader) (map[usb.ID]*Vendor, map[uint8]*Class, error) {
var class *Class var class *Class
var subclass *SubClass var subclass *SubClass
parseClass := func(level int, raw uint64, name string) error { parseClass := func(level int, id uint64, name string) error {
id := uint8(raw)
switch level { switch level {
case 0: case 0:
class = &Class{ class = &Class{
Name: name, Name: name,
} }
classes[id] = class classes[usb.Class(id)] = class
case 1: case 1:
if class == nil { if class == nil {
@@ -178,9 +176,9 @@ func ParseIDs(r io.Reader) (map[usb.ID]*Vendor, map[uint8]*Class, error) {
Name: name, Name: name,
} }
if class.SubClass == nil { if class.SubClass == nil {
class.SubClass = make(map[uint8]*SubClass) class.SubClass = make(map[usb.Class]*SubClass)
} }
class.SubClass[id] = subclass class.SubClass[usb.Class(id)] = subclass
case 2: case 2:
if subclass == nil { if subclass == nil {
@@ -190,7 +188,7 @@ func ParseIDs(r io.Reader) (map[usb.ID]*Vendor, map[uint8]*Class, error) {
if subclass.Protocol == nil { if subclass.Protocol == nil {
subclass.Protocol = make(map[uint8]string) subclass.Protocol = make(map[uint8]string)
} }
subclass.Protocol[id] = name subclass.Protocol[uint8(id)] = name
default: default:
return fmt.Errorf("too many levels of nesting for class") return fmt.Errorf("too many levels of nesting for class")

View File

@@ -46,13 +46,13 @@ var (
}, },
}, },
} }
testDBClasses = map[uint8]*Class{ testDBClasses = map[usb.Class]*Class{
0x00: { 0x00: {
Name: "(Defined at Interface level)", Name: "(Defined at Interface level)",
}, },
0x01: { 0x01: {
Name: "Audio", Name: "Audio",
SubClass: map[uint8]*SubClass{ SubClass: map[usb.Class]*SubClass{
0x01: {Name: "Control Device"}, 0x01: {Name: "Control Device"},
0x02: {Name: "Streaming"}, 0x02: {Name: "Streaming"},
0x03: {Name: "MIDI Streaming"}, 0x03: {Name: "MIDI Streaming"},
@@ -60,7 +60,7 @@ var (
}, },
0x02: { 0x02: {
Name: "Communications", Name: "Communications",
SubClass: map[uint8]*SubClass{ SubClass: map[usb.Class]*SubClass{
0x01: {Name: "Direct Line"}, 0x01: {Name: "Direct Line"},
0x02: { 0x02: {
Name: "Abstract (modem)", Name: "Abstract (modem)",