Skip to content

Commit

Permalink
[add] Flex porting
Browse files Browse the repository at this point in the history
  • Loading branch information
lpascal-ledger committed Apr 4, 2024
1 parent ac54252 commit 2e10d58
Show file tree
Hide file tree
Showing 79 changed files with 164 additions and 84 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#*******************************************************************************
# Ledger App
# (c) 2017 Ledger
# (c) 2017-2024 Ledger
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,6 +41,7 @@ ICON_NANOS = icons/nanos_icon_password_manager.gif
ICON_NANOSP = icons/nanox_icon_password_manager.gif
ICON_NANOX = icons/nanox_icon_password_manager.gif
ICON_STAX = icons/stax_icon_password_manager_32px.gif
ICON_FLEX = icons/stax_icon_password_manager_32px.gif

DEFINES += OS_IO_SEPROXYHAL
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
Expand All @@ -58,7 +59,7 @@ else
DEFINES += TESTING
endif

ifneq ($(TARGET_NAME), TARGET_STAX)
ifneq ($(TARGET_NAME), $(filter $(TARGET_NAME), TARGET_STAX TARGET_FLEX))
$(info Using BAGL)
DEFINES += HAVE_BAGL
DEFINES += HAVE_UX_FLOW
Expand Down
2 changes: 1 addition & 1 deletion ledger_app.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[app]
build_directory="."
devices = ["nanos", "nanos+", "nanox", "stax"]
devices = ["nanos", "nanos+", "nanox", "stax", "flex"]
sdk = "c"

[tests]
Expand Down
2 changes: 1 addition & 1 deletion src/keyboards/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#pragma once

#if !defined(TARGET_STAX)
#if !defined(SCREEN_SIZE_WALLET)

#include <os_io_seproxyhal.h>
#include <ux.h>
Expand Down
2 changes: 1 addition & 1 deletion src/keyboards/keyboard_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "keyboard.h"

#if !defined(TARGET_STAX)
#if !defined(SCREEN_SIZE_WALLET)

void bolos_ux_hslider3_init(unsigned int total_count) {
G_keyboard_ctx.hslider3_total = total_count;
Expand Down
2 changes: 1 addition & 1 deletion src/keyboards/text_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdint.h>
#include <ux.h>

#if !defined(TARGET_STAX)
#if !defined(SCREEN_SIZE_WALLET)

#include "keyboard.h"

Expand Down
4 changes: 2 additions & 2 deletions src/nano/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdbool.h>
#include <string.h>

#if !defined(TARGET_STAX)
#if !defined(SCREEN_SIZE_WALLET)

#include <hid_mapping.h>

Expand Down Expand Up @@ -638,4 +638,4 @@ void ui_idle() {
}
}

#endif // if !defined(TARGET_STAX)
#endif // if !defined(SCREEN_SIZE_WALLET)
File renamed without changes.
2 changes: 1 addition & 1 deletion src/stax/password_list.h → src/nbgl/password_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#define DISPLAYED_PASSWORD_PER_PAGE 5

#if defined(TARGET_STAX)
#if defined(SCREEN_SIZE_WALLET)

void password_list_reset();

Expand Down
58 changes: 42 additions & 16 deletions src/stax/ui.c → src/nbgl/ui.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Password Manager application
* (c) 2017-2023 Ledger SAS
* (c) 2017-2024 Ledger SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,7 +18,7 @@
#include <os.h>
#include <string.h>

#if defined(TARGET_STAX)
#if defined(SCREEN_SIZE_WALLET)

#include <nbgl_layout.h>
#include <nbgl_page.h>
Expand Down Expand Up @@ -97,13 +97,15 @@ static const char *const infoTypes[] = {"Version", "Passwords"};
static const char *const infoContents[] = {APPVERSION, "(c) 2017-2023 Ledger"};
static const char *const availableKbl[] = {"QWERTY", "QWERTY INT.", "AZERTY"};

#define SETTINGS_CHARSET_OPTIONS_NUMBER 5
#define SETTINGS_KEYBOARD_OPTIONS_NUMBER 3
#define SETTINGS_MISC_OPTIONS_NUMBER 1
#define SETTINGS_INFO_NUMBER 2
#define SETTINGS_PAGE_NUMBER 4
#define SETTINGS_FIRST_PAGE_STAX_OPTIONS_NUMBER 5
#define SETTINGS_FIRST_PAGE_FLEX_OPTIONS_NUMBER 4
#define SETTINGS_SECOND_PAGE_STAX_OPTIONS_NUMBER 1
#define SETTINGS_SECOND_PAGE_FLEX_OPTIONS_NUMBER 2
#define SETTINGS_KEYBOARD_OPTIONS_NUMBER 3
#define SETTINGS_INFO_NUMBER 2
#define SETTINGS_PAGE_NUMBER 4

static nbgl_layoutSwitch_t switches[SETTINGS_CHARSET_OPTIONS_NUMBER];
static nbgl_layoutSwitch_t switches[SETTINGS_FIRST_PAGE_STAX_OPTIONS_NUMBER];

static void _prepare_kbl_choice(nbgl_pageContent_t *content) {
content->type = CHOICES_LIST;
Expand Down Expand Up @@ -149,22 +151,40 @@ static bool display_settings_navigation(uint8_t page, nbgl_pageContent_t *conten
.subText = "('-', ' ', '_')",
.token = BARS_TOKEN,
.tuneId = TUNE_TAP_CASUAL};
#if defined(TARGET_STAX)
switches[4] = (nbgl_layoutSwitch_t){.initState = has_charset_option(EXT_SYMBOLS_BITFLAG),
.text = "Use special characters",
.subText = NULL,
.token = EXT_SYMBOLS_TOKEN,
.tuneId = TUNE_TAP_CASUAL};
content->switchesList.nbSwitches = SETTINGS_FIRST_PAGE_STAX_OPTIONS_NUMBER;
#else // TARGET_STAX
content->switchesList.nbSwitches = SETTINGS_FIRST_PAGE_FLEX_OPTIONS_NUMBER;
#endif // TARGET_STAX
content->type = SWITCHES_LIST;
content->switchesList.nbSwitches = SETTINGS_CHARSET_OPTIONS_NUMBER;
content->switchesList.switches = &switches[0];
PRINTF("PAGE 1 READY TO DISPLAY\n");
} else if (page == 1) {
switches[0] = (nbgl_layoutSwitch_t){.initState = N_storage.press_enter_after_typing,
.text = "Press enter",
.subText = "after writing the password",
.token = NO_ENTER_TOKEN,
size_t index_after_charset = 0;
#if defined(TARGET_FLEX)
switches[0] = (nbgl_layoutSwitch_t){.initState = has_charset_option(EXT_SYMBOLS_BITFLAG),
.text = "Use special characters",
.subText = NULL,
.token = EXT_SYMBOLS_TOKEN,
.tuneId = TUNE_TAP_CASUAL};
index_after_charset++;
content->switchesList.nbSwitches = SETTINGS_SECOND_PAGE_FLEX_OPTIONS_NUMBER;
#else // TARGET_FLEX
content->switchesList.nbSwitches = SETTINGS_SECOND_PAGE_STAX_OPTIONS_NUMBER;
#endif // TARGET_FLEX
switches[index_after_charset] =
(nbgl_layoutSwitch_t){.initState = N_storage.press_enter_after_typing,
.text = "Press enter",
.subText = "after writing the password",
.token = NO_ENTER_TOKEN,
.tuneId = TUNE_TAP_CASUAL};

content->type = SWITCHES_LIST;
content->switchesList.nbSwitches = SETTINGS_MISC_OPTIONS_NUMBER;
content->switchesList.switches = &switches[0];
} else if (page == 2) {
_prepare_kbl_choice(content);
Expand Down Expand Up @@ -685,9 +705,15 @@ void ui_idle() {
nbgl_useCaseChoice(
&C_stax_icon_password_manager_64px,
"Disclaimer",
"Be sure to backup your passwords every time you\nupdate either your device"
"\nOS or this application:\nhttps://passwords.ledger.com\n\nIf not, they "
#if defined(TARGET_STAX)
"Be sure to backup your passwords every time you update either your device "
"OS or this application: https://passwords.ledger.com\n\nIf not, they "
"will be lost.",
#else // TARGET_STAX
"Be sure to backup your passwords every time you update either your device "
"OS or this application: https://passwords.ledger.com\nIf not, they "
"will be lost.",
#endif
"Yes, I understand",
"No, this is too complicated",
startup_callback);
Expand Down
4 changes: 2 additions & 2 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "options.h"
#include "globals.h"

#if !defined(TARGET_STAX)
#if !defined(SCREEN_SIZE_WALLET)

static uint8_t charset_options;

Expand All @@ -26,7 +26,7 @@ uint8_t get_charset_options() {
return N_storage.charset_options;
}

#endif // !defined(TARGET_STAX)
#endif // !defined(SCREEN_SIZE_WALLET)

void init_charset_options() {
// default: uppercase (1) + lowercase (2) + numbers (4) = 7
Expand Down
2 changes: 1 addition & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ typedef struct internalStorage_t {
*/
size_t metadata_count;
uint8_t metadatas[MAX_METADATAS];
#if defined(TARGET_STAX)
#if defined(SCREEN_SIZE_WALLET)
uint8_t charset_options;
#endif
} internalStorage_t;
Expand Down
12 changes: 8 additions & 4 deletions tests/functional/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

from passwordsManager_cmd import PasswordsManagerCommand
from tests_vectors import tests_vectors
from stax.navigator import CustomStaxNavigator
from nbgl.navigator import CustomNBGLNavigator

from ragger.conftest import configuration

pytest_plugins = ("ragger.conftest.base_conftest", )
Expand Down Expand Up @@ -40,15 +41,18 @@ def cmd(custom_backend, firmware):

@pytest.fixture
def navigator(custom_backend, firmware):
navigator = CustomStaxNavigator(custom_backend, firmware)
navigator = CustomNBGLNavigator(custom_backend, firmware)
yield navigator


@pytest.fixture(autouse=True)
def use_on_firmware(request, firmware):
if request.node.get_closest_marker('use_on_firmware'):
current_firmware = request.node.get_closest_marker('use_on_firmware').args[0].lower()
if current_firmware != firmware.device:
accepted_firmware = request.node.get_closest_marker('use_on_firmware').args[0]
if isinstance(accepted_firmware, str):
accepted_firmware = [accepted_firmware]

if firmware.device not in [f.lower() for f in accepted_firmware]:
pytest.skip(f'skipped on this firmware: "{firmware.device}" is not '\
f'"{current_firmware}"')

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ragger.navigator.navigator import Navigator
from time import sleep

from .screen import CustomStaxScreen
from .screen import CustomNBGLScreen


class CustomNavInsID(BaseNavInsID):
Expand Down Expand Up @@ -47,10 +47,10 @@ class CustomNavInsID(BaseNavInsID):
DISCLAIMER_REJECT = auto()


class CustomStaxNavigator(Navigator):
class CustomNBGLNavigator(Navigator):

def __init__(self, backend, firmware):
self.screen = CustomStaxScreen(backend, firmware)
self.screen = CustomNBGLScreen(backend, firmware)
callbacks = {
# has to be defined for Ragger Navigator internals
NavInsID.WAIT: sleep,
Expand All @@ -74,7 +74,7 @@ def __init__(self, backend, firmware):
CustomNavInsID.CONFIRM_YES: self.screen.confirmation.confirm,
CustomNavInsID.CONFIRM_NO: self.screen.confirmation.reject,
CustomNavInsID.KEYBOARD_WRITE: self.screen.keyboard.write,
CustomNavInsID.KEYBOARD_TO_CONFIRM: self.screen.keyboard_confirm.tap,
CustomNavInsID.KEYBOARD_TO_CONFIRM: self.screen.keyboard_confirm.confirm,
CustomNavInsID.KEYBOARD_TO_MENU: self.screen.keyboard_cancel.tap,
CustomNavInsID.LIST_CHOOSE: self._choose,
CustomNavInsID.CHOOSE_KBL_QWERTY: partial(self._choose, 0),
Expand Down
45 changes: 45 additions & 0 deletions tests/functional/nbgl/screen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from ragger.backend import BackendInterface
from ragger.firmware import Firmware
from ragger.firmware.nbgl import MetaScreen
from ragger.firmware.nbgl.use_cases import UseCaseChoice, UseCaseHomeExt, UseCaseReview, \
UseCaseSettings
from ragger.firmware.nbgl.layouts import ChoiceList, FullKeyboardLetters, \
KeyboardConfirmationButton, LeftHeader


class RadioList:

def __init__(self, backend: BackendInterface, firmware: Firmware):
self.backend = backend
self.firmware = firmware

def choose(self, index: int):
if self.firmware == Firmware.STAX:
positions = [(200, 130), (200, 210), (200, 290), (200, 370), (200, 450)]
else: # Firmware.FLEX
positions = [(240, 140), (240, 230), (240, 320), (240, 410), (240, 500)]
assert 0 <= index <= 4, "Choice index must be in [0, 4]"
self.backend.finger_touch(*positions[index])


class CustomNBGLScreen(metaclass=MetaScreen):

# "backup your data" disclaimer, displayed the first time the app is started
use_case_disclaimer = UseCaseChoice
# "choose your keyboard layout" choice, displayed the first time the app is started
layout_kbl_choice = ChoiceList
# home page
use_case_home = UseCaseHomeExt
# app settings
use_case_settings = UseCaseSettings
# main app menu, where to choose actions (write, display, create, delete, ... passwords)
use_case_menu = UseCaseSettings
use_case_confirmation = UseCaseReview
# choose a password menu (for action like write, display or delete)
layout_menu_choice = ChoiceList
layout_list_choice = RadioList
# Keyboard for naming password when creating one
layout_keyboard = FullKeyboardLetters
# confirm and cancel action (delete, delete all, create, ...)
layout_keyboard_confirm = KeyboardConfirmationButton
layout_keyboard_cancel = LeftHeader
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .navigator import CustomNavInsID


@pytest.mark.use_on_firmware("stax")
@pytest.mark.use_on_firmware(["stax", "flex"])
def test_immediate_quit(navigator):
instructions = [
CustomNavInsID.DISCLAIMER_CONFIRM,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .navigator import CustomNavInsID


@pytest.mark.use_on_firmware("stax")
@pytest.mark.use_on_firmware(["stax", "flex"])
def test_delete_one_password(navigator, functional_test_directory):
instructions = [
CustomNavInsID.DISCLAIMER_CONFIRM,
Expand All @@ -26,7 +26,7 @@ def test_delete_one_password(navigator, functional_test_directory):
screen_change_before_first_instruction=False)


@pytest.mark.use_on_firmware("stax")
@pytest.mark.use_on_firmware(["stax", "flex"])
def test_delete_all_passwords(navigator, functional_test_directory):
instructions = [
CustomNavInsID.DISCLAIMER_CONFIRM,
Expand All @@ -46,7 +46,7 @@ def test_delete_all_passwords(navigator, functional_test_directory):
screen_change_before_first_instruction=False)


@pytest.mark.use_on_firmware("stax")
@pytest.mark.use_on_firmware(["stax", "flex"])
def test_create_password(navigator, functional_test_directory):
instructions = [
CustomNavInsID.DISCLAIMER_CONFIRM,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
from .navigator import CustomNavInsID



@pytest.mark.use_on_firmware("stax")
@pytest.mark.use_on_firmware(["stax", "flex"])
def test_settings_screens(navigator, functional_test_directory):
instructions = [
CustomNavInsID.DISCLAIMER_CONFIRM,
Expand Down
9 changes: 6 additions & 3 deletions tests/functional/passwordsManager_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from exception import DeviceException
from ragger.backend import BackendInterface
from ragger.firmware import Firmware
from ragger.firmware.stax.positions import BUTTON_ABOVE_LOWER_MIDDLE
from ragger.firmware.nbgl.positions import FLEX_BUTTON_ABOVE_LOWER_MIDDLE, \
STAX_BUTTON_ABOVE_LOWER_MIDDLE

CLA_SDK: int = 0xb0
CLA: int = 0xe0
Expand Down Expand Up @@ -32,8 +33,10 @@ def __init__(self,
self.approved: bool = False

def approve(self):
if self.firmware.has_nbgl:
self.transport.finger_touch(*BUTTON_ABOVE_LOWER_MIDDLE)
if self.firmware == Firmware.STAX:
self.transport.finger_touch(*STAX_BUTTON_ABOVE_LOWER_MIDDLE)
elif self.firmware == Firmware.FLEX:
self.transport.finger_touch(*FLEX_BUTTON_ABOVE_LOWER_MIDDLE)
else:
self.transport.both_click()

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions tests/functional/snapshots/flex/create_password/00000.png
1 change: 1 addition & 0 deletions tests/functional/snapshots/flex/create_password/00001.png
Loading

0 comments on commit 2e10d58

Please sign in to comment.