Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flex porting #76

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 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 All @@ -24,7 +24,7 @@ all: default

APPNAME ="Passwords"
APPVERSION_M=1
APPVERSION_N=2
APPVERSION_N=3
APPVERSION_P=0
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)

Expand All @@ -37,10 +37,11 @@ HAVE_APPLICATION_FLAG_GLOBAL_PIN = 1

DEFINES += APPNAME=\"$(APPNAME)\"

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_NANOS = icons/nanos_icon_passwords.gif
ICON_NANOSP = icons/nanox_icon_passwords.gif
ICON_NANOX = icons/nanox_icon_passwords.gif
ICON_STAX = icons/stax_icon_passwords.gif
ICON_FLEX = icons/flex_icon_passwords.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,10 +59,9 @@ 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
ifneq ($(TARGET_NAME), TARGET_NANOS)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_GLO096
Expand Down
Binary file added icons/flex_icon_passwords.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
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
3 changes: 2 additions & 1 deletion src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void app_main() {
create_new_password("password1", sizeof("password1") - 1);
create_new_password("password2", sizeof("password2") - 1);
create_new_password("password3", sizeof("password3") - 1);
#endif
#endif // POPULATE

for (;;) {
BEGIN_TRY {
TRY {
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 All @@ -32,7 +32,7 @@
// parameter
#define KEYBOARD_RENDER_WORD \
3 // callback is called with a -1 when requesting complete word, or the char
// index else, returnin 0 implies no char is to be displayed

Check failure on line 35 in src/keyboards/keyboard.h

View workflow job for this annotation

GitHub Actions / Check misspellings

returnin ==> returning, return in
typedef const bagl_element_t* (*keyboard_callback_t)(unsigned int event, unsigned int value);

// bolos ux context (not mandatory if redesigning a bolos ux)
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
105 changes: 86 additions & 19 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,39 @@ 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];
} 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 @@ -241,7 +260,11 @@ static void display_settings_page() {
* Password creation & callback
*/
static char password_name[MAX_METANAME + 1] = {0};
static int textIndex, keyboardIndex = 0;

#if API_LEVEL <= 15
static int textIndex = 0;
#endif // API_LEVEL <= 15
static int keyboardIndex = 0;

static void create_password(void) {
PRINTF("Creating new password '%s'\n", password_name);
Expand Down Expand Up @@ -293,8 +316,27 @@ static void key_press_callback(const char touchedKey) {
// every characters
mask = -1;
}
PRINTF("New password name: '%s'\n", password_name);
nbgl_layoutUpdateKeyboard(layoutContext, keyboardIndex, mask, false, LOWER_CASE);
#if API_LEVEL <= 15 // TODO: to be removed once Stax API_LEVEL goes from 15 to 18
nbgl_layoutUpdateEnteredText(layoutContext, textIndex, false, 0, &(password_name[0]), false);
#else
nbgl_layoutConfirmationButton_t confirmationButton = {.active = true,
.token = CREATE_TOKEN,
.text = PIC("Create password")};
nbgl_layoutKeyboardContent_t keyboardContent = {
.type = KEYBOARD_WITH_BUTTON,
.title = "New password nickname",
.text = password_name,
.numbered = false,
.number = 0,
.grayedOut = false,
.textToken = KBD_TEXT_TOKEN,
.confirmationButton = confirmationButton,
.tuneId = CREATE_TOKEN,
};
nbgl_layoutUpdateKeyboardContent(layoutContext, &keyboardContent);
#endif
nbgl_refreshSpecialWithPostRefresh(BLACK_AND_WHITE_REFRESH, POST_REFRESH_FORCE_POWER_ON);
}

Expand All @@ -318,19 +360,38 @@ static void display_create_pwd_page() {
nbgl_layoutAddProgressIndicator(layoutContext, 0, 0, true, BACK_BUTTON_TOKEN, TUNE_TAP_CASUAL);
nbgl_layoutAddCenteredInfo(layoutContext, &centeredInfo);
keyboardIndex = nbgl_layoutAddKeyboard(layoutContext, &kbdInfo);
strlcpy(password_name, "", 1);

#if API_LEVEL <= 15 // TODO: to be removed once Stax API_LEVEL goes from 15 to 18
nbgl_layoutAddConfirmationButton(layoutContext,
true,
"Create password",
CREATE_TOKEN,
TUNE_TAP_CASUAL);
strlcpy(password_name, "", 1);
textIndex = nbgl_layoutAddEnteredText(layoutContext,
false,
0,
password_name,
false,
32,
KBD_TEXT_TOKEN);
#else // API_LEVEL <= 15
nbgl_layoutConfirmationButton_t confirmationButton = {.active = true,
.token = CREATE_TOKEN,
.text = PIC("Create password")};
nbgl_layoutKeyboardContent_t keyboardContent = {
.type = KEYBOARD_WITH_BUTTON,
.title = PIC("New password nickname"),
.text = &(password_name[0]),
.numbered = false,
.number = 0,
.grayedOut = false,
.textToken = KBD_TEXT_TOKEN,
.confirmationButton = confirmationButton,
.tuneId = CREATE_TOKEN,
};
nbgl_layoutAddKeyboardContent(layoutContext, &keyboardContent);
#endif // API_LEVEL <= 15
nbgl_layoutDraw(layoutContext);
}

Expand Down Expand Up @@ -680,21 +741,27 @@ void startup_callback(bool choice) {
}

void ui_idle() {
// First start: the keyboard layout is not selected yet
if (N_storage.keyboard_layout == HID_MAPPING_NONE) {
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);
} else {
display_home_page();
}
}

void ui_request_user_approval(message_pair_t *msg) {
display_approval_page(msg);
}
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
18 changes: 11 additions & 7 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 touch.navigator import CustomTouchNavigator

from ragger.conftest import configuration

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


@pytest.fixture
def navigator(custom_backend, firmware):
navigator = CustomStaxNavigator(custom_backend, firmware)
def navigator(custom_backend, firmware, golden_run):
navigator = CustomTouchNavigator(custom_backend, firmware, golden_run)
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:
pytest.skip(f'skipped on this firmware: "{firmware.device}" is not '\
f'"{current_firmware}"')
accepted_firmwares = request.node.get_closest_marker('use_on_firmware').args[0]
if isinstance(accepted_firmwares, str):
accepted_firmwares = [accepted_firmwares]

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


def pytest_configure(config):
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.touch.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.
Loading
Loading