215 строки
4,5 КиБ
Go
215 строки
4,5 КиБ
Go
package descriptor
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
)
|
|
|
|
var configurationCDCHID = [configurationTypeLen]byte{
|
|
configurationTypeLen,
|
|
TypeConfiguration,
|
|
0x64, 0x00, // adjust length as needed
|
|
0x03, // number of interfaces
|
|
0x01, // configuration value
|
|
0x00, // index to string description
|
|
0xa0, // attributes
|
|
0x32, // maxpower
|
|
}
|
|
|
|
var ConfigurationCDCHID = ConfigurationType{
|
|
data: configurationCDCHID[:],
|
|
}
|
|
|
|
var interfaceHID = [interfaceTypeLen]byte{
|
|
interfaceTypeLen,
|
|
TypeInterface,
|
|
0x02, // InterfaceNumber
|
|
0x00, // AlternateSetting
|
|
0x02, // NumEndpoints
|
|
0x03, // InterfaceClass
|
|
0x00, // InterfaceSubClass
|
|
0x00, // InterfaceProtocol
|
|
0x00, // Interface
|
|
}
|
|
|
|
var InterfaceHID = InterfaceType{
|
|
data: interfaceHID[:],
|
|
}
|
|
|
|
const (
|
|
ClassHIDTypeLen = 9
|
|
)
|
|
|
|
type ClassHIDType struct {
|
|
data []byte
|
|
}
|
|
|
|
func (d ClassHIDType) Bytes() []byte {
|
|
return d.data[:]
|
|
}
|
|
|
|
func (d ClassHIDType) Length(v uint8) {
|
|
d.data[0] = byte(v)
|
|
}
|
|
|
|
func (d ClassHIDType) Type(v uint8) {
|
|
d.data[1] = byte(v)
|
|
}
|
|
|
|
func (d ClassHIDType) HID(v uint16) {
|
|
binary.LittleEndian.PutUint16(d.data[2:4], v)
|
|
}
|
|
|
|
func (d ClassHIDType) CountryCode(v uint8) {
|
|
d.data[4] = byte(v)
|
|
}
|
|
|
|
func (d ClassHIDType) NumDescriptors(v uint8) {
|
|
d.data[5] = byte(v)
|
|
}
|
|
|
|
func (d ClassHIDType) ClassType(v uint8) {
|
|
d.data[6] = byte(v)
|
|
}
|
|
|
|
func (d ClassHIDType) ClassLength(v uint16) {
|
|
binary.LittleEndian.PutUint16(d.data[7:9], v)
|
|
}
|
|
|
|
var errNoClassHIDFound = errors.New("no classHID found")
|
|
|
|
// FindClassHIDType tries to find the ClassHID class in the descriptor.
|
|
func FindClassHIDType(des, class []byte) (ClassHIDType, error) {
|
|
if len(des) < ClassHIDTypeLen || len(class) == 0 {
|
|
return ClassHIDType{}, errNoClassHIDFound
|
|
}
|
|
|
|
// search only for ClassHIDType without the ClassLength,
|
|
// in case it has already been set.
|
|
idx := bytes.Index(des, class[:ClassHIDTypeLen-2])
|
|
if idx == -1 {
|
|
return ClassHIDType{}, errNoClassHIDFound
|
|
}
|
|
|
|
return ClassHIDType{data: des[idx : idx+ClassHIDTypeLen]}, nil
|
|
}
|
|
|
|
var classHID = [ClassHIDTypeLen]byte{
|
|
ClassHIDTypeLen,
|
|
TypeClassHID,
|
|
0x11, // HID version L
|
|
0x01, // HID version H
|
|
0x00, // CountryCode
|
|
0x01, // NumDescriptors
|
|
0x22, // ClassType
|
|
0x90, // ClassLength L
|
|
0x00, // ClassLength H
|
|
}
|
|
|
|
var ClassHID = ClassHIDType{
|
|
data: classHID[:],
|
|
}
|
|
|
|
var CDCHID = Descriptor{
|
|
Device: DeviceCDC.Bytes(),
|
|
Configuration: Append([][]byte{
|
|
ConfigurationCDCHID.Bytes(),
|
|
InterfaceAssociationCDC.Bytes(),
|
|
InterfaceCDCControl.Bytes(),
|
|
ClassSpecificCDCHeader.Bytes(),
|
|
ClassSpecificCDCACM.Bytes(),
|
|
ClassSpecificCDCUnion.Bytes(),
|
|
ClassSpecificCDCCallManagement.Bytes(),
|
|
EndpointEP1IN.Bytes(),
|
|
InterfaceCDCData.Bytes(),
|
|
EndpointEP2OUT.Bytes(),
|
|
EndpointEP3IN.Bytes(),
|
|
InterfaceHID.Bytes(),
|
|
ClassHID.Bytes(),
|
|
EndpointEP4IN.Bytes(),
|
|
EndpointEP5OUT.Bytes(),
|
|
}),
|
|
HID: map[uint16][]byte{
|
|
2: Append([][]byte{
|
|
HIDUsagePageGenericDesktop,
|
|
HIDUsageDesktopKeyboard,
|
|
HIDCollectionApplication,
|
|
HIDReportID(2),
|
|
|
|
HIDUsagePageKeyboard,
|
|
HIDUsageMinimum(224),
|
|
HIDUsageMaximum(231),
|
|
HIDLogicalMinimum(0),
|
|
HIDLogicalMaximum(1),
|
|
HIDReportSize(1),
|
|
HIDReportCount(8),
|
|
HIDInputDataVarAbs,
|
|
HIDReportCount(1),
|
|
HIDReportSize(8),
|
|
HIDInputConstVarAbs,
|
|
HIDReportCount(3),
|
|
HIDReportSize(1),
|
|
HIDUsagePageLED,
|
|
HIDUsageMinimum(1),
|
|
HIDUsageMaximum(3),
|
|
HIDOutputDataVarAbs,
|
|
HIDReportCount(5),
|
|
HIDReportSize(1),
|
|
HIDOutputConstVarAbs,
|
|
HIDReportCount(6),
|
|
HIDReportSize(8),
|
|
HIDLogicalMinimum(0),
|
|
HIDLogicalMaximum(255),
|
|
|
|
HIDUsagePageKeyboard,
|
|
HIDUsageMinimum(0),
|
|
HIDUsageMaximum(255),
|
|
HIDInputDataAryAbs,
|
|
HIDCollectionEnd,
|
|
|
|
HIDUsagePageGenericDesktop,
|
|
HIDUsageDesktopMouse,
|
|
HIDCollectionApplication,
|
|
HIDUsageDesktopPointer,
|
|
HIDCollectionPhysical,
|
|
HIDReportID(1),
|
|
|
|
HIDUsagePageButton,
|
|
HIDUsageMinimum(1),
|
|
HIDUsageMaximum(5),
|
|
HIDLogicalMinimum(0),
|
|
HIDLogicalMaximum(1),
|
|
HIDReportCount(5),
|
|
HIDReportSize(1),
|
|
HIDInputDataVarAbs,
|
|
HIDReportCount(1),
|
|
HIDReportSize(3),
|
|
HIDInputConstVarAbs,
|
|
|
|
HIDUsagePageGenericDesktop,
|
|
HIDUsageDesktopX,
|
|
HIDUsageDesktopY,
|
|
HIDUsageDesktopWheel,
|
|
HIDLogicalMinimum(-127),
|
|
HIDLogicalMaximum(127),
|
|
HIDReportSize(8),
|
|
HIDReportCount(3),
|
|
HIDInputDataVarRel,
|
|
HIDCollectionEnd,
|
|
HIDCollectionEnd,
|
|
|
|
HIDUsagePageConsumer,
|
|
HIDUsageConsumerControl,
|
|
HIDCollectionApplication,
|
|
HIDReportID(3),
|
|
HIDLogicalMinimum(0),
|
|
HIDLogicalMaximum(8191),
|
|
HIDUsageMinimum(0),
|
|
HIDUsageMaximum(0x1FFF),
|
|
HIDReportSize(16),
|
|
HIDReportCount(1),
|
|
HIDInputDataAryAbs,
|
|
HIDCollectionEnd}),
|
|
},
|
|
}
|