Add component for USB CTAP.
This commit is contained in:
@@ -1,16 +1,111 @@
|
||||
diff --git a/boards/components/src/lib.rs b/boards/components/src/lib.rs
|
||||
index dc56c94d2..917497af4 100644
|
||||
--- a/boards/components/src/lib.rs
|
||||
+++ b/boards/components/src/lib.rs
|
||||
@@ -36,3 +36,4 @@ pub mod spi;
|
||||
pub mod st7735;
|
||||
pub mod temperature;
|
||||
pub mod touch;
|
||||
+pub mod usb_ctap;
|
||||
diff --git a/boards/components/src/usb_ctap.rs b/boards/components/src/usb_ctap.rs
|
||||
new file mode 100644
|
||||
index 000000000..69e95c3c7
|
||||
--- /dev/null
|
||||
+++ b/boards/components/src/usb_ctap.rs
|
||||
@@ -0,0 +1,88 @@
|
||||
+//! Component for CTAP over USB.
|
||||
+
|
||||
+use capsules::usb::usb_ctap::CtapUsbSyscallDriver;
|
||||
+use capsules::usb::usbc_ctap_hid::ClientCtapHID;
|
||||
+use core::mem::MaybeUninit;
|
||||
+use kernel::capabilities;
|
||||
+use kernel::component::Component;
|
||||
+use kernel::create_capability;
|
||||
+use kernel::hil;
|
||||
+use kernel::static_init_half;
|
||||
+
|
||||
+// Setup static space for the objects.
|
||||
+#[macro_export]
|
||||
+macro_rules! usb_ctap_component_buf {
|
||||
+ ($C:ty) => {{
|
||||
+ use capsules::usb::usb_ctap::CtapUsbSyscallDriver;
|
||||
+ use capsules::usb::usbc_ctap_hid::ClientCtapHID;
|
||||
+ use core::mem::MaybeUninit;
|
||||
+ static mut BUF1: MaybeUninit<ClientCtapHID<'static, 'static, $C>> = MaybeUninit::uninit();
|
||||
+ static mut BUF2: MaybeUninit<CtapUsbSyscallDriver<'static, 'static, $C>> =
|
||||
+ MaybeUninit::uninit();
|
||||
+ (&mut BUF1, &mut BUF2)
|
||||
+ };};
|
||||
+}
|
||||
+
|
||||
+pub struct UsbCtapComponent<C: 'static + hil::usb::UsbController<'static>> {
|
||||
+ board_kernel: &'static kernel::Kernel,
|
||||
+ controller: &'static C,
|
||||
+ max_ctrl_packet_size: u8,
|
||||
+ vendor_id: u16,
|
||||
+ product_id: u16,
|
||||
+ strings: &'static [&'static str],
|
||||
+}
|
||||
+
|
||||
+impl<C: 'static + hil::usb::UsbController<'static>> UsbCtapComponent<C> {
|
||||
+ pub fn new(
|
||||
+ board_kernel: &'static kernel::Kernel,
|
||||
+ controller: &'static C,
|
||||
+ max_ctrl_packet_size: u8,
|
||||
+ vendor_id: u16,
|
||||
+ product_id: u16,
|
||||
+ strings: &'static [&'static str],
|
||||
+ ) -> Self {
|
||||
+ Self {
|
||||
+ board_kernel,
|
||||
+ controller,
|
||||
+ max_ctrl_packet_size,
|
||||
+ vendor_id,
|
||||
+ product_id,
|
||||
+ strings,
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+impl<C: 'static + hil::usb::UsbController<'static>> Component for UsbCtapComponent<C> {
|
||||
+ type StaticInput = (
|
||||
+ &'static mut MaybeUninit<ClientCtapHID<'static, 'static, C>>,
|
||||
+ &'static mut MaybeUninit<CtapUsbSyscallDriver<'static, 'static, C>>,
|
||||
+ );
|
||||
+ type Output = &'static CtapUsbSyscallDriver<'static, 'static, C>;
|
||||
+
|
||||
+ unsafe fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
|
||||
+ let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
|
||||
+
|
||||
+ let usb_ctap = static_init_half!(
|
||||
+ static_buffer.0,
|
||||
+ ClientCtapHID<'static, 'static, C>,
|
||||
+ ClientCtapHID::new(
|
||||
+ self.controller,
|
||||
+ self.max_ctrl_packet_size,
|
||||
+ self.vendor_id,
|
||||
+ self.product_id,
|
||||
+ self.strings,
|
||||
+ )
|
||||
+ );
|
||||
+ self.controller.set_client(usb_ctap);
|
||||
+
|
||||
+ // Configure the USB userspace driver
|
||||
+ let usb_driver = static_init_half!(
|
||||
+ static_buffer.1,
|
||||
+ CtapUsbSyscallDriver<'static, 'static, C>,
|
||||
+ CtapUsbSyscallDriver::new(usb_ctap, self.board_kernel.create_grant(&grant_cap))
|
||||
+ );
|
||||
+ usb_ctap.set_client(usb_driver);
|
||||
+
|
||||
+ usb_driver
|
||||
+ }
|
||||
+}
|
||||
diff --git a/boards/nordic/nrf52840_dongle/src/main.rs b/boards/nordic/nrf52840_dongle/src/main.rs
|
||||
index d72d204..8b97f8d 100644
|
||||
index d72d20482..118ea6d68 100644
|
||||
--- a/boards/nordic/nrf52840_dongle/src/main.rs
|
||||
+++ b/boards/nordic/nrf52840_dongle/src/main.rs
|
||||
@@ -15,6 +15,7 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred
|
||||
use kernel::component::Component;
|
||||
#[allow(unused_imports)]
|
||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
||||
+use kernel::hil::usb::UsbController;
|
||||
use nrf52840::gpio::Pin;
|
||||
use nrf52_components::{self, UartChannel, UartPins};
|
||||
|
||||
@@ -45,6 +46,17 @@ const PAN_ID: u16 = 0xABCD;
|
||||
@@ -45,6 +45,17 @@ const PAN_ID: u16 = 0xABCD;
|
||||
/// UART Writer
|
||||
pub mod io;
|
||||
|
||||
@@ -28,7 +123,7 @@ index d72d204..8b97f8d 100644
|
||||
// State for loading and holding applications.
|
||||
// How should the kernel respond when a process faults.
|
||||
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
|
||||
@@ -96,6 +108,11 @@ pub struct Platform {
|
||||
@@ -96,6 +107,11 @@ pub struct Platform {
|
||||
capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52840::rtc::Rtc<'static>>,
|
||||
>,
|
||||
nvmc: &'static nrf52840::nvmc::SyscallDriver,
|
||||
@@ -40,7 +135,7 @@ index d72d204..8b97f8d 100644
|
||||
}
|
||||
|
||||
impl kernel::Platform for Platform {
|
||||
@@ -115,6 +132,7 @@ impl kernel::Platform for Platform {
|
||||
@@ -115,6 +131,7 @@ impl kernel::Platform for Platform {
|
||||
capsules::temperature::DRIVER_NUM => f(Some(self.temp)),
|
||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
||||
@@ -48,57 +143,29 @@ index d72d204..8b97f8d 100644
|
||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
||||
_ => f(None),
|
||||
}
|
||||
@@ -323,6 +341,49 @@ pub unsafe fn reset_handler() {
|
||||
@@ -323,6 +340,21 @@ pub unsafe fn reset_handler() {
|
||||
)
|
||||
);
|
||||
|
||||
+ // Enable power events to be sent to USB controller
|
||||
+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||
+ nrf52840::power::POWER.enable_interrupts();
|
||||
+
|
||||
+ // Configure USB controller
|
||||
+ let usb:
|
||||
+ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ > = {
|
||||
+ let usb_ctap = static_init!(
|
||||
+ capsules::usb::usbc_ctap_hid::ClientCtapHID<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ >,
|
||||
+ capsules::usb::usbc_ctap_hid::ClientCtapHID::new(
|
||||
+ &nrf52840::usbd::USBD,
|
||||
+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||
+ VENDOR_ID,
|
||||
+ PRODUCT_ID,
|
||||
+ STRINGS,
|
||||
+ )
|
||||
+ );
|
||||
+ nrf52840::usbd::USBD.set_client(usb_ctap);
|
||||
+
|
||||
+ // Enable power events to be sent to USB controller
|
||||
+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||
+ nrf52840::power::POWER.enable_interrupts();
|
||||
+
|
||||
+ // Configure the USB userspace driver
|
||||
+ let usb_driver = static_init!(
|
||||
+ capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ >,
|
||||
+ capsules::usb::usb_ctap::CtapUsbSyscallDriver::new(
|
||||
+ usb_ctap,
|
||||
+ board_kernel.create_grant(&memory_allocation_capability)
|
||||
+ )
|
||||
+ );
|
||||
+ usb_ctap.set_client(usb_driver);
|
||||
+ usb_driver as &'static _
|
||||
+ };
|
||||
+ let usb = components::usb_ctap::UsbCtapComponent::new(
|
||||
+ board_kernel,
|
||||
+ &nrf52840::usbd::USBD,
|
||||
+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||
+ VENDOR_ID,
|
||||
+ PRODUCT_ID,
|
||||
+ STRINGS,
|
||||
+ )
|
||||
+ .finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
||||
+
|
||||
nrf52_components::NrfClockComponent::new().finalize(());
|
||||
|
||||
let platform = Platform {
|
||||
@@ -338,6 +399,7 @@ pub unsafe fn reset_handler() {
|
||||
@@ -338,6 +370,7 @@ pub unsafe fn reset_handler() {
|
||||
alarm,
|
||||
analog_comparator,
|
||||
nvmc,
|
||||
@@ -107,18 +174,10 @@ index d72d204..8b97f8d 100644
|
||||
};
|
||||
|
||||
diff --git a/boards/nordic/nrf52840dk/src/main.rs b/boards/nordic/nrf52840dk/src/main.rs
|
||||
index 2ebb384..303a451 100644
|
||||
index 2ebb384d8..4a7bfffdd 100644
|
||||
--- a/boards/nordic/nrf52840dk/src/main.rs
|
||||
+++ b/boards/nordic/nrf52840dk/src/main.rs
|
||||
@@ -72,6 +72,7 @@ use kernel::common::dynamic_deferred_call::{DynamicDeferredCall, DynamicDeferred
|
||||
use kernel::component::Component;
|
||||
#[allow(unused_imports)]
|
||||
use kernel::{capabilities, create_capability, debug, debug_gpio, debug_verbose, static_init};
|
||||
+use kernel::hil::usb::UsbController;
|
||||
use nrf52840::gpio::Pin;
|
||||
use nrf52_components::{self, UartChannel, UartPins};
|
||||
|
||||
@@ -113,6 +114,17 @@ pub mod io;
|
||||
@@ -113,6 +113,17 @@ pub mod io;
|
||||
// - Set to true to use Segger RTT over USB.
|
||||
const USB_DEBUGGING: bool = false;
|
||||
|
||||
@@ -136,7 +195,7 @@ index 2ebb384..303a451 100644
|
||||
// State for loading and holding applications.
|
||||
// How should the kernel respond when a process faults.
|
||||
const FAULT_RESPONSE: kernel::procs::FaultResponse = kernel::procs::FaultResponse::Panic;
|
||||
@@ -164,6 +176,11 @@ pub struct Platform {
|
||||
@@ -164,6 +175,11 @@ pub struct Platform {
|
||||
>,
|
||||
nonvolatile_storage: &'static capsules::nonvolatile_storage_driver::NonvolatileStorage<'static>,
|
||||
nvmc: &'static nrf52840::nvmc::SyscallDriver,
|
||||
@@ -148,7 +207,7 @@ index 2ebb384..303a451 100644
|
||||
}
|
||||
|
||||
impl kernel::Platform for Platform {
|
||||
@@ -184,6 +201,7 @@ impl kernel::Platform for Platform {
|
||||
@@ -184,6 +200,7 @@ impl kernel::Platform for Platform {
|
||||
capsules::analog_comparator::DRIVER_NUM => f(Some(self.analog_comparator)),
|
||||
capsules::nonvolatile_storage_driver::DRIVER_NUM => f(Some(self.nonvolatile_storage)),
|
||||
nrf52840::nvmc::DRIVER_NUM => f(Some(self.nvmc)),
|
||||
@@ -156,57 +215,29 @@ index 2ebb384..303a451 100644
|
||||
kernel::ipc::DRIVER_NUM => f(Some(&self.ipc)),
|
||||
_ => f(None),
|
||||
}
|
||||
@@ -448,6 +466,49 @@ pub unsafe fn reset_handler() {
|
||||
@@ -448,6 +465,21 @@ pub unsafe fn reset_handler() {
|
||||
)
|
||||
);
|
||||
|
||||
+ // Enable power events to be sent to USB controller
|
||||
+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||
+ nrf52840::power::POWER.enable_interrupts();
|
||||
+
|
||||
+ // Configure USB controller
|
||||
+ let usb:
|
||||
+ &'static capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ > = {
|
||||
+ let usb_ctap = static_init!(
|
||||
+ capsules::usb::usbc_ctap_hid::ClientCtapHID<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ >,
|
||||
+ capsules::usb::usbc_ctap_hid::ClientCtapHID::new(
|
||||
+ &nrf52840::usbd::USBD,
|
||||
+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||
+ VENDOR_ID,
|
||||
+ PRODUCT_ID,
|
||||
+ STRINGS,
|
||||
+ )
|
||||
+ );
|
||||
+ nrf52840::usbd::USBD.set_client(usb_ctap);
|
||||
+
|
||||
+ // Enable power events to be sent to USB controller
|
||||
+ nrf52840::power::POWER.set_usb_client(&nrf52840::usbd::USBD);
|
||||
+ nrf52840::power::POWER.enable_interrupts();
|
||||
+
|
||||
+ // Configure the USB userspace driver
|
||||
+ let usb_driver = static_init!(
|
||||
+ capsules::usb::usb_ctap::CtapUsbSyscallDriver<
|
||||
+ 'static,
|
||||
+ 'static,
|
||||
+ nrf52840::usbd::Usbd<'static>,
|
||||
+ >,
|
||||
+ capsules::usb::usb_ctap::CtapUsbSyscallDriver::new(
|
||||
+ usb_ctap,
|
||||
+ board_kernel.create_grant(&memory_allocation_capability)
|
||||
+ )
|
||||
+ );
|
||||
+ usb_ctap.set_client(usb_driver);
|
||||
+ usb_driver as &'static _
|
||||
+ };
|
||||
+ let usb = components::usb_ctap::UsbCtapComponent::new(
|
||||
+ board_kernel,
|
||||
+ &nrf52840::usbd::USBD,
|
||||
+ capsules::usb::usbc_client::MAX_CTRL_PACKET_SIZE_NRF52840,
|
||||
+ VENDOR_ID,
|
||||
+ PRODUCT_ID,
|
||||
+ STRINGS,
|
||||
+ )
|
||||
+ .finalize(components::usb_ctap_component_buf!(nrf52840::usbd::Usbd));
|
||||
+
|
||||
nrf52_components::NrfClockComponent::new().finalize(());
|
||||
|
||||
let platform = Platform {
|
||||
@@ -464,6 +525,7 @@ pub unsafe fn reset_handler() {
|
||||
@@ -464,6 +496,7 @@ pub unsafe fn reset_handler() {
|
||||
analog_comparator,
|
||||
nonvolatile_storage,
|
||||
nvmc,
|
||||
@@ -215,7 +246,7 @@ index 2ebb384..303a451 100644
|
||||
};
|
||||
|
||||
diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs
|
||||
index 256fc0e..ae458b3 100644
|
||||
index 256fc0e9d..ae458b309 100644
|
||||
--- a/capsules/src/driver.rs
|
||||
+++ b/capsules/src/driver.rs
|
||||
@@ -26,6 +26,7 @@ pub enum NUM {
|
||||
@@ -227,7 +258,7 @@ index 256fc0e..ae458b3 100644
|
||||
// Radio
|
||||
BleAdvertising = 0x30000,
|
||||
diff --git a/capsules/src/usb/mod.rs b/capsules/src/usb/mod.rs
|
||||
index 767f5de..3f3a4f6 100644
|
||||
index 767f5de83..3f3a4f646 100644
|
||||
--- a/capsules/src/usb/mod.rs
|
||||
+++ b/capsules/src/usb/mod.rs
|
||||
@@ -1,5 +1,7 @@
|
||||
@@ -240,7 +271,7 @@ index 767f5de..3f3a4f6 100644
|
||||
+pub mod usbc_ctap_hid;
|
||||
diff --git a/capsules/src/usb/usb_ctap.rs b/capsules/src/usb/usb_ctap.rs
|
||||
new file mode 100644
|
||||
index 0000000..da3d16d
|
||||
index 000000000..da3d16d85
|
||||
--- /dev/null
|
||||
+++ b/capsules/src/usb/usb_ctap.rs
|
||||
@@ -0,0 +1,355 @@
|
||||
@@ -601,10 +632,10 @@ index 0000000..da3d16d
|
||||
+}
|
||||
diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs
|
||||
new file mode 100644
|
||||
index 0000000..d97b72d
|
||||
index 000000000..642039120
|
||||
--- /dev/null
|
||||
+++ b/capsules/src/usb/usbc_ctap_hid.rs
|
||||
@@ -0,0 +1,363 @@
|
||||
@@ -0,0 +1,369 @@
|
||||
+//! A USB HID client of the USB hardware interface
|
||||
+
|
||||
+use super::descriptors;
|
||||
@@ -687,7 +718,7 @@ index 0000000..d97b72d
|
||||
+ max_ctrl_packet_size: u8,
|
||||
+ vendor_id: u16,
|
||||
+ product_id: u16,
|
||||
+ strings: &'static [&'static str]
|
||||
+ strings: &'static [&'static str],
|
||||
+ ) -> Self {
|
||||
+ let interfaces: &mut [InterfaceDescriptor] = &mut [
|
||||
+ // Interface declared in the FIDO2 specification, section 8.1.8.1
|
||||
@@ -701,13 +732,19 @@ index 0000000..d97b72d
|
||||
+
|
||||
+ let endpoints: &[&[EndpointDescriptor]] = &[&[
|
||||
+ EndpointDescriptor {
|
||||
+ endpoint_address: EndpointAddress::new_const(ENDPOINT_NUM, TransferDirection::HostToDevice),
|
||||
+ endpoint_address: EndpointAddress::new_const(
|
||||
+ ENDPOINT_NUM,
|
||||
+ TransferDirection::HostToDevice,
|
||||
+ ),
|
||||
+ transfer_type: TransferType::Interrupt,
|
||||
+ max_packet_size: 64,
|
||||
+ interval: 5,
|
||||
+ },
|
||||
+ EndpointDescriptor {
|
||||
+ endpoint_address: EndpointAddress::new_const(ENDPOINT_NUM, TransferDirection::DeviceToHost),
|
||||
+ endpoint_address: EndpointAddress::new_const(
|
||||
+ ENDPOINT_NUM,
|
||||
+ TransferDirection::DeviceToHost,
|
||||
+ ),
|
||||
+ transfer_type: TransferType::Interrupt,
|
||||
+ max_packet_size: 64,
|
||||
+ interval: 5,
|
||||
@@ -717,8 +754,8 @@ index 0000000..d97b72d
|
||||
+ let (device_descriptor_buffer, other_descriptor_buffer) =
|
||||
+ descriptors::create_descriptor_buffers(
|
||||
+ descriptors::DeviceDescriptor {
|
||||
+ vendor_id: vendor_id,
|
||||
+ product_id: product_id,
|
||||
+ vendor_id,
|
||||
+ product_id,
|
||||
+ manufacturer_string: 1,
|
||||
+ product_string: 2,
|
||||
+ serial_number_string: 3,
|
||||
@@ -969,7 +1006,7 @@ index 0000000..d97b72d
|
||||
+ }
|
||||
+}
|
||||
diff --git a/chips/nrf52840/src/lib.rs b/chips/nrf52840/src/lib.rs
|
||||
index 942d028..ce73e1f 100644
|
||||
index 942d0288f..ce73e1f82 100644
|
||||
--- a/chips/nrf52840/src/lib.rs
|
||||
+++ b/chips/nrf52840/src/lib.rs
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Reference in New Issue
Block a user