Example #1
0
 def __init__(self, app, phy, scsi_device, usbclass, sub, proto):
     super(USBMassStorageInterface, self).__init__(
         app=app,
         phy=phy,
         interface_number=0,
         interface_alternate=0,
         interface_class=usbclass,
         interface_subclass=sub,
         interface_protocol=proto,
         interface_string_index=0,
         endpoints=[
             USBEndpoint(app=app,
                         phy=phy,
                         number=1,
                         direction=USBEndpoint.direction_out,
                         transfer_type=USBEndpoint.transfer_type_bulk,
                         sync_type=USBEndpoint.sync_type_none,
                         usage_type=USBEndpoint.usage_type_data,
                         max_packet_size=0x40,
                         interval=0,
                         handler=self.handle_data_available),
             USBEndpoint(app=app,
                         phy=phy,
                         number=3,
                         direction=USBEndpoint.direction_in,
                         transfer_type=USBEndpoint.transfer_type_bulk,
                         sync_type=USBEndpoint.sync_type_none,
                         usage_type=USBEndpoint.usage_type_data,
                         max_packet_size=0x40,
                         interval=0,
                         handler=self.handle_buffer_available),
         ],
         usb_class=USBMassStorageClass(app, phy, scsi_device),
     )
     self.scsi_device = scsi_device
Example #2
0
 def __init__(self, app, phy, vid=0x2548, pid=0x1001, rev=0x0010, cs_interfaces=None, cdc_cls=None, bmCapabilities=0x01, **kwargs):
     if cdc_cls is None:
         cdc_cls = self.get_default_class(app, phy)
     cs_interfaces = [
         # Header Functional Descriptor
         FD(app, phy, FD.Header, '\x01\x01'),
         # Call Management Functional Descriptor
         FD(app, phy, FD.CM, struct.pack('BB', bmCapabilities, USBCDCDevice.bDataInterface)),
         FD(app, phy, FD.DLM, struct.pack('B', bmCapabilities)),
         FD(app, phy, FD.UN, struct.pack('BB', USBCDCDevice.bControlInterface, USBCDCDevice.bDataInterface)),
     ]
     interfaces = [
         USBInterface(
             app=app, phy=phy,
             interface_number=self.bDataInterface,
             interface_alternate=0,
             interface_class=USBClass.CDCData,
             interface_subclass=self.bDataSubclass,
             interface_protocol=self.bDataProtocol,
             interface_string_index=0,
             endpoints=[
                 USBEndpoint(
                     app=app,
                     phy=phy,
                     number=0x1,
                     direction=USBEndpoint.direction_out,
                     transfer_type=USBEndpoint.transfer_type_bulk,
                     sync_type=USBEndpoint.sync_type_none,
                     usage_type=USBEndpoint.usage_type_data,
                     max_packet_size=0x40,
                     interval=0x00,
                     handler=self.handle_ep1_data_available
                 ),
                 USBEndpoint(
                     app=app,
                     phy=phy,
                     number=0x2,
                     direction=USBEndpoint.direction_in,
                     transfer_type=USBEndpoint.transfer_type_bulk,
                     sync_type=USBEndpoint.sync_type_none,
                     usage_type=USBEndpoint.usage_type_data,
                     max_packet_size=0x40,
                     interval=0x00,
                     handler=self.handle_ep2_buffer_available
                 )
             ],
             usb_class=cdc_cls
         )
     ]
     super(USBCdcDlDevice, self).__init__(
         app, phy,
         vid=vid, pid=pid, rev=rev,
         interfaces=interfaces, cs_interfaces=cs_interfaces, cdc_cls=cdc_cls,
         bmCapabilities=0x03, **kwargs
     )
     self.receive_buffer = b''
Example #3
0
 def __init__(self, app, phy, num=0):
     # TODO: un-hardcode string index
     super(USBHubInterface, self).__init__(
         app=app,
         phy=phy,
         interface_number=num,
         interface_alternate=0,
         interface_class=USBClass.Hub,
         interface_subclass=0,
         interface_protocol=0,
         interface_string_index=0,
         endpoints=[
             USBEndpoint(
                 app=app,
                 phy=phy,
                 number=0x2,
                 direction=USBEndpoint.direction_in,
                 transfer_type=USBEndpoint.transfer_type_interrupt,
                 sync_type=USBEndpoint.sync_type_none,
                 usage_type=USBEndpoint.usage_type_data,
                 max_packet_size=0x40,
                 interval=0x40,
                 handler=self.handle_buffer_available
             )
         ],
         descriptors={
             DescriptorType.hub: self.get_hub_descriptor
         },
         usb_class=USBHubClass(app, phy)
     )
Example #4
0
    def __init__(self, app, phy):
        super(USBKeyboardInterface, self).__init__(
            app=app,
            phy=phy,
            interface_number=0,
            interface_alternate=0,
            interface_class=USBClass.HID,
            interface_subclass=0,
            interface_protocol=0,
            interface_string_index=0,
            endpoints=[
                USBEndpoint(app=app,
                            phy=phy,
                            number=2,
                            direction=USBEndpoint.direction_in,
                            transfer_type=USBEndpoint.transfer_type_interrupt,
                            sync_type=USBEndpoint.sync_type_none,
                            usage_type=USBEndpoint.usage_type_data,
                            max_packet_size=0x40,
                            interval=0x40,
                            handler=self.handle_buffer_available)
            ],
            descriptors={
                DescriptorType.hid: self.get_hid_descriptor,
                DescriptorType.report: self.get_report_descriptor
            },
            usb_class=USBKeyboardClass(app, phy))

        empty_preamble = [0x00] * 10
        text = [0x0f, 0x00, 0x16, 0x00, 0x28, 0x00]

        self.keys = [chr(x) for x in empty_preamble + text]
        self.call_count = 0
        self.first_call = None
Example #5
0
 def __init__(self, app, phy, interface_number):
     super(USBFtdiInterface, self).__init__(
         app=app,
         phy=phy,
         interface_number=interface_number,
         interface_alternate=0,
         interface_class=USBClass.VendorSpecific,
         interface_subclass=0xff,
         interface_protocol=0xff,
         interface_string_index=0,
         endpoints=[
             USBEndpoint(app=app,
                         phy=phy,
                         number=1,
                         direction=USBEndpoint.direction_out,
                         transfer_type=USBEndpoint.transfer_type_bulk,
                         sync_type=USBEndpoint.sync_type_none,
                         usage_type=USBEndpoint.usage_type_data,
                         max_packet_size=0x40,
                         interval=0,
                         handler=self.handle_data_available),
             USBEndpoint(
                 app=app,
                 phy=phy,
                 number=3,
                 direction=USBEndpoint.direction_in,
                 transfer_type=USBEndpoint.transfer_type_bulk,
                 sync_type=USBEndpoint.sync_type_none,
                 usage_type=USBEndpoint.usage_type_data,
                 max_packet_size=0x40,
                 interval=0,
                 handler=self.
                 handle_ep3_buffer_available  # at this point, we don't send data to the host
             )
         ],
     )
     self.txq = Queue()
Example #6
0
 def __init__(self, app, phy, vid=0x2548, pid=0x1001, rev=0x0010, bmCapabilities=0x03, interfaces=None, cs_interfaces=None, cdc_cls=None, **kwargs):
     if cs_interfaces is None:
         cs_interfaces = []
     if cdc_cls is None:
         cdc_cls = self.get_default_class(app, phy)
     if interfaces is None:
         interfaces = []
     control_interface = USBCDCControlInterface(
         app=app, phy=phy,
         interface_number=self.bControlInterface, interface_alternate=0,
         interface_class=USBClass.CDC,
         interface_subclass=self.bControlSubclass,
         interface_protocol=self.bControlProtocol,
         interface_string_index=0,
         endpoints=[
             USBEndpoint(
                 app=app, phy=phy, number=0x3,
                 direction=USBEndpoint.direction_in,
                 transfer_type=USBEndpoint.transfer_type_interrupt,
                 sync_type=USBEndpoint.sync_type_none,
                 usage_type=USBEndpoint.usage_type_data,
                 max_packet_size=0x40,
                 interval=9,
                 handler=self.handle_ep3_buffer_available
             )
         ],
         cs_interfaces=cs_interfaces,
     )
     interfaces.insert(0, control_interface)
     super(USBCDCDevice, self).__init__(
         app=app, phy=phy,
         device_class=USBClass.CDC,
         device_subclass=0,
         protocol_rel_num=0,
         max_packet_size_ep0=64,
         vendor_id=vid,
         product_id=pid,
         device_rev=rev,
         manufacturer_string='UMAP2 NetSolutions',
         product_string='UMAP2 CDC-TRON',
         serial_number_string='UMAP2-13337-CDC',
         configurations=[
             USBConfiguration(
                 app=app, phy=phy,
                 index=1, string='Emulated CDC',
                 interfaces=interfaces,
             )
         ])
Example #7
0
 def get_endpoint(self,
                  num,
                  direction,
                  transfer_type,
                  max_packet_size=0x40):
     return USBEndpoint(
         app=self.app,
         phy=self.phy,
         number=num,
         direction=direction,
         transfer_type=transfer_type,
         sync_type=USBEndpoint.sync_type_none,
         usage_type=USBEndpoint.usage_type_data,
         max_packet_size=max_packet_size,
         interval=1,
         handler=self.global_handler,
         usb_class=USBVendorSpecificClass(self.app, self.phy),
         usb_vendor=USBVendorSpecificVendor(self.app, self.phy))
Example #8
0
    def __init__(self, app, phy):
        descriptors = {
            DescriptorType.hid: self.get_icc_descriptor
        }
        self.clock_frequencies = [
            0x00003267, 0x000064ce, 0x0000c99d, 0x0001933a, 0x00032674, 0x00064ce7,
            0x000c99ce, 0x00025cd7, 0x0003f011, 0x00004334, 0x00008669, 0x00010cd1,
            0x000219a2, 0x00043345, 0x0008668a, 0x0002a00b, 0x00003073, 0x000060e6,
            0x0000c1cc, 0x00018399, 0x00030732, 0x00060e63, 0x000122b3, 0x0001e47f,
            0x00015006, 0x00009736, 0x0000fc04, 0x00002853, 0x000050a5, 0x0000a14a,
            0x00014295, 0x00028529, 0x000078f8, 0x0000493e, 0x0000927c, 0x000124f8,
            0x000249f0, 0x000493e0, 0x000927c0, 0x0001b774, 0x0002dc6c, 0x000030d4,
            0x000061a8, 0x0000c350, 0x000186a0, 0x00030d40, 0x00061a80, 0x0001e848,
            0x0000dbba, 0x00016e36, 0x0000f424, 0x00006ddd, 0x0000b71b
        ]

        self.data_rates = []

        self.clock_freq = self.clock_frequencies[0]
        self.data_rate = 0 if not self.data_rates else self.data_rates[0]

        endpoints = [
            # CCID command pipe
            USBEndpoint(
                app=app,
                phy=phy,
                number=1,
                direction=USBEndpoint.direction_out,
                transfer_type=USBEndpoint.transfer_type_bulk,
                sync_type=USBEndpoint.sync_type_none,
                usage_type=USBEndpoint.usage_type_data,
                max_packet_size=0x40,
                interval=0,
                handler=self.handle_data_available
            ),
            # CCID response pipe
            USBEndpoint(
                app=app,
                phy=phy,
                number=2,
                direction=USBEndpoint.direction_in,
                transfer_type=USBEndpoint.transfer_type_bulk,
                sync_type=USBEndpoint.sync_type_none,
                usage_type=USBEndpoint.usage_type_data,
                max_packet_size=0x40,
                interval=0,
                handler=None
            ),
            # CCID event notification pipe
            USBEndpoint(
                app=app,
                phy=phy,
                number=3,
                direction=USBEndpoint.direction_in,
                transfer_type=USBEndpoint.transfer_type_interrupt,
                sync_type=USBEndpoint.sync_type_none,
                usage_type=USBEndpoint.usage_type_data,
                max_packet_size=8,
                interval=0,
                handler=self.handle_buffer_available
            ),
        ]

        # TODO: un-hardcode string index (last arg before 'verbose')
        super(USBSmartcardInterface, self).__init__(
            app=app,
            phy=phy,
            interface_number=0,
            interface_alternate=0,
            interface_class=USBClass.SmartCard,
            interface_subclass=0,
            interface_protocol=0,
            interface_string_index=0,
            endpoints=endpoints,
            descriptors=descriptors,
            usb_class=USBSmartcardClass(app, phy)
        )

        self.proto = 0
        self.abProtocolDataStructure = b'\x11\x00\x00\x0a\x00'
        self.clock_status = 0x00
        self.int_q = Queue()
        self.int_q.put(b'\x50\x03')

        self.operations = {
            PcToRdrOpcode.IccPowerOn: self.handle_PcToRdr_IccPowerOn,
            PcToRdrOpcode.IccPowerOff: self.handle_PcToRdr_IccPowerOff,
            PcToRdrOpcode.GetSlotStatus: self.handle_PcToRdr_GetSlotStatus,
            PcToRdrOpcode.XfrBlock: self.handle_PcToRdr_XfrBlock,
            PcToRdrOpcode.GetParameters: self.handle_PcToRdr_GetParameters,
            PcToRdrOpcode.ResetParameters: self.handle_PcToRdr_ResetParameters,
            PcToRdrOpcode.SetParameters: self.handle_PcToRdr_SetParameters,
            PcToRdrOpcode.Escape: self.handle_PcToRdr_Escape,
            PcToRdrOpcode.IccClock: self.handle_PcToRdr_IccClock,
            PcToRdrOpcode.T0APDU: self.handle_PcToRdr_T0APDU,
            PcToRdrOpcode.Secure: self.handle_PcToRdr_Secure,
            PcToRdrOpcode.Mechanical: self.handle_PcToRdr_Mechanical,
            PcToRdrOpcode.Abort: self.handle_PcToRdr_Abort,
            PcToRdrOpcode.SetDataRateAndClock_Frequency: self.handle_PcToRdr_SetDataRateAndClock_Frequency,
        }
Example #9
0
 def __init__(self,
              app,
              phy,
              vid=0x0d8c,
              pid=0x000c,
              rev=0x0001,
              *args,
              **kwargs):
     audio_streaming = AudioStreaming(app, phy, 2, 1)
     usb_class = USBAudioClass(app, phy)
     super(USBAudioDevice, self).__init__(
         app=app,
         phy=phy,
         device_class=USBClass.Unspecified,
         device_subclass=0,
         protocol_rel_num=0,
         max_packet_size_ep0=0x40,
         vendor_id=vid,
         product_id=pid,
         device_rev=rev,
         manufacturer_string='UMAP2 Sound Inc.',
         product_string='UMAP2 Audio Adapter',
         serial_number_string='UMAP2-12345-AUDIO',
         configurations=[
             USBConfiguration(
                 app=app,
                 phy=phy,
                 index=1,
                 string='UMAP2 Audio Configuration',
                 attributes=USBConfiguration.ATTR_BASE,
                 interfaces=[
                     # standard AC interface (4.3.1)
                     # At this point - with no endpoints
                     USBAudioControlInterface(
                         app=app,
                         phy=phy,
                         iface_num=0,
                         iface_alt=0,
                         iface_str_idx=0,
                         cs_ifaces=[
                             # Class specific AC interface: header (4.3.2)
                             USBCSInterface(
                                 'ACHeader', app, phy,
                                 '\x01\x00\x01\x64\x00\x02\x01\x02'),
                             # Class specific AC interface: input terminal (Table 4.3.2.1)
                             USBCSInterface(
                                 'ACInputTerminal0', app, phy,
                                 '\x02\x01\x01\x01\x00\x02\x03\x00\x00\x00'
                             ),
                             USBCSInterface(
                                 'ACInputTerminal1', app, phy,
                                 '\x02\x02\x01\x02\x00\x01\x01\x00\x00\x00'
                             ),
                             # Class specific AC interface: output terminal (Table 4.3.2.2)
                             USBCSInterface('ACOutputTerminal0', app, phy,
                                            '\x03\x06\x01\x03\x00\x09\x00'),
                             USBCSInterface('ACOutputTerminal1', app, phy,
                                            '\x03\x07\x01\x01\x00\x08\x00'),
                             # Class specific AC interface: selector unit (Table 4.3.2.4)
                             USBCSInterface('ACSelectorUnit', app, phy,
                                            '\x05\x08\x01\x0a\x00'),
                             # Class specific AC interface: feature unit (Table 4.3.2.5)
                             USBCSInterface(
                                 'ACFeatureUnit0', app, phy,
                                 '\x06\x09\x0f\x01\x01\x02\x02\x00'),
                             USBCSInterface('ACFeatureUnit1', app, phy,
                                            '\x06\x0a\x02\x01\x43\x00\x00'),
                             USBCSInterface('ACFeatureUnit2', app, phy,
                                            '\x06\x0d\x02\x01\x03\x00\x00'),
                             # Class specific AC interface: mixer unit (Table 4.3.2.3)
                             USBCSInterface(
                                 'ACMixerUnit', app, phy,
                                 '\x04\x0f\x02\x01\x0d\x02\x03\x00\x00\x00\x00'
                             ),
                         ],
                         usb_class=usb_class),
                     USBAudioStreamingInterface(
                         app=app,
                         phy=phy,
                         iface_num=1,
                         iface_alt=0,
                         iface_str_idx=0,
                         cs_ifaces=[
                             USBCSInterface('ASGeneral', app, phy,
                                            '\x01\x01\x01\x01\x00'),
                             USBCSInterface(
                                 'ASFormatType', app, phy,
                                 '\x02\x01\x02\x02\x10\x02\x44\xac\x00\x44\xac\x00'
                             ),
                         ],
                         endpoints=[
                             USBEndpoint(
                                 app=app,
                                 phy=phy,
                                 number=1,
                                 direction=USBEndpoint.direction_out,
                                 transfer_type=USBEndpoint.
                                 transfer_type_isochronous,
                                 sync_type=USBEndpoint.sync_type_adaptive,
                                 usage_type=USBEndpoint.usage_type_data,
                                 max_packet_size=0x40,
                                 interval=1,
                                 handler=audio_streaming.data_available,
                                 cs_endpoints=[
                                     USBCSEndpoint('ASEndpoint', app, phy,
                                                   '\x01\x01\x01\x01\x00')
                                 ],
                                 usb_class=usb_class,
                             )
                         ],
                         usb_class=usb_class,
                     ),
                     USBAudioStreamingInterface(
                         app=app,
                         phy=phy,
                         iface_num=2,
                         iface_alt=0,
                         iface_str_idx=0,
                         cs_ifaces=[
                             USBCSInterface('ASGeneral', app, phy,
                                            '\x01\x07\x01\x01\x00'),
                             USBCSInterface(
                                 'ASFormatType', app, phy,
                                 '\x02\x01\x01\x02\x10\x02\x44\xac\x00\x44\xac\x00'
                             ),
                         ],
                         endpoints=[
                             USBEndpoint(
                                 app=app,
                                 phy=phy,
                                 number=2,
                                 direction=USBEndpoint.direction_in,
                                 transfer_type=USBEndpoint.
                                 transfer_type_isochronous,
                                 sync_type=USBEndpoint.sync_type_async,
                                 usage_type=USBEndpoint.usage_type_data,
                                 max_packet_size=0x40,
                                 interval=1,
                                 handler=audio_streaming.buffer_available,
                                 cs_endpoints=[
                                     USBCSEndpoint('ASEndpoint', app, phy,
                                                   '\x01\x01\x00\x00\x00')
                                 ],
                                 usb_class=usb_class,
                             )
                         ],
                         usb_class=usb_class,
                     )
                 ]),
         ],
         usb_vendor=None)
Example #10
0
    def __init__(self, app, phy):
        if not mtpdeviceloaded:
            raise Exception('You cannot use USBMtp until you install pymtpdevice')
        # TODO: un-hardcode string index (last arg before 'verbose')
        super(USBMtpInterface, self).__init__(
            app=app,
            phy=phy,
            interface_number=0,
            interface_alternate=0,
            interface_class=USBClass.VendorSpecific,
            interface_subclass=0xff,
            interface_protocol=0,
            interface_string_index=0,
            endpoints=[
                USBEndpoint(
                    app=app,
                    phy=phy,
                    number=1,
                    direction=USBEndpoint.direction_out,
                    transfer_type=USBEndpoint.transfer_type_bulk,
                    sync_type=USBEndpoint.sync_type_none,
                    usage_type=USBEndpoint.usage_type_data,
                    max_packet_size=64,
                    interval=0,
                    handler=self.handle_ep1_data_available
                ),
                USBEndpoint(
                    app=app,
                    phy=phy,
                    number=2,
                    direction=USBEndpoint.direction_in,
                    transfer_type=USBEndpoint.transfer_type_bulk,
                    sync_type=USBEndpoint.sync_type_none,
                    usage_type=USBEndpoint.usage_type_data,
                    max_packet_size=64,
                    interval=0,
                    handler=None
                ),
                USBEndpoint(
                    app=app,
                    phy=phy,
                    number=3,
                    direction=USBEndpoint.direction_in,
                    transfer_type=USBEndpoint.transfer_type_interrupt,
                    sync_type=USBEndpoint.sync_type_none,
                    usage_type=USBEndpoint.usage_type_data,
                    max_packet_size=64,
                    interval=32,
                    handler=None
                ),
            ],
        )
        self.object = MtpObject.from_fs_recursive('mtp_fs')
        # self.object = MtpObject.from_fs_recursive('mtp_fs/eits.mp3')
        self.storage_info = MtpStorageInfo(
            st_type=1,
            fs_type=2,
            access=0,
            max_cap=150000,
            free_bytes=0,
            free_objs=0,
            desc='MyStorage',
            vol_id='Python MTP Device Stack',
        )
        self.storage = MtpStorage(self.storage_info)
        self.storage.add_object(self.object)
        self.dev_info = MtpDeviceInfo(
            std_version=0x0064,
            mtp_vendor_ext_id=0x00000006,
            mtp_version=0x0064,
            mtp_extensions='microsoft.com: 1.0;',
            functional_mode=0x0000,
            capture_formats=[],
            playback_formats=[],
            manufacturer='UMAP2',
            model='Role',
            device_version='1.2',
            serial_number='3031323334353637',
        )
        properties = [
            MtpDeviceProperty(MtpDevicePropertyCode.MTP_DeviceFriendlyName, 0, MStr('UmapMtpDevice'), MStr('')),
            MtpDeviceProperty(MtpDevicePropertyCode.BatteryLevel, 0, UInt8(100), UInt8(0))
        ]
        self.dev = MtpDevice(self.dev_info, properties, self.logger)
        self.dev.add_storage(self.storage)
        self.dev.set_fuzzer(app.fuzzer)
        self.api = MtpApi(self.dev)

        # OS String descriptor
        # self.add_string_with_id(50, 'MTP'.encode('utf-16') + b'\x00\x00')
        self.add_string_with_id(0xee, 'MSFT100'.encode('utf-16') + b'\x00\x00')
Example #11
0
    def __init__(self, app, phy, int_num, usbclass, sub, proto):
        self.filename = time.strftime('%Y%m%d%H%M%S', time.localtime())
        self.filename += '.pcl'
        self.writing = False

        endpoints0 = [
            USBEndpoint(
                app=app,
                phy=phy,
                number=1,  # endpoint address
                direction=USBEndpoint.direction_out,
                transfer_type=USBEndpoint.transfer_type_bulk,
                sync_type=USBEndpoint.sync_type_none,
                usage_type=USBEndpoint.usage_type_data,
                max_packet_size=0x40,  # max packet size
                interval=0x80,  # polling interval, see USB 2.0 spec Table 9-13
                handler=self.handle_data_available  # handler function
            ),
            USBEndpoint(
                app=app,
                phy=phy,
                number=2,  # endpoint address
                direction=USBEndpoint.direction_in,
                transfer_type=USBEndpoint.transfer_type_bulk,
                sync_type=USBEndpoint.sync_type_none,
                usage_type=USBEndpoint.usage_type_data,
                max_packet_size=0x40,  # max packet size
                interval=0,  # polling interval, see USB 2.0 spec Table 9-13
                handler=None  # handler function
            )
        ]

        endpoints1 = [
            USBEndpoint(app=app,
                        phy=phy,
                        number=1,
                        direction=USBEndpoint.direction_out,
                        transfer_type=USBEndpoint.transfer_type_bulk,
                        sync_type=USBEndpoint.sync_type_none,
                        usage_type=USBEndpoint.usage_type_data,
                        max_packet_size=0x40,
                        interval=0x80,
                        handler=self.handle_data_available),
            USBEndpoint(app=app,
                        phy=phy,
                        number=2,
                        direction=USBEndpoint.direction_in,
                        transfer_type=USBEndpoint.transfer_type_bulk,
                        sync_type=USBEndpoint.sync_type_none,
                        usage_type=USBEndpoint.usage_type_data,
                        max_packet_size=0x40,
                        interval=0,
                        handler=None)
        ]
        if int_num == 0:
            endpoints = endpoints0
        if int_num == 1:
            endpoints = endpoints1

        # TODO: un-hardcode string index (last arg before 'verbose')
        super(USBPrinterInterface, self).__init__(
            app=app,
            phy=phy,
            interface_number=int_num,
            interface_alternate=0,
            interface_class=usbclass,
            interface_subclass=sub,
            interface_protocol=proto,
            interface_string_index=0,
            endpoints=endpoints,
            usb_class=USBPrinterClass(app, phy),
        )