From 8c4d35b7598d93e69241f27641c332a0d6c5d459 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 02:44:35 -0700 Subject: [PATCH 01/17] style: Update encryption ui - Added a parameter in ui_scrollable screen to allow header only on first screen --- .../inheritance_encrypt_data.c | 7 +- common/core/ui_core_confirm.c | 13 ++ common/core/ui_core_confirm.h | 6 + .../user_interface/ui_scroll_page.c | 129 +++++++++++++++--- .../user_interface/ui_scroll_page.h | 17 +++ src/settings/user_configuration.c | 2 +- 6 files changed, 154 insertions(+), 20 deletions(-) diff --git a/apps/inheritance_app/inheritance_encrypt_data.c b/apps/inheritance_app/inheritance_encrypt_data.c index 3b40f5f14..606a4046f 100644 --- a/apps/inheritance_app/inheritance_encrypt_data.c +++ b/apps/inheritance_app/inheritance_encrypt_data.c @@ -315,9 +315,10 @@ STATIC bool inheritance_encryption_get_user_verification(void) { &encryption_context->request_pointer->plain_data[i]; if (data->has_is_verified_on_device && data->is_verified_on_device) { - if (!core_scroll_page(UI_TEXT_VERIFY_MESSAGE, - (const char *)&data->message.bytes, - inheritance_send_error)) { + if (!core_scroll_non_sticky_heading_page( + UI_TEXT_VERIFY_MESSAGE, + (const char *)&data->message.bytes, + inheritance_send_error)) { return false; } } diff --git a/common/core/ui_core_confirm.c b/common/core/ui_core_confirm.c index 9ec08bfb2..39d29d96b 100644 --- a/common/core/ui_core_confirm.c +++ b/common/core/ui_core_confirm.c @@ -65,6 +65,7 @@ #include "error.pb.h" #include "events.h" #include "ui_screens.h" +#include "ui_scroll_page.h" /***************************************************************************** * EXTERN VARIABLES @@ -135,3 +136,15 @@ bool core_scroll_page(const char *title, ui_scrollable_page(title, body, MENU_SCROLL_HORIZONTAL, false); return wait_for_event(reject_cb); } + +// TODO: merge with above function +bool core_scroll_non_sticky_heading_page(const char *title, + const char *body, + ui_core_rejection_cb *reject_cb) { + scrollable_page_options_t options = { + .is_heading_sticky = false, + .are_cancel_accept_btn_visible = false, + .page_orientation = MENU_SCROLL_HORIZONTAL}; + ui_scrollable_page_with_options(title, body, options); + return wait_for_event(reject_cb); +} diff --git a/common/core/ui_core_confirm.h b/common/core/ui_core_confirm.h index ea168173e..a25c1e2df 100644 --- a/common/core/ui_core_confirm.h +++ b/common/core/ui_core_confirm.h @@ -74,4 +74,10 @@ bool core_scroll_page(const char *title, const char *body, ui_core_rejection_cb *reject_cb); +/** + * @brief Copy of above function, to be merged eventually. + */ +bool core_scroll_non_sticky_heading_page(const char *title, + const char *body, + ui_core_rejection_cb *reject_cb); #endif diff --git a/common/interfaces/user_interface/ui_scroll_page.c b/common/interfaces/user_interface/ui_scroll_page.c index a24a089db..baa7d914f 100644 --- a/common/interfaces/user_interface/ui_scroll_page.c +++ b/common/interfaces/user_interface/ui_scroll_page.c @@ -58,6 +58,8 @@ */ #include "ui_scroll_page.h" +#include + #include "stdlib.h" #include "ui_events_priv.h" #ifdef DEV_BUILD @@ -238,6 +240,31 @@ static void page_update_buttons(void) { return; } +static void page_update_header(void) { + if (!gp_scrollabe_page_data->bool_only_first_page_header_visible) { + return; + } + + ASSERT((NULL != gp_scrollabe_page_data) && (NULL != gp_scrollabe_page_lvgl)); + + bool is_heading_hidden = gp_scrollabe_page_data->curr_page_num != 1; + + lv_coord_t scroll_page_height = 48; + lv_align_t scroll_page_aligment = LV_ALIGN_IN_TOP_MID; + + if (!is_heading_hidden) { + scroll_page_height = 32; + scroll_page_aligment = LV_ALIGN_CENTER; + } + + lv_obj_set_size( + gp_scrollabe_page_lvgl->p_ui_page_lvgl, 128, scroll_page_height); + lv_obj_align( + gp_scrollabe_page_lvgl->p_ui_page_lvgl, NULL, scroll_page_aligment, 0, 0); + lv_obj_set_hidden(gp_scrollabe_page_lvgl->p_ui_header_lvgl, + is_heading_hidden); +} + static void page_update_footnote(void) { ASSERT((NULL != gp_scrollabe_page_data) && (NULL != gp_scrollabe_page_lvgl)); @@ -264,7 +291,6 @@ static void page_update_icons(void) { page_update_arrows(); page_update_buttons(); page_update_footnote(); - return; } @@ -400,10 +426,17 @@ static void page_arrow_handler(lv_obj_t *pLvglArrowObject, LV_ALIGN_IN_TOP_MID, 0, 0); + page_update_header(); page_update_icons(); } } else if (LV_KEY_LEFT == keyPressed) { if (true == page_decrement()) { + /*** + * We have to update header before calculating scroll distance + * other wise the current page height is decrease instead of previous + * page height + */ + page_update_header(); lv_label_set_style(gp_scrollabe_page_lvgl->p_ui_left_arrow_lvgl, LV_LABEL_STYLE_MAIN, &(gp_scrollabe_page_lvgl->ui_arrow_pressed_style)); @@ -443,8 +476,8 @@ static void page_arrow_handler(lv_obj_t *pLvglArrowObject, } case LV_EVENT_DELETE: { - /* Destruct object and data variables in case the object is being deleted - * directly using lv_obj_clean() */ + /* Destruct object and data variables in case the object is being + * deleted directly using lv_obj_clean() */ ui_scrollable_destructor(); break; } @@ -514,9 +547,10 @@ static void ui_scrollable_page_create(void) { * Create a label on page gp_scrollabe_page_lvgl->p_ui_page_lvgl which * contains the body holding the actual text Size of the label is * lv_page_get_fit_width(gp_scrollabe_page_lvgl->p_ui_page_lvgl) - 16, - * lv_page_get_fit_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl) Text will be - * broken into multiple lines, but only 2 or 3 lines (32 pixels/ 48 pixels) - * are available on the page. So this creates a scrollable label on the page. + * lv_page_get_fit_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl) Text will + * be broken into multiple lines, but only 2 or 3 lines (32 pixels/ 48 + * pixels) are available on the page. So this creates a scrollable label on + * the page. */ gp_scrollabe_page_lvgl->p_ui_body_lvgl = lv_label_create(gp_scrollabe_page_lvgl->p_ui_page_lvgl, NULL); @@ -557,7 +591,8 @@ static void ui_scrollable_page_create(void) { // Pad with \n if there are 2 rows of text and pad with \n\n if there are 3 // rows of text - if (32 == scroll_page_height) { + if (32 == scroll_page_height && + !gp_scrollabe_page_data->bool_only_first_page_header_visible) { lv_label_set_text(paddingLabel, "\n"); } else { lv_label_set_text(paddingLabel, "\n\n"); @@ -581,9 +616,10 @@ static void ui_scrollable_page_create(void) { lv_group_focus_obj(gp_scrollabe_page_lvgl->p_ui_body_lvgl); /** - * Create a labels on current screen to hold the left and right arrows icons. - * These icons will be placed on the left and right side of the screen. - * These icons will be visible conditionally (if there is anything to scroll) + * Create a labels on current screen to hold the left and right arrows + * icons. These icons will be placed on the left and right side of the + * screen. These icons will be visible conditionally (if there is anything + * to scroll) */ /* TODO: Handle vertical scrolling input by processing page_orientation * argument */ @@ -612,8 +648,8 @@ static void ui_scrollable_page_create(void) { lv_style_copy(&(gp_scrollabe_page_lvgl->ui_arrow_released_style), &lv_style_plain); - /* gp_scrollabe_page_lvgl->ui_arrow_pressed_style: This style will be drawn on - * the arrow if scrolling icon is pressed */ + /* gp_scrollabe_page_lvgl->ui_arrow_pressed_style: This style will be drawn + * on the arrow if scrolling icon is pressed */ lv_style_copy(&(gp_scrollabe_page_lvgl->ui_arrow_pressed_style), &lv_style_plain); (gp_scrollabe_page_lvgl->ui_arrow_pressed_style).body.main_color = @@ -627,9 +663,9 @@ static void ui_scrollable_page_create(void) { /** * Calculate the number of pages/max number of times full scrolling can take - * place Total number of scrolls = Total height of content on page / Height of - * page We have already padded the content on page with label paddingLabel and - * therefore we do not need to consider padding here + * place Total number of scrolls = Total height of content on page / Height + * of page We have already padded the content on page with label + * paddingLabel and therefore we do not need to consider padding here */ int16_t totalPageHeight = (int16_t)lv_page_get_scrl_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl); @@ -639,6 +675,25 @@ static void ui_scrollable_page_create(void) { gp_scrollabe_page_data->curr_page_num = 1; gp_scrollabe_page_data->total_page_num = totalPageHeight / currPageHeight; + /** + * Recalculate the total pages if heading is only visible on the first page + */ + if (gp_scrollabe_page_data->bool_only_first_page_header_visible) { + gp_scrollabe_page_data->total_page_num = 1; + int16_t first_page_height = currPageHeight; + + gp_scrollabe_page_data->curr_page_num = 2; + page_update_header(); + + int16_t curr_page_height = + (int16_t)lv_obj_get_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl); + gp_scrollabe_page_data->total_page_num += + (totalPageHeight - first_page_height) / curr_page_height; + + gp_scrollabe_page_data->curr_page_num = 1; + page_update_header(); + } + /** * Create buttons on the screen for cancellation and confirmation. * These buttons will be visible conditionally (if the current page is the @@ -669,7 +724,8 @@ static void ui_scrollable_page_create(void) { lv_label_create(lv_scr_act(), NULL); } - /* Update all icons: Left/right arrows, Accept/Cancel buttons and Footnote */ + /* Update all icons: Left/right arrows, Accept/Cancel buttons and Footnote + */ page_update_icons(); return; @@ -714,3 +770,44 @@ void ui_scrollable_page(const char *p_page_ui_heading, return; } + +void ui_scrollable_page_with_options(const char *p_page_ui_heading, + const char *p_page_ui_body, + scrollable_page_options_t options) { + if (NULL == p_page_ui_body) { + return; + } + + lv_obj_clean(lv_scr_act()); + + gp_scrollabe_page_data = + (scrolling_page_data_t *)malloc(sizeof(scrolling_page_data_t)); + ASSERT(NULL != gp_scrollabe_page_data); + + gp_scrollabe_page_data->p_ui_heading = p_page_ui_heading; + gp_scrollabe_page_data->p_ui_body = p_page_ui_body; + gp_scrollabe_page_data->bool_accept_cancel_visible = + options.are_cancel_accept_btn_visible; + gp_scrollabe_page_data->bool_only_first_page_header_visible = + !options.is_heading_sticky; + + /* Below fields will be overwritten below, when page settings are being + * applied */ + gp_scrollabe_page_data->total_page_num = 1; + gp_scrollabe_page_data->curr_page_num = 1; + gp_scrollabe_page_data->bool_left_arrow_hidden = true; + gp_scrollabe_page_data->bool_right_arrow_hidden = true; + gp_scrollabe_page_data->bool_accept_cancel_hidden = false; + + ui_scrollable_page_create(); + +#ifdef DEV_BUILD + ekp_enqueue(LV_KEY_UP, DEFAULT_DELAY); + for (int i = 0; i < gp_scrollabe_page_data->total_page_num; i++) + ekp_enqueue(LV_KEY_RIGHT, DEFAULT_DELAY); + // ekp_enqueue(LV_KEY_DOWN,DEFAULT_DELAY); + ekp_enqueue(LV_KEY_ENTER, DEFAULT_DELAY); +#endif + + return; +} diff --git a/common/interfaces/user_interface/ui_scroll_page.h b/common/interfaces/user_interface/ui_scroll_page.h index d49b0d305..b19de8330 100644 --- a/common/interfaces/user_interface/ui_scroll_page.h +++ b/common/interfaces/user_interface/ui_scroll_page.h @@ -26,6 +26,7 @@ typedef struct { bool bool_right_arrow_hidden; bool bool_accept_cancel_visible; bool bool_accept_cancel_hidden; + bool bool_only_first_page_header_visible; } scrolling_page_data_t; typedef struct { @@ -40,6 +41,7 @@ typedef struct { lv_obj_t *p_ui_cancel_btn_lvgl; lv_obj_t *p_ui_accept_btn_lvgl; lv_obj_t *p_ui_footnote_lvgl; + lv_obj_t *p_ui_padding_label; } scrolling_page_lvgl_t; typedef enum { @@ -47,6 +49,12 @@ typedef enum { MENU_SCROLL_UNDEFINED, } e_scrollable_page_orientation_t; +typedef struct { + e_scrollable_page_orientation_t page_orientation; + bool are_cancel_accept_btn_visible; + bool is_heading_sticky; +} scrollable_page_options_t; + /** * @brief This API renders a scrollable UI page with a optional heading, 2-3 * rows of scrollable text, cancel and accept buttons, and a footnote depicting @@ -77,6 +85,15 @@ void ui_scrollable_page(const char *p_page_ui_heading, e_scrollable_page_orientation_t page_orientation, bool bool_cancel_accept_btn_visible); +/** + * @brief A copy of above function but with more options, designed to be replace + * it entirely and provide more options + * + */ +void ui_scrollable_page_with_options(const char *p_page_ui_heading, + const char *p_page_ui_body, + scrollable_page_options_t options); + #ifdef UI_HOR_SCROLL_PAGE_UNIT_TESTS /** * @brief This function tests the functionality of the ui_scrollable_page() API. diff --git a/src/settings/user_configuration.c b/src/settings/user_configuration.c index 9e3ff4d4c..a8ea3e4d4 100644 --- a/src/settings/user_configuration.c +++ b/src/settings/user_configuration.c @@ -142,4 +142,4 @@ void rotate_display(void) { FLASH_SAVE_NOW); } return; -} \ No newline at end of file +} From 66c50e43ee4305ef0576757fa48ec3591d9ec4d8 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 02:48:56 -0700 Subject: [PATCH 02/17] style: Update decryption ui --- apps/inheritance_app/inheritance_decrypt_data.c | 4 ++-- src/constant_texts.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/inheritance_app/inheritance_decrypt_data.c b/apps/inheritance_app/inheritance_decrypt_data.c index 60583d6eb..b8d3dd8df 100644 --- a/apps/inheritance_app/inheritance_decrypt_data.c +++ b/apps/inheritance_app/inheritance_decrypt_data.c @@ -321,9 +321,9 @@ static bool show_data(void) { if (tag == INHERITANCE_ONLY_SHOW_ON_DEVICE) { if (!core_scroll_page( - UI_TEXT_VERIFY_MESSAGE, + UI_TEXT_PIN, ///< TODO: Figure out a way to make this generic (const char *)&decryption_context->data[i] - .plain_data[3], ///> sizeof (tag) + sizeof (length) = 3 + .plain_data[3], ///< sizeof (tag) + sizeof (length) = 3 inheritance_send_error)) { return false; } diff --git a/src/constant_texts.h b/src/constant_texts.h index 06ad28608..135583d1d 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -53,6 +53,7 @@ #define UI_TEXT_BLIND_SIGNING_WARNING \ LV_SYMBOL_WARNING " Blind Signing\nProceed at your own risk!" #define UI_TEXT_VERIFY_HD_PATH "Verify Derivation Path" +#define UI_TEXT_PIN "PIN" // product hash extern const char *product_hash; From 9b588517ef36357f53ba93323dcf99d138b75848 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 04:49:17 -0700 Subject: [PATCH 03/17] style: Update auth wallet ui --- .../inheritance_app/inheritance_auth_wallet.c | 43 ++++++++++++++++++- src/constant_texts.c | 2 + src/constant_texts.h | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 515e0f494..b7fe25530 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -20,12 +20,14 @@ #include "bip39.h" #include "card_fetch_data.h" #include "card_pair.h" +#include "constant_texts.h" #include "core_error.h" #include "inheritance/core.pb.h" #include "inheritance_api.h" #include "inheritance_priv.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" +#include "ui_core_confirm.h" #include "ui_delay.h" /***************************************************************************** * EXTERN VARIABLES @@ -148,6 +150,44 @@ static bool auth_wallet_get_signature(); * STATIC FUNCTIONS *****************************************************************************/ +static bool check_which_request(const inheritance_query_t *query, + pb_size_t which_request) { + if (which_request != query->encrypt.which_request) { + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_REQUEST); + return false; + } + + return true; +} + +STATIC bool auth_wallet_handle_inititate_query(inheritance_query_t *query) { + char wallet_name[NAME_SIZE] = ""; + char msg[100] = ""; + + if (!check_which_request(query, + INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG) || + !get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, + (uint8_t *)wallet_name, + inheritance_send_error)) { + // TODO: update this for nominee + return false; + } + + snprintf(msg, + sizeof(msg), + ui_text_inheritance_wallet_auth_flow_confirmation, + wallet_name); + + if (!core_confirmation(msg, inheritance_send_error)) { + return false; + } + + // TODO: update flow status here + + return true; +} + static bool verify_auth_wallet_inputs() { if (auth->data.challenge_size == 0 || auth->data.challenge_size < CHALLENGE_SIZE_MIN || @@ -349,7 +389,8 @@ void inheritance_auth_wallet(inheritance_query_t *query) { auth->do_wallet_based = query->auth_wallet.initiate.do_wallet_based; set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_INIT); - if (verify_auth_wallet_inputs() && auth_wallet_get_entropy() && + if (verify_auth_wallet_inputs() && + auth_wallet_handle_inititate_query(query) && auth_wallet_get_entropy() && auth_wallet_get_pairs() && auth_wallet_get_signature() && send_result()) { delay_scr_init(ui_text_inheritance_wallet_auth_success, DELAY_TIME); } diff --git a/src/constant_texts.c b/src/constant_texts.c index 51d9aff08..6646d20fd 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -530,6 +530,8 @@ const char *ui_critical_card_health_migrate_data = // App specific // Inheritance +const char *ui_text_inheritance_wallet_auth_flow_confirmation = + "Start %s wallet authentication?"; const char *ui_text_inheritance_wallet_authenticating = "Wallet\nauthenticating..."; const char *ui_text_inheritance_wallet_auth_success = diff --git a/src/constant_texts.h b/src/constant_texts.h index 135583d1d..92ceeb11b 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -374,6 +374,7 @@ extern const char *ui_critical_card_health_migrate_data; // App specific // Inheritance +extern const char *ui_text_inheritance_wallet_auth_flow_confirmation; extern const char *ui_text_inheritance_wallet_authenticating; extern const char *ui_text_inheritance_wallet_auth_success; extern const char *ui_text_inheritance_wallet_auth_fail; From e0685075074d6b35220597b39c95bb5d24d6322e Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Mon, 2 Sep 2024 00:02:34 -0700 Subject: [PATCH 04/17] fix: Card wallet fetch screen text --- src/card_operations/card_fetch_wallet_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/card_operations/card_fetch_wallet_list.c b/src/card_operations/card_fetch_wallet_list.c index 01bf0c2cc..9376f33af 100644 --- a/src/card_operations/card_fetch_wallet_list.c +++ b/src/card_operations/card_fetch_wallet_list.c @@ -187,8 +187,8 @@ bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, .skip_card_removal = true, .expected_family_id = get_family_id()}, - .frontend = {.heading = ui_text_place_card_below, - .msg = ui_text_tap_1_2_cards}}; + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; card_fetch_wallet_list_response_t response = {.wallet_list = &wallets_in_card, .card_info = {0}}; From 4ef8d21f7745943ea485368dec6aea6cda99ea7b Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Mon, 2 Sep 2024 04:19:01 -0700 Subject: [PATCH 05/17] fix: Handle cases for decryption and auth wallet for nominee --- .../inheritance_app/inheritance_auth_wallet.c | 25 +++++++++++-------- .../inheritance_decrypt_data.c | 22 ++++++++++------ src/card_operations/card_fetch_encrypt_data.c | 4 +-- src/card_operations/card_fetch_wallet_list.c | 9 +++++-- src/card_operations/card_pair.c | 3 +-- src/constant_texts.c | 4 +++ src/constant_texts.h | 2 ++ src/settings/card_health_check.c | 3 ++- src/settings/factory_reset.c | 3 ++- src/settings/sync_with_cards.c | 3 ++- 10 files changed, 51 insertions(+), 27 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index b7fe25530..c2fc32758 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -166,18 +166,23 @@ STATIC bool auth_wallet_handle_inititate_query(inheritance_query_t *query) { char msg[100] = ""; if (!check_which_request(query, - INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG) || - !get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, - (uint8_t *)wallet_name, - inheritance_send_error)) { - // TODO: update this for nominee + INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG)) { return false; } - - snprintf(msg, - sizeof(msg), - ui_text_inheritance_wallet_auth_flow_confirmation, - wallet_name); + if (get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, + (uint8_t *)wallet_name, + NULL)) { + snprintf(msg, + sizeof(msg), + ui_text_inheritance_wallet_auth_flow_confirmation, + wallet_name); + + } else { + snprintf(msg, + sizeof(msg), + "%s", + ui_text_inheritance_wallet_auth_flow_confirmation_generic); + } if (!core_confirmation(msg, inheritance_send_error)) { return false; diff --git a/apps/inheritance_app/inheritance_decrypt_data.c b/apps/inheritance_app/inheritance_decrypt_data.c index b8d3dd8df..4a34ecfea 100644 --- a/apps/inheritance_app/inheritance_decrypt_data.c +++ b/apps/inheritance_app/inheritance_decrypt_data.c @@ -209,17 +209,23 @@ STATIC bool inheritance_handle_initiate_query(inheritance_query_t *query) { if (!check_which_request( query, INHERITANCE_DECRYPT_DATA_WITH_PIN_REQUEST_INITIATE_TAG) || - !validate_request_data(&query->decrypt) || - !get_wallet_name_by_id(query->decrypt.initiate.wallet_id, - (uint8_t *)wallet_name, - inheritance_send_error)) { + !validate_request_data(&query->decrypt)) { return false; } - snprintf(msg, - sizeof(msg), - ui_text_inheritance_decryption_flow_confirmation, - wallet_name); + if (get_wallet_name_by_id( + query->decrypt.initiate.wallet_id, (uint8_t *)wallet_name, NULL)) { + snprintf(msg, + sizeof(msg), + ui_text_inheritance_decryption_flow_confirmation, + wallet_name); + + } else { + snprintf(msg, + sizeof(msg), + "%s", + ui_text_inheritance_decryption_flow_confirmation_generic); + } if (!core_confirmation(msg, inheritance_send_error)) { return false; diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 356f4ee0f..af2672e55 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -61,6 +61,7 @@ #include "buzzer.h" #include "card_fetch_data.h" +#include "card_fetch_wallet_list.h" #include "card_internal.h" #include "card_utils.h" #include "nfc.h" @@ -107,8 +108,7 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, char wallet_name[NAME_SIZE] = ""; #if USE_SIMULATOR == 0 - // Confirm NULL use for rejection_cb - ASSERT(get_wallet_name_by_id(wallet_id, (uint8_t *)wallet_name, NULL)); + card_fetch_wallet_name(wallet_id, wallet_name); #endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); diff --git a/src/card_operations/card_fetch_wallet_list.c b/src/card_operations/card_fetch_wallet_list.c index 9376f33af..85a446368 100644 --- a/src/card_operations/card_fetch_wallet_list.c +++ b/src/card_operations/card_fetch_wallet_list.c @@ -63,6 +63,7 @@ #include +#include "app_error.h" #include "card_internal.h" #include "card_operation_typedefs.h" #include "card_utils.h" @@ -132,7 +133,10 @@ card_error_type_e card_fetch_wallet_list( if (card_data.nfc_data.status == SW_NO_ERROR || card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { - buzzer_start(BUZZER_DURATION); + if (card_data.nfc_data.status == SW_RECORD_NOT_FOUND || + config->operation.buzzer_on_success) { + buzzer_start(BUZZER_DURATION); + } if (!config->operation.skip_card_removal) { wait_for_card_removal(); } @@ -186,7 +190,8 @@ bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { card_fetch_wallet_list_config_t configuration = { .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, .skip_card_removal = true, - .expected_family_id = get_family_id()}, + .expected_family_id = get_family_id(), + .buzzer_on_success = false}, .frontend = {.heading = ui_text_tap_1_2_cards, .msg = ui_text_place_card_below}}; diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 91f2b4307..2ca6b481e 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -514,7 +514,6 @@ card_error_type_e single_card_pair_operation(char *heading, } buzzer_start(BUZZER_DURATION); - wait_for_card_removal(); break; } @@ -534,4 +533,4 @@ card_error_type_e single_card_pair_operation(char *heading, nfc_deselect_card(); return card_data.error_type; -} \ No newline at end of file +} diff --git a/src/constant_texts.c b/src/constant_texts.c index 6646d20fd..f7026d280 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -532,6 +532,8 @@ const char *ui_critical_card_health_migrate_data = // Inheritance const char *ui_text_inheritance_wallet_auth_flow_confirmation = "Start %s wallet authentication?"; +const char *ui_text_inheritance_wallet_auth_flow_confirmation_generic = + "Start wallet authentication?"; const char *ui_text_inheritance_wallet_authenticating = "Wallet\nauthenticating..."; const char *ui_text_inheritance_wallet_auth_success = @@ -547,6 +549,8 @@ const char *ui_text_inheritance_encryption_flow_failure = "Encryption Failed"; const char *ui_text_inheritance_decryption_flow_confirmation = "Proceed to decrypt data for %s?"; +const char *ui_text_inheritance_decryption_flow_confirmation_generic = + "Proceed to decrypt data?"; const char *ui_text_inheritance_decryption_flow_success = "Decryption Success"; const char *ui_text_inheritance_decryption_flow_failure = "Decryption Failed"; diff --git a/src/constant_texts.h b/src/constant_texts.h index 92ceeb11b..10050c03e 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -375,6 +375,7 @@ extern const char *ui_critical_card_health_migrate_data; // Inheritance extern const char *ui_text_inheritance_wallet_auth_flow_confirmation; +extern const char *ui_text_inheritance_wallet_auth_flow_confirmation_generic; extern const char *ui_text_inheritance_wallet_authenticating; extern const char *ui_text_inheritance_wallet_auth_success; extern const char *ui_text_inheritance_wallet_auth_fail; @@ -385,6 +386,7 @@ extern const char *ui_text_inheritance_encryption_flow_success; extern const char *ui_text_inheritance_encryption_flow_failure; extern const char *ui_text_inheritance_decryption_flow_confirmation; +extern const char *ui_text_inheritance_decryption_flow_confirmation_generic; extern const char *ui_text_inheritance_decryption_flow_success; extern const char *ui_text_inheritance_decryption_flow_failure; diff --git a/src/settings/card_health_check.c b/src/settings/card_health_check.c index f45ae8f77..04739c3fd 100644 --- a/src/settings/card_health_check.c +++ b/src/settings/card_health_check.c @@ -107,6 +107,7 @@ void card_health_check(void) { configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = true; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = NULL; configuration.frontend.msg = ui_text_card_health_check_start; @@ -201,4 +202,4 @@ void card_health_check(void) { } return; -} \ No newline at end of file +} diff --git a/src/settings/factory_reset.c b/src/settings/factory_reset.c index 5c0e4bb0a..b0290ffd3 100644 --- a/src/settings/factory_reset.c +++ b/src/settings/factory_reset.c @@ -217,6 +217,7 @@ static bool get_wallet_list_from_two_cards(wallet_list_t *wallet_list) { configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = false; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = ui_text_tap_1_2_cards; configuration.frontend.msg = ui_text_place_card_below; @@ -365,4 +366,4 @@ void clear_device_data(void) { // Reset device to apply new settings BSP_reset(); -} \ No newline at end of file +} diff --git a/src/settings/sync_with_cards.c b/src/settings/sync_with_cards.c index b5d0bc213..44797702c 100644 --- a/src/settings/sync_with_cards.c +++ b/src/settings/sync_with_cards.c @@ -140,6 +140,7 @@ static bool get_wallets_from_card(wallet_list_t *wallet_list, configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = false; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = ui_text_tap_1_2_cards; configuration.frontend.msg = ui_text_place_card_below; @@ -328,4 +329,4 @@ void sync_with_cards(void) { delay_scr_init(msg, DELAY_TIME); return; -} \ No newline at end of file +} From 455121f5206ca9c0c74fdaa684453ee8ece6be47 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 16:01:43 +0530 Subject: [PATCH 06/17] fix(app): Integrate get wallet name to other flows --- src/card_operations/card_fetch_data.h | 14 ++++ src/card_operations/card_fetch_decrypt_data.c | 45 +++++++++++ src/card_operations/card_fetch_encrypt_data.c | 79 ++++++++++++++++++- 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/src/card_operations/card_fetch_data.h b/src/card_operations/card_fetch_data.h index fcd4a7b68..ebe052ebc 100644 --- a/src/card_operations/card_fetch_data.h +++ b/src/card_operations/card_fetch_data.h @@ -14,6 +14,8 @@ #include +#include "card_fetch_wallet_list.h" +#include "card_internal.h" #include "card_operation_typedefs.h" #include "stdbool.h" #include "stdint.h" @@ -51,6 +53,18 @@ typedef struct { * GLOBAL FUNCTION PROTOTYPES *****************************************************************************/ +/** + * @brief Fetches wallet list from card after applet initialization. + * + * @param card_data card_operation_data_t used for applet init. + * + * @return The card error type indicating the result of the operation. + */ +card_error_type_e card_get_wallet_list( + card_operation_data_t card_data, + const card_fetch_wallet_list_config_t *configuration, + card_fetch_wallet_list_response_t *response); + /** * @brief Fetches and encrypts data for a given wallet ID. * diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index 5a22e66c8..a3bca6c99 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -65,6 +65,7 @@ #include "card_internal.h" #include "card_utils.h" #include "nfc.h" +#include "ui_delay.h" #include "ui_instruction.h" /***************************************************************************** @@ -127,6 +128,50 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); #endif + // Fetch wallet list from card + wallet_list_t wallets_in_card = {0}; + card_fetch_wallet_list_config_t configuration = { + .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, + .skip_card_removal = true, + .expected_family_id = card_data.nfc_data.family_id, + .buzzer_on_success = false}, + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; + + card_fetch_wallet_list_response_t response = { + .wallet_list = &wallets_in_card, .card_info = {0}}; +#if USE_SIMULATOR == 0 + card_error_type_e status = + card_get_wallet_list(card_data, &configuration, &response); +#endif + // If the tapped card is not paired, it is a terminal case in the flow + if (true == response.card_info.pairing_error) { + return CARD_OPERATION_DEFAULT_INVALID; + } + + // At this stage, either there is no core error message set, or it is set + // but we want to overwrite the error message using user facing messages in + // this flow + uint32_t card_fault_status = 0; + if (1 == response.card_info.recovery_mode) { + card_fault_status = NFC_NULL_PTR_ERROR; + } else if (CARD_OPERATION_SUCCESS != status) { + card_fault_status = response.card_info.status; + } + + for (uint8_t i = 0; i < wallets_in_card.count; i++) { + if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == + 0) { + memcpy(wallet_name, + (const char *)wallets_in_card.wallet[i].name, + NAME_SIZE); + break; + } + } + if (0 == strlen(wallet_name)) { + delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + return CARD_OPERATION_DEFAULT_INVALID; + } if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index af2672e55..764ca5064 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -66,6 +66,7 @@ #include "card_utils.h" #include "nfc.h" #include "pow_utilities.h" +#include "ui_delay.h" #include "ui_instruction.h" /***************************************************************************** @@ -87,7 +88,38 @@ /***************************************************************************** * STATIC VARIABLES *****************************************************************************/ +card_error_type_e card_get_wallet_list( + card_operation_data_t card_data, + const card_fetch_wallet_list_config_t *configuration, + card_fetch_wallet_list_response_t *response) { + if (NULL == configuration || NULL == response || + NULL == response->wallet_list) { + return CARD_OPERATION_DEFAULT_INVALID; + } + if (CARD_OPERATION_SUCCESS == card_data.error_type) { + card_data.nfc_data.status = nfc_list_all_wallet(response->wallet_list); + + if (card_data.nfc_data.status == SW_NO_ERROR || + card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { + if (card_data.nfc_data.status == SW_RECORD_NOT_FOUND || + configuration->operation.buzzer_on_success) { + buzzer_start(BUZZER_DURATION); + } + if (!configuration->operation.skip_card_removal) { + wait_for_card_removal(); + } + // break; + } else { + card_handle_errors(&card_data); + } + } + response->card_info.pairing_error = card_data.nfc_data.pairing_error; + response->card_info.tapped_card = card_data.nfc_data.tapped_card; + response->card_info.recovery_mode = card_data.nfc_data.recovery_mode; + response->card_info.status = card_data.nfc_data.status; + return card_data.error_type; +} /***************************************************************************** * GLOBAL VARIABLES *****************************************************************************/ @@ -107,9 +139,6 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, card_operation_data_t card_data = {0}; char wallet_name[NAME_SIZE] = ""; -#if USE_SIMULATOR == 0 - card_fetch_wallet_name(wallet_id, wallet_name); -#endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); @@ -128,6 +157,50 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); #endif + // Fetch wallet list from card + wallet_list_t wallets_in_card = {0}; + card_fetch_wallet_list_config_t configuration = { + .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, + .skip_card_removal = true, + .expected_family_id = card_data.nfc_data.family_id, + .buzzer_on_success = false}, + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; + + card_fetch_wallet_list_response_t response = { + .wallet_list = &wallets_in_card, .card_info = {0}}; +#if USE_SIMULATOR == 0 + card_error_type_e status = + card_get_wallet_list(card_data, &configuration, &response); +#endif + // If the tapped card is not paired, it is a terminal case in the flow + if (true == response.card_info.pairing_error) { + return CARD_OPERATION_DEFAULT_INVALID; + } + + // At this stage, either there is no core error message set, or it is set + // but we want to overwrite the error message using user facing messages in + // this flow + uint32_t card_fault_status = 0; + if (1 == response.card_info.recovery_mode) { + card_fault_status = NFC_NULL_PTR_ERROR; + } else if (CARD_OPERATION_SUCCESS != status) { + card_fault_status = response.card_info.status; + } + + for (uint8_t i = 0; i < wallets_in_card.count; i++) { + if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == + 0) { + memcpy(wallet_name, + (const char *)wallets_in_card.wallet[i].name, + NAME_SIZE); + break; + } + } + if (0 == strlen(wallet_name)) { + delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + return CARD_OPERATION_DEFAULT_INVALID; + } if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { From 2c9c7b1bbfc000faca58ffb359bd1ccc3c053a6d Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 16:12:17 +0530 Subject: [PATCH 07/17] fix(app): Simulator build --- src/card_operations/card_fetch_decrypt_data.c | 2 +- src/card_operations/card_fetch_encrypt_data.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index a3bca6c99..68b193217 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -143,7 +143,6 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 card_error_type_e status = card_get_wallet_list(card_data, &configuration, &response); -#endif // If the tapped card is not paired, it is a terminal case in the flow if (true == response.card_info.pairing_error) { return CARD_OPERATION_DEFAULT_INVALID; @@ -172,6 +171,7 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); return CARD_OPERATION_DEFAULT_INVALID; } +#endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 764ca5064..336387f0f 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -172,7 +172,6 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 card_error_type_e status = card_get_wallet_list(card_data, &configuration, &response); -#endif // If the tapped card is not paired, it is a terminal case in the flow if (true == response.card_info.pairing_error) { return CARD_OPERATION_DEFAULT_INVALID; @@ -201,6 +200,7 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); return CARD_OPERATION_DEFAULT_INVALID; } +#endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { From 9d984d8ae60a9dfadc9983071dbd111947dd8a2f Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 17:42:22 +0530 Subject: [PATCH 08/17] fix(app): Decryption ui --- src/card_operations/card_fetch_decrypt_data.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index 68b193217..b03cb9477 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -107,9 +107,6 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, card_operation_data_t card_data = {0}; char wallet_name[NAME_SIZE] = ""; -#if USE_SIMULATOR == 0 - card_fetch_wallet_name(wallet_id, wallet_name); -#endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); From 1350d59f2bb54437045471f7b368661d935f7a11 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 02:44:35 -0700 Subject: [PATCH 09/17] style: Update encryption ui - Added a parameter in ui_scrollable screen to allow header only on first screen --- .../inheritance_encrypt_data.c | 7 +- common/core/ui_core_confirm.c | 13 ++ common/core/ui_core_confirm.h | 6 + .../user_interface/ui_scroll_page.c | 129 +++++++++++++++--- .../user_interface/ui_scroll_page.h | 17 +++ src/settings/user_configuration.c | 2 +- 6 files changed, 154 insertions(+), 20 deletions(-) diff --git a/apps/inheritance_app/inheritance_encrypt_data.c b/apps/inheritance_app/inheritance_encrypt_data.c index 3b40f5f14..606a4046f 100644 --- a/apps/inheritance_app/inheritance_encrypt_data.c +++ b/apps/inheritance_app/inheritance_encrypt_data.c @@ -315,9 +315,10 @@ STATIC bool inheritance_encryption_get_user_verification(void) { &encryption_context->request_pointer->plain_data[i]; if (data->has_is_verified_on_device && data->is_verified_on_device) { - if (!core_scroll_page(UI_TEXT_VERIFY_MESSAGE, - (const char *)&data->message.bytes, - inheritance_send_error)) { + if (!core_scroll_non_sticky_heading_page( + UI_TEXT_VERIFY_MESSAGE, + (const char *)&data->message.bytes, + inheritance_send_error)) { return false; } } diff --git a/common/core/ui_core_confirm.c b/common/core/ui_core_confirm.c index 9ec08bfb2..39d29d96b 100644 --- a/common/core/ui_core_confirm.c +++ b/common/core/ui_core_confirm.c @@ -65,6 +65,7 @@ #include "error.pb.h" #include "events.h" #include "ui_screens.h" +#include "ui_scroll_page.h" /***************************************************************************** * EXTERN VARIABLES @@ -135,3 +136,15 @@ bool core_scroll_page(const char *title, ui_scrollable_page(title, body, MENU_SCROLL_HORIZONTAL, false); return wait_for_event(reject_cb); } + +// TODO: merge with above function +bool core_scroll_non_sticky_heading_page(const char *title, + const char *body, + ui_core_rejection_cb *reject_cb) { + scrollable_page_options_t options = { + .is_heading_sticky = false, + .are_cancel_accept_btn_visible = false, + .page_orientation = MENU_SCROLL_HORIZONTAL}; + ui_scrollable_page_with_options(title, body, options); + return wait_for_event(reject_cb); +} diff --git a/common/core/ui_core_confirm.h b/common/core/ui_core_confirm.h index ea168173e..a25c1e2df 100644 --- a/common/core/ui_core_confirm.h +++ b/common/core/ui_core_confirm.h @@ -74,4 +74,10 @@ bool core_scroll_page(const char *title, const char *body, ui_core_rejection_cb *reject_cb); +/** + * @brief Copy of above function, to be merged eventually. + */ +bool core_scroll_non_sticky_heading_page(const char *title, + const char *body, + ui_core_rejection_cb *reject_cb); #endif diff --git a/common/interfaces/user_interface/ui_scroll_page.c b/common/interfaces/user_interface/ui_scroll_page.c index a24a089db..baa7d914f 100644 --- a/common/interfaces/user_interface/ui_scroll_page.c +++ b/common/interfaces/user_interface/ui_scroll_page.c @@ -58,6 +58,8 @@ */ #include "ui_scroll_page.h" +#include + #include "stdlib.h" #include "ui_events_priv.h" #ifdef DEV_BUILD @@ -238,6 +240,31 @@ static void page_update_buttons(void) { return; } +static void page_update_header(void) { + if (!gp_scrollabe_page_data->bool_only_first_page_header_visible) { + return; + } + + ASSERT((NULL != gp_scrollabe_page_data) && (NULL != gp_scrollabe_page_lvgl)); + + bool is_heading_hidden = gp_scrollabe_page_data->curr_page_num != 1; + + lv_coord_t scroll_page_height = 48; + lv_align_t scroll_page_aligment = LV_ALIGN_IN_TOP_MID; + + if (!is_heading_hidden) { + scroll_page_height = 32; + scroll_page_aligment = LV_ALIGN_CENTER; + } + + lv_obj_set_size( + gp_scrollabe_page_lvgl->p_ui_page_lvgl, 128, scroll_page_height); + lv_obj_align( + gp_scrollabe_page_lvgl->p_ui_page_lvgl, NULL, scroll_page_aligment, 0, 0); + lv_obj_set_hidden(gp_scrollabe_page_lvgl->p_ui_header_lvgl, + is_heading_hidden); +} + static void page_update_footnote(void) { ASSERT((NULL != gp_scrollabe_page_data) && (NULL != gp_scrollabe_page_lvgl)); @@ -264,7 +291,6 @@ static void page_update_icons(void) { page_update_arrows(); page_update_buttons(); page_update_footnote(); - return; } @@ -400,10 +426,17 @@ static void page_arrow_handler(lv_obj_t *pLvglArrowObject, LV_ALIGN_IN_TOP_MID, 0, 0); + page_update_header(); page_update_icons(); } } else if (LV_KEY_LEFT == keyPressed) { if (true == page_decrement()) { + /*** + * We have to update header before calculating scroll distance + * other wise the current page height is decrease instead of previous + * page height + */ + page_update_header(); lv_label_set_style(gp_scrollabe_page_lvgl->p_ui_left_arrow_lvgl, LV_LABEL_STYLE_MAIN, &(gp_scrollabe_page_lvgl->ui_arrow_pressed_style)); @@ -443,8 +476,8 @@ static void page_arrow_handler(lv_obj_t *pLvglArrowObject, } case LV_EVENT_DELETE: { - /* Destruct object and data variables in case the object is being deleted - * directly using lv_obj_clean() */ + /* Destruct object and data variables in case the object is being + * deleted directly using lv_obj_clean() */ ui_scrollable_destructor(); break; } @@ -514,9 +547,10 @@ static void ui_scrollable_page_create(void) { * Create a label on page gp_scrollabe_page_lvgl->p_ui_page_lvgl which * contains the body holding the actual text Size of the label is * lv_page_get_fit_width(gp_scrollabe_page_lvgl->p_ui_page_lvgl) - 16, - * lv_page_get_fit_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl) Text will be - * broken into multiple lines, but only 2 or 3 lines (32 pixels/ 48 pixels) - * are available on the page. So this creates a scrollable label on the page. + * lv_page_get_fit_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl) Text will + * be broken into multiple lines, but only 2 or 3 lines (32 pixels/ 48 + * pixels) are available on the page. So this creates a scrollable label on + * the page. */ gp_scrollabe_page_lvgl->p_ui_body_lvgl = lv_label_create(gp_scrollabe_page_lvgl->p_ui_page_lvgl, NULL); @@ -557,7 +591,8 @@ static void ui_scrollable_page_create(void) { // Pad with \n if there are 2 rows of text and pad with \n\n if there are 3 // rows of text - if (32 == scroll_page_height) { + if (32 == scroll_page_height && + !gp_scrollabe_page_data->bool_only_first_page_header_visible) { lv_label_set_text(paddingLabel, "\n"); } else { lv_label_set_text(paddingLabel, "\n\n"); @@ -581,9 +616,10 @@ static void ui_scrollable_page_create(void) { lv_group_focus_obj(gp_scrollabe_page_lvgl->p_ui_body_lvgl); /** - * Create a labels on current screen to hold the left and right arrows icons. - * These icons will be placed on the left and right side of the screen. - * These icons will be visible conditionally (if there is anything to scroll) + * Create a labels on current screen to hold the left and right arrows + * icons. These icons will be placed on the left and right side of the + * screen. These icons will be visible conditionally (if there is anything + * to scroll) */ /* TODO: Handle vertical scrolling input by processing page_orientation * argument */ @@ -612,8 +648,8 @@ static void ui_scrollable_page_create(void) { lv_style_copy(&(gp_scrollabe_page_lvgl->ui_arrow_released_style), &lv_style_plain); - /* gp_scrollabe_page_lvgl->ui_arrow_pressed_style: This style will be drawn on - * the arrow if scrolling icon is pressed */ + /* gp_scrollabe_page_lvgl->ui_arrow_pressed_style: This style will be drawn + * on the arrow if scrolling icon is pressed */ lv_style_copy(&(gp_scrollabe_page_lvgl->ui_arrow_pressed_style), &lv_style_plain); (gp_scrollabe_page_lvgl->ui_arrow_pressed_style).body.main_color = @@ -627,9 +663,9 @@ static void ui_scrollable_page_create(void) { /** * Calculate the number of pages/max number of times full scrolling can take - * place Total number of scrolls = Total height of content on page / Height of - * page We have already padded the content on page with label paddingLabel and - * therefore we do not need to consider padding here + * place Total number of scrolls = Total height of content on page / Height + * of page We have already padded the content on page with label + * paddingLabel and therefore we do not need to consider padding here */ int16_t totalPageHeight = (int16_t)lv_page_get_scrl_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl); @@ -639,6 +675,25 @@ static void ui_scrollable_page_create(void) { gp_scrollabe_page_data->curr_page_num = 1; gp_scrollabe_page_data->total_page_num = totalPageHeight / currPageHeight; + /** + * Recalculate the total pages if heading is only visible on the first page + */ + if (gp_scrollabe_page_data->bool_only_first_page_header_visible) { + gp_scrollabe_page_data->total_page_num = 1; + int16_t first_page_height = currPageHeight; + + gp_scrollabe_page_data->curr_page_num = 2; + page_update_header(); + + int16_t curr_page_height = + (int16_t)lv_obj_get_height(gp_scrollabe_page_lvgl->p_ui_page_lvgl); + gp_scrollabe_page_data->total_page_num += + (totalPageHeight - first_page_height) / curr_page_height; + + gp_scrollabe_page_data->curr_page_num = 1; + page_update_header(); + } + /** * Create buttons on the screen for cancellation and confirmation. * These buttons will be visible conditionally (if the current page is the @@ -669,7 +724,8 @@ static void ui_scrollable_page_create(void) { lv_label_create(lv_scr_act(), NULL); } - /* Update all icons: Left/right arrows, Accept/Cancel buttons and Footnote */ + /* Update all icons: Left/right arrows, Accept/Cancel buttons and Footnote + */ page_update_icons(); return; @@ -714,3 +770,44 @@ void ui_scrollable_page(const char *p_page_ui_heading, return; } + +void ui_scrollable_page_with_options(const char *p_page_ui_heading, + const char *p_page_ui_body, + scrollable_page_options_t options) { + if (NULL == p_page_ui_body) { + return; + } + + lv_obj_clean(lv_scr_act()); + + gp_scrollabe_page_data = + (scrolling_page_data_t *)malloc(sizeof(scrolling_page_data_t)); + ASSERT(NULL != gp_scrollabe_page_data); + + gp_scrollabe_page_data->p_ui_heading = p_page_ui_heading; + gp_scrollabe_page_data->p_ui_body = p_page_ui_body; + gp_scrollabe_page_data->bool_accept_cancel_visible = + options.are_cancel_accept_btn_visible; + gp_scrollabe_page_data->bool_only_first_page_header_visible = + !options.is_heading_sticky; + + /* Below fields will be overwritten below, when page settings are being + * applied */ + gp_scrollabe_page_data->total_page_num = 1; + gp_scrollabe_page_data->curr_page_num = 1; + gp_scrollabe_page_data->bool_left_arrow_hidden = true; + gp_scrollabe_page_data->bool_right_arrow_hidden = true; + gp_scrollabe_page_data->bool_accept_cancel_hidden = false; + + ui_scrollable_page_create(); + +#ifdef DEV_BUILD + ekp_enqueue(LV_KEY_UP, DEFAULT_DELAY); + for (int i = 0; i < gp_scrollabe_page_data->total_page_num; i++) + ekp_enqueue(LV_KEY_RIGHT, DEFAULT_DELAY); + // ekp_enqueue(LV_KEY_DOWN,DEFAULT_DELAY); + ekp_enqueue(LV_KEY_ENTER, DEFAULT_DELAY); +#endif + + return; +} diff --git a/common/interfaces/user_interface/ui_scroll_page.h b/common/interfaces/user_interface/ui_scroll_page.h index d49b0d305..b19de8330 100644 --- a/common/interfaces/user_interface/ui_scroll_page.h +++ b/common/interfaces/user_interface/ui_scroll_page.h @@ -26,6 +26,7 @@ typedef struct { bool bool_right_arrow_hidden; bool bool_accept_cancel_visible; bool bool_accept_cancel_hidden; + bool bool_only_first_page_header_visible; } scrolling_page_data_t; typedef struct { @@ -40,6 +41,7 @@ typedef struct { lv_obj_t *p_ui_cancel_btn_lvgl; lv_obj_t *p_ui_accept_btn_lvgl; lv_obj_t *p_ui_footnote_lvgl; + lv_obj_t *p_ui_padding_label; } scrolling_page_lvgl_t; typedef enum { @@ -47,6 +49,12 @@ typedef enum { MENU_SCROLL_UNDEFINED, } e_scrollable_page_orientation_t; +typedef struct { + e_scrollable_page_orientation_t page_orientation; + bool are_cancel_accept_btn_visible; + bool is_heading_sticky; +} scrollable_page_options_t; + /** * @brief This API renders a scrollable UI page with a optional heading, 2-3 * rows of scrollable text, cancel and accept buttons, and a footnote depicting @@ -77,6 +85,15 @@ void ui_scrollable_page(const char *p_page_ui_heading, e_scrollable_page_orientation_t page_orientation, bool bool_cancel_accept_btn_visible); +/** + * @brief A copy of above function but with more options, designed to be replace + * it entirely and provide more options + * + */ +void ui_scrollable_page_with_options(const char *p_page_ui_heading, + const char *p_page_ui_body, + scrollable_page_options_t options); + #ifdef UI_HOR_SCROLL_PAGE_UNIT_TESTS /** * @brief This function tests the functionality of the ui_scrollable_page() API. diff --git a/src/settings/user_configuration.c b/src/settings/user_configuration.c index 9e3ff4d4c..a8ea3e4d4 100644 --- a/src/settings/user_configuration.c +++ b/src/settings/user_configuration.c @@ -142,4 +142,4 @@ void rotate_display(void) { FLASH_SAVE_NOW); } return; -} \ No newline at end of file +} From c5a69cc8a82e248ac3bd254fa07bd0265f602503 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 02:48:56 -0700 Subject: [PATCH 10/17] style: Update decryption ui --- apps/inheritance_app/inheritance_decrypt_data.c | 4 ++-- src/constant_texts.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/inheritance_app/inheritance_decrypt_data.c b/apps/inheritance_app/inheritance_decrypt_data.c index 60583d6eb..b8d3dd8df 100644 --- a/apps/inheritance_app/inheritance_decrypt_data.c +++ b/apps/inheritance_app/inheritance_decrypt_data.c @@ -321,9 +321,9 @@ static bool show_data(void) { if (tag == INHERITANCE_ONLY_SHOW_ON_DEVICE) { if (!core_scroll_page( - UI_TEXT_VERIFY_MESSAGE, + UI_TEXT_PIN, ///< TODO: Figure out a way to make this generic (const char *)&decryption_context->data[i] - .plain_data[3], ///> sizeof (tag) + sizeof (length) = 3 + .plain_data[3], ///< sizeof (tag) + sizeof (length) = 3 inheritance_send_error)) { return false; } diff --git a/src/constant_texts.h b/src/constant_texts.h index 06ad28608..135583d1d 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -53,6 +53,7 @@ #define UI_TEXT_BLIND_SIGNING_WARNING \ LV_SYMBOL_WARNING " Blind Signing\nProceed at your own risk!" #define UI_TEXT_VERIFY_HD_PATH "Verify Derivation Path" +#define UI_TEXT_PIN "PIN" // product hash extern const char *product_hash; From e29fe52e04c92acd95a4554643af3a55bd5f0ebc Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 04:49:17 -0700 Subject: [PATCH 11/17] style: Update auth wallet ui --- .../inheritance_app/inheritance_auth_wallet.c | 43 ++++++++++++++++++- src/constant_texts.c | 2 + src/constant_texts.h | 1 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 819acb55d..4e4787ef7 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -20,12 +20,14 @@ #include "bip39.h" #include "card_fetch_data.h" #include "card_pair.h" +#include "constant_texts.h" #include "core_error.h" #include "inheritance/core.pb.h" #include "inheritance_api.h" #include "inheritance_priv.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" +#include "ui_core_confirm.h" #include "ui_delay.h" /***************************************************************************** * EXTERN VARIABLES @@ -148,6 +150,44 @@ static bool auth_wallet_get_signature(); * STATIC FUNCTIONS *****************************************************************************/ +static bool check_which_request(const inheritance_query_t *query, + pb_size_t which_request) { + if (which_request != query->encrypt.which_request) { + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_REQUEST); + return false; + } + + return true; +} + +STATIC bool auth_wallet_handle_inititate_query(inheritance_query_t *query) { + char wallet_name[NAME_SIZE] = ""; + char msg[100] = ""; + + if (!check_which_request(query, + INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG) || + !get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, + (uint8_t *)wallet_name, + inheritance_send_error)) { + // TODO: update this for nominee + return false; + } + + snprintf(msg, + sizeof(msg), + ui_text_inheritance_wallet_auth_flow_confirmation, + wallet_name); + + if (!core_confirmation(msg, inheritance_send_error)) { + return false; + } + + // TODO: update flow status here + + return true; +} + static bool verify_auth_wallet_inputs() { if (auth->data.challenge_size == 0 || auth->data.challenge_size < CHALLENGE_SIZE_MIN || @@ -351,7 +391,8 @@ void inheritance_auth_wallet(inheritance_query_t *query) { auth->do_wallet_based = query->auth_wallet.initiate.do_wallet_based; set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_INIT); - if (verify_auth_wallet_inputs() && auth_wallet_get_entropy() && + if (verify_auth_wallet_inputs() && + auth_wallet_handle_inititate_query(query) && auth_wallet_get_entropy() && auth_wallet_get_pairs() && auth_wallet_get_signature() && send_result()) { delay_scr_init(ui_text_inheritance_wallet_auth_success, DELAY_TIME); } diff --git a/src/constant_texts.c b/src/constant_texts.c index c919cf56d..62361b0f8 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -530,6 +530,8 @@ const char *ui_critical_card_health_migrate_data = // App specific // Inheritance +const char *ui_text_inheritance_wallet_auth_flow_confirmation = + "Start %s wallet authentication?"; const char *ui_text_inheritance_wallet_authenticating = "Wallet\nauthenticating..."; const char *ui_text_inheritance_wallet_auth_success = diff --git a/src/constant_texts.h b/src/constant_texts.h index 135583d1d..92ceeb11b 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -374,6 +374,7 @@ extern const char *ui_critical_card_health_migrate_data; // App specific // Inheritance +extern const char *ui_text_inheritance_wallet_auth_flow_confirmation; extern const char *ui_text_inheritance_wallet_authenticating; extern const char *ui_text_inheritance_wallet_auth_success; extern const char *ui_text_inheritance_wallet_auth_fail; From b3c9763a622e7fc8587b632d757d25fbfd4dd831 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Mon, 2 Sep 2024 00:02:34 -0700 Subject: [PATCH 12/17] fix: Card wallet fetch screen text --- src/card_operations/card_fetch_wallet_list.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/card_operations/card_fetch_wallet_list.c b/src/card_operations/card_fetch_wallet_list.c index 01bf0c2cc..9376f33af 100644 --- a/src/card_operations/card_fetch_wallet_list.c +++ b/src/card_operations/card_fetch_wallet_list.c @@ -187,8 +187,8 @@ bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, .skip_card_removal = true, .expected_family_id = get_family_id()}, - .frontend = {.heading = ui_text_place_card_below, - .msg = ui_text_tap_1_2_cards}}; + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; card_fetch_wallet_list_response_t response = {.wallet_list = &wallets_in_card, .card_info = {0}}; From 51625efa7592bcd41c1bfe10bcacb5d60c9603d9 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Mon, 2 Sep 2024 04:19:01 -0700 Subject: [PATCH 13/17] fix: Handle cases for decryption and auth wallet for nominee --- .../inheritance_app/inheritance_auth_wallet.c | 25 +++++++++++-------- .../inheritance_decrypt_data.c | 22 ++++++++++------ src/card_operations/card_fetch_encrypt_data.c | 4 +-- src/card_operations/card_fetch_wallet_list.c | 9 +++++-- src/card_operations/card_pair.c | 3 +-- src/constant_texts.c | 4 +++ src/constant_texts.h | 2 ++ src/settings/card_health_check.c | 3 ++- src/settings/factory_reset.c | 3 ++- src/settings/sync_with_cards.c | 3 ++- 10 files changed, 51 insertions(+), 27 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 4e4787ef7..c499e4a87 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -166,18 +166,23 @@ STATIC bool auth_wallet_handle_inititate_query(inheritance_query_t *query) { char msg[100] = ""; if (!check_which_request(query, - INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG) || - !get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, - (uint8_t *)wallet_name, - inheritance_send_error)) { - // TODO: update this for nominee + INHERITANCE_AUTH_WALLET_REQUEST_INITIATE_TAG)) { return false; } - - snprintf(msg, - sizeof(msg), - ui_text_inheritance_wallet_auth_flow_confirmation, - wallet_name); + if (get_wallet_name_by_id(query->auth_wallet.initiate.wallet_id, + (uint8_t *)wallet_name, + NULL)) { + snprintf(msg, + sizeof(msg), + ui_text_inheritance_wallet_auth_flow_confirmation, + wallet_name); + + } else { + snprintf(msg, + sizeof(msg), + "%s", + ui_text_inheritance_wallet_auth_flow_confirmation_generic); + } if (!core_confirmation(msg, inheritance_send_error)) { return false; diff --git a/apps/inheritance_app/inheritance_decrypt_data.c b/apps/inheritance_app/inheritance_decrypt_data.c index b8d3dd8df..4a34ecfea 100644 --- a/apps/inheritance_app/inheritance_decrypt_data.c +++ b/apps/inheritance_app/inheritance_decrypt_data.c @@ -209,17 +209,23 @@ STATIC bool inheritance_handle_initiate_query(inheritance_query_t *query) { if (!check_which_request( query, INHERITANCE_DECRYPT_DATA_WITH_PIN_REQUEST_INITIATE_TAG) || - !validate_request_data(&query->decrypt) || - !get_wallet_name_by_id(query->decrypt.initiate.wallet_id, - (uint8_t *)wallet_name, - inheritance_send_error)) { + !validate_request_data(&query->decrypt)) { return false; } - snprintf(msg, - sizeof(msg), - ui_text_inheritance_decryption_flow_confirmation, - wallet_name); + if (get_wallet_name_by_id( + query->decrypt.initiate.wallet_id, (uint8_t *)wallet_name, NULL)) { + snprintf(msg, + sizeof(msg), + ui_text_inheritance_decryption_flow_confirmation, + wallet_name); + + } else { + snprintf(msg, + sizeof(msg), + "%s", + ui_text_inheritance_decryption_flow_confirmation_generic); + } if (!core_confirmation(msg, inheritance_send_error)) { return false; diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 356f4ee0f..af2672e55 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -61,6 +61,7 @@ #include "buzzer.h" #include "card_fetch_data.h" +#include "card_fetch_wallet_list.h" #include "card_internal.h" #include "card_utils.h" #include "nfc.h" @@ -107,8 +108,7 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, char wallet_name[NAME_SIZE] = ""; #if USE_SIMULATOR == 0 - // Confirm NULL use for rejection_cb - ASSERT(get_wallet_name_by_id(wallet_id, (uint8_t *)wallet_name, NULL)); + card_fetch_wallet_name(wallet_id, wallet_name); #endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); diff --git a/src/card_operations/card_fetch_wallet_list.c b/src/card_operations/card_fetch_wallet_list.c index 9376f33af..85a446368 100644 --- a/src/card_operations/card_fetch_wallet_list.c +++ b/src/card_operations/card_fetch_wallet_list.c @@ -63,6 +63,7 @@ #include +#include "app_error.h" #include "card_internal.h" #include "card_operation_typedefs.h" #include "card_utils.h" @@ -132,7 +133,10 @@ card_error_type_e card_fetch_wallet_list( if (card_data.nfc_data.status == SW_NO_ERROR || card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { - buzzer_start(BUZZER_DURATION); + if (card_data.nfc_data.status == SW_RECORD_NOT_FOUND || + config->operation.buzzer_on_success) { + buzzer_start(BUZZER_DURATION); + } if (!config->operation.skip_card_removal) { wait_for_card_removal(); } @@ -186,7 +190,8 @@ bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { card_fetch_wallet_list_config_t configuration = { .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, .skip_card_removal = true, - .expected_family_id = get_family_id()}, + .expected_family_id = get_family_id(), + .buzzer_on_success = false}, .frontend = {.heading = ui_text_tap_1_2_cards, .msg = ui_text_place_card_below}}; diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 91f2b4307..2ca6b481e 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -514,7 +514,6 @@ card_error_type_e single_card_pair_operation(char *heading, } buzzer_start(BUZZER_DURATION); - wait_for_card_removal(); break; } @@ -534,4 +533,4 @@ card_error_type_e single_card_pair_operation(char *heading, nfc_deselect_card(); return card_data.error_type; -} \ No newline at end of file +} diff --git a/src/constant_texts.c b/src/constant_texts.c index 62361b0f8..127c0469a 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -532,6 +532,8 @@ const char *ui_critical_card_health_migrate_data = // Inheritance const char *ui_text_inheritance_wallet_auth_flow_confirmation = "Start %s wallet authentication?"; +const char *ui_text_inheritance_wallet_auth_flow_confirmation_generic = + "Start wallet authentication?"; const char *ui_text_inheritance_wallet_authenticating = "Wallet\nauthenticating..."; const char *ui_text_inheritance_wallet_auth_success = @@ -547,6 +549,8 @@ const char *ui_text_inheritance_encryption_flow_failure = "Encryption Failed"; const char *ui_text_inheritance_decryption_flow_confirmation = "Proceed to decrypt data for %s?"; +const char *ui_text_inheritance_decryption_flow_confirmation_generic = + "Proceed to decrypt data?"; const char *ui_text_inheritance_decryption_flow_success = "Decryption Success"; const char *ui_text_inheritance_decryption_flow_failure = "Decryption Failed"; diff --git a/src/constant_texts.h b/src/constant_texts.h index 92ceeb11b..10050c03e 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -375,6 +375,7 @@ extern const char *ui_critical_card_health_migrate_data; // Inheritance extern const char *ui_text_inheritance_wallet_auth_flow_confirmation; +extern const char *ui_text_inheritance_wallet_auth_flow_confirmation_generic; extern const char *ui_text_inheritance_wallet_authenticating; extern const char *ui_text_inheritance_wallet_auth_success; extern const char *ui_text_inheritance_wallet_auth_fail; @@ -385,6 +386,7 @@ extern const char *ui_text_inheritance_encryption_flow_success; extern const char *ui_text_inheritance_encryption_flow_failure; extern const char *ui_text_inheritance_decryption_flow_confirmation; +extern const char *ui_text_inheritance_decryption_flow_confirmation_generic; extern const char *ui_text_inheritance_decryption_flow_success; extern const char *ui_text_inheritance_decryption_flow_failure; diff --git a/src/settings/card_health_check.c b/src/settings/card_health_check.c index f45ae8f77..04739c3fd 100644 --- a/src/settings/card_health_check.c +++ b/src/settings/card_health_check.c @@ -107,6 +107,7 @@ void card_health_check(void) { configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = true; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = NULL; configuration.frontend.msg = ui_text_card_health_check_start; @@ -201,4 +202,4 @@ void card_health_check(void) { } return; -} \ No newline at end of file +} diff --git a/src/settings/factory_reset.c b/src/settings/factory_reset.c index 5c0e4bb0a..b0290ffd3 100644 --- a/src/settings/factory_reset.c +++ b/src/settings/factory_reset.c @@ -217,6 +217,7 @@ static bool get_wallet_list_from_two_cards(wallet_list_t *wallet_list) { configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = false; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = ui_text_tap_1_2_cards; configuration.frontend.msg = ui_text_place_card_below; @@ -365,4 +366,4 @@ void clear_device_data(void) { // Reset device to apply new settings BSP_reset(); -} \ No newline at end of file +} diff --git a/src/settings/sync_with_cards.c b/src/settings/sync_with_cards.c index b5d0bc213..44797702c 100644 --- a/src/settings/sync_with_cards.c +++ b/src/settings/sync_with_cards.c @@ -140,6 +140,7 @@ static bool get_wallets_from_card(wallet_list_t *wallet_list, configuration.operation.acceptable_cards = ACCEPTABLE_CARDS_ALL; configuration.operation.skip_card_removal = false; configuration.operation.expected_family_id = get_family_id(); + configuration.operation.buzzer_on_success = true; configuration.frontend.heading = ui_text_tap_1_2_cards; configuration.frontend.msg = ui_text_place_card_below; @@ -328,4 +329,4 @@ void sync_with_cards(void) { delay_scr_init(msg, DELAY_TIME); return; -} \ No newline at end of file +} From 0bbb38e4c2e0b7bc733df6e7270a801a3d68c4e3 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 16:01:43 +0530 Subject: [PATCH 14/17] fix(app): Integrate get wallet name to other flows --- src/card_operations/card_fetch_data.h | 14 ++++ src/card_operations/card_fetch_decrypt_data.c | 45 +++++++++++ src/card_operations/card_fetch_encrypt_data.c | 79 ++++++++++++++++++- 3 files changed, 135 insertions(+), 3 deletions(-) diff --git a/src/card_operations/card_fetch_data.h b/src/card_operations/card_fetch_data.h index fcd4a7b68..ebe052ebc 100644 --- a/src/card_operations/card_fetch_data.h +++ b/src/card_operations/card_fetch_data.h @@ -14,6 +14,8 @@ #include +#include "card_fetch_wallet_list.h" +#include "card_internal.h" #include "card_operation_typedefs.h" #include "stdbool.h" #include "stdint.h" @@ -51,6 +53,18 @@ typedef struct { * GLOBAL FUNCTION PROTOTYPES *****************************************************************************/ +/** + * @brief Fetches wallet list from card after applet initialization. + * + * @param card_data card_operation_data_t used for applet init. + * + * @return The card error type indicating the result of the operation. + */ +card_error_type_e card_get_wallet_list( + card_operation_data_t card_data, + const card_fetch_wallet_list_config_t *configuration, + card_fetch_wallet_list_response_t *response); + /** * @brief Fetches and encrypts data for a given wallet ID. * diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index 5a22e66c8..a3bca6c99 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -65,6 +65,7 @@ #include "card_internal.h" #include "card_utils.h" #include "nfc.h" +#include "ui_delay.h" #include "ui_instruction.h" /***************************************************************************** @@ -127,6 +128,50 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); #endif + // Fetch wallet list from card + wallet_list_t wallets_in_card = {0}; + card_fetch_wallet_list_config_t configuration = { + .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, + .skip_card_removal = true, + .expected_family_id = card_data.nfc_data.family_id, + .buzzer_on_success = false}, + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; + + card_fetch_wallet_list_response_t response = { + .wallet_list = &wallets_in_card, .card_info = {0}}; +#if USE_SIMULATOR == 0 + card_error_type_e status = + card_get_wallet_list(card_data, &configuration, &response); +#endif + // If the tapped card is not paired, it is a terminal case in the flow + if (true == response.card_info.pairing_error) { + return CARD_OPERATION_DEFAULT_INVALID; + } + + // At this stage, either there is no core error message set, or it is set + // but we want to overwrite the error message using user facing messages in + // this flow + uint32_t card_fault_status = 0; + if (1 == response.card_info.recovery_mode) { + card_fault_status = NFC_NULL_PTR_ERROR; + } else if (CARD_OPERATION_SUCCESS != status) { + card_fault_status = response.card_info.status; + } + + for (uint8_t i = 0; i < wallets_in_card.count; i++) { + if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == + 0) { + memcpy(wallet_name, + (const char *)wallets_in_card.wallet[i].name, + NAME_SIZE); + break; + } + } + if (0 == strlen(wallet_name)) { + delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + return CARD_OPERATION_DEFAULT_INVALID; + } if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index af2672e55..764ca5064 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -66,6 +66,7 @@ #include "card_utils.h" #include "nfc.h" #include "pow_utilities.h" +#include "ui_delay.h" #include "ui_instruction.h" /***************************************************************************** @@ -87,7 +88,38 @@ /***************************************************************************** * STATIC VARIABLES *****************************************************************************/ +card_error_type_e card_get_wallet_list( + card_operation_data_t card_data, + const card_fetch_wallet_list_config_t *configuration, + card_fetch_wallet_list_response_t *response) { + if (NULL == configuration || NULL == response || + NULL == response->wallet_list) { + return CARD_OPERATION_DEFAULT_INVALID; + } + if (CARD_OPERATION_SUCCESS == card_data.error_type) { + card_data.nfc_data.status = nfc_list_all_wallet(response->wallet_list); + + if (card_data.nfc_data.status == SW_NO_ERROR || + card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { + if (card_data.nfc_data.status == SW_RECORD_NOT_FOUND || + configuration->operation.buzzer_on_success) { + buzzer_start(BUZZER_DURATION); + } + if (!configuration->operation.skip_card_removal) { + wait_for_card_removal(); + } + // break; + } else { + card_handle_errors(&card_data); + } + } + response->card_info.pairing_error = card_data.nfc_data.pairing_error; + response->card_info.tapped_card = card_data.nfc_data.tapped_card; + response->card_info.recovery_mode = card_data.nfc_data.recovery_mode; + response->card_info.status = card_data.nfc_data.status; + return card_data.error_type; +} /***************************************************************************** * GLOBAL VARIABLES *****************************************************************************/ @@ -107,9 +139,6 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, card_operation_data_t card_data = {0}; char wallet_name[NAME_SIZE] = ""; -#if USE_SIMULATOR == 0 - card_fetch_wallet_name(wallet_id, wallet_name); -#endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); @@ -128,6 +157,50 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); #endif + // Fetch wallet list from card + wallet_list_t wallets_in_card = {0}; + card_fetch_wallet_list_config_t configuration = { + .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, + .skip_card_removal = true, + .expected_family_id = card_data.nfc_data.family_id, + .buzzer_on_success = false}, + .frontend = {.heading = ui_text_tap_1_2_cards, + .msg = ui_text_place_card_below}}; + + card_fetch_wallet_list_response_t response = { + .wallet_list = &wallets_in_card, .card_info = {0}}; +#if USE_SIMULATOR == 0 + card_error_type_e status = + card_get_wallet_list(card_data, &configuration, &response); +#endif + // If the tapped card is not paired, it is a terminal case in the flow + if (true == response.card_info.pairing_error) { + return CARD_OPERATION_DEFAULT_INVALID; + } + + // At this stage, either there is no core error message set, or it is set + // but we want to overwrite the error message using user facing messages in + // this flow + uint32_t card_fault_status = 0; + if (1 == response.card_info.recovery_mode) { + card_fault_status = NFC_NULL_PTR_ERROR; + } else if (CARD_OPERATION_SUCCESS != status) { + card_fault_status = response.card_info.status; + } + + for (uint8_t i = 0; i < wallets_in_card.count; i++) { + if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == + 0) { + memcpy(wallet_name, + (const char *)wallets_in_card.wallet[i].name, + NAME_SIZE); + break; + } + } + if (0 == strlen(wallet_name)) { + delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + return CARD_OPERATION_DEFAULT_INVALID; + } if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { From db52edc047f419da87f80661a074811d4d8dfe66 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 16:12:17 +0530 Subject: [PATCH 15/17] fix(app): Simulator build --- src/card_operations/card_fetch_decrypt_data.c | 2 +- src/card_operations/card_fetch_encrypt_data.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index a3bca6c99..68b193217 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -143,7 +143,6 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 card_error_type_e status = card_get_wallet_list(card_data, &configuration, &response); -#endif // If the tapped card is not paired, it is a terminal case in the flow if (true == response.card_info.pairing_error) { return CARD_OPERATION_DEFAULT_INVALID; @@ -172,6 +171,7 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); return CARD_OPERATION_DEFAULT_INVALID; } +#endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 764ca5064..336387f0f 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -172,7 +172,6 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 card_error_type_e status = card_get_wallet_list(card_data, &configuration, &response); -#endif // If the tapped card is not paired, it is a terminal case in the flow if (true == response.card_info.pairing_error) { return CARD_OPERATION_DEFAULT_INVALID; @@ -201,6 +200,7 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); return CARD_OPERATION_DEFAULT_INVALID; } +#endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { for (int i = 0; i < msg_count; i++) { From a05bc515b88f4ca9fe114692c47f2defb183251e Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 3 Sep 2024 17:42:22 +0530 Subject: [PATCH 16/17] fix(app): Decryption ui --- src/card_operations/card_fetch_decrypt_data.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index 68b193217..b03cb9477 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -107,9 +107,6 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, card_operation_data_t card_data = {0}; char wallet_name[NAME_SIZE] = ""; -#if USE_SIMULATOR == 0 - card_fetch_wallet_name(wallet_id, wallet_name); -#endif instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); From a51c956bac5c7d66a0b5af7c9f0c314ca41370a1 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Thu, 5 Sep 2024 16:37:23 +0530 Subject: [PATCH 17/17] chore(app): Review changes --- src/card_operations/card_fetch_data.h | 12 --- src/card_operations/card_fetch_decrypt_data.c | 43 +---------- src/card_operations/card_fetch_encrypt_data.c | 76 +------------------ src/card_operations/card_fetch_wallet_list.c | 65 +++++++++++----- src/card_operations/card_fetch_wallet_list.h | 6 +- 5 files changed, 52 insertions(+), 150 deletions(-) diff --git a/src/card_operations/card_fetch_data.h b/src/card_operations/card_fetch_data.h index ebe052ebc..109039473 100644 --- a/src/card_operations/card_fetch_data.h +++ b/src/card_operations/card_fetch_data.h @@ -53,18 +53,6 @@ typedef struct { * GLOBAL FUNCTION PROTOTYPES *****************************************************************************/ -/** - * @brief Fetches wallet list from card after applet initialization. - * - * @param card_data card_operation_data_t used for applet init. - * - * @return The card error type indicating the result of the operation. - */ -card_error_type_e card_get_wallet_list( - card_operation_data_t card_data, - const card_fetch_wallet_list_config_t *configuration, - card_fetch_wallet_list_response_t *response); - /** * @brief Fetches and encrypts data for a given wallet ID. * diff --git a/src/card_operations/card_fetch_decrypt_data.c b/src/card_operations/card_fetch_decrypt_data.c index b03cb9477..ab4a8d67d 100644 --- a/src/card_operations/card_fetch_decrypt_data.c +++ b/src/card_operations/card_fetch_decrypt_data.c @@ -124,48 +124,7 @@ card_error_type_e card_fetch_decrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); -#endif - // Fetch wallet list from card - wallet_list_t wallets_in_card = {0}; - card_fetch_wallet_list_config_t configuration = { - .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, - .skip_card_removal = true, - .expected_family_id = card_data.nfc_data.family_id, - .buzzer_on_success = false}, - .frontend = {.heading = ui_text_tap_1_2_cards, - .msg = ui_text_place_card_below}}; - - card_fetch_wallet_list_response_t response = { - .wallet_list = &wallets_in_card, .card_info = {0}}; -#if USE_SIMULATOR == 0 - card_error_type_e status = - card_get_wallet_list(card_data, &configuration, &response); - // If the tapped card is not paired, it is a terminal case in the flow - if (true == response.card_info.pairing_error) { - return CARD_OPERATION_DEFAULT_INVALID; - } - - // At this stage, either there is no core error message set, or it is set - // but we want to overwrite the error message using user facing messages in - // this flow - uint32_t card_fault_status = 0; - if (1 == response.card_info.recovery_mode) { - card_fault_status = NFC_NULL_PTR_ERROR; - } else if (CARD_OPERATION_SUCCESS != status) { - card_fault_status = response.card_info.status; - } - - for (uint8_t i = 0; i < wallets_in_card.count; i++) { - if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == - 0) { - memcpy(wallet_name, - (const char *)wallets_in_card.wallet[i].name, - NAME_SIZE); - break; - } - } - if (0 == strlen(wallet_name)) { - delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + if (!card_fetch_wallet_name(card_data, wallet_id, wallet_name)) { return CARD_OPERATION_DEFAULT_INVALID; } #endif diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 336387f0f..5fdb8b23b 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -59,6 +59,8 @@ * INCLUDES *****************************************************************************/ +#include + #include "buzzer.h" #include "card_fetch_data.h" #include "card_fetch_wallet_list.h" @@ -88,38 +90,7 @@ /***************************************************************************** * STATIC VARIABLES *****************************************************************************/ -card_error_type_e card_get_wallet_list( - card_operation_data_t card_data, - const card_fetch_wallet_list_config_t *configuration, - card_fetch_wallet_list_response_t *response) { - if (NULL == configuration || NULL == response || - NULL == response->wallet_list) { - return CARD_OPERATION_DEFAULT_INVALID; - } - if (CARD_OPERATION_SUCCESS == card_data.error_type) { - card_data.nfc_data.status = nfc_list_all_wallet(response->wallet_list); - if (card_data.nfc_data.status == SW_NO_ERROR || - card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { - if (card_data.nfc_data.status == SW_RECORD_NOT_FOUND || - configuration->operation.buzzer_on_success) { - buzzer_start(BUZZER_DURATION); - } - if (!configuration->operation.skip_card_removal) { - wait_for_card_removal(); - } - // break; - } else { - card_handle_errors(&card_data); - } - } - - response->card_info.pairing_error = card_data.nfc_data.pairing_error; - response->card_info.tapped_card = card_data.nfc_data.tapped_card; - response->card_info.recovery_mode = card_data.nfc_data.recovery_mode; - response->card_info.status = card_data.nfc_data.status; - return card_data.error_type; -} /***************************************************************************** * GLOBAL VARIABLES *****************************************************************************/ @@ -156,48 +127,7 @@ card_error_type_e card_fetch_encrypt_data(const uint8_t *wallet_id, #if USE_SIMULATOR == 0 memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); -#endif - // Fetch wallet list from card - wallet_list_t wallets_in_card = {0}; - card_fetch_wallet_list_config_t configuration = { - .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, - .skip_card_removal = true, - .expected_family_id = card_data.nfc_data.family_id, - .buzzer_on_success = false}, - .frontend = {.heading = ui_text_tap_1_2_cards, - .msg = ui_text_place_card_below}}; - - card_fetch_wallet_list_response_t response = { - .wallet_list = &wallets_in_card, .card_info = {0}}; -#if USE_SIMULATOR == 0 - card_error_type_e status = - card_get_wallet_list(card_data, &configuration, &response); - // If the tapped card is not paired, it is a terminal case in the flow - if (true == response.card_info.pairing_error) { - return CARD_OPERATION_DEFAULT_INVALID; - } - - // At this stage, either there is no core error message set, or it is set - // but we want to overwrite the error message using user facing messages in - // this flow - uint32_t card_fault_status = 0; - if (1 == response.card_info.recovery_mode) { - card_fault_status = NFC_NULL_PTR_ERROR; - } else if (CARD_OPERATION_SUCCESS != status) { - card_fault_status = response.card_info.status; - } - - for (uint8_t i = 0; i < wallets_in_card.count; i++) { - if (memcmp(wallet_id, wallets_in_card.wallet[i].id, WALLET_ID_SIZE) == - 0) { - memcpy(wallet_name, - (const char *)wallets_in_card.wallet[i].name, - NAME_SIZE); - break; - } - } - if (0 == strlen(wallet_name)) { - delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); + if (!card_fetch_wallet_name(card_data, wallet_id, wallet_name)) { return CARD_OPERATION_DEFAULT_INVALID; } #endif diff --git a/src/card_operations/card_fetch_wallet_list.c b/src/card_operations/card_fetch_wallet_list.c index 85a446368..42aaa86b5 100644 --- a/src/card_operations/card_fetch_wallet_list.c +++ b/src/card_operations/card_fetch_wallet_list.c @@ -184,42 +184,64 @@ card_error_type_e card_fetch_wallet_list( return card_data.error_type; } -bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { +bool card_fetch_wallet_name(card_operation_data_t card_data, + const uint8_t *wallet_id, + char *wallet_name) { wallet_list_t wallets_in_card = {0}; - card_fetch_wallet_list_config_t configuration = { - .operation = {.acceptable_cards = ACCEPTABLE_CARDS_ALL, - .skip_card_removal = true, - .expected_family_id = get_family_id(), - .buzzer_on_success = false}, - .frontend = {.heading = ui_text_tap_1_2_cards, - .msg = ui_text_place_card_below}}; - - card_fetch_wallet_list_response_t response = {.wallet_list = &wallets_in_card, - .card_info = {0}}; - // P0 abort is the only condition we want to exit the flow // Card abort error will be explicitly shown here as error codes - card_error_type_e status = card_fetch_wallet_list(&configuration, &response); + while (1) { + card_data.nfc_data.acceptable_cards = ACCEPTABLE_CARDS_ALL; + card_initialize_applet(&card_data); + + if (CARD_OPERATION_SUCCESS == card_data.error_type) { + card_data.nfc_data.status = nfc_list_all_wallet(&wallets_in_card); + + if (card_data.nfc_data.status == SW_NO_ERROR || + card_data.nfc_data.status == SW_RECORD_NOT_FOUND) { + break; + } else { + card_handle_errors(&card_data); + } + } + if (CARD_OPERATION_CARD_REMOVED == card_data.error_type || + CARD_OPERATION_RETAP_BY_USER_REQUIRED == card_data.error_type) { + const char *error_msg = card_data.error_message; + /** + * In case the same card as before is tapped, the user should be told to + * tap a different card instead of the default message "Wrong card + * sequence" + */ + if (SW_CONDITIONS_NOT_SATISFIED == card_data.nfc_data.status) { + error_msg = ui_text_tap_another_card; + } + if (CARD_OPERATION_SUCCESS == indicate_card_error(error_msg)) { + // Re-render the instruction screen + instruction_scr_init(ui_text_place_card_below, ui_text_tap_1_2_cards); + continue; + } + } + // If control reached here, it is an unrecoverable error, so break + break; + } + + card_error_type_e status = card_data.error_type; if (CARD_OPERATION_P0_OCCURED == status) { return false; } // If the tapped card is not paired, it is a terminal case in the flow - if (true == response.card_info.pairing_error) { + if (card_data.nfc_data.pairing_error) { + delay_scr_init(ui_text_device_and_card_not_paired, DELAY_TIME); return false; } - // At this stage, either there is no core error message set, or it is set but - // we want to overwrite the error message using user facing messages in this - // flow - clear_core_error_screen(); - uint32_t card_fault_status = 0; - if (1 == response.card_info.recovery_mode) { + if (1 == card_data.nfc_data.recovery_mode) { card_fault_status = NFC_NULL_PTR_ERROR; } else if (CARD_OPERATION_SUCCESS != status) { - card_fault_status = response.card_info.status; + card_fault_status = card_data.nfc_data.status; } for (uint8_t i = 0; i < wallets_in_card.count; i++) { @@ -231,6 +253,7 @@ bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name) { } if (0 == strlen(wallet_name)) { + delay_scr_init(ui_text_wallet_doesnt_exists_on_this_card, DELAY_TIME); return false; } diff --git a/src/card_operations/card_fetch_wallet_list.h b/src/card_operations/card_fetch_wallet_list.h index 4d6cc5b4d..a8b7eca1e 100644 --- a/src/card_operations/card_fetch_wallet_list.h +++ b/src/card_operations/card_fetch_wallet_list.h @@ -15,6 +15,7 @@ #include #include +#include "card_internal.h" #include "card_operation_typedefs.h" #include "wallet_list.h" @@ -69,6 +70,7 @@ card_error_type_e card_fetch_wallet_list( * copied. * @return true if the wallet name is successfully fetched, false otherwise. */ -bool card_fetch_wallet_name(const uint8_t *wallet_id, char *wallet_name); - +bool card_fetch_wallet_name(card_operation_data_t card_data, + const uint8_t *wallet_id, + char *wallet_name); #endif /* CARD_FETCH_WALLET_LIST_H */