use usb_util::Transfer;
use usb_util::TransferBuffer;
use usb_util::TransferStatus;
use usb_util::UsbRequestSetup;
use crate::usb::backend::endpoint::ControlEndpointState;
use crate::usb::backend::error::Result;
use crate::usb::backend::fido_backend::transfer::FidoTransfer;
pub struct BackendTransferHandle {
handle: Box<dyn GenericTransferHandle>,
}
impl BackendTransferHandle {
pub fn new(handle: impl GenericTransferHandle + 'static) -> Self {
BackendTransferHandle {
handle: Box::new(handle),
}
}
pub fn cancel(&self) -> Result<()> {
self.handle.cancel()
}
}
pub enum BackendTransferType {
HostDevice(Transfer),
FidoDevice(FidoTransfer),
}
pub trait BackendTransfer {
fn status(&self) -> TransferStatus;
fn actual_length(&self) -> usize;
fn buffer(&self) -> &TransferBuffer;
fn set_callback<C: 'static + Fn(BackendTransferType) + Send + Sync>(&mut self, cb: C);
}
impl BackendTransfer for BackendTransferType {
fn status(&self) -> TransferStatus {
match self {
BackendTransferType::HostDevice(transfer) => BackendTransfer::status(transfer),
BackendTransferType::FidoDevice(transfer) => BackendTransfer::status(transfer),
}
}
fn actual_length(&self) -> usize {
match self {
BackendTransferType::HostDevice(transfer) => BackendTransfer::actual_length(transfer),
BackendTransferType::FidoDevice(transfer) => BackendTransfer::actual_length(transfer),
}
}
fn buffer(&self) -> &TransferBuffer {
match self {
BackendTransferType::HostDevice(transfer) => BackendTransfer::buffer(transfer),
BackendTransferType::FidoDevice(transfer) => BackendTransfer::buffer(transfer),
}
}
fn set_callback<C: 'static + Fn(BackendTransferType) + Send + Sync>(&mut self, cb: C) {
match self {
BackendTransferType::HostDevice(transfer) => {
BackendTransfer::set_callback(transfer, cb)
}
BackendTransferType::FidoDevice(transfer) => {
BackendTransfer::set_callback(transfer, cb)
}
}
}
}
pub trait GenericTransferHandle: Send {
fn cancel(&self) -> Result<()>;
}
#[derive(Copy, Clone)]
pub struct ControlTransferState {
pub ctl_ep_state: ControlEndpointState,
pub control_request_setup: UsbRequestSetup,
pub executed: bool,
}