Skip to content

Commit

Permalink
Merge pull request #489 from betrusted-io/feature-478
Browse files Browse the repository at this point in the history
Implement #478
  • Loading branch information
bunnie authored Jan 29, 2024
2 parents f008520 + e2daf45 commit b979508
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions RELEASE-v0.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ perform the Xous firmware upgrade. This requires running manual update commands,
- `sigchat` moved to its own repo with AGPL licensing: https://github.com/betrusted-io/sigchat
- Formatting and contribution standards have been modified. Formatting with `rustfmt` and trailing white space removal is now mandatory for all Xous contributions, see [#477](https://github.com/betrusted-io/xous-core/pull/477) for a discussion of how we got there and why.
- The repo has gone through a "flag day" where all the crates have been formatted, which means commits before the flag day may be more difficult to undo. The changes are committed on a crate-by-crate basis, so if something is really broken we can undo the formatting for the crate and add an exception to the rustfmt rules.
- Implement #478: backlight should turn on automatically when a U2F/FIDO packet comes in from the host, allowing users in dark conditions to see the screen and know what they are approving.


## Roadmap
Expand Down
9 changes: 7 additions & 2 deletions services/status/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,10 @@ fn wrapped_main() -> ! {
// ------------------ lay out our public API infrastructure
// ok, now that we have a GID, we can continue on with our merry way
let status_gid: Gid = Gid::new(canvas_gid);
// allow only one connection, from keyboard to us.
let status_sid = xns.register_name(SERVER_NAME_STATUS, Some(1)).unwrap();
// Expected connections:
// - from keyboard
// - from USB HID
let status_sid = xns.register_name(SERVER_NAME_STATUS, Some(2)).unwrap();
// create a connection for callback hooks
let cb_cid = xous::connect(status_sid).unwrap();
unsafe { CB_TO_MAIN_CONN = Some(cb_cid) };
Expand Down Expand Up @@ -395,6 +397,9 @@ fn wrapped_main() -> ! {
kbd.lock()
.unwrap()
.register_observer(SERVER_NAME_STATUS, StatusOpcode::Keypress.to_u32().unwrap() as usize);
// register the USB U2F event listener - point to the same handler as key press since our intention is to
// just toggle the backlight
usb_hid.register_u2f_observer(SERVER_NAME_STATUS, StatusOpcode::Keypress.to_u32().unwrap() as usize);

let autobacklight_enabled = Arc::new(Mutex::new(true));
let (tx, rx): (Sender<BacklightThreadOps>, Receiver<BacklightThreadOps>) = unbounded();
Expand Down
9 changes: 9 additions & 0 deletions services/usb-device-xous/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub(crate) enum Opcode {
DebugUsbOp = 9,
/// Set autotype rate
SetAutotypeRate = 10,
/// Register a USB event observer
RegisterUsbObserver = 11,

/// Send a U2F message
U2fTx = 128,
Expand Down Expand Up @@ -139,3 +141,10 @@ pub struct UsbSerialBinary {
pub d: [u8; SERIAL_BINARY_BUFLEN],
pub len: usize,
}

/// this structure is used to register a USB listener.
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)]
pub(crate) struct UsbListenerRegistration {
pub server_name: xous_ipc::String<64>,
pub listener_op_id: usize,
}
10 changes: 10 additions & 0 deletions services/usb-device-xous/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,16 @@ impl UsbHid {
)
.unwrap();
}

pub fn register_u2f_observer(&self, server_name: &str, action_opcode: usize) {
let kr = UsbListenerRegistration {
server_name: xous_ipc::String::<64>::from_str(server_name),
listener_op_id: action_opcode,
};
let buf = Buffer::into_buf(kr).unwrap();
buf.lend(self.conn, Opcode::RegisterUsbObserver.to_u32().unwrap())
.expect("couldn't register listener");
}
}

use core::sync::atomic::{AtomicU32, Ordering};
Expand Down
30 changes: 30 additions & 0 deletions services/usb-device-xous/src/main_hw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ pub(crate) fn main_hw() -> ! {
let mut was_suspend = true;
let mut autotype_delay_ms = 30;

// event observer connection
let mut observer_conn: Option<xous::CID> = None;
let mut observer_op: Option<usize> = None;

#[cfg(feature = "minimal")]
std::thread::spawn(move || {
// this keeps the watchdog alive in minimal mode; if there's no event, eventually the watchdog times
Expand Down Expand Up @@ -492,6 +496,15 @@ pub(crate) fn main_hw() -> ! {
xous::return_scalar(msg.sender, 1).expect("couldn't return compatibility status")
}),
Some(Opcode::U2fRxDeferred) => {
// notify the event listener, if any
if observer_conn.is_some() && observer_op.is_some() {
xous::try_send_message(
observer_conn.unwrap(),
xous::Message::new_scalar(observer_op.unwrap(), 0, 0, 0, 0),
)
.ok();
}

if fido_listener_pid.is_none() {
fido_listener_pid = msg.sender.pid();
}
Expand Down Expand Up @@ -1537,6 +1550,23 @@ pub(crate) fn main_hw() -> ! {
serial_trng_interval.store(TRNG_REFILL_DELAY_MS, Ordering::SeqCst);
}
}
Some(Opcode::RegisterUsbObserver) => {
let buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
let ur = buffer.as_flat::<UsbListenerRegistration, _>().unwrap();
if observer_conn.is_none() {
match xns.request_connection_blocking(ur.server_name.as_str()) {
Ok(cid) => {
observer_conn = Some(cid);
observer_op = Some(ur.listener_op_id as usize);
}
Err(e) => {
log::error!("couldn't connect to observer: {:?}", e);
observer_conn = None;
observer_op = None;
}
}
}
}
Some(Opcode::Quit) => {
log::warn!("Quit received, goodbye world!");
break;
Expand Down

0 comments on commit b979508

Please sign in to comment.