diff --git a/src_nbgl/ui_sign_message.c b/src_nbgl/ui_sign_message.c index 3850780..93312a0 100644 --- a/src_nbgl/ui_sign_message.c +++ b/src_nbgl/ui_sign_message.c @@ -1,4 +1,4 @@ -#include +#include "nbgl_page.h" #include "shared_context.h" #include "ui_callbacks.h" #include "ui_nbgl.h" @@ -21,10 +21,13 @@ typedef enum { static e_ui_191_action g_action; static nbgl_contentTagValue_t pair; -static nbgl_contentTagValueList_t tagValueList; +static nbgl_contentTagValueList_t pairs_list; -static uint32_t eip191MessageIdx = 0; -static uint32_t stringsTmpTmpIdx = 0; +static uint32_t g_display_buffer_idx; +static uint32_t g_rcv_buffer_idx; +static bool g_skipped; + +static void ui_191_process_state(void); static void reject_message(void) { io_seproxyhal_touch_signMessage_cancel(); @@ -43,16 +46,18 @@ static void ui_191_finish_cb(bool confirm) { } static void ui_191_skip_cb(void) { - nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb); + g_skipped = true; + skip_rest_of_message(); } -static void getTagValues(void) { +static bool ui_191_update_display_buffer(void) { uint16_t len = 0; bool reached; - strncpy(g_stax_shared_buffer + eip191MessageIdx, - strings.tmp.tmp + stringsTmpTmpIdx, - SHARED_BUFFER_SIZE - eip191MessageIdx); + g_stax_shared_buffer[g_display_buffer_idx] = '\0'; + strlcat(g_stax_shared_buffer + g_display_buffer_idx, + strings.tmp.tmp + g_rcv_buffer_idx, + sizeof(g_stax_shared_buffer) - g_display_buffer_idx); reached = nbgl_getTextMaxLenInNbLines(LARGE_MEDIUM_FONT, (char *) g_stax_shared_buffer, SCREEN_WIDTH - (2 * BORDER_MARGIN), @@ -60,51 +65,59 @@ static void getTagValues(void) { &len, false); - stringsTmpTmpIdx = len - eip191MessageIdx; - eip191MessageIdx = len; - g_stax_shared_buffer[eip191MessageIdx] = '\0'; + g_rcv_buffer_idx += (len - g_display_buffer_idx); + g_display_buffer_idx = len; + g_stax_shared_buffer[g_display_buffer_idx] = '\0'; - if (!reached && eip191MessageIdx < SHARED_BUFFER_SIZE) { - stringsTmpTmpIdx = 0; + if (!reached) { + g_rcv_buffer_idx = 0; question_switcher(); - } else if (reached || eip191MessageIdx == SHARED_BUFFER_SIZE) { - eip191MessageIdx = 0; + return false; } - - pair.value = g_stax_shared_buffer; - pair.item = "Message"; - tagValueList.nbPairs = 1; - tagValueList.pairs = &pair; - tagValueList.smallCaseForValue = false; - tagValueList.nbMaxLinesForValue = NB_MAX_LINES_IN_REVIEW; - tagValueList.wrapping = false; + g_display_buffer_idx = 0; + return true; } static void ui_191_data_cb(bool more) { if (more) { - switch (g_action) { - case UI_191_ACTION_IDLE: - g_action = UI_191_ACTION_ADVANCE_IN_MESSAGE; - __attribute__((fallthrough)); - case UI_191_ACTION_ADVANCE_IN_MESSAGE: - getTagValues(); - nbgl_useCaseReviewStreamingContinueExt(&tagValueList, - ui_191_data_cb, - ui_191_skip_cb); - break; - case UI_191_ACTION_GO_TO_SIGN: - nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb); - break; - } + ui_191_process_state(); } else { ui_191_finish_cb(false); } } +static void ui_191_show_message(void) { + pair.value = g_stax_shared_buffer; + pair.item = "Message"; + pairs_list.nbPairs = 1; + pairs_list.pairs = &pair; + pairs_list.smallCaseForValue = false; + pairs_list.nbMaxLinesForValue = NB_MAX_LINES_IN_REVIEW; + pairs_list.wrapping = false; + nbgl_useCaseReviewStreamingContinueExt(&pairs_list, ui_191_data_cb, ui_191_skip_cb); +} + +static void ui_191_process_state(void) { + switch (g_action) { + case UI_191_ACTION_IDLE: + g_action = UI_191_ACTION_ADVANCE_IN_MESSAGE; + __attribute__((fallthrough)); + case UI_191_ACTION_ADVANCE_IN_MESSAGE: + if (ui_191_update_display_buffer()) { + ui_191_show_message(); + } + break; + case UI_191_ACTION_GO_TO_SIGN: + nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb); + break; + } +} + void ui_191_start(void) { g_action = UI_191_ACTION_IDLE; - eip191MessageIdx = 0; - stringsTmpTmpIdx = 0; + g_display_buffer_idx = 0; + g_rcv_buffer_idx = 0; + g_skipped = false; nbgl_useCaseReviewStreamingStart(TYPE_MESSAGE | SKIPPABLE_OPERATION, &C_Review_64px, @@ -115,12 +128,17 @@ void ui_191_start(void) { void ui_191_switch_to_message(void) { // Get following part of the message - getTagValues(); + ui_191_process_state(); } void ui_191_switch_to_sign(void) { g_action = UI_191_ACTION_GO_TO_SIGN; - // Next callback must display the hold to approve screen + if (g_skipped) { + nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb); + } else if (g_display_buffer_idx > 0) { + // still on an incomplete display buffer, show it before the last page + ui_191_show_message(); + } } void ui_191_switch_to_question(void) {