Skip to content

Commit

Permalink
Implement POC of Stax app with home + settings screen
Browse files Browse the repository at this point in the history
  • Loading branch information
agrojean-ledger committed Jan 10, 2024
1 parent 4db5271 commit f5561ae
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 85 deletions.
1 change: 1 addition & 0 deletions ledger_device_sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ num-traits = { version = "0.2.14", default_features = false }
rand_core = { version = "0.6.3", default_features = false }
zeroize = { version = "1.6.0", default_features = false }
numtoa = "0.2.4"
const-zero = "0.1.1"

[profile.release]
opt-level = 's'
Expand Down
90 changes: 45 additions & 45 deletions ledger_device_sdk/examples/stax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,17 @@
// Force boot section to be embedded in
use ledger_device_sdk as _;

use ledger_device_sdk::nbgl::{home, Home};
use ledger_device_sdk::nbgl::Home;
use ledger_device_sdk::uxapp::UxEvent;
use ledger_device_sdk::io::*;
use ledger_secure_sdk_sys::seph;
use ledger_secure_sdk_sys::*;
use const_zero::const_zero;

use include_gif::include_gif;

#[no_mangle]
pub static G_ux_params: bolos_ux_params_t = bolos_ux_params_t {
ux_id: 0,
len: 0,
u: bolos_ux_params_s__bindgen_ty_1 {
pairing_request: bolos_ux_params_s__bindgen_ty_1__bindgen_ty_1 {
type_: 0,
pairing_info_len: 0,
pairing_info: [0; 16],
},
},
};
pub static mut G_ux_params: bolos_ux_params_t = unsafe { const_zero!(bolos_ux_params_t) };

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
Expand Down Expand Up @@ -106,45 +100,51 @@ fn wait_any() {
}
}

pub enum Instruction {
GetVersion,
GetAppName,
}

impl TryFrom<ApduHeader> for Instruction {
type Error = StatusWords;

fn try_from(value: ApduHeader) -> Result<Self, Self::Error> {
match value.ins {
3 => Ok(Instruction::GetVersion),
4 => Ok(Instruction::GetAppName),
_ => Err(StatusWords::NothingReceived),
}
}
}

#[no_mangle]
extern "C" fn sample_main() {
unsafe {
nbgl_refreshReset();
}

// works
home(&BTC_BMP);
wait_any();

// does not work

// let icon = nbgl_icon_details_t {
// width: 64,
// height: 64,
// bpp: 2,
// isFile: true,
// bitmap: BTC_BMP.as_ptr(),
// };

// Home::new()
// .app_name("Bitcoin\0")
// .icon(&icon)
// .top_right_cb(|| {
// let icon2 = nbgl_icon_details_t {
// width: 64,
// height: 64,
// bpp: 2,
// isFile: true,
// bitmap: BTC_BMP.as_ptr(),
// };
// unsafe { nbgl_refreshReset(); }
// Home::new().icon(&icon2).app_name("Ethereum\0").show();
// wait_any();
// })
// .quit_cb(|| exit_app(12))
// .show();

// wait_any();
let mut comm = Comm::new();

let icon = nbgl_icon_details_t {
width: 64,
height: 64,
bpp: 2,
isFile: true,
bitmap: BTC_BMP.as_ptr(),
};

let mut myHome = Home::new(Some(&mut comm))
.app_name("Stax Sample\0")
.icon(&icon);

myHome.show();

loop {
match myHome.get_events::<Instruction>() {
Event::Command(ins) => (),
_ => (),
};
}

exit_app(0);
}
Expand Down
8 changes: 8 additions & 0 deletions ledger_device_sdk/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@ impl Comm {
seph::Events::BleReceive => ble::receive(&mut self.apdu_buffer, spi_buffer),

seph::Events::TickerEvent => return Some(Event::Ticker),

#[cfg(target_os = "stax")]
seph::Events::ScreenTouch => {
unsafe {
ux_process_finger_event(spi_buffer.as_mut_ptr());
}
}

_ => (),
}

Expand Down
121 changes: 81 additions & 40 deletions ledger_device_sdk/src/nbgl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use core::mem::transmute;
use ledger_secure_sdk_sys::nbgl_icon_details_t;
use crate::io::{self, ApduHeader, Comm, Event, Reply};
use ledger_secure_sdk_sys::seph;
use ledger_secure_sdk_sys::*;

pub struct Home<'a> {
app_name: &'static str,
Expand All @@ -8,17 +11,73 @@ pub struct Home<'a> {
with_settings: bool,
top_right_cb: Option<fn()>,
quit_cb: Option<fn()>,
comm: Option<&'a mut Comm>,
}

const infoTypes: [*const ::core::ffi::c_char; 2] = [
"Version\0".as_ptr() as *const ::core::ffi::c_char,
"Developer\0".as_ptr() as *const ::core::ffi::c_char,
];

const infoContents: [*const ::core::ffi::c_char; 2] = [
env!("CARGO_PKG_VERSION").as_ptr() as *const ::core::ffi::c_char,
"Ledger\0".as_ptr() as *const ::core::ffi::c_char,
];

fn settings_nav(page: u8, content: *mut nbgl_pageContent_s) -> bool
{
if page == 0 {
unsafe {
(*content).type_ = ledger_secure_sdk_sys::INFOS_LIST;
(*content).__bindgen_anon_1.infosList.nbInfos = 2;
(*content).__bindgen_anon_1.infosList.infoTypes = infoTypes.as_ptr();
(*content).__bindgen_anon_1.infosList.infoContents = infoContents.as_ptr();
}
} else {
return false;
}
true
}

fn settings() {
unsafe {
ledger_secure_sdk_sys::nbgl_useCaseSettings(
"My App\0".as_ptr() as *const core::ffi::c_char,
0 as u8,
1 as u8,
false as bool,
transmute((|| home_nav()) as fn()),
transmute((|arg1,arg2| settings_nav(arg1,arg2)) as fn(u8, *mut nbgl_pageContent_s) -> bool),
transmute((|| exit_app(12)) as fn()),
);
}
}

fn home_nav() {
unsafe {
ledger_secure_sdk_sys::nbgl_useCaseHome(
"My App\0".as_ptr() as *const core::ffi::c_char,
core::ptr::null(),
core::ptr::null(),
true as bool,
transmute((|| settings()) as fn()),
transmute((|| exit_app(12)) as fn()),
);
}
}


impl<'a> Home<'a> {
pub fn new() -> Home<'a> {
pub fn new(comm: Option<&'a mut Comm>) -> Home<'a> {

Home {
app_name: "AppName\0",
icon: None,
tagline: None,
with_settings: false,
top_right_cb: None,
quit_cb: None,
comm,
}
}

Expand Down Expand Up @@ -47,52 +106,34 @@ impl<'a> Home<'a> {
}
}

pub fn show(&self) {
// let bop: unsafe extern "C" fn() = self.top_right_cb.unwrap() as unsafe extern "C" fn();
pub fn show(&mut self)
{
unsafe {
ledger_secure_sdk_sys::nbgl_useCaseHome(
self.app_name.as_ptr() as *const core::ffi::c_char,
self.icon.unwrap() as *const nbgl_icon_details_t,
core::ptr::null(),
self.with_settings,
// match self.top_right_cb {
// None => None,
// Some(f) => Some(f),
// },
transmute(self.top_right_cb),
// Some(bop),
transmute(self.quit_cb),
)
true as bool,
transmute((|| settings()) as fn()),
transmute((|| exit_app(12)) as fn()),
);

}
}
}

extern "C" fn do_nothing() {}
extern "C" fn exit() {
ledger_secure_sdk_sys::exit_app(0);
}
pub fn home(image: &[u8]) {
let icon = ledger_secure_sdk_sys::nbgl_icon_details_t {
width: 64,
height: 64,
bpp: 2,
isFile: true,
bitmap: image.as_ptr(),
};
unsafe {
// appName: *const ::core::ffi::c_char,
// appIcon: *const nbgl_icon_details_t,
// tagline: *const ::core::ffi::c_char,
// withSettings: bool,
// topRightCallback: nbgl_callback_t,
// quitCallback: nbgl_callback_t
ledger_secure_sdk_sys::nbgl_useCaseHome(
"AppName\0".as_ptr() as *const core::ffi::c_char,
&icon,
core::ptr::null(),
false,
Some(do_nothing),
Some(exit),
);
pub fn get_events<T: TryFrom<ApduHeader>>(&mut self) -> Event<T>
where Reply: From<<T as TryFrom<ApduHeader>>::Error>
{
loop {
match &mut self.comm {
None => (),
Some(comm) => {
if let Event::Command(ins) = comm.next_event() {
return Event::Command(ins);
}
}
}
}
}
}

2 changes: 2 additions & 0 deletions ledger_device_sdk/src/seph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum Events {
ButtonPush = SEPROXYHAL_TAG_BUTTON_PUSH_EVENT as u8,
DisplayProcessed = SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT as u8,
BleReceive = SEPROXYHAL_TAG_BLE_RECV_EVENT as u8,
ScreenTouch = SEPROXYHAL_TAG_FINGER_EVENT as u8,
Unknown = 0xff,
}
#[repr(u8)]
Expand All @@ -44,6 +45,7 @@ impl From<u8> for Events {
SEPROXYHAL_TAG_BUTTON_PUSH_EVENT => Events::ButtonPush,
SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT => Events::DisplayProcessed,
SEPROXYHAL_TAG_BLE_RECV_EVENT => Events::BleReceive,
SEPROXYHAL_TAG_FINGER_EVENT => Events::ScreenTouch,
_ => Events::Unknown,
}
}
Expand Down

0 comments on commit f5561ae

Please sign in to comment.