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}), }, }