cargo fmt

This commit is contained in:
Nicolas Stalder
2023-01-24 22:48:43 +01:00
parent 55e219fc7c
commit 19893557d1
7 changed files with 151 additions and 147 deletions
+34 -25
View File
@@ -6,12 +6,8 @@ use interchange::{Interchange, Requester};
use crate::{
constants::*,
types::{
ClassRequest,
packet::RawPacket,
Status,
},
pipe::Pipe,
types::{packet::RawPacket, ClassRequest, Status},
};
use usb_device::class_prelude::*;
@@ -55,7 +51,12 @@ where
let pipe = Pipe::new(write, request_pipe, card_issuers_data);
let interface_number = allocator.interface();
let string_index = allocator.string();
Self { interface_number, string_index, read, /* interrupt, */ pipe }
Self {
interface_number,
string_index,
read,
/* interrupt, */ pipe,
}
}
/// Read response from application (if any) and start writing it to
@@ -73,7 +74,7 @@ where
}
}
pub fn send_wait_extension (&mut self) -> Status {
pub fn send_wait_extension(&mut self) -> Status {
if self.pipe.send_wait_extension() {
// We should send another wait extension later
Status::ReceivedData(1_000.milliseconds())
@@ -88,9 +89,7 @@ where
Bus: 'static + UsbBus,
I: 'static + Interchange<REQUEST = Vec<u8, N>, RESPONSE = Vec<u8, N>>,
{
fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter)
-> Result<()>
{
fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
writer.interface_alt(
self.interface_number,
0,
@@ -99,10 +98,7 @@ where
TransferMode::Bulk as u8,
Some(self.string_index),
)?;
writer.write(
FUNCTIONAL_INTERFACE,
&FUNCTIONAL_INTERFACE_DESCRIPTOR,
)?;
writer.write(FUNCTIONAL_INTERFACE, &FUNCTIONAL_INTERFACE_DESCRIPTOR)?;
writer.endpoint(&self.pipe.write).unwrap();
writer.endpoint(&self.read).unwrap();
// writer.endpoint(&self.interrupt).unwrap();
@@ -110,8 +106,7 @@ where
}
fn get_string(&self, index: StringIndex, _lang_id: u16) -> Option<&str> {
(self.string_index == index)
.then_some(FUNCTIONAL_INTERFACE_STRING)
(self.string_index == index).then_some(FUNCTIONAL_INTERFACE_STRING)
}
#[inline(never)]
@@ -122,13 +117,17 @@ where
}
fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
if addr != self.pipe.write.address() { return; }
if addr != self.pipe.write.address() {
return;
}
self.pipe.maybe_send_packet();
}
fn endpoint_out(&mut self, addr: EndpointAddress) {
if addr != self.read.address() { return; }
if addr != self.read.address() {
return;
}
// let maybe_packet = RawPacket::try_from(
// |packet| self.read.read(packet));
@@ -148,12 +147,17 @@ where
if let Ok(packet) = maybe_packet {
self.pipe.handle_packet(packet);
}
}
fn control_in(&mut self, transfer: ControlIn<Bus>) {
use usb_device::control::*;
let Request { request_type, recipient, index, request, .. } = *transfer.request();
let Request {
request_type,
recipient,
index,
request,
..
} = *transfer.request();
if index != u8::from(self.interface_number) as u16 {
return;
}
@@ -165,12 +169,12 @@ where
// not strictly needed, as our bNumClockSupported = 0
ClassRequest::GetClockFrequencies => {
transfer.accept_with(&CLOCK_FREQUENCY_KHZ).ok();
},
}
// not strictly needed, as our bNumDataRatesSupported = 0
ClassRequest::GetDataRates => {
transfer.accept_with_static(&DATA_RATE_BPS).ok();
},
}
_ => panic!("unexpected direction for {:?}", &request),
}
}
@@ -185,8 +189,14 @@ where
fn control_out(&mut self, transfer: ControlOut<Bus>) {
use usb_device::control::*;
let Request { request_type, recipient, index, request, value, .. }
= *transfer.request();
let Request {
request_type,
recipient,
index,
request,
value,
..
} = *transfer.request();
if index as u8 != u8::from(self.interface_number) {
return;
}
@@ -215,5 +225,4 @@ where
}
}
}
}
+20 -12
View File
@@ -49,7 +49,8 @@ pub const PIN_SUPPORT: u8 = 0;
// cf. Sec. 5.1 in: https://www.usb.org/sites/default/files/DWG_Smart-Card_CCID_Rev110.pdf
pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// bcdCCID rev1.10
0x10, 0x01,
0x10,
0x01,
// bMaxSlotIndex
// NUM_SLOTS - 1,
// "An USB-ICC is regarded as a single slot CCID."
@@ -57,8 +58,10 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// bVoltageSupport (5.0V)
0x01,
// dwProtocols: APDU level, T=1 only (0 = T=0, 3 = T0+T1)
0x02, 0x00, 0x00, 0x00,
0x02,
0x00,
0x00,
0x00,
// dwDefaultClock (3.58 MHz)
CLOCK_FREQUENCY_KHZ[0],
CLOCK_FREQUENCY_KHZ[1],
@@ -71,7 +74,6 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
CLOCK_FREQUENCY_KHZ[3],
// bNumClockSupported
0x00,
// dwDataRate (9600 bps)
DATA_RATE_BPS[0],
DATA_RATE_BPS[1],
@@ -84,17 +86,21 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
DATA_RATE_BPS[3],
// bNumDataRatesSupported
0x00,
// dwMaxIFSD (254)
MAX_IFSD[0],
MAX_IFSD[1],
MAX_IFSD[2],
MAX_IFSD[3],
// dwSyncProtocols: none
0x00, 0x00, 0x00, 0x00,
0x00,
0x00,
0x00,
0x00,
// dwMechanical: no special characteristics
0x00, 0x00, 0x00, 0x00,
0x00,
0x00,
0x00,
0x00,
// dwFeatures, see following comments
// Auto configuration based on ATR
// Auto activation on insert
@@ -106,21 +112,23 @@ pub const FUNCTIONAL_INTERFACE_DESCRIPTOR: [u8; 52] = [
// 0xFE, 0x00, 0x04, 0x00,
// ICCD: lower word (=0840): only requests valid for USB-ICC
// upper word: 0000 = char level, 0002 = short APDU, 0004 = short+exteded APDU
0x40, 0x08, 0x04, 0x00,
0x40,
0x08,
0x04,
0x00,
// dwMaxCCIDMsgLen (3072)
// gnuk: 271
MAX_MSG_LENGTH_LE[0],
MAX_MSG_LENGTH_LE[1],
MAX_MSG_LENGTH_LE[2],
MAX_MSG_LENGTH_LE[3],
// bClassGetResponse ("echo"), as per ICCD spec
0xFF,
// bClassEnvelope ("echo"), as per ICCD spec, gnuk: 0
0xFF,
// wlcdLayout (none)
0x00, 0x00,
0x00,
0x00,
// bPinSupport
// ICCD: "No PIN pad, not relevant, fixed for legacy reasons"
PIN_SUPPORT,
+1 -1
View File
@@ -7,8 +7,8 @@
extern crate delog;
generate_macros!();
pub mod constants;
pub mod class;
pub mod constants;
pub mod pipe;
pub mod types;
+66 -69
View File
@@ -5,16 +5,8 @@ use interchange::{Interchange, Requester};
use crate::{
constants::*,
types::packet::{
Chain,
Command as PacketCommand,
DataBlock,
Error as PacketError,
ExtPacket,
RawPacket,
XfrBlock,
ChainedPacket as _,
PacketWithData as _,
Chain, ChainedPacket as _, Command as PacketCommand, DataBlock, Error as PacketError,
ExtPacket, PacketWithData as _, RawPacket, XfrBlock,
},
};
@@ -73,7 +65,6 @@ where
request_pipe: Requester<I>,
card_issuers_data: Option<&[u8]>,
) -> Self {
// assert!(MAX_MSG_LENGTH >= PACKET_SIZE);
Self {
@@ -136,7 +127,6 @@ where
}
}
impl<Bus, I, const N: usize> Pipe<Bus, I, N>
where
Bus: 'static + UsbBus,
@@ -235,7 +225,6 @@ where
}
fn handle_transfer(&mut self, command: XfrBlock) {
// state: Idle, Receiving, Processing, Sending,
//
// conts: BeginsAndEnds, Begins, Ends, Continues, ExpectDataBlock,
@@ -243,7 +232,6 @@ where
// info!("handle xfrblock").ok();
// info!("{:X?}", &command);
match self.state {
State::Idle => {
// invariant: BUFFER_SIZE >= PACKET_SIZE
match command.chain() {
@@ -266,49 +254,48 @@ where
self.state = State::Receiving;
self.send_empty_datablock(Chain::ExpectingMore);
}
_ => panic!("unexpectedly in idle state"),
_ => panic!("unexpectedly in idle state"),
}
}
State::Receiving => {
match command.chain() {
Chain::Continues => {
info!("continues");
let message = self.interchange.request_mut().unwrap();
assert!(command.data().len() + message.len() <= MAX_MSG_LENGTH);
message.extend_from_slice(command.data()).unwrap();
self.send_empty_datablock(Chain::ExpectingMore);
}
Chain::Ends => {
info!("ends");
let message = self.interchange.request_mut().unwrap();
assert!(command.data().len() + message.len() <= MAX_MSG_LENGTH);
message.extend_from_slice(command.data()).unwrap();
self.call_app();
self.state = State::Processing;
}
_ => panic!("unexpectedly in receiving state"),
State::Receiving => match command.chain() {
Chain::Continues => {
info!("continues");
let message = self.interchange.request_mut().unwrap();
assert!(command.data().len() + message.len() <= MAX_MSG_LENGTH);
message.extend_from_slice(command.data()).unwrap();
self.send_empty_datablock(Chain::ExpectingMore);
}
}
Chain::Ends => {
info!("ends");
let message = self.interchange.request_mut().unwrap();
assert!(command.data().len() + message.len() <= MAX_MSG_LENGTH);
message.extend_from_slice(command.data()).unwrap();
self.call_app();
self.state = State::Processing;
}
_ => panic!("unexpectedly in receiving state"),
},
State::Processing => {
// info!("handle xfrblock").ok();
// info!("{:X?}", &command).ok();
panic!("ccid pipe unexpectedly received command while in processing state: {:?}", &command);
panic!(
"ccid pipe unexpectedly received command while in processing state: {:?}",
&command
);
}
State::ReadyToSend => {
panic!("unexpectedly in ready-to-send state")
}
State::Sending => {
match command.chain() {
Chain::ExpectingMore => {
self.prime_outbox();
}
_ => panic!("unexpectedly in receiving state"),
State::Sending => match command.chain() {
Chain::ExpectingMore => {
self.prime_outbox();
}
}
_ => panic!("unexpectedly in receiving state"),
},
}
}
@@ -346,7 +333,9 @@ where
#[inline(never)]
fn call_app(&mut self) {
self.interchange.send_request().expect("could not deposit command");
self.interchange
.send_request()
.expect("could not deposit command");
self.started_processing = true;
self.state = State::Processing;
}
@@ -358,7 +347,6 @@ where
// self.interchange.state()).ok();
if interchange::State::Responded == self.interchange.state() {
// we should have an open XfrBlock allowance
self.state = State::ReadyToSend;
self.sent = 0;
@@ -372,31 +360,44 @@ where
return;
}
if self.outbox.is_some() { panic!(); }
if self.outbox.is_some() {
panic!();
}
// if let Some(message) = self.interchange.response() {
let message: &mut Vec<u8, N> = unsafe { (*self.interchange.interchange.get()).rp_mut() };
let message: &mut Vec<u8, N> = unsafe { (*self.interchange.interchange.get()).rp_mut() };
let chunk_size = core::cmp::min(PACKET_SIZE - 10, message.len() - self.sent);
let chunk = &message[self.sent..][..chunk_size];
self.sent += chunk_size;
let more = self.sent < message.len();
let chunk_size = core::cmp::min(PACKET_SIZE - 10, message.len() - self.sent);
let chunk = &message[self.sent..][..chunk_size];
self.sent += chunk_size;
let more = self.sent < message.len();
let chain = match (self.state, more) {
(State::ReadyToSend, true) => { self.state = State::Sending; Chain::Begins }
(State::ReadyToSend, false) => { self.state = State::Idle; Chain::BeginsAndEnds }
(State::Sending, true) => Chain::Continues,
(State::Sending, false) => { self.state = State::Idle; Chain::Ends }
// logically impossible
_ => { return; }
};
let chain = match (self.state, more) {
(State::ReadyToSend, true) => {
self.state = State::Sending;
Chain::Begins
}
(State::ReadyToSend, false) => {
self.state = State::Idle;
Chain::BeginsAndEnds
}
(State::Sending, true) => Chain::Continues,
(State::Sending, false) => {
self.state = State::Idle;
Chain::Ends
}
// logically impossible
_ => {
return;
}
};
let primed_packet = DataBlock::new(self.seq, chain, chunk);
// info!("priming {:?}", &primed_packet).ok();
self.outbox = Some(primed_packet.into());
let primed_packet = DataBlock::new(self.seq, chain, chunk);
// info!("priming {:?}", &primed_packet).ok();
self.outbox = Some(primed_packet.into());
// fast-lane response attempt
self.maybe_send_packet();
// fast-lane response attempt
self.maybe_send_packet();
// }
}
@@ -418,7 +419,7 @@ where
packet.resize_default(10).ok();
packet[0] = 0x6c;
packet[6] = self.seq;
packet[7] = 1<<6;
packet[7] = 1 << 6;
packet[8] = error as u8;
self.send_packet_assuming_possible(packet);
}
@@ -450,7 +451,6 @@ where
self.seq,
Chain::BeginsAndEnds,
&atr,
// T=0, T=1, command chaining/extended Lc+Le/no logical channels, card issuer's data "Solo 2"
// 3B 8C 80 01 80 73 C0 21 C0 56 53 6F 6C 6F 20 32 A4
// https://smartcard-atr.apdu.fr/parse?ATR=3B+8C+80+01+80+73+C0+21+C0+56+53+6F+6C+6F+20+32+A4
@@ -464,7 +464,6 @@ where
self.send_packet_assuming_possible(packet.into());
}
fn send_packet_assuming_possible(&mut self, packet: RawPacket) {
if self.outbox.is_some() {
// Previous transaction will fail, but we'll be ready for new transactions.
@@ -494,7 +493,6 @@ where
} else {
self.outbox = None;
}
}
Ok(_) => panic!("short write"),
@@ -502,7 +500,7 @@ where
// fine, can't write try later
// this shouldn't happen probably
info!("waiting to send");
},
}
Err(_) => panic!("unexpected send error"),
}
@@ -522,5 +520,4 @@ where
info!("ABORT expected for seq = {}", _seq);
todo!();
}
}
-1
View File
@@ -29,4 +29,3 @@ impl core::convert::TryFrom<u8> for ClassRequest {
})
}
}
+29 -39
View File
@@ -2,7 +2,6 @@ use core::convert::TryInto;
use crate::constants::*;
pub type RawPacket = heapless::Vec<u8, PACKET_SIZE>;
pub type ExtPacket = heapless::Vec<u8, MAX_MSG_LENGTH>;
@@ -28,7 +27,6 @@ pub enum Message {
}
pub trait Packet: core::ops::Deref<Target = ExtPacket> {
#[inline]
fn slot(&self) -> u8 {
// we have only one slot
@@ -37,17 +35,16 @@ pub trait Packet: core::ops::Deref<Target = ExtPacket> {
}
#[inline]
fn seq(&self) -> u8 { self[6] }
fn seq(&self) -> u8 {
self[6]
}
}
pub trait PacketWithData: Packet {
#[inline]
fn data(&self) -> &[u8] {
// let len = u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize;
let declared_len =
u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize;
let declared_len = u32::from_le_bytes(self[1..5].try_into().unwrap()) as usize;
let len = core::cmp::min(MAX_MSG_LENGTH - 10, declared_len);
// hprintln!("delcared = {}, len = {}", declared_len, len).ok();
&self[10..][..len]
@@ -55,7 +52,6 @@ pub trait PacketWithData: Packet {
}
pub trait ChainedPacket: Packet {
#[inline(always)]
fn chain(&self) -> Chain {
let level_parameter = u16::from_le_bytes(self[8..10].try_into().unwrap());
@@ -86,19 +82,18 @@ impl<'a> DataBlock<'a> {
}
impl core::fmt::Debug for DataBlock<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut debug_struct = f.debug_struct("DataBlock");
debug_struct
.field("seq", &self.seq)
;
debug_struct.field("seq", &self.seq);
let l = core::cmp::min(self.data.len(), 16);
let escaped_bytes: heapless::Vec<u8, 64> =
self.data.iter().take(l)
.flat_map(|byte| core::ascii::escape_default(*byte))
.collect();
let l = core::cmp::min(self.data.len(), 16);
let escaped_bytes: heapless::Vec<u8, 64> = self
.data
.iter()
.take(l)
.flat_map(|byte| core::ascii::escape_default(*byte))
.collect();
let data_as_str = &core::str::from_utf8(&escaped_bytes).unwrap();
debug_struct
@@ -109,7 +104,6 @@ impl core::fmt::Debug for DataBlock<'_> {
}
}
// WELL. DataBlock does not deref to RawPacket
// impl Deref for DataBlock<_> {
// type Target: &
@@ -144,7 +138,6 @@ impl From<DataBlock<'_>> for RawPacket {
#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum CommandType {
// REQUESTS
// supported
@@ -158,7 +151,7 @@ pub enum CommandType {
// unsupported
ResetParameters = 0x6d,
SetParameters = 0x61,
Escape = 0x6b,// for vendor commands
Escape = 0x6b, // for vendor commands
IccClock = 0x7e,
T0Apdu = 0x6a,
Secure = 0x69,
@@ -314,9 +307,10 @@ pub enum Chain {
impl Chain {
pub fn transfer_ongoing(&self) -> bool {
matches!(self, Chain::BeginsAndEnds |
Chain::Ends |
Chain::ExpectingMore)
matches!(
self,
Chain::BeginsAndEnds | Chain::Ends | Chain::ExpectingMore
)
}
}
@@ -326,36 +320,34 @@ pub enum Response {
}
impl core::fmt::Debug for Command {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut debug_struct = f.debug_struct("Command");
// write!("Command({:?})", &self.command_type()));
// // "Command");
// write!("Command({:?})", &self.command_type()));
// // "Command");
debug_struct
.field("cmd", &self.command_type())
.field("seq", &self.seq())
;
.field("seq", &self.seq());
if let Command::XfrBlock(block) = self {
let l = core::cmp::min(self.len(), 8);
let escaped_bytes: heapless::Vec<u8, 64> =
block.data().iter().take(l)
.flat_map(|byte| core::ascii::escape_default(*byte))
.collect();
let escaped_bytes: heapless::Vec<u8, 64> = block
.data()
.iter()
.take(l)
.flat_map(|byte| core::ascii::escape_default(*byte))
.collect();
let data_as_str = &core::str::from_utf8(&escaped_bytes).unwrap();
debug_struct
.field("chain", &block.chain())
.field("len", &block.data().len())
;
.field("len", &block.data().len());
if l < self.len() {
debug_struct.field("data[..8]", &format_args!("b'{}'", data_as_str))
} else {
debug_struct.field("data", &format_args!("b'{}'", data_as_str))
}
;
};
}
// let mut debug_struct = match self.msg_type() {
@@ -364,8 +356,6 @@ impl core::fmt::Debug for Command {
// };
// let has_data = self.len() > 0;
debug_struct
.finish()
debug_struct.finish()
}
}
+1
View File
@@ -0,0 +1 @@