Bump heapless

This commit is contained in:
Nicolas Stalder
2021-06-10 23:21:41 +02:00
parent b7a9ecd185
commit 644336c38b
6 changed files with 51 additions and 78 deletions
+1 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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())
}
}
+10
View File
@@ -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
View File
@@ -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
View File
@@ -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>;