transferOne control transfer, blocking on the reply

fn transfer(&self, ep: u8, setup: Setup, out: &[u8]) -> Result<TransferOutcome>
fn transfer_timeout(&self, ep: u8, setup: Setup, out: &[u8], timeout: Duration) -> Result<TransferOutcome>

Blocks

ParameterTypeDescription
epu80 for EP0, or a control endpoint number the real device declares.
setupSetupEight-byte setup packet.
out&[u8]OUT data stage, sent after the setup packet. Empty for an IN transfer.

Ok(_) means the box replied. A TransferStatus other than Ok comes back inside the TransferOutcome, not as an error.

transfer uses DEFAULT_TRANSFER_TIMEOUT (1.5 s). The box gives up after ~800 ms. Keep transfer_timeout ≥800 ms.

A SET_CONFIGURATION or SET_INTERFACE sent here changes only the real device. The clone and the endpoints the host chip polls stay where the game PC set them.

EXAMPLE
use medius::{Device, Setup, TransferStatus};

let device = Device::find()?;
device.allow_imperfect_clones(true)?;

let reply = device.transfer(0, Setup::new(0x80, 0x06, 0x0100, 0x0000, 18), &[])?;
if reply.status == TransferStatus::Ok {
    println!("device descriptor: {:02x?}", reply.data());
}

On AsyncDevicetransfer awaits the native reply

On AsyncDevice, transfer and transfer_timeout are futures, awaited like any query.

EXAMPLE
use futures::executor::block_on;
use medius::{AsyncDevice, Setup, TransferStatus};

let device = AsyncDevice::open("/dev/ttyACM0")?;
device.allow_imperfect_clones(true)?;
let reply = block_on(device.transfer(0, Setup::new(0x80, 0x06, 0x0100, 0x0000, 18), &[]))?;
if reply.status == TransferStatus::Ok {
    println!("device descriptor: {:02x?}", reply.data());
}