mirror of
https://github.com/trussed-dev/apdu-dispatch.git
synced 2026-06-20 04:16:15 -07:00
Bump heapless
This commit is contained in:
+1
-2
@@ -9,8 +9,7 @@ license = "Apache-2.0 OR MIT"
|
||||
|
||||
[dependencies]
|
||||
delog = "0.1.0"
|
||||
heapless = "0.6"
|
||||
heapless-bytes = "0.2.0"
|
||||
heapless = "0.7"
|
||||
|
||||
# Components
|
||||
iso7816 = { git = "https://github.com/ycrypto/iso7816", branch = "main" }
|
||||
|
||||
+2
-4
@@ -1,10 +1,8 @@
|
||||
pub use iso7816::{Command, Data, Status};
|
||||
pub use iso7816::{Command, Data, Interface, Status};
|
||||
pub type Result = iso7816::Result<()>;
|
||||
|
||||
pub use crate::{ArrayLength, dispatch::Interface};
|
||||
|
||||
/// An App can receive and respond APDUs at behest of the ApduDispatch.
|
||||
pub trait App<C: ArrayLength<u8>, R: ArrayLength<u8>>: iso7816::App {
|
||||
pub trait App<const C: usize, const R: usize>: iso7816::App {
|
||||
/// Given parsed APDU for select command.
|
||||
/// Write response data back to buf, and return length of payload. Return APDU Error code on error.
|
||||
/// Alternatively, the app can defer the response until later by returning it in `poll()`.
|
||||
|
||||
+15
-14
@@ -11,8 +11,8 @@
|
||||
use core::convert::TryInto;
|
||||
use crate::App;
|
||||
use crate::{Command, response, interchanges};
|
||||
use crate::command::Size as CommandSize;
|
||||
use crate::response::Size as ResponseSize;
|
||||
use crate::command::SIZE as CommandSize;
|
||||
use crate::response::SIZE as ResponseSize;
|
||||
|
||||
use iso7816::{
|
||||
Aid,
|
||||
@@ -45,7 +45,7 @@ struct ApduBuffer {
|
||||
}
|
||||
|
||||
impl ApduBuffer {
|
||||
fn request(&mut self, command: &iso7816::Command<impl heapless_bytes::ArrayLength<u8>>) {
|
||||
fn request<const S: usize>(&mut self, command: &iso7816::Command<S>) {
|
||||
match &mut self.raw {
|
||||
RawApduBuffer::Request(buffered) => {
|
||||
buffered.extend_from_command(command).ok();
|
||||
@@ -81,10 +81,10 @@ pub struct ApduDispatch {
|
||||
|
||||
impl ApduDispatch
|
||||
{
|
||||
fn apdu_type(apdu: &iso7816::Command<impl heapless_bytes::ArrayLength<u8>>) -> RequestType {
|
||||
fn apdu_type<const S: usize>(apdu: &iso7816::Command<S>) -> RequestType {
|
||||
if apdu.instruction() == Instruction::Select && (apdu.p1 & 0x04) != 0 {
|
||||
// RequestType::Select(Aid::try_from_slice(apdu.data()).unwrap())
|
||||
RequestType::Select(Aid::new(apdu.data(), apdu.data().len()))
|
||||
RequestType::Select(Aid::new(apdu.data()))
|
||||
} else if apdu.instruction() == Instruction::GetResponse {
|
||||
RequestType::GetResponse
|
||||
} else {
|
||||
@@ -148,9 +148,9 @@ impl ApduDispatch
|
||||
|
||||
|
||||
#[inline(never)]
|
||||
fn buffer_chained_apdu_if_needed(&mut self, command: iso7816::Command<impl heapless_bytes::ArrayLength<u8>>, inferface: Interface) -> RequestType {
|
||||
fn buffer_chained_apdu_if_needed<const S: usize>(&mut self, command: iso7816::Command<S>, interface: Interface) -> RequestType {
|
||||
|
||||
self.current_interface = inferface;
|
||||
self.current_interface = interface;
|
||||
// iso 7816-4 5.1.1
|
||||
// check Apdu level chaining and buffer if necessary.
|
||||
if !command.class().chain().not_the_last() {
|
||||
@@ -182,7 +182,7 @@ impl ApduDispatch
|
||||
apdu_type
|
||||
}
|
||||
} else {
|
||||
match inferface {
|
||||
match interface {
|
||||
// acknowledge
|
||||
Interface::Contact => {
|
||||
self.contact.respond(&Status::Success.try_into().unwrap())
|
||||
@@ -202,8 +202,8 @@ impl ApduDispatch
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_apdu<SIZE: heapless_bytes::ArrayLength<u8>>(message: &interchanges::Data)
|
||||
-> Result<iso7816::Command<SIZE>> {
|
||||
fn parse_apdu<const S: usize>(message: &interchanges::Data)
|
||||
-> Result<iso7816::Command<S>> {
|
||||
|
||||
debug!(">> {}", hex_str!(message.as_slice(), sep:""));
|
||||
match iso7816::Command::try_from(message) {
|
||||
@@ -214,6 +214,7 @@ impl ApduDispatch
|
||||
info!("apdu bad");
|
||||
match _error {
|
||||
FromSliceError::TooShort => { info!("TooShort"); },
|
||||
FromSliceError::TooLong => { info!("TooLong"); },
|
||||
FromSliceError::InvalidClass => { info!("InvalidClass"); },
|
||||
FromSliceError::InvalidFirstBodyByteForExtended => { info!("InvalidFirstBodyByteForExtended"); },
|
||||
FromSliceError::InvalidSliceLength => { info!("InvalidSliceLength"); },
|
||||
@@ -238,7 +239,7 @@ impl ApduDispatch
|
||||
};
|
||||
|
||||
// Parse the message as an APDU.
|
||||
match Self::parse_apdu::<interchanges::Size>(&message) {
|
||||
match Self::parse_apdu::<{interchanges::SIZE}>(&message) {
|
||||
Ok(command) => {
|
||||
// The Apdu may be standalone or part of a chain.
|
||||
self.buffer_chained_apdu_if_needed(command, interface)
|
||||
@@ -291,7 +292,7 @@ impl ApduDispatch
|
||||
|
||||
let to_send = &res[..boundary];
|
||||
let remaining = &res[boundary..];
|
||||
let mut message = interchanges::Data::try_from_slice(to_send).unwrap();
|
||||
let mut message = interchanges::Data::from_slice(to_send).unwrap();
|
||||
let return_code = if remaining.len() > 255 {
|
||||
// XX = 00 indicates more than 255 bytes of data
|
||||
0x6100u16
|
||||
@@ -310,7 +311,7 @@ impl ApduDispatch
|
||||
} else {
|
||||
info!("Still {} bytes in response buffer", remaining.len());
|
||||
(
|
||||
RawApduBuffer::Response(response::Data::try_from_slice(remaining).unwrap()),
|
||||
RawApduBuffer::Response(response::Data::from_slice(remaining).unwrap()),
|
||||
message
|
||||
)
|
||||
}
|
||||
@@ -318,7 +319,7 @@ impl ApduDispatch
|
||||
} else {
|
||||
// Add success code
|
||||
res.extend_from_slice(&[0x90,00]).ok();
|
||||
(RawApduBuffer::None, interchanges::Data::try_from_slice(&res.as_slice()).unwrap())
|
||||
(RawApduBuffer::None, interchanges::Data::from_slice(&res.as_slice()).unwrap())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
pub const SIZE: usize = 3072;
|
||||
pub type Data = iso7816::Data<SIZE>;
|
||||
|
||||
interchange::interchange! {
|
||||
Contact: (Data, Data)
|
||||
}
|
||||
|
||||
interchange::interchange! {
|
||||
Contactless: (Data, Data)
|
||||
}
|
||||
+17
-7
@@ -4,13 +4,23 @@
|
||||
extern crate delog;
|
||||
generate_macros!();
|
||||
|
||||
pub use iso7816;
|
||||
|
||||
pub mod command {
|
||||
pub const SIZE: usize = 7609;
|
||||
pub type Data = iso7816::Data<SIZE>;
|
||||
}
|
||||
|
||||
pub mod response {
|
||||
pub const SIZE: usize = 7609;
|
||||
pub type Data = iso7816::Data<SIZE>;
|
||||
}
|
||||
|
||||
// What apps can expect to send and recieve.
|
||||
pub type Command = iso7816::Command<{command::SIZE}>;
|
||||
pub type Response = iso7816::Response<{response::SIZE}>;
|
||||
|
||||
pub mod app;
|
||||
pub use app::App;
|
||||
pub mod dispatch;
|
||||
pub mod types;
|
||||
pub use iso7816;
|
||||
pub use heapless;
|
||||
pub use heapless_bytes;
|
||||
|
||||
pub use heapless::ArrayLength;
|
||||
pub use types::{Command, Response, command, response, interchanges};
|
||||
pub mod interchanges;
|
||||
|
||||
+6
-51
@@ -1,55 +1,10 @@
|
||||
use heapless_bytes::Unsigned;
|
||||
pub const SIZE: usize = 3072;
|
||||
pub type Data = iso7816::Data<SIZE>;
|
||||
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type U6144 = <
|
||||
heapless::consts::U4096 as core::ops::Add<heapless::consts::U2048>
|
||||
>::Output;
|
||||
|
||||
type U7168 = <
|
||||
U6144 as core::ops::Add<heapless::consts::U1024>
|
||||
>::Output;
|
||||
|
||||
pub type U7609 = <
|
||||
U7168 as core::ops::Add<heapless::consts::U441>
|
||||
>::Output;
|
||||
|
||||
type U3072 = <
|
||||
heapless::consts::U2048 as core::ops::Add<heapless::consts::U1024>
|
||||
>::Output;
|
||||
|
||||
|
||||
pub mod command {
|
||||
use super::*;
|
||||
pub type Size = U7609;
|
||||
pub const SIZE: usize = Size::USIZE;
|
||||
pub type Data = iso7816::Bytes<Size>;
|
||||
interchange::interchange! {
|
||||
Contact: (Data, Data)
|
||||
}
|
||||
|
||||
pub mod response {
|
||||
use super::*;
|
||||
pub type Size = U7609;
|
||||
pub const SIZE: usize = Size::USIZE;
|
||||
pub type Data = iso7816::Bytes<Size>;
|
||||
interchange::interchange! {
|
||||
Contactless: (Data, Data)
|
||||
}
|
||||
|
||||
pub mod interchanges {
|
||||
use super::*;
|
||||
pub type Size = U3072;
|
||||
pub const SIZE: usize = Size::USIZE;
|
||||
pub type Data = iso7816::Bytes<Size>;
|
||||
|
||||
interchange::interchange! {
|
||||
Contact: (Data, Data)
|
||||
}
|
||||
|
||||
interchange::interchange! {
|
||||
Contactless: (Data, Data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// What apps can expect to send and recieve.
|
||||
pub type Command = iso7816::Command<command::Size>;
|
||||
pub type Response = iso7816::Response<response::Size>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user