1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use crate::hid_class::descriptor::HidProtocol;
use delegate::delegate;
use embedded_time::duration::Milliseconds;
use usb_device::bus::{InterfaceNumber, StringIndex, UsbBus};
use usb_device::class_prelude::DescriptorWriter;
use crate::hid_class::prelude::*;
use crate::interface::raw::{RawInterface, RawInterfaceConfig};
use crate::interface::{InterfaceClass, WrappedInterface, WrappedInterfaceConfig};
use crate::UsbHidError;
#[rustfmt::skip]
pub const FIDO_REPORT_DESCRIPTOR: &[u8] = &[
0x06, 0xD0, 0xF1, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 0x02, 0xC0, ];
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(C, align(8))]
pub struct RawFidoMsg {
pub packet: [u8; 64],
}
impl Default for RawFidoMsg {
fn default() -> RawFidoMsg {
RawFidoMsg { packet: [0u8; 64] }
}
}
pub struct RawFidoInterface<'a, B: UsbBus> {
inner: RawInterface<'a, B>,
}
impl<'a, B: UsbBus> RawFidoInterface<'a, B> {
pub fn write_report(&self, report: &RawFidoMsg) -> Result<(), UsbHidError> {
self.inner
.write_report(&report.packet)
.map(|_| ())
.map_err(UsbHidError::from)
}
pub fn read_report(&self) -> usb_device::Result<RawFidoMsg> {
let mut report = RawFidoMsg::default();
match self.inner.read_report(&mut report.packet) {
Err(e) => Err(e),
Ok(_) => Ok(report),
}
}
pub fn default_config() -> WrappedInterfaceConfig<Self, RawInterfaceConfig<'a>> {
WrappedInterfaceConfig::new(
RawInterfaceBuilder::new(FIDO_REPORT_DESCRIPTOR)
.description("U2F Token")
.in_endpoint(UsbPacketSize::Bytes64, Milliseconds(5))
.unwrap()
.with_out_endpoint(UsbPacketSize::Bytes64, Milliseconds(5))
.unwrap()
.build(),
(),
)
}
}
impl<'a, B: UsbBus> InterfaceClass<'a> for RawFidoInterface<'a, B> {
delegate! {
to self.inner{
fn report_descriptor(&self) -> &'_ [u8];
fn id(&self) -> InterfaceNumber;
fn write_descriptors(&self, writer: &mut DescriptorWriter) -> usb_device::Result<()>;
fn get_string(&self, index: StringIndex, _lang_id: u16) -> Option<&'_ str>;
fn reset(&mut self);
fn set_report(&mut self, data: &[u8]) -> usb_device::Result<()>;
fn get_report(&mut self, data: &mut [u8]) -> usb_device::Result<usize>;
fn get_report_ack(&mut self) -> usb_device::Result<()>;
fn set_idle(&mut self, report_id: u8, value: u8);
fn get_idle(&self, report_id: u8) -> u8;
fn set_protocol(&mut self, protocol: HidProtocol);
fn get_protocol(&self) -> HidProtocol;
}
}
}
impl<'a, B: UsbBus> WrappedInterface<'a, B, RawInterface<'a, B>> for RawFidoInterface<'a, B> {
fn new(interface: RawInterface<'a, B>, _: ()) -> Self {
Self { inner: interface }
}
}