Update in the application's workflow

This commit is contained in:
Mirna
2020-11-10 16:57:31 +02:00
parent bed4bff7ac
commit 84dec3f636

View File

@@ -30,6 +30,41 @@ mod example {
use libtock_drivers::timer::Timer; use libtock_drivers::timer::Timer;
use libtock_drivers::timer::Timestamp; use libtock_drivers::timer::Timestamp;
#[derive(Copy, Clone, Debug, PartialEq)]
enum ReturnCode {
/// Operation completed successfully
SUCCESS,
/// Generic failure condition
FAIL,
/// Underlying system is busy; retry
EBUSY,
/// The component is powered down
EOFF,
/// An invalid parameter was passed
EINVAL,
/// Operation canceled by a call
ECANCEL,
/// Memory required not available
ENOMEM,
/// Operation or command is unsupported
ENOSUPPORT,
}
impl From<isize> for ReturnCode {
fn from(original: isize) -> ReturnCode {
match original {
0 => ReturnCode::SUCCESS,
-1 => ReturnCode::FAIL,
-2 => ReturnCode::EBUSY,
-4 => ReturnCode::EOFF,
-6 => ReturnCode::EINVAL,
-8 => ReturnCode::ECANCEL,
-9 => ReturnCode::ENOMEM,
_ => ReturnCode::ENOSUPPORT,
}
}
}
/// Helper function to write on console the received packet. /// Helper function to write on console the received packet.
fn print_rx_buffer(buf: &mut [u8]) { fn print_rx_buffer(buf: &mut [u8]) {
if let Some((last, bytes)) = buf.split_last() { if let Some((last, bytes)) = buf.split_last() {
@@ -44,11 +79,20 @@ mod example {
} }
/// Function to identify the time elapsed for a transmission request. /// Function to identify the time elapsed for a transmission request.
fn bench_transmit(console: &mut Console, timer: &Timer, title: &str, mut buf: &mut [u8]) { fn bench_transmit(
console: &mut Console,
timer: &Timer,
title: &str,
mut buf: &mut [u8],
) -> ReturnCode {
let amount = buf.len(); let amount = buf.len();
let start = Timestamp::<f64>::from_clock_value(timer.get_current_clock().flex_unwrap()); let start = Timestamp::<f64>::from_clock_value(timer.get_current_clock().flex_unwrap());
match NfcTag::transmit(&mut buf, amount) { match NfcTag::transmit(&mut buf, amount) {
Ok(_) => (), Ok(_) => (),
Err(TockError::Command(CommandError {
return_code: -8, /* ECANCEL: No Field*/
..
})) => return ReturnCode::ECANCEL,
Err(_) => writeln!(Console::new(), " -- tx error!").unwrap(), Err(_) => writeln!(Console::new(), " -- tx error!").unwrap(),
} }
let end = Timestamp::<f64>::from_clock_value(timer.get_current_clock().flex_unwrap()); let end = Timestamp::<f64>::from_clock_value(timer.get_current_clock().flex_unwrap());
@@ -63,9 +107,10 @@ mod example {
) )
.unwrap(); .unwrap();
console.flush(); console.flush();
ReturnCode::SUCCESS
} }
fn receive_packet(console: &mut Console, mut buf: &mut [u8; 256]) -> bool { fn receive_packet(console: &mut Console, mut buf: &mut [u8; 256]) -> ReturnCode {
match NfcTag::receive(&mut buf) { match NfcTag::receive(&mut buf) {
Ok(RecvOp { Ok(RecvOp {
recv_amount: amount, recv_amount: amount,
@@ -75,74 +120,71 @@ mod example {
print_rx_buffer(&mut buf[..amount]); print_rx_buffer(&mut buf[..amount]);
} }
} }
Err(TockError::Command(CommandError { Err(TockError::Command(CommandError { return_code, .. })) => return return_code.into(),
return_code: -4, /* EOFF: Not Ready */ Err(_) => {
.. writeln!(console, " -- RX Err").unwrap();
})) => return false, return ReturnCode::ECANCEL;
// For the example app, just print any other received error without handling. }
Err(TockError::Command(CommandError {
return_code: value, ..
})) => writeln!(console, " -- Err({})!", value).unwrap(),
Err(_) => writeln!(console, " -- RX Err").unwrap(),
} }
true ReturnCode::SUCCESS
} }
fn transmit_reply(mut console: &mut Console, timer: &Timer, buf: &[u8]) -> bool { fn transmit_reply(mut console: &mut Console, timer: &Timer, buf: &[u8]) -> ReturnCode {
let mut return_code = ReturnCode::SUCCESS;
match buf[0] { match buf[0] {
0xe0 /* RATS */=> { 0xe0 /* RATS */=> {
let mut answer_to_select = [0x05, 0x78, 0x80, 0xB1, 0x00]; let mut answer_to_select = [0x05, 0x78, 0x80, 0xB1, 0x00];
bench_transmit(&mut console, &timer, "TX: ATS", &mut answer_to_select); return_code = bench_transmit(&mut console, &timer, "TX: ATS", &mut answer_to_select);
} }
0xc2 /* DESELECT */ => { 0xc2 /* DESELECT */ => {
// Ignore the request // Ignore the request
let mut command_error = [0x6A, 0x81]; let mut command_error = [0x6A, 0x81];
bench_transmit(&mut console, &timer, "TX: DESELECT", &mut command_error); return_code = bench_transmit(&mut console, &timer, "TX: DESELECT", &mut command_error);
} }
0x02 | 0x03 /* APDU Prefix */ => match buf[2] { 0x02 | 0x03 /* APDU Prefix */ => match buf[2] {
// If the received packet is applet selection command (FIDO 2) // If the received packet is applet selection command (FIDO 2)
0xa4 /* SELECT */ => if buf[3] == 0x04 && buf[5] == 0x08 && buf[6] == 0xa0 { 0xa4 /* SELECT */ => if buf[3] == 0x04 && buf[5] == 0x08 && buf[6] == 0xa0 {
// Vesion: "FIDO_2_0" // Vesion: "FIDO_2_0"
let mut reply = [buf[0], 0x46, 0x49, 0x44, 0x4f, 0x5f, 0x32, 0x5f, 0x30, 0x90, 0x00,]; let mut reply = [buf[0], 0x46, 0x49, 0x44, 0x4f, 0x5f, 0x32, 0x5f, 0x30, 0x90, 0x00,];
bench_transmit(&mut console, &timer, "TX: Version Str", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: Version Str", &mut reply);
} else { } else if (buf[6] == 0xd2 && buf[7] == 0x76) || (buf[6] == 0xe1 && (buf[7] == 0x03 || buf[7] == 0x04)){
let mut reply = [buf[0], 0x90, 0x00]; let mut reply = [buf[0], 0x90, 0x00];
bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply);
} } else /* Unknown file */ {
let mut reply = [buf[0], 0x6a, 0x82];
return_code = bench_transmit(&mut console, &timer, "TX: 0x6A82", &mut reply);
}
0xb0 /* READ */ => match buf[5] { 0xb0 /* READ */ => match buf[5] {
0x02 => { 0x02 => {
let mut reply = [buf[0], 0x12, 0x90, 0x00,]; let mut reply = [buf[0], 0x12, 0x90, 0x00,];
bench_transmit(&mut console, &timer, "TX: File Size", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: File Size", &mut reply);
} }
0x12 => { 0x12 => {
let mut reply = [buf[0], 0xd1, 0x01, 0x0e, 0x55, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65, let mut reply = [buf[0], 0xd1, 0x01, 0x0e, 0x55, 0x77, 0x77, 0x77, 0x2e, 0x6f, 0x70, 0x65,
0x6e, 0x73, 0x6b, 0x2e, 0x64, 0x65, 0x76, 0x90, 0x00,]; 0x6e, 0x73, 0x6b, 0x2e, 0x64, 0x65, 0x76, 0x90, 0x00,];
bench_transmit(&mut console, &timer, "TX: NDEF", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: NDEF", &mut reply);
} }
0x0f => { 0x0f => {
let mut reply = [buf[0], 0x00, 0x0f, 0x20, 0x00, 0x7f, 0x00, 0x7f, 0x04, 0x06, 0xe1, 0x04, let mut reply = [buf[0], 0x00, 0x0f, 0x20, 0x00, 0x7f, 0x00, 0x7f, 0x04, 0x06, 0xe1, 0x04,
0x00, 0x7f, 0x00, 0x00, 0x90, 0x00,]; 0x00, 0x7f, 0x00, 0x00, 0x90, 0x00,];
bench_transmit(&mut console, &timer, "TX: CC", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: CC", &mut reply);
} }
_ => { _ => {
let mut reply = [buf[0], 0x90, 0x00]; let mut reply = [buf[0], 0x90, 0x00];
bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply);
} }
} }
_ => { _ => {
let mut reply = [buf[0], 0x90, 0x00]; let mut reply = [buf[0], 0x90, 0x00];
bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply); return_code = bench_transmit(&mut console, &timer, "TX: 0x9000", &mut reply);
} }
} }
0x26 | 0x52 | 0x50 /* REQA | WUPA | Halt */ => { 0x26 | 0x52 | 0x50 /* REQA | WUPA | Halt */ => {
if NfcTag::disable_emulation() { return ReturnCode::EOFF;
writeln!(console, " -- TAG DISABLED").unwrap();
}
return false;
} }
_ => (), _ => (),
} }
true return_code
} }
pub fn nfc(mut console: &mut Console) { pub fn nfc(mut console: &mut Console) {
@@ -160,19 +202,35 @@ mod example {
let mut state_change_counter = 0; let mut state_change_counter = 0;
loop { loop {
while !NfcTag::enable_emulation() {} let mut rx_buf = [0; 256];
// Configure Type 4 tag match receive_packet(&mut console, &mut rx_buf) {
while !NfcTag::configure(4) {} ReturnCode::EOFF => {
state_change_counter += 1; // Not configured
loop { while !NfcTag::enable_emulation() {}
let mut rx_buf = [0; 256]; // Configure Type 4 tag
// Await a successful receive while !NfcTag::configure(4) {}
while !receive_packet(&mut console, &mut rx_buf) {} }
// If the reader restarts the communication and we can't ReturnCode::ECANCEL /* field lost */ => {
// reply to the received packet, then disable the tag. NfcTag::disable_emulation();
if !transmit_reply(&mut console, &timer, &rx_buf) { }
state_change_counter += 1; ReturnCode::EBUSY /* awaiting select*/ => (),
break; ReturnCode::ENOMEM => {
writeln!(console, " -- Amount more than buffer limit").unwrap()
}
ReturnCode::FAIL => writeln!(console, " -- Invalid CRC").unwrap(),
ReturnCode::EINVAL /* covered in driver interface */ => (),
ReturnCode::ENOSUPPORT => (),
ReturnCode::SUCCESS => {
// If the reader restarts the communication then disable the tag.
match transmit_reply(&mut console, &timer, &rx_buf) {
ReturnCode::ECANCEL | ReturnCode::EOFF => {
if NfcTag::disable_emulation() {
writeln!(console, " -- TAG DISABLED").unwrap();
}
state_change_counter += 1;
}
_ => (),
}
} }
} }
if state_change_counter > 100 { if state_change_counter > 100 {