facedancer.backends.hydradancer module

Backend for the Hydradancer boards.

Supports 5 endpoints, with addresses between 0 and 7. Supports low, full and high-speed.

class facedancer.backends.hydradancer.HydradancerBoard[source]

Bases: object

Handles the communication with the Hydradancer control board and manages the events it sends.

CHECK_HYDRADANCER_READY = 57
CLEAR_HALT = 60
CONFIGURED = 59
DEVICE_TO_HOST = 1
DISABLE_USB = 54
DO_BUS_RESET = 58
ENABLE_USB_CONNECTION = 50
ENDP_STATE_ACK = 0
ENDP_STATE_NAK = 2
ENDP_STATE_STALL = 3
EP_POLL_NUMBER = 1
EVENT_QUEUE_SIZE = 100
GET_EVENT = 52
HOST_TO_DEVICE = 0
INCOMPATIBLE_EP = [[], [9], [10], [11], [8, 12], [13], [14], [15], [4], [1], [2], [3], [4], [5], [6], [7]]
MAX_PACKET_SIZE = 1024
SET_ADDRESS = 51
SET_ENDPOINT_MAPPING = 53
SET_EP_RESPONSE = 56
SET_SPEED = 55
SUPPORTED_EP_NUM = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
__init__()[source]

Get handles on the USB control board, and wait for Hydradancer to be ready

clear_halt(endpoint_number: int, direction: USBDirection)[source]
configure(endpoint_numbers)[source]
connect()[source]

Enable the USB2 connection on the emulation board

control_buffer_available()[source]

Returns True if the control buffer is available. Since this buffer is shared between EP0 IN/EP0 OUT, only the OUT status is used for both.

disconnect()[source]

Disable the USB2 connection on the emulation board, and reset internal states on both control and emulation boards.

facedancer_to_hydradancer_speed = {DeviceSpeed.LOW: 0, DeviceSpeed.FULL: 1, DeviceSpeed.HIGH: 2}
fetch_events()[source]

Poll the status of the endpoints. The state are accumulated (like on the boards), and cleared when sending or reading data (which will trigger a similar clear on the boards). Thus, self.ep_status should always be in sync with the endpoint’s status on the boards.

in_buffer_empty(ep_num)[source]

Returns True if the IN buffer for target endpoint ep_num is ready for priming

nak_on_endpoint(ep_num)[source]

Returns True if the IN Endpoint has sent a NAK (meaning a host has sent an IN request)

out_buffer_available(ep_num)[source]

Returns True if the OUT buffer for target endpoint ep_num is full

read(ep_num, blocking=False)[source]

Read from target endpoint ep_num. If blocking=True, wait until the endpoint’s buffer is full.

reinit(keep_ep0: bool = False)[source]
send(ep_num, data)[source]

Prime target endpoint ep_num.

set_address(address, defer=False)[source]

Set the USB address on the emulation board

set_endpoint_mapping(ep_num)[source]

Maps emulated endpoints (endpoints facing the target) to Facedancer’s host endpoints (control board endpoints)

set_usb2_speed(device_speed: DeviceSpeed = DeviceSpeed.FULL)[source]

Set the speed of the USB2 device. Speed is physically determined by the host, so the emulation board must be configured.

stall_endpoint(ep_num, direction=0)[source]

Stall the ep_num endpoint on the emulation board. STALL will be cleared automatically after next SETUP packet received.

timeout_ms_poll = 1
wait_board_ready()[source]

Wait until the Hydradancer boards are ready, try to disconnect at some point to reset the internal states, hoping it will be ready next time.

exception facedancer.backends.hydradancer.HydradancerBoardFatalError[source]

Bases: Exception

class facedancer.backends.hydradancer.HydradancerEvent(event_type: int = -1, value: int = -1)[source]

Bases: object

EVENT_BUS_RESET = 0
EVENT_IN_BUFFER_AVAILABLE = 1
EVENT_NAK = 3
EVENT_OUT_BUFFER_AVAILABLE = 2
event_type: int = -1
static from_bytes(data: bytes)[source]
value: int = -1
class facedancer.backends.hydradancer.HydradancerHostApp(device: USBDevice = None, verbose: int = 0, quirks: List[str] = [])[source]

Bases: FacedancerApp, FacedancerBackend

Backend for the HydraUSB3 boards.

DEVICE_TO_HOST = 1
HOST_TO_DEVICE = 0
MANUFACTURER_STRING = 'Quarkslab https://www.quarkslab.com/ & HydraBus https://hydrabus.com/'
USB2_MAX_EP_IN = 16
__init__(device: USBDevice = None, verbose: int = 0, quirks: List[str] = [])[source]

Initializes the backend.

Parameters:
  • device – The device that will act as our Facedancer. (Optional)

  • verbose – The verbosity level of the given application. (Optional)

  • quirks – List of USB platform quirks. (Optional)

ack_status_stage(direction: USBDirection = USBDirection.OUT, endpoint_number: int = 0, blocking: bool = False)[source]

Handles the status stage of a correctly completed control request, by priming the appropriate endpoint to handle the status phase.

Parameters:
  • direction – Determines if we’re ACK’ing an IN or OUT vendor request. (This should match the direction of the DATA stage.)

  • endpoint_number – The endpoint number on which the control request occurred.

  • blocking – True if we should wait for the ACK to be fully issued before returning.

app_name = 'Hydradancer Host'
classmethod appropriate_for_environment(backend_name: str) bool[source]

Determines if the current environment seems appropriate for using this backend.

Parameters:

backend_name – Backend name being requested. (Optional)

clear_halt(endpoint_number: int, direction: USBDirection)[source]

Clears a halt condition on the provided non-control endpoint.

Parameters:
  • endpoint_number – The endpoint number

  • direction – The endpoint direction; or OUT if not provided.

configured(configuration: USBConfiguration)[source]

Callback that’s issued when a USBDevice is configured, e.g. by the SET_CONFIGURATION request. Allows us to apply the new configuration.

Parameters:

configuration – The USBConfiguration object applied by the SET_CONFIG request.

connect(usb_device: USBDevice, max_packet_size_ep0: int = 64, device_speed: DeviceSpeed = DeviceSpeed.FULL)[source]

Prepares backend to connect to the target host and emulate a given device.

Parameters:
  • usb_device – The USBDevice object that represents the emulated device.

  • max_packet_size_ep0 – Max packet size for control endpoint.

  • device_speed – Requested usb speed for the Facedancer board.

current_setup_req = None
disconnect()[source]

Disconnects Facedancer from the target host.

get_version()[source]

Returns information about the active Facedancer version.

handle_bus_reset()[source]

Triggers Hydradancer to perform its side of a bus reset.

handle_control_request()[source]
handle_data_endpoints()[source]

Handle IN or OUT requests on non-control endpoints.

read_from_endpoint(endpoint_number: int) bytes[source]

Reads a block of data from the given endpoint.

Parameters:

endpoint_number – The number of the OUT endpoint on which data is to be rx’d.

reset()[source]

Triggers the Facedancer to handle its side of a bus reset.

send_on_endpoint(endpoint_number: int, data: bytes, blocking: bool = True)[source]

Sends a collection of USB data on a given endpoint.

Parameters:
  • endpoint_number – The number of the IN endpoint on which data should be sent.

  • data – The data to be sent.

  • blocking – If true, this function should wait for the transfer to complete.

service_irqs()[source]

Core routine of the Facedancer execution/event loop. Continuously monitors the Facedancer’s execution status, and reacts as events occur.

set_address(address: int, defer: bool = False)[source]

Sets the device address of the Facedancer. Usually only used during initial configuration.

Parameters:
  • address – The address the Facedancer should assume.

  • defer – True iff the set_address request should wait for an active transaction to finish.

stall_endpoint(endpoint_number: int, direction: USBDirection = USBDirection.OUT)[source]

Stalls the provided endpoint, as defined in the USB spec.

Parameters:

endpoint_number – The number of the endpoint to be stalled.