From 16eebea2fb09572d52ed2c3d2af34c473681ec04 Mon Sep 17 00:00:00 2001 From: Nik Date: Sun, 9 Oct 2022 12:46:29 +0200 Subject: [PATCH] patterns: Added USB Descriptor pattern --- patterns/usb.hexpat | 270 ++++++++++++++++++++++++ tests/patterns/test_data/usb.hexpat.bin | Bin 0 -> 82 bytes 2 files changed, 270 insertions(+) create mode 100644 patterns/usb.hexpat create mode 100644 tests/patterns/test_data/usb.hexpat.bin diff --git a/patterns/usb.hexpat b/patterns/usb.hexpat new file mode 100644 index 0000000..9e7982d --- /dev/null +++ b/patterns/usb.hexpat @@ -0,0 +1,270 @@ +#include +#include +#include + +enum DescriptorType : u8 { + DeviceDescriptor = 0x01, + ConfigDescriptor = 0x02, + StringDescriptor = 0x03, + InterfaceDescriptor = 0x04, + EndpointDescriptor = 0x05, + DeviceQualifierDescriptor = 0x06, + OtherSpeedConfigurationDescriptor = 0x07, + InterfacePowerDescriptor = 0x08, + OTGDescriptor = 0x09, + DebugDescriptor = 0x0A, + InterfaceAssociationDescriptor = 0x0B, + + HIDDescriptor = 0x21, + ReportDescriptor = 0x22, + PhysicalDescriptor = 0x23 +}; + +enum InterfaceClass : u8 { + UseClassInformationInInterfaceDescriptors = 0x00, + Audio = 0x01, + CommunicationAndCDCControl = 0x02, + HID = 0x03, + Physical = 0x05, + Image = 0x06, + Printer = 0x07, + MassStorage = 0x08, + Hub = 0x09, + CDCData = 0x0A, + SmartCard = 0x0B, + ContentSecurity = 0x0C, + Video = 0x0E, + PersonalHealthcare = 0x0F, + AudioVideoDevice = 0x10, + BillboardDevice = 0x11, + USBTypeCBridge = 0x12, + I3CDevice = 0x3C, + DiagnosticDevice = 0xDC, + WirelessController = 0xE0, + Miscellaneous = 0xEF, + ApplicationSpecific = 0xFE, + VendorSpecific = 0xFF +}; + +enum CountryCode : u8 { + NotSupported = 0, + Arabic = 1, + Belgian = 2, + CanadianBilingual = 3, + CanadianFrench = 4, + CzechRepublic = 5, + Danish = 6, + Finnish = 7, + French = 8, + German = 9, + Greek = 10, + Hebrew = 11, + Hungary = 12, + International = 13, + Italian = 14, + JapanKatakana = 15, + Korean = 16, + LatinAmerican = 17, + Dutch = 18, + Norwegian = 19, + PersianFarsi = 20, + Polish = 21, + Portuguese = 22, + Russian = 23, + Slovakian = 24, + Spanish = 25, + Swedish = 26, + SwissFrench = 27, + SwissGerman = 28, + Switzerland = 29, + Taiwan = 30, + TurkishQ = 31, + EnglishUK = 32, + EnglishUS = 33, + Yugoslavian = 34, + TurkishF = 35, + Reserved = 36 ... 255 +}; + +enum HubInterfaceSubClass : u8 { + Hub = 0x00 +}; + +enum AudioVideoDeviceSubClass : u8 { + AVControlInterface = 0x01, + AVDataVideoStreamingInterface = 0x02, + AVDataAudioStreamingInterface = 0x03 +}; + +enum HubInterfaceProtocol : u8 { + FullSpeedHub = 0x00, + HiSpeedHubWithSingleTT = 0x01, + HiSpeedHubWithMultipleTTs = 0x02 +}; + +struct Ampere { + u8 amps; +} [[sealed, format("format_ampere")]]; + +fn format_ampere(Ampere ampere) { + return std::format("{} mA", ampere.amps * 2); +}; + +bitfield ConfigAttributes { + padding : 1; + SelfPowered : 1; + RemoteWakeup : 1; + padding : 5; +} [[left_to_right]]; + +struct BCD { + u8 bytes[Size]; +} [[sealed, format("format_bcd")]]; + +fn format_bcd(ref auto bcd) { + str result; + for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1) + result += std::format("{:X}.", bcd.bytes[i]); + + return std::string::substr(result, 0, std::string::length(result) - 1); +}; + +struct DeviceDescriptor { + BCD<2> bcdUSB; + InterfaceClass bDeviceClass; + if (bDeviceClass == InterfaceClass::Hub) { + HubInterfaceSubClass bDeviceSubClass; + if (bDeviceSubClass == HubInterfaceSubClass::Hub) + HubInterfaceProtocol bDeviceSubClass; + else + u8 bDeviceSubClass; + } else if (bDeviceClass == InterfaceClass::AudioVideoDevice) { + AudioVideoDeviceSubClass bDeviceSubClass; + u8 bDeviceSubClass; + } else { + u8 bDeviceSubClass; + u8 bDeviceSubClass; + } +}; + +struct ConfigDescriptor { + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + ConfigAttributes bmAttributes; + Ampere bMaxPower; +}; + +struct StringDescriptor { + char bString[parent.bLength - 2]; +}; + +struct InterfaceDescriptor { + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + + InterfaceClass bInterfaceClass; + if (bInterfaceClass == InterfaceClass::Hub) { + HubInterfaceSubClass bInterfaceSubClass; + if (bInterfaceSubClass == HubInterfaceSubClass::Hub) + HubInterfaceProtocol bInterfaceProtocol; + else + u8 bInterfaceProtocol; + } else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) { + AudioVideoDeviceSubClass bInterfaceSubClass; + u8 bInterfaceProtocol; + } else { + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + } + + u8 iInterface; +}; + +enum EndpointDirection : u8 { + OUT = 0, + IN = 1 +}; + +fn format_direction(u8 value) { + EndpointDirection direction; + direction = value; + return direction; +}; + +bitfield EndpointAddress { + Direction : 1 [[format("format_direction")]]; + padding : 3; + EndpointNumber : 4; +} [[left_to_right]]; + +bitfield EndpointAttributes { + TransferType : 2; + SynchronizationType : 2; + UsageType : 2; +} [[right_to_left]]; + +struct EndpointDescriptor { + EndpointAddress bEndPointAddress; + EndpointAttributes bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; +}; + +struct OtherSpeedConfigurationDescriptor { + ConfigDescriptor content [[inline]]; +}; + +struct DeviceQualifierDescriptor { + DeviceDescriptor deviceDescriptor [[inline]]; + u8 bMaxPacketSize0; + u8 bNumConfigurations; + padding[1]; +}; + +bitfield OTGAttributes { + SRPSupport : 1; + HNPSupport : 1; +} [[right_to_left]]; + +struct OTGDescriptor { + OTGAttributes bmAttributes; +}; + +struct HIDDescriptor { + BCD<2> bcdVersion; + CountryCode bCountryCode; + u8 bNumDescriptors; + DescriptorType bDescriptorType; + u16 wDescriptorLength; +}; + +struct USBDescriptor { + u8 bLength; + DescriptorType bDescriptorType; + + if (bDescriptorType == DescriptorType::DeviceDescriptor) + DeviceDescriptor deviceDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::ConfigDescriptor) + ConfigDescriptor configDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::StringDescriptor) + StringDescriptor stringDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::InterfaceDescriptor) + InterfaceDescriptor interfaceDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::EndpointDescriptor) + EndpointDescriptor endpointDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor) + OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor) + DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::OTGDescriptor) + OTGDescriptor otgDescriptor [[inline]]; + else if (bDescriptorType == DescriptorType::HIDDescriptor) + HIDDescriptor hidDescriptor [[inline]]; + + padding[bLength - ($ - addressof(this))]; +}; + +USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00; \ No newline at end of file diff --git a/tests/patterns/test_data/usb.hexpat.bin b/tests/patterns/test_data/usb.hexpat.bin new file mode 100644 index 0000000000000000000000000000000000000000..966afa790190dbd1aa0639327a41e84e4d602bdc GIT binary patch literal 82 zcmd;N(qv#{WLWTvlZAnSiJ5_cfm2a{k%3WZBLh2YBQpaNBReZln1zv(9j`(M2CzaP F1prG^2ebeH literal 0 HcmV?d00001