devices/usb/backend/
utils.rs1use std::sync::Arc;
6
7use anyhow::Context;
8use base::error;
9use sync::Mutex;
10use usb_util::TransferStatus;
11
12use crate::usb::backend::device::BackendDeviceType;
13use crate::usb::backend::error::Error;
14use crate::usb::backend::error::Result;
15use crate::usb::xhci::xhci_transfer::XhciTransferState;
16use crate::utils::EventHandler;
17
18#[macro_export]
19macro_rules! multi_dispatch {
30 ($self:ident, $enum:ident, $($types:ident )+, $func:ident) => {
31 match $self {
32 $(
33 $enum::$types(device) => device.$func(),
34 )+
35 }
36 };
37 ($self:ident, $enum:ident, $($types:ident )+, $func:ident, $param:expr) => {
38 match $self {
39 $(
40 $enum::$types(device) => device.$func($param),
41 )+
42 }
43 };
44 ($self:ident, $enum:ident, $($types:ident )+, $func:ident, $param1:expr, $param2: expr) => {
45 match $self {
46 $(
47 $enum::$types(device) => device.$func($param1, $param2),
48 )+
49 }
50 };
51 ($self:ident, $enum:ident, $($types:ident )+, $func:ident, $param1:expr, $param2: expr, $param3: expr) => {
52 match $self {
53 $(
54 $enum::$types(device) => device.$func($param1, $param2, $param3),
55 )+
56 }
57 };
58}
59
60pub(crate) use multi_dispatch;
61
62pub struct UsbUtilEventHandler {
63 pub device: Arc<Mutex<BackendDeviceType>>,
64}
65
66impl EventHandler for UsbUtilEventHandler {
67 fn on_event(&self) -> anyhow::Result<()> {
68 match &mut *self.device.lock() {
69 BackendDeviceType::HostDevice(host_device) => host_device
70 .device
71 .lock()
72 .poll_transfers()
73 .context("UsbUtilEventHandler poll_transfers failed"),
74 BackendDeviceType::FidoDevice(fido_device) => fido_device
75 .read_hidraw_file()
76 .context("FidoDeviceEventHandler failed to read hidraw device"),
77 }
78 }
79}
80
81pub fn update_transfer_state(state: &mut XhciTransferState, status: TransferStatus) -> Result<()> {
83 if status == TransferStatus::Cancelled {
84 *state = XhciTransferState::Cancelled;
85 return Ok(());
86 }
87
88 match *state {
89 XhciTransferState::Cancelling => {
90 *state = XhciTransferState::Cancelled;
91 }
92 XhciTransferState::Submitted { .. } => {
93 *state = XhciTransferState::Completed;
94 }
95 _ => {
96 error!("xhci trasfer state is invalid");
97 *state = XhciTransferState::Completed;
98 return Err(Error::BadXhciTransferState);
99 }
100 }
101 Ok(())
102}