diff --git a/third_party/libtock-drivers/src/nfc.rs b/third_party/libtock-drivers/src/nfc.rs index 8e90b6b..6bf685b 100644 --- a/third_party/libtock-drivers/src/nfc.rs +++ b/third_party/libtock-drivers/src/nfc.rs @@ -1,6 +1,7 @@ +use crate::result::TockError; use crate::util; use core::cell::Cell; -use libtock_core::result::{ENOMEM, SUCCESS}; +use core::mem; use libtock_core::{callback, syscalls}; const DRIVER_NUMBER: usize = 0x30003; @@ -24,11 +25,10 @@ mod allow_nr { pub const RECEIVE: usize = 2; } -pub enum TransOrRecvStatus { - Error, - InvalidBuffer, - OOM, - Success, +#[allow(dead_code)] +pub struct RecvOp { + pub result_code: usize, + pub recv_amount: usize, } pub struct NfcTag {} @@ -76,61 +76,53 @@ impl NfcTag { /// 1. Share with the driver a buffer. /// 2. Subscribe to having a successful receive callback. /// 3. Issue the request for reception. - pub fn receive(buf: &mut [u8; 256]) -> TransOrRecvStatus { - let result = syscalls::allow(DRIVER_NUMBER, allow_nr::RECEIVE, buf); - if result.is_err() { - return TransOrRecvStatus::InvalidBuffer; - } - + pub fn receive(buf: &mut [u8; 256]) -> Result { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::RECEIVE, buf)?; + // set callback with 2 arguments, to receive ReturnCode and RX Amount let done = Cell::new(false); - let mut alarm = || done.set(true); - let subscription = syscalls::subscribe::( + let result_code = Cell::new(None); + let recv_amount = Cell::new(None); + let mut callback = |result, amount| { + result_code.set(Some(result)); + recv_amount.set(Some(amount)); + done.set(true) + }; + let subscription = syscalls::subscribe::( DRIVER_NUMBER, subscribe_nr::RECEIVE, - &mut alarm, - ); - if subscription.is_err() { - return TransOrRecvStatus::Error; - } - - let result_code = - unsafe { syscalls::raw::command(DRIVER_NUMBER, command_nr::RECEIVE, 0, 0) }; - match result_code { - SUCCESS => (), - ENOMEM => return TransOrRecvStatus::OOM, - _ => return TransOrRecvStatus::Error, - } - + &mut callback, + )?; + syscalls::command(DRIVER_NUMBER, command_nr::RECEIVE, 0, 0)?; util::yieldk_for(|| done.get()); - TransOrRecvStatus::Success + mem::drop(subscription); + mem::drop(result); + Ok(RecvOp { + result_code: result_code.get().unwrap(), + recv_amount: recv_amount.get().unwrap(), + }) } /// 1. Share with the driver a buffer containing the app's reply. /// 2. Subscribe to having a successful transmission callback. /// 3. Issue the request for transmitting. - pub fn transmit(buf: &mut [u8], amount: usize) -> TransOrRecvStatus { - let result = syscalls::allow(DRIVER_NUMBER, allow_nr::TRANSMIT, buf); - if result.is_err() { - return TransOrRecvStatus::InvalidBuffer; - } - + pub fn transmit(buf: &mut [u8], amount: usize) -> Result { + let result = syscalls::allow(DRIVER_NUMBER, allow_nr::TRANSMIT, buf)?; + // set callback with 1 argument, to receive ReturnCode let done = Cell::new(false); - let mut alarm = || done.set(true); - let subscription = syscalls::subscribe::( + let result_code = Cell::new(None); + let mut callback = |result| { + result_code.set(Some(result)); + done.set(true) + }; + let subscription = syscalls::subscribe::( DRIVER_NUMBER, subscribe_nr::TRANSMIT, - &mut alarm, - ); - if subscription.is_err() { - return TransOrRecvStatus::Error; - } - - let result_code = syscalls::command(DRIVER_NUMBER, command_nr::TRANSMIT, amount, 0); - if result_code.is_err() { - return TransOrRecvStatus::Error; - } - + &mut callback, + )?; + syscalls::command(DRIVER_NUMBER, command_nr::TRANSMIT, amount, 0)?; util::yieldk_for(|| done.get()); - TransOrRecvStatus::Success + mem::drop(subscription); + mem::drop(result); + Ok(result_code.get().unwrap()) } }