From 28286a2e4695fcbd7af1e2d68943a801c0dc1c98 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Fri, 29 Dec 2023 04:12:52 +0530 Subject: [PATCH 01/32] feat (app): Manager add wallet selector flow --- apps/manager_app/manager_app.c | 4 + apps/manager_app/manager_app_priv.h | 7 + apps/manager_app/wallet_selector.c | 234 ++++++++++++++++++ common/cypherock-common | 2 +- common/interfaces/user_interface/ui_menu.c | 11 +- common/interfaces/user_interface/ui_menu.h | 14 +- common/proto-options/manager/common.options | 3 + .../proto-options/manager/get_wallets.options | 2 - .../manager/wallet_selector.options | 1 + src/constant_texts.c | 4 + src/constant_texts.h | 1 + 11 files changed, 270 insertions(+), 13 deletions(-) create mode 100644 apps/manager_app/wallet_selector.c create mode 100644 common/proto-options/manager/common.options create mode 100644 common/proto-options/manager/wallet_selector.options diff --git a/apps/manager_app/manager_app.c b/apps/manager_app/manager_app.c index 37106c05..4e980d59 100644 --- a/apps/manager_app/manager_app.c +++ b/apps/manager_app/manager_app.c @@ -164,6 +164,10 @@ void manager_app_main(usb_event_t usb_evt, const void *app_config) { manager_confirm_firmware_update(&query); break; } + case MANAGER_QUERY_SELECT_WALLET_TAG: { + manager_wallet_selector(&query); + break; + } default: { /* In case we ever encounter invalid query, convey to the host app */ manager_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, diff --git a/apps/manager_app/manager_app_priv.h b/apps/manager_app/manager_app_priv.h index 28d33def..8f763df0 100644 --- a/apps/manager_app/manager_app_priv.h +++ b/apps/manager_app/manager_app_priv.h @@ -89,4 +89,11 @@ void manager_export_wallets(manager_query_t *query); * @param query Reference to the decoded query struct from the host app */ void manager_confirm_firmware_update(manager_query_t *query); + +/** + * @brief + * + * @param query Reference to the decoded query struct from the host app + */ +void manager_wallet_selector(manager_query_t *query); #endif diff --git a/apps/manager_app/wallet_selector.c b/apps/manager_app/wallet_selector.c new file mode 100644 index 00000000..7f48ca58 --- /dev/null +++ b/apps/manager_app/wallet_selector.c @@ -0,0 +1,234 @@ +/** + * @file wallet_selector.c + * @author Cypherock X1 Team + * @brief Exports list of existing wallets to the host + * @copyright Copyright (c) 2023 HODL TECH PTE LTD + *
You may obtain a copy of license at https://mitcc.org/ + * + ****************************************************************************** + * @attention + * + * (c) Copyright 2023 by HODL TECH PTE LTD + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * "Commons Clause" License Condition v1.0 + * + * The Software is provided to you by the Licensor under the License, + * as defined below, subject to the following condition. + * + * Without limiting other conditions in the License, the grant of + * rights under the License will not include, and the License does not + * grant to you, the right to Sell the Software. + * + * For purposes of the foregoing, "Sell" means practicing any or all + * of the rights granted to you under the License to provide to third + * parties, for a fee or other consideration (including without + * limitation fees for hosting or consulting/ support services related + * to the Software), a product or service whose value derives, entirely + * or substantially, from the functionality of the Software. Any license + * notice or attribution required by the License must also include + * this Commons Clause License Condition notice. + * + * Software: All X1Wallet associated files. + * License: MIT + * Licensor: HODL TECH PTE LTD + * + ****************************************************************************** + */ + +/***************************************************************************** + * INCLUDES + *****************************************************************************/ +#include "events.h" +#include "flash_api.h" +#include "manager_api.h" +#include "ui_core_confirm.h" +#include "wallet_list.h" + +/***************************************************************************** + * EXTERN VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * PRIVATE MACROS AND DEFINES + *****************************************************************************/ + +/***************************************************************************** + * PRIVATE TYPEDEFS + *****************************************************************************/ + +/***************************************************************************** + * STATIC FUNCTION PROTOTYPES + *****************************************************************************/ +/** + * @brief Checks if the provided query contains expected request. + * @details The function performs the check on the request type and if the check + * fails, then it will send an error to the host manager app and return false. + * + * @param query Reference to an instance of manager_query_t containing query + * received from host app + * @param which_request The expected request type enum + * + * @return bool Indicating if the check succeeded or failed + * @retval true If the query contains the expected request + * @retval false If the query does not contain the expected request + */ +static bool check_which_request(const manager_query_t *query, + pb_size_t which_request); + +/** + * @brief The functions presents wallet list to the user & waits for input. + * @details The function waits for user action and returns true if the + * selections was completed by the user. In case if user chooses a wallet + * that is unusable, the function will convey the situation to the user & + * prompt the user to choose a wallet again. + * + * @param flash_wallet_idx Reference to store the selected wallet index as on + * flash + * + * @return bool Indicating if the user chose a valid wallet to continue with + * @retval true If user chose a valid wallet + * @retval false If user rejected, timeout happened, or abort received. + */ +// static bool choose_wallet(uint8_t *flash_wallet_idx); + +/** + * @brief Fills wallet list in structure type manager_wallet_item_t with + * details of the provided wallet_idx on device storage. + * + * @param wallet a Pointer to the structure to be filled + * @param wallet_idx Index of wallet in storage whose details are to be copied + */ +static void fill_wallet(manager_wallet_item_t *wallet, uint8_t wallet_idx); + +/***************************************************************************** + * STATIC VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * GLOBAL VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * STATIC FUNCTIONS + *****************************************************************************/ +static bool check_which_request(const manager_query_t *query, + pb_size_t which_request) { + if (which_request != query->get_wallets.which_request) { + manager_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_REQUEST); + return false; + } + + return true; +} + +// static bool choose_wallet(uint8_t *flash_wallet_idx) { + +// } + +static void fill_wallet(manager_wallet_item_t *wallet, uint8_t wallet_idx) { + const Flash_Wallet *flash_wallet = get_wallet_by_index(wallet_idx); + ASSERT(flash_wallet != NULL); + + snprintf(wallet->name, sizeof(wallet->name), "%s", flash_wallet->wallet_name); + memcpy(wallet->id, flash_wallet->wallet_id, WALLET_ID_SIZE); + + uint8_t wallet_info = flash_wallet->wallet_info; + wallet->has_passphrase = WALLET_IS_PASSPHRASE_SET(wallet_info); + wallet->has_pin = WALLET_IS_PIN_SET(wallet_info); + + ASSERT(NULL != flash_wallet); + + // Wallet is NOT in usable state if + // 1. It is in locked state in any of the X1 cards + // 2. Wallet state in X1 Vault flash is not VALID_WALLET + // 3. Card state in X1 Vault flash is not 0xF + if (flash_wallet->is_wallet_locked || VALID_WALLET != flash_wallet->state || + 0x0F != flash_wallet->cards_states) { + wallet->is_valid = false; + } else { + wallet->is_valid = true; + } +} + +/***************************************************************************** + * GLOBAL FUNCTIONS + *****************************************************************************/ +void manager_wallet_selector(manager_query_t *query) { + if (!check_which_request(query, MANAGER_SELECT_WALLET_REQUEST_INITIATE_TAG)) { + return; + } + + /* Create an array of pointers holding the string to display on the menu. */ + const char *options[MAX_WALLETS_ALLOWED] = {0}; + static uint16_t choice_idx = 0; + uint8_t option_count = get_wallet_list(&options[0]); + + while (true) { + menu_init_with_choice( + options, option_count, "Wallet Select", choice_idx, true); + + evt_status_t events = get_events(EVENT_CONFIG_UI, MAX_INACTIVITY_TIMEOUT); + if (true == events.p0_event.flag) { + // core will handle p0 events, exit now + break; + } + if (UI_EVENT_REJECT == events.ui_event.event_type) { + // user rejected, send error and exit + manager_send_error(ERROR_COMMON_ERROR_USER_REJECTION_TAG, + ERROR_USER_REJECTION_CONFIRMATION); + break; + } + + uint8_t flash_wallet_idx = 0; + choice_idx = events.ui_event.list_selection - 1; + + ASSERT(UI_EVENT_LIST_CHOICE == events.ui_event.event_type); + ASSERT(SUCCESS == + get_index_by_name(options[choice_idx], &flash_wallet_idx)); + if (get_wallet_data_by_id(get_wallet_id(flash_wallet_idx), &wallet, NULL)) { + manager_result_t result = + init_manager_result(MANAGER_RESULT_SELECT_WALLET_TAG); + result.select_wallet.which_response = + MANAGER_SELECT_WALLET_RESPONSE_RESULT_TAG; + result.select_wallet.result.has_wallet = true; + fill_wallet(&result.select_wallet.result.wallet, flash_wallet_idx); + + manager_send_result(&result); + break; + } else { + bool retry_choice = + core_scroll_page(NULL, ui_text_wallet_selector_invalid, NULL); + + if (false == retry_choice) { + // user selected to choose a different wallet + manager_send_error(ERROR_COMMON_ERROR_USER_REJECTION_TAG, + ERROR_USER_REJECTION_CONFIRMATION); + break; + } + } + } + + return; +} \ No newline at end of file diff --git a/common/cypherock-common b/common/cypherock-common index aa836c79..1563db21 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit aa836c796375c7c1bdb90f35011b0be0e35d80df +Subproject commit 1563db21a8a4b6cd2cccdbb2c5228b33ee7b9fc7 diff --git a/common/interfaces/user_interface/ui_menu.c b/common/interfaces/user_interface/ui_menu.c index 8ea408dc..ca8c556f 100644 --- a/common/interfaces/user_interface/ui_menu.c +++ b/common/interfaces/user_interface/ui_menu.c @@ -79,10 +79,11 @@ static struct Menu_Object *obj = NULL; */ static void menu_create(); -void menu_init(const char *option_list[], - const int number_of_options, - const char heading[], - const bool back_button_allowed) { +void menu_init_with_choice(const char *option_list[], + const int number_of_options, + const char heading[], + const int initial_selection, + const bool back_button_allowed) { ASSERT(NULL != option_list); ASSERT(NULL != heading); @@ -96,7 +97,7 @@ void menu_init(const char *option_list[], if (data != NULL) { data->number_of_options = number_of_options; - data->current_index = 0; + data->current_index = initial_selection; data->back_button_allowed = back_button_allowed; snprintf(data->heading, sizeof(data->heading), "%s", heading); diff --git a/common/interfaces/user_interface/ui_menu.h b/common/interfaces/user_interface/ui_menu.h index 3faa2c1d..7869ff7e 100644 --- a/common/interfaces/user_interface/ui_menu.h +++ b/common/interfaces/user_interface/ui_menu.h @@ -17,6 +17,9 @@ #define MENU_MAX_NUMBER_OF_OPTIONS 12 #define MAX_LEN_OF_MENU_OPTIONS 25 +// wrapper for reducing changes in codebase +#define menu_init(o, n, h, b) menu_init_with_choice(o, n, h, 0, b) + /** * @brief struct to store Menu data and meta data * @details @@ -59,6 +62,7 @@ struct Menu_Object { * @param option_list Array of char array for options * @param number_of_options Number of options * @param heading Heading text + * @param initial_selection The default selected choice * @param back_button_allowed Show a back button * * @return @@ -69,9 +73,9 @@ struct Menu_Object { * * @note */ -void menu_init(const char *option_list[], - int number_of_options, - const char heading[], - bool back_button_allowed); - +void menu_init_with_choice(const char *option_list[], + const int number_of_options, + const char heading[], + const int initial_selection, + const bool back_button_allowed); #endif // UI_MENU_H \ No newline at end of file diff --git a/common/proto-options/manager/common.options b/common/proto-options/manager/common.options new file mode 100644 index 00000000..d23a4ba5 --- /dev/null +++ b/common/proto-options/manager/common.options @@ -0,0 +1,3 @@ +# Options for file common/cypherock-common/proto/manager/common.proto +manager.WalletItem.id type:FT_STATIC max_size:32 fixed_length:true +manager.WalletItem.name type:FT_STATIC max_size:16 fixed_length:true diff --git a/common/proto-options/manager/get_wallets.options b/common/proto-options/manager/get_wallets.options index d2426ba2..5ef99e17 100644 --- a/common/proto-options/manager/get_wallets.options +++ b/common/proto-options/manager/get_wallets.options @@ -1,4 +1,2 @@ # Options for file common/cypherock-common/proto/manager/get_wallets.proto -manager.WalletItem.id type:FT_STATIC max_size:32 fixed_length:true -manager.WalletItem.name type:FT_STATIC max_size:16 fixed_length:true manager.GetWalletsResultResponse.wallet_list type:FT_STATIC max_count:4 fixed_length:true diff --git a/common/proto-options/manager/wallet_selector.options b/common/proto-options/manager/wallet_selector.options new file mode 100644 index 00000000..aa049223 --- /dev/null +++ b/common/proto-options/manager/wallet_selector.options @@ -0,0 +1 @@ +# Options for file common/cypherock-common/proto/manager/wallet_selector.proto diff --git a/src/constant_texts.c b/src/constant_texts.c index 500b2503..83e34d30 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -183,6 +183,10 @@ const char *ui_text_joystick_left = "Toggle joystick left"; const char *ui_text_joystick_center = "Center click joystick"; const char *ui_text_joystick_checkup_complete = "Joystick instructions complete"; +const char *ui_text_wallet_selector_invalid = + "The selected wallet is misconfigured\n" + "Visit the wallet from main menu to fix it\n" + "Or choose a different wallet to continue"; // Onboarding flow text const char *ui_text_onboarding_welcome = "Welcome"; diff --git a/src/constant_texts.h b/src/constant_texts.h index 4eab8efd..4d9e788c 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -148,6 +148,7 @@ extern const char *ui_text_joystick_down; extern const char *ui_text_joystick_left; extern const char *ui_text_joystick_center; extern const char *ui_text_joystick_checkup_complete; +extern const char *ui_text_wallet_selector_invalid; // Onboarding text extern const char *ui_text_onboarding_welcome; From ab5a2750f05752c70fbabb67aa1854e023b69bf1 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:33:07 +0530 Subject: [PATCH 02/32] chore (build): Correct vscode config settings --- .vscode/launch.json | 4 ++-- .vscode/settings.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b1060a49..7ce14a4c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -28,7 +28,7 @@ { "name": "Main Debug [Launch]", "cwd": "${workspaceRoot}", - "executable": "build/Cypherock-Main.elf", + "executable": "build/Main/Cypherock-Main.elf", "request": "launch", "type": "cortex-debug", "servertype": "openocd", @@ -44,7 +44,7 @@ { "name": "Main Debug [Attach]", "cwd": "${workspaceRoot}", - "executable": "build/Cypherock-Main.elf", + "executable": "build/Main/Cypherock-Main.elf", "request": "attach", "type": "cortex-debug", "servertype": "openocd", diff --git a/.vscode/settings.json b/.vscode/settings.json index 58df5a94..eb22ad69 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,10 +8,10 @@ "FIRMWARE_TYPE":"Main", }, "terminal.integrated.env.linux": { - "PATH": "${workspaceFolder}/venv/bin:${env:PATH}", + "PATH": "${env:HOME}/.local/bin:${workspaceFolder}/venv/bin:${env:PATH}", }, "terminal.integrated.env.osx": { - "PATH": "${workspaceFolder}/venv/bin:${env:PATH}", + "PATH": "${env:HOME}/.local/bin:${workspaceFolder}/venv/bin:${env:PATH}", }, "terminal.integrated.env.windows": { "PATH": "${workspaceFolder}/venv/Scripts:${workspaceFolder}/venv/bin:${env:PATH}", From 10c4c26eb647cbef260cbdf8a7e4469a9edff1cf Mon Sep 17 00:00:00 2001 From: vrockz747 Date: Mon, 4 Mar 2024 17:11:39 +0530 Subject: [PATCH 03/32] fix (app): Prf-6996 --- common/coin_support/eth_sign_data/abi_decode.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/common/coin_support/eth_sign_data/abi_decode.c b/common/coin_support/eth_sign_data/abi_decode.c index fc33e968..73cc7732 100644 --- a/common/coin_support/eth_sign_data/abi_decode.c +++ b/common/coin_support/eth_sign_data/abi_decode.c @@ -60,7 +60,9 @@ #include #include "abi.h" +#include "address.h" #include "assert_conf.h" +#include "evm_priv.h" #include "utils.h" /* Global functions @@ -215,11 +217,11 @@ ui_display_node *ABI_Stringify(Abi_Type_e inputAbiType, case Abi_address_e: { char staticBufferInUTF8[43] = "0x"; - byte_array_to_hex_string(pAbiTypeData + Abi_address_e_OFFSET_BE, - 20, - &(staticBufferInUTF8[2]), - 41); - + // generating checksum'd address + ethereum_address_checksum((pAbiTypeData + Abi_address_e_OFFSET_BE), + &(staticBufferInUTF8[2]), + false, + g_evm_app->chain_id); ui_node = ui_create_display_node("Datatype:address\0", 25, &(staticBufferInUTF8[0]), From d3ca8a1eea3f96300cdc590e984db15c2d82aad7 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:41:32 +0530 Subject: [PATCH 04/32] chore: Update common submodule --- common/cypherock-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cypherock-common b/common/cypherock-common index 1563db21..7fcd2bcf 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit 1563db21a8a4b6cd2cccdbb2c5228b33ee7b9fc7 +Subproject commit 7fcd2bcf6b1a90ead126191444c7fdd07c40764a From d3f477146f0397f50f771995ae502853d7fd694f Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Mon, 4 Mar 2024 17:53:47 +0530 Subject: [PATCH 05/32] chore (build): Remove unused func --- .../core/controller/card_upgrade_controller.c | 140 ----- .../core/controller/controller_level_four.h | 398 -------------- .../initial_device_provision_contoller.c | 516 ------------------ .../initial_verify_card_controller.c | 116 ---- .../receive_transaction_controller_b_eth.c | 108 ---- .../receive_transaction_controller_b_near.c | 117 ---- .../receive_transaction_controller_b_solana.c | 108 ---- .../receive_transaction_controller_eth.c | 220 -------- .../receive_transaction_controller_near.c | 364 ------------ .../receive_transaction_controller_solana.c | 205 ------- .../send_transaction_controller_b_eth.c | 136 ----- .../send_transaction_controller_b_solana.c | 122 ----- .../send_transaction_controller_eth.c | 267 --------- .../send_transaction_controller_solana.c | 282 ---------- .../controller/sign_message_controller_eth.c | 229 -------- .../sign_messgae_controller_b_eth.c | 103 ---- .../controller/verify_wallet_controller.c | 113 ---- .../controller/verify_wallet_controller_b.c | 73 --- .../controller/wallet_locked_controller.c | 186 ------- .../controller/wallet_locked_controller_b.c | 76 --- .../core/tasks/card_upgrade_tasks.c | 86 --- .../tasks/initial_device_provision_tasks.c | 91 --- .../tasks/receive_transaction_tasks_eth.c | 172 ------ .../tasks/receive_transaction_tasks_near.c | 247 --------- .../tasks/receive_transaction_tasks_solana.c | 156 ------ .../core/tasks/send_transaction_tasks_eth.c | 326 ----------- .../tasks/send_transaction_tasks_solana.c | 260 --------- .../core/tasks/sign_message_tasks_eth.c | 178 ------ src/level_four/core/tasks/tasks_level_four.h | 123 ----- .../core/tasks/verify_wallet_task.c | 134 ----- .../core/tasks/wallet_locked_tasks.c | 129 ----- .../controller/card_action_controllers.h | 19 - .../controller/controller_tap_cards.c | 305 ----------- .../controller/controller_tap_cards.h | 202 ------- .../retrieve_key_from_card_controllers.c | 127 ----- .../controller/tap_one_card_controllers.c | 116 ---- ...onstruct_from_four_cards_to_verify_tasks.c | 99 ---- .../reconstruct_from_threshold_cards_tasks.c | 71 --- .../tasks/retrieve_key_from_card_tasks.c | 84 --- .../tap_cards/tasks/tap_one_card_tasks.c | 105 ---- .../tap_cards/tasks/tasks_tap_cards.h | 97 ---- .../tap_cards/tasks/write_to_cards_tasks.c | 115 ---- .../controller/controller_add_wallet.h | 35 -- .../controller/controller_arbitrary_data.c | 253 --------- .../controller/controller_arbitrary_data_b.c | 98 ---- .../add_wallet/tasks/tasks_add_wallet.h | 38 -- .../add_wallet/tasks/tasks_arbitrary_data.c | 226 -------- .../controller/advanced_settings_controller.c | 95 ---- .../controller/controller_advanced_settings.h | 35 -- .../tasks/advanced_settings_tasks.c | 105 ---- .../tasks/tasks_advanced_settings.h | 34 -- .../controller/controller_old_wallet.c | 107 ---- .../controller/controller_old_wallet.h | 65 --- .../controller/controller_old_wallet_b.c | 107 ---- .../old_wallet/tasks/tasks_old_wallet.c | 115 ---- .../old_wallet/tasks/tasks_old_wallet.h | 34 -- 56 files changed, 8468 deletions(-) delete mode 100644 src/level_four/core/controller/card_upgrade_controller.c delete mode 100644 src/level_four/core/controller/controller_level_four.h delete mode 100644 src/level_four/core/controller/initial_device_provision_contoller.c delete mode 100644 src/level_four/core/controller/initial_verify_card_controller.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_b_eth.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_b_near.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_b_solana.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_eth.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_near.c delete mode 100644 src/level_four/core/controller/receive_transaction_controller_solana.c delete mode 100644 src/level_four/core/controller/send_transaction_controller_b_eth.c delete mode 100644 src/level_four/core/controller/send_transaction_controller_b_solana.c delete mode 100644 src/level_four/core/controller/send_transaction_controller_eth.c delete mode 100644 src/level_four/core/controller/send_transaction_controller_solana.c delete mode 100644 src/level_four/core/controller/sign_message_controller_eth.c delete mode 100644 src/level_four/core/controller/sign_messgae_controller_b_eth.c delete mode 100644 src/level_four/core/controller/verify_wallet_controller.c delete mode 100644 src/level_four/core/controller/verify_wallet_controller_b.c delete mode 100644 src/level_four/core/controller/wallet_locked_controller.c delete mode 100644 src/level_four/core/controller/wallet_locked_controller_b.c delete mode 100644 src/level_four/core/tasks/card_upgrade_tasks.c delete mode 100644 src/level_four/core/tasks/initial_device_provision_tasks.c delete mode 100644 src/level_four/core/tasks/receive_transaction_tasks_eth.c delete mode 100644 src/level_four/core/tasks/receive_transaction_tasks_near.c delete mode 100644 src/level_four/core/tasks/receive_transaction_tasks_solana.c delete mode 100644 src/level_four/core/tasks/send_transaction_tasks_eth.c delete mode 100644 src/level_four/core/tasks/send_transaction_tasks_solana.c delete mode 100644 src/level_four/core/tasks/sign_message_tasks_eth.c delete mode 100644 src/level_four/core/tasks/tasks_level_four.h delete mode 100644 src/level_four/core/tasks/verify_wallet_task.c delete mode 100644 src/level_four/core/tasks/wallet_locked_tasks.c delete mode 100644 src/level_four/tap_cards/controller/card_action_controllers.h delete mode 100644 src/level_four/tap_cards/controller/controller_tap_cards.c delete mode 100644 src/level_four/tap_cards/controller/controller_tap_cards.h delete mode 100644 src/level_four/tap_cards/controller/retrieve_key_from_card_controllers.c delete mode 100644 src/level_four/tap_cards/controller/tap_one_card_controllers.c delete mode 100644 src/level_four/tap_cards/tasks/reconstruct_from_four_cards_to_verify_tasks.c delete mode 100644 src/level_four/tap_cards/tasks/reconstruct_from_threshold_cards_tasks.c delete mode 100644 src/level_four/tap_cards/tasks/retrieve_key_from_card_tasks.c delete mode 100644 src/level_four/tap_cards/tasks/tap_one_card_tasks.c delete mode 100644 src/level_four/tap_cards/tasks/tasks_tap_cards.h delete mode 100644 src/level_four/tap_cards/tasks/write_to_cards_tasks.c delete mode 100644 src/level_three/add_wallet/controller/controller_add_wallet.h delete mode 100644 src/level_three/add_wallet/controller/controller_arbitrary_data.c delete mode 100644 src/level_three/add_wallet/controller/controller_arbitrary_data_b.c delete mode 100644 src/level_three/add_wallet/tasks/tasks_add_wallet.h delete mode 100644 src/level_three/add_wallet/tasks/tasks_arbitrary_data.c delete mode 100644 src/level_three/advanced_settings/controller/advanced_settings_controller.c delete mode 100644 src/level_three/advanced_settings/controller/controller_advanced_settings.h delete mode 100644 src/level_three/advanced_settings/tasks/advanced_settings_tasks.c delete mode 100644 src/level_three/advanced_settings/tasks/tasks_advanced_settings.h delete mode 100644 src/level_three/old_wallet/controller/controller_old_wallet.c delete mode 100644 src/level_three/old_wallet/controller/controller_old_wallet.h delete mode 100644 src/level_three/old_wallet/controller/controller_old_wallet_b.c delete mode 100644 src/level_three/old_wallet/tasks/tasks_old_wallet.c delete mode 100644 src/level_three/old_wallet/tasks/tasks_old_wallet.h diff --git a/src/level_four/core/controller/card_upgrade_controller.c b/src/level_four/core/controller/card_upgrade_controller.c deleted file mode 100644 index 943d9293..00000000 --- a/src/level_four/core/controller/card_upgrade_controller.c +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file card_upgrade_controller.c - * @author Cypherock X1 Team - * @brief Card upgrade next controller. - * Handles post event (only next events) operations for card upgrade - *flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "nfc.h" -#include "ui_instruction.h" - -extern Flow_level flow_level; -extern Counter counter; -extern Wallet wallet; - -char *textDisplay; -char text[80]; - -#ifdef DEV_BUILD -static uint16_t number_of_apdus_sent; -#endif // DEV_BUILD - -void card_upgrade_controller() { -#ifdef DEV_BUILD - switch (flow_level.level_three) { - case CARD_UPGRADE_TAP_CARD_MESSAGE: - flow_level.level_three = CARD_UPGRADE_SELECT_CARD; - break; - - case CARD_UPGRADE_SELECT_CARD: { - while (nfc_select_card() != STM_SUCCESS) - ; - flow_level.level_three = CARD_UPGRADE_FORWARD_MESSAGE; - number_of_apdus_sent = 0; - snprintf(text, sizeof(text), "Sending APDU\n%d", number_of_apdus_sent); - textDisplay = text; - instruction_scr_change_text(textDisplay, false); - uint8_t arr[4]; - arr[0] = STATUS_CMD_SUCCESS; - transmit_data_to_app(STATUS_PACKET, arr, 4); - } break; - - case CARD_UPGRADE_FORWARD_MESSAGE: { - uint8_t *data_array = NULL; - uint16_t msg_size = 0; - if (get_usb_msg_by_cmd_type(APDU_PACKET, &data_array, &msg_size)) { - uint8_t max_tries = 5; - uint8_t recv_apdu[255], recv_len = 236; - ret_code_t err_code = STM_ERROR_BUSY; - - while (max_tries--) { - err_code = adafruit_pn532_in_data_exchange( - data_array, msg_size, recv_apdu, &recv_len); - - if (err_code == STM_SUCCESS) { - break; - } - } - - if (err_code == STM_SUCCESS) { - transmit_data_to_app(APDU_PACKET, recv_apdu, recv_len); - number_of_apdus_sent++; - snprintf( - text, sizeof(text), "Sending APDU\n%d", number_of_apdus_sent); - textDisplay = text; - instruction_scr_change_text(textDisplay, false); - } else { - uint8_t arr[4]; - arr[0] = STATUS_CMD_FAILURE; - transmit_data_to_app(STATUS_PACKET, arr, sizeof(arr)); - instruction_scr_destructor(); - mark_error_screen(ui_text_card_command_send_error); - reset_flow_level(); - } - clear_message_received_data(); - } else if (get_usb_msg_by_cmd_type(STOP_CARD_UPGRADE, NULL, NULL)) { - mark_error_screen(ui_text_card_update_done); - reset_flow_level(); - clear_message_received_data(); - } - } break; - - default: - break; - } -#endif -} diff --git a/src/level_four/core/controller/controller_level_four.h b/src/level_four/core/controller/controller_level_four.h deleted file mode 100644 index ab6adff4..00000000 --- a/src/level_four/core/controller/controller_level_four.h +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @file controller_level_four.h - * @author Cypherock X1 Team - * @brief Header for level four controllers. - * Houses the declarations of controllers for level one tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef CONTROLLER_LEVEL_FOUR_H -#define CONTROLLER_LEVEL_FOUR_H - -#pragma once - -#include "controller_main.h" -#include "cryptoauthlib.h" -#include "eth.h" -#include "flash_config.h" -#include "near.h" -#include "solana.h" -#include "tasks.h" - -#define DEFAULT_ATECC_RETRIES 5 - -#define DEVICE_SERIAL_SIZE 32 -#define MAXIMUM_COIN_SUPPORTED (14 + 5) // 5 for segwit support - -typedef enum { - slot_0_unused = 0U, - slot_1_unused = 1U, - slot_2_auth_key = 2U, - slot_3_nfc_pair_key = 3U, - slot_4_unused = 4U, - slot_5_challenge = 5U, - slot_6_io_key = 6U, - slot_7_unused = 7U, - slot_8_serial = 8U, - slot_9_unused = 9U, - slot_10_unused = 10U, - slot_11_unused = 11U, - slot_12_unused = 12U, - slot_13_unused = 13U, - slot_14_unused = 14U, - slot_15_unused = 15U -} atecc_slot_define_t; - -typedef struct { - uint8_t device_serial[DEVICE_SERIAL_SIZE], retries; - ATCA_STATUS status; - ATCAIfaceCfg *cfg_atecc608a_iface; -} atecc_data_t; - -extern atecc_data_t atecc_data; - -typedef enum { - provision_empty = 0, - provision_incomplete = 1, - provision_complete = 2, - provision_v1_complete = 3 -} provision_status_t; - -extern uint8_t provision_date[4]; -extern uint8_t auth_card_number; -extern solana_unsigned_txn solana_unsigned_txn_ptr; - -/** - * @brief Stores the device specific information during provisioning process. - * @details The device specific information is stored temporarily in the RAM - * during the 2nd phase of device provisioning. These are received from the - * in-house provisioning tool before a device is ready for use. - * - * @see Perm_Ext_Keys_Struct, Perm_Key_Data_Struct, Flash_Perm_Struct, - * device_provision_controller(), FIREWALL_NVDATA_APP_KEYS_ADDR, - * START_DEVICE_PROVISION, desktop_listener_task() - * @since v1.0.0 - */ -#pragma pack(push, 1) -typedef struct Provision_Data_Struct { - uint8_t device_private_key[32]; - uint8_t device_public_key[ECDSA_PUB_KEY_SIZE]; - uint8_t self_key_path[FS_KEYSTORE_KEYPATH_LEN]; - uint8_t priv_key[FS_KEYSTORE_PRIVKEY_LEN]; - uint8_t card_root_xpub[FS_KEYSTORE_XPUB_LEN]; -} Provision_Data_struct; -#pragma pack(pop) - -extern Provision_Data_struct provision_keys_data; - -/** - * @brief Stores the generated xpubs list for the add coin process. - * @details The generated xpubs list is stored temporarily in the RAM during the - * add coin process before it is sent to the desktop app. - * - * @see MAXIMUM_COIN_SUPPORTED, Add_Coin_Data, add_coin_controller(), - * add_coin_task(), desktop_listener_task(), ADD_COIN_START - * @since v1.0.0 - * - * @note The number of entries in the list should not be greater than the - * maximum number of coins supported (ref MAXIMUM_COIN_SUPPORTED). - */ -#pragma pack(push, 1) -typedef struct Cmd_Add_Coin_t { - uint8_t xpub[XPUB_SIZE]; -} Cmd_Add_Coin_t; -#pragma pack(pop) - -/** - * @brief send transaction data - * @details The transaction data is stored temporarily in the RAM during the - * intermediate phases of send transaction process. - * - * @see send_transaction_controller(), send_transaction_task(), - * desktop_listener_task(), SEND_TXN_START - * @since v1.0.0 - */ -#pragma pack(push, 1) -typedef struct Send_Transaction_Data { - uint8_t transaction_confirmation_list_index; - txn_metadata transaction_metadata; - -} Send_Transaction_Data; -#pragma pack(pop) - -extern Coin_Specific_Data_Struct coin_specific_data; -extern uint8_t *eth_unsigned_txn_byte_array; -extern Send_Transaction_Data var_send_transaction_data; - -/** - * @brief Card upgrade controller available for development purposes. - * @details This controller is used to upgrade the card using a desktop app. - * - * @see card_upgrade_task(), desktop_listener_task(), START_CARD_UPGRADE - * @since v1.0.0 - */ -void card_upgrade_controller(); - -/** - * @brief Device provision controller - * @details This controller is used to provision the device using the desktop - * app. - * - * @see desktop_listener_task(), - * START_DEVICE_PROVISION - * @since v1.0.0 - */ -void device_provision_controller(); - -/** - * @brief This controller is executed for verifying card in main application. - * @details This controller is used to verify the card with the servers using - * the desktop app. - * - * @see task_card_verification(), desktop_listener_task(), START_CARD_AUTH - * @since v1.0.0 - */ -void verify_card_controller(); - -/** - * @brief This controller is executed for verifying card in initial application. - * @details This controller is used to verify the card using the desktop app in - * initial application. - * - * @see initial_verify_card_task(), desktop_listener_task(), START_CARD_AUTH - * @since v1.0.0 - */ -void initial_verify_card_controller(); - -/** - * @brief This controller is executed when the name of a wallet is clicked and - * it is locked. - * @details This controller is used to handle next event for unlocking the - * wallet using the proof of work mechanism where the X1Wallet does the proof of - * work and sends the result to the card. - * - * @see wallet_locked_task(), wallet_locked_controller_b() - * @since v1.0.0 - */ -void wallet_locked_controller(); - -/** - * @brief Back button controller for wallet locked flow - * @details This controller is used to handle back button event for unlocking - * the wallet using the proof of work mechanism. - * - * @see wallet_locked_controller(), wallet_locked_task() - * @since v1.0.0 - */ -void wallet_locked_controller_b(); - -/** - * @brief Next button controller is executed for processing and signing unsigned - * transaction of Ethereum. - * @details This controller is used to process and sign the unsigned transaction - * for ETH that is requested from the desktop app. - * - * @see send_transaction_controller_b_eth(), send_transaction_tasks_eth(), - * send_transaction_controller(), send_transaction_tasks(), - * send_transaction_controller_b() - * @since v1.0.0 - */ -void send_transaction_controller_eth(); - -/** - * @brief Back button controller for send transaction Ethereum flow. - * @details This controller is used to handle back button events during - * processing and signing unsigned transaction for ETH. - * - * @see send_transaction_controller_eth(), send_transaction_tasks_eth(), - * send_transaction_controller(), send_transaction_tasks() - * @since v1.0.0 - */ -void send_transaction_controller_b_eth(); - -/** - * @brief Next button controller is executed for processing and signing messages - * of Ethereum. - * @details This controller is used to process and sign the messages for ETH - * that is requested from the desktop app. - * - */ -void sign_message_controller_eth(); - -/** - * @brief Back button controller for sign message Ethereum flow. - * @details This controller is used to handle back button events during - * processing and signing messages for ETH. - * - */ -void sign_message_controller_b_eth(); - -/** - * @brief Next button controller is executed for processing and signing unsigned - * transaction. - */ -void send_transaction_controller_solana(); - -/** - * @brief Back button controller is executed for handling cancellation of the - * ongoing process. - */ -void send_transaction_controller_b_solana(); - -/** - * @brief Next button controller is executed for generating address using xpub. - * @details This controller handles is used to generate receiving address for - * the BTC coins requested by desktop from a list of supported coins. - * - * @see receive_transaction_controller_b(), receive_transaction_tasks(), - * desktop_listener_task(), RECV_TXN_START, - * receive_transaction_controller_eth(), receive_transaction_tasks_eth() - * @since v1.0.0 - */ -void receive_transaction_controller_near(); - -/** - * @brief Next button controller is executed for generating address using xpub - * of Ethereum. - * @details This controller handles is used to generate receiving address for - * the ETH coins requested by desktop from a list of supported coins. - * - * @see receive_transaction_controller_b_eth(), receive_transaction_tasks_eth(), - * desktop_listener_task(), RECV_TXN_START, receive_transaction_controller(), - * receive_transaction_tasks() - * @since v1.0.0 - */ -void receive_transaction_controller_eth(); - -/** - * @brief Back button controller for receive transaction Ethereum flow. - * @details This controller is used to handle back button events during - * generating receiving address for ETH. - * - * @see receive_transaction_controller_eth(), receive_transaction_tasks_eth(), - * desktop_listener_task(), RECV_TXN_START, receive_transaction_controller(), - * receive_transaction_tasks() - * @since v1.0.0 - */ -void receive_transaction_controller_b_eth(); - -/** - * @brief Back button controller for receive transaction Near flow. - * @details This controller is used to handle back button events during - * receiving flow for Near. - * - * @see receive_transaction_controller_eth(), receive_transaction_tasks_eth(), - * desktop_listener_task(), RECV_TXN_START, receive_transaction_controller(), - * receive_transaction_tasks() - * @since v1.0.0 - */ -void receive_transaction_controller_b_near(); - -/** - * @brief Next button controller is executed for generating address using xpub - * of Ethereum. - * @details This controller handles is used to generate receiving address for - * the ETH coins requested by desktop from a list of supported coins. - * - * @see receive_transaction_controller_b_eth(), receive_transaction_tasks_eth(), - * desktop_listener_task(), RECV_TXN_START, receive_transaction_controller(), - * receive_transaction_tasks() - * @since v1.0.0 - */ -void receive_transaction_controller_solana(); - -/** - * @brief Back button controller for receive transaction Ethereum flow. - * @details This controller is used to handle back button events during - * generating receiving address for ETH. - * - * @see receive_transaction_controller_eth(), receive_transaction_tasks_eth(), - * desktop_listener_task(), RECV_TXN_START, receive_transaction_controller(), - * receive_transaction_tasks() - * @since v1.0.0 - */ -void receive_transaction_controller_b_solana(); - -/** - * @brief This controller is executed for verifying wallet added or restored on - * the device and cards. - * @details This controller is used to verify the wallet added or restored on - * the device and cards. - * - * @see verify_wallet_controller_b(), verify_wallet_tasks(), - * generate_wallet_controller(), - * restore_wallet_controller(), - * @since v1.0.0 - */ -void verify_wallet_controller(); - -/** - * @brief Back button controller for verify wallet flow. - * @details This controller is used to handle back button events during wallet - * verification of newly added wallet. - * - * @see verify_wallet_controller(), verify_wallet_tasks(), - * generate_wallet_controller(), - * restore_wallet_controller(), - * @since v1.0.0 - */ -void verify_wallet_controller_b(); - -/** - * @brief - * @details - * - * @return uint8_t Provision status of the device - * @retval 0 Not provisioned - * @retval 1 Semi-provisioned (serial and IO-Protection Key present) - * @retval 2 Fully provisioned - * @retval 3 External auth configuration - */ -provision_status_t check_provision_status(); - -/** - * @brief fetch device serial and check if UID in the serial matches MCU UID - * or not - * @details - * - * @return uint32_t device serial fetch status or failure status - * @retval 0 fetched successfully - * @retval 1 device UID doesn't match with serial UID - */ -uint32_t get_device_serial(); - -/** - * @brief Request ATECC to generate signature on the hash with private available - * on SLOT-3 - * @details - * - * @param [in] hash - hash to be signed - * @param [out] sign - signature generated - * - * @return ATCA_SUCCESS on success, otherwise an error code. - * - * @see atcab_init(), atcab_sign(), ATCAIfaceCfg, cfg_atecc608a_iface - * @since v1.0.0 - */ -uint8_t atecc_nfc_sign_hash(const uint8_t *hash, uint8_t *sign); - -/** - * @brief Request ATECC to perform ECDH operation on pub_key with private key - * from SLOT-3 - * @details - * - * @param [in] pub_key - public key to be used for ECDH - * @param [out] shared_secret - shared secret generated - * - * @return ATCA_SUCCESS on success, otherwise an error code. - * - * @see atcab_init(), atcab_ecdh(), atcab_ecdh_ioenc(), ATCAIfaceCfg, - * cfg_atecc608a_iface - * @since v1.0.0 - */ -uint8_t atecc_nfc_ecdh(const uint8_t *pub_key, uint8_t *shared_secret); - -#endif \ No newline at end of file diff --git a/src/level_four/core/controller/initial_device_provision_contoller.c b/src/level_four/core/controller/initial_device_provision_contoller.c deleted file mode 100644 index e7919d1f..00000000 --- a/src/level_four/core/controller/initial_device_provision_contoller.c +++ /dev/null @@ -1,516 +0,0 @@ -/** - * @file initial_device_provision_contoller.c - * @author Cypherock X1 Team - * @brief Device provision controller. - * Handles post event (only next events) operations for device - *provision flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip32.h" -#include "communication.h" -#include "controller_level_four.h" -#include "cryptoauthlib.h" -#include "curves.h" -#include "flash_api.h" -#include "nist256p1.h" -#include "string.h" -#include "ui_delay.h" -#include "ui_instruction.h" -#if USE_SIMULATOR == 0 -#include "stm32l4xx_it.h" -#endif - -#define ATECC_CFG_88_MASK 0x4C -#define ATECC_CFG_89_MASK 0x01 - -#define ATECC_CFG_88_MASK_OLD_PROV 44 - -#if X1WALLET_INITIAL -// slot-5 shouldn't be locked -uint8_t atecc_slot_to_lock[] = {slot_2_auth_key, - slot_3_nfc_pair_key, - slot_6_io_key, - slot_8_serial, - slot_0_unused, - slot_1_unused, - slot_4_unused, - slot_7_unused, - slot_9_unused, - slot_10_unused, - slot_11_unused, - slot_12_unused, - slot_13_unused, - slot_14_unused, - slot_15_unused}; - -uint8_t provision_date[4]; -Provision_Data_struct provision_keys_data; - -extern lv_task_t *listener_task; -static lv_task_t *timeout_task; - -static void __timeout_listener(); -static void lock_all_slots(); -#endif - -uint32_t get_device_serial() { - atecc_data.retries = DEFAULT_ATECC_RETRIES; - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); - atecc_data.status = atcab_read_zone(ATCA_ZONE_DATA, - slot_8_serial, - 0, - 0, - atecc_data.device_serial, - DEVICE_SERIAL_SIZE); - } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - if (atecc_data.status == ATCA_SUCCESS) { - if (0 != memcmp(atecc_data.device_serial + 8, (void *)UID_BASE, 12)) { - return 1; - } else { - return SUCCESS; - } - } - return atecc_data.status; -} - -provision_status_t check_provision_status() { - uint8_t cfg[128]; - memset(cfg, 0, 128); - atecc_data.retries = DEFAULT_ATECC_RETRIES; - - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); - atecc_data.status = atcab_read_config_zone(cfg); - } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - if (atecc_data.status != ATCA_SUCCESS) { - LOG_CRITICAL("xxx30: %d", atecc_data.status); - return -1; - } - - if (cfg[86] == 0x00 && - cfg[87] == 0x00) { // config zone and data zones are locked - - if (cfg[88] == 0xBF && - cfg[89] == - 0xFE) { // device serial and IO key are programmed and locked - return provision_incomplete; - - } else if ((cfg[88] & ATECC_CFG_88_MASK) == 0x00 && - (cfg[89] & ATECC_CFG_89_MASK) == - 0x00) { // private key slots are locked - return provision_complete; - } else if ((cfg[88] & ATECC_CFG_88_MASK_OLD_PROV) == 0x00 && - (cfg[89] & ATECC_CFG_89_MASK) == - 0x00) { // NFC private key slot not locked - return provision_v1_complete; - } else { - return provision_empty; - } - } else { - return provision_empty; - } -} - -void device_provision_controller() { -#if X1WALLET_INITIAL - switch (flow_level.level_three) { - case GENERATE_PROVSION_DATA: { - uint8_t io_protection_key[IO_KEY_SIZE] = {0}; - uint8_t serial_no[38] = {0}; - uint8_t test_ecc608_configdata[128] = { - // changes : i2c address = 0x30, secure boot disabled, - 0x01, 0x23, 0x00, 0x00, // serial no part1 - 0x00, 0x00, 0x00, 0x00, // rev no - 0x00, 0x00, 0x00, 0x00, 0x01, // serial no part2 - 0x01, // AES enabled - 0x01, // I2C enabled - 0x00, // reserved - 0xC0, // 0x60, //I2C address : coverts to 0x30 - 0x00, // reserved - 0x00, // counter match disabled - 0x00, // 0x01, //chipmode - 0x85, 0x00, 0x82, 0x00, 0x86, 0x46, 0x87, 0x46, 0x87, 0x46, 0x8F, - 0x46, 0x8F, 0x0F, 0x9F, 0x8F, 0x0F, 0x0F, 0x8F, 0x0F, 0x0F, 0x8F, - 0x0F, 0x8F, 0x0F, 0x8F, 0x0F, 0x0F, 0x0D, 0x1F, 0x0F, 0x0F, 0xFF, - 0xFF, 0xFF, - 0xFF, // monotonic counter 0 not attached to any key - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, - 0xFF, // monotonic counter 1 not attached to any key - 0x00, 0x00, 0x00, 0x00, - 0x00, // use lock key disabled - 0x00, // volatile key permission disabled - 0x00, 0x00, // secure boot not used - 0x00, // KdflvLoc not used - 0x69, 0x76, // KdflvStr not used - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved - 0x00, // use later - 0x00, // not used I2C address - 0x55, // data zone unlocked - 0x55, // config zone unlocked - 0xFF, 0xFF, // slot unlocked - 0x0E, 0x61, // ChipOptions - 0x00, 0x00, 0x00, 0x00, // certificate formatting disabled - 0x73, 0x00, 0x73, 0x00, 0x73, 0x00, 0x73, 0x00, 0x73, 0x00, 0x18, - 0x00, 0x7C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3A, 0x00, 0x3C, 0x00, - 0x30, 0x00, 0x3C, 0x00, 0x30, 0x00, 0x32, 0x00, 0x30, 0x00}; - - atecc_data.retries = DEFAULT_ATECC_RETRIES; - - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - OTG_FS_IRQHandler(); - if (atecc_data.status != ATCA_SUCCESS) { - LOG_ERROR("PERR0-0x%02x", atecc_data.status); - } - - // atecc initialize - atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - // check atecc config and data zone lock atecc_data.status - bool is_locked = false; - atecc_data.status = atcab_is_locked(LOCK_ZONE_CONFIG, &is_locked); - - if (!is_locked || atecc_data.status != ATCA_SUCCESS) { - atecc_data.status = atcab_write_config_zone(test_ecc608_configdata); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - atecc_data.status = atcab_lock_config_zone(); - } - - is_locked = false; - atecc_data.status = atcab_is_locked(LOCK_ZONE_DATA, &is_locked); - - if (!is_locked || atecc_data.status != ATCA_SUCCESS) { - atecc_data.status = atcab_lock_data_zone(); - } - - memset(atecc_data.device_serial, 0, DEVICE_SERIAL_SIZE); - - provision_status_t provision_status = check_provision_status(); - // check if device already provisioned - if (provision_status == provision_empty) { - // called again if not locked in previous configuration - is_locked = false; - atecc_data.status = atcab_is_locked(LOCK_ZONE_CONFIG, &is_locked); - - if (!is_locked || atecc_data.status != ATCA_SUCCESS) { - atecc_data.status = atcab_lock_config_zone(); - } - - is_locked = false; - atecc_data.status = atcab_is_locked(LOCK_ZONE_DATA, &is_locked); - - if (!is_locked || atecc_data.status != ATCA_SUCCESS) { - atecc_data.status = atcab_lock_data_zone(); - } - - // fill whole serial_no with random - atecc_data.status = atcab_random(serial_no); - - // overwrite date 4bytes - memcpy(serial_no, provision_date, 4); - - // overwrite hw no 4bytes - uint32_t u32Temp = FW_get_hardware_version(); - memcpy(serial_no + 4, &u32Temp, 4); - -#if USE_SIMULATOR == 0 - // overwrite MCU UID 12 bytes - u32Temp = HAL_GetUIDw0(); - memcpy(serial_no + 8, &u32Temp, 4); - u32Temp = HAL_GetUIDw1(); - memcpy(serial_no + 12, &u32Temp, 4); - u32Temp = HAL_GetUIDw2(); - memcpy(serial_no + 16, &u32Temp, 4); -#endif - - atecc_data.status = atcab_write_zone( - ATCA_ZONE_DATA, slot_8_serial, 0, 0, serial_no, 32); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - // generate and write IO key - random_generate(io_protection_key, IO_KEY_SIZE); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - atecc_data.status = atcab_write_zone(ATCA_ZONE_DATA, - slot_6_io_key, - 0, - 0, - io_protection_key, - IO_KEY_SIZE); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - if (atecc_data.status == ATCA_SUCCESS) { - if (set_io_protection_key(io_protection_key) == SUCCESS_) { - // locking IO_KEY and serial number slots - atecc_data.status = atcab_lock_data_slot(slot_6_io_key); - atecc_data.status = atcab_lock_data_slot(slot_8_serial); - get_device_serial(); - } else { - memset(serial_no, 0, 32); - LOG_ERROR("PERR1-IO"); - continue; - } - } else { - memset(serial_no, 0, 32); - LOG_ERROR("PERR1-0x%02x", atecc_data.status); - continue; - } - } else if (provision_status == provision_incomplete) { - get_device_serial(); - } else { - lv_obj_clean(lv_scr_act()); - mark_error_screen(ui_text_device_already_provisioned); - reset_flow_level(); - flow_level.level_one = 6; - flow_level.show_error_screen = true; - return; - } - } while ((atecc_data.status != ATCA_SUCCESS) && (--atecc_data.retries)); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - transmit_data_to_app(ADD_DEVICE_PROVISION, atecc_data.device_serial, 32); - - flow_level.level_three = PROVISION_STATUS_WAIT; - lv_task_set_prio(listener_task, - LV_TASK_PRIO_MID); // explicitly enable task listener - - timeout_task = - lv_task_create(__timeout_listener, 10000, LV_TASK_PRIO_HIGH, NULL); - lv_task_once(timeout_task); - } break; - - case PROVISION_STATUS_WAIT: { - // do nothing, just wait - } break; - - case PROVISION_SAVE_EXT_KEYS: { - uint8_t private_write_key[36] = {0}; - Perm_Key_Data_Struct perm_key_data; - uint8_t digest[SHA256_DIGEST_LENGTH]; - lv_task_del(timeout_task); - - get_io_protection_key(perm_key_data.io_protection_key); - - ecdsa_get_public_key33(&nist256p1, - provision_keys_data.device_private_key, - perm_key_data.ext_keys.device_auth_public_key); - if (0 != memcmp(provision_keys_data.device_public_key, - perm_key_data.ext_keys.device_auth_public_key, - 33)) { - comm_reject_request(CONFIRM_PROVISION, 0); - flow_level.level_three = PROVISION_UNSUCCESSFUL; - break; - } - - atecc_data.retries = DEFAULT_ATECC_RETRIES; - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - OTG_FS_IRQHandler(); - atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); - if (atecc_data.status != ATCA_SUCCESS) { - continue; - } - - memset(private_write_key, 0, sizeof(private_write_key)); - memcpy( - &private_write_key[4], provision_keys_data.device_private_key, 32); - atecc_data.status = atcab_priv_write(slot_2_auth_key, - private_write_key, - slot_6_io_key, - perm_key_data.io_protection_key); - if (atecc_data.status != ATCA_SUCCESS) { - LOG_ERROR("PERR2-0x%02x", atecc_data.status); - continue; - } - - memset(private_write_key, 0, sizeof(private_write_key)); - memcpy(&private_write_key[4], provision_keys_data.priv_key, 32); - atecc_data.status = atcab_priv_write(slot_3_nfc_pair_key, - private_write_key, - slot_6_io_key, - perm_key_data.io_protection_key); - if (atecc_data.status != ATCA_SUCCESS) { - LOG_ERROR("PERR3-0x%02x", atecc_data.status); - continue; - } - } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - if (atecc_data.status != ATCA_SUCCESS) { - comm_reject_request(CONFIRM_PROVISION, 0); - flow_level.level_three = PROVISION_UNSUCCESSFUL; - break; - } - - sha256_Raw(provision_keys_data.priv_key, - sizeof(provision_keys_data.priv_key), - digest); - memcpy(perm_key_data.ext_keys.self_key_id, digest, FS_KEYSTORE_KEYID_LEN); - memcpy(perm_key_data.ext_keys.self_key_path, - provision_keys_data.self_key_path, - FS_KEYSTORE_KEYPATH_LEN); - memcpy(perm_key_data.ext_keys.card_root_xpub, - provision_keys_data.card_root_xpub, - FS_KEYSTORE_XPUB_LEN); - - if (set_ext_key(&perm_key_data.ext_keys) == SUCCESS_) { - lock_all_slots(); - - if (check_provision_status() == provision_complete) - transmit_one_byte_confirm(CONFIRM_PROVISION); - else { - comm_reject_request(CONFIRM_PROVISION, 0); - flow_level.level_three = PROVISION_UNSUCCESSFUL; - LOG_ERROR("PERR5-LOCK"); - break; - } - } else { - comm_reject_request(CONFIRM_PROVISION, 0); - flow_level.level_three = PROVISION_UNSUCCESSFUL; - LOG_ERROR("PERR2-KEY"); - break; - } - reset_flow_level(); - flow_level.level_one = 10; - lv_obj_clean(lv_scr_act()); - - } break; - - case PROVISION_UNSUCCESSFUL: { - lv_obj_clean(lv_scr_act()); - mark_error_screen(ui_text_provision_fail); - reset_flow_level(); - flow_level.level_one = 6; - flow_level.show_error_screen = true; - } break; - - default: - break; - } -} - -void lock_all_slots() { - uint8_t usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - - atecc_data.retries = DEFAULT_ATECC_RETRIES; - bool lock = false; - uint32_t err_count = 0; - atecc_data.status = ATCA_FUNC_FAIL; - do { - err_count = 0; - for (uint32_t i = 0; i < sizeof(atecc_slot_to_lock); i++) { - lock = false; - atecc_data.status = atcab_is_slot_locked(atecc_slot_to_lock[i], &lock); - if (atecc_data.status != ATCA_SUCCESS) { - LOG_CRITICAL("PERR4=0x%02x, retry-%d, slot=%d", - atecc_data.retries, - atecc_data.status, - atecc_slot_to_lock[i]); - err_count++; - } else if (lock == true) { - continue; - } - atecc_data.status = atcab_lock_data_slot(atecc_slot_to_lock[i]); - if (atecc_data.status != ATCA_SUCCESS) { - LOG_CRITICAL("PERR5=0x%02x, retry-%d, slot=%d", - atecc_data.retries, - atecc_data.status, - atecc_slot_to_lock[i]); - err_count++; - } - } - } while (err_count != 0 && --atecc_data.retries); - - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); -} - -static void __timeout_listener() { - mark_error_screen(ui_text_provision_fail); - instruction_scr_destructor(); - reset_flow_level(); - flow_level.level_one = - 6; // on command not received take to get-started screen - lv_task_del(timeout_task); -#endif -} \ No newline at end of file diff --git a/src/level_four/core/controller/initial_verify_card_controller.c b/src/level_four/core/controller/initial_verify_card_controller.c deleted file mode 100644 index d3c831fd..00000000 --- a/src/level_four/core/controller/initial_verify_card_controller.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file initial_verify_card_controller.c - * @author Cypherock X1 Team - * @brief Verify card next controller (initial). - * Handles post event (only next events) operations for card - *verification flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "base58.h" -#include "bip32.h" -#include "buzzer.h" -#include "communication.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" -#include "curves.h" -#include "flash_api.h" -#include "nfc.h" -#include "nist256p1.h" -#include "ui_instruction.h" -#if USE_SIMULATOR == 0 -#include "stm32l4xx_it.h" -#endif - -uint8_t atecc_nfc_sign_hash(const uint8_t *hash, uint8_t *sign) { - atecc_data.retries = DEFAULT_ATECC_RETRIES; - - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - if (atecc_data.status != ATCA_SUCCESS) - LOG_CRITICAL("PAIR SG: %04x, count:%d", - atecc_data.status, - DEFAULT_ATECC_RETRIES - atecc_data.retries); - atcab_init(atecc_data.cfg_atecc608a_iface); - atecc_data.status = atcab_sign(slot_3_nfc_pair_key, hash, sign); - } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - return atecc_data.status; -} - -uint8_t atecc_nfc_ecdh(const uint8_t *pub_key, uint8_t *shared_secret) { - uint8_t io_key[IO_KEY_SIZE]; - atecc_data.retries = DEFAULT_ATECC_RETRIES; - - if (get_io_protection_key(io_key) != SUCCESS_) - return -1; - - bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); - NVIC_DisableIRQ(OTG_FS_IRQn); - do { - if (atecc_data.status != ATCA_SUCCESS) - LOG_CRITICAL("ECDH: %04x, count:%d", - atecc_data.status, - DEFAULT_ATECC_RETRIES - atecc_data.retries); - atcab_init(atecc_data.cfg_atecc608a_iface); - atecc_data.status = - atcab_ecdh_ioenc(slot_3_nfc_pair_key, pub_key, shared_secret, io_key); - } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); - if (usb_irq_enable_on_entry == true) - NVIC_EnableIRQ(OTG_FS_IRQn); - - return atecc_data.status; -} \ No newline at end of file diff --git a/src/level_four/core/controller/receive_transaction_controller_b_eth.c b/src/level_four/core/controller/receive_transaction_controller_b_eth.c deleted file mode 100644 index 9d83662c..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_b_eth.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file receive_transaction_controller_b_eth.c - * @author Cypherock X1 Team - * @brief Receive transaction next controller for ETH. - * Handles post event (only back/cancel events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -extern Wallet_credential_data wallet_credential_data; - -void receive_transaction_controller_b_eth() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_ETH: { - comm_reject_request(RECV_TXN_USER_VERIFIED_COINS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case RECV_TXN_ENTER_PIN_ETH: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - - } break; - - case RECV_TXN_ENTER_PASSPHRASE_ETH: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_ETH: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_ETH; - } break; - - case RECV_TXN_DISPLAY_ADDR_ETH: { - comm_reject_request(RECV_TXN_USER_VERIFIED_ADDRESS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - default: - break; - } - return; -} diff --git a/src/level_four/core/controller/receive_transaction_controller_b_near.c b/src/level_four/core/controller/receive_transaction_controller_b_near.c deleted file mode 100644 index 7d3d00b5..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_b_near.c +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file receive_transaction_controller_b.c - * @author Cypherock X1 Team - * @brief Receive transaction back controller for BTC. - * Handles post event (only back/cancel events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -void receive_transaction_controller_b_near() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_NEAR: { - comm_reject_request(RECV_TXN_USER_VERIFIED_COINS, 0); - reset_flow_level(); - } break; - - case RECV_TXN_ENTER_PIN_NEAR: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - - } break; - - case RECV_TXN_ENTER_PASSPHRASE_NEAR: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_NEAR: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_NEAR; - } break; - - case RECV_TXN_DISPLAY_ACC_NEAR: { - comm_reject_request(RECV_TXN_USER_VERIFIED_ADDRESS, 0); - reset_flow_level(); - } break; - - case RECV_TXN_DISPLAY_ADDR_NEAR: { - comm_reject_request(RECV_TXN_USER_VERIFIED_ADDRESS, 0); - reset_flow_level(); - } break; - - case RECV_TXN_SELECT_REPLACE_ACC_NEAR: { - comm_reject_request(RECV_TXN_REPLACE_ACCOUNT, 0); - reset_flow_level(); - - } break; - - case RECV_TXN_VERIFY_SAVE_ACC_NEAR: { - flow_level.level_three = RECV_TXN_SELECT_REPLACE_ACC_NEAR; - } break; - - default: - reset_flow_level(); - break; - } -} diff --git a/src/level_four/core/controller/receive_transaction_controller_b_solana.c b/src/level_four/core/controller/receive_transaction_controller_b_solana.c deleted file mode 100644 index fa9c4f15..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_b_solana.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file receive_transaction_controller_b_solana.c - * @author Cypherock X1 Team - * @brief Receive transaction next controller for SOLANA. - * Handles post event (only back/cancel events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -extern Wallet_credential_data wallet_credential_data; - -void receive_transaction_controller_b_solana() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_SOLANA: { - comm_reject_request(RECV_TXN_USER_VERIFIED_COINS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case RECV_TXN_ENTER_PIN_SOLANA: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - - } break; - - case RECV_TXN_ENTER_PASSPHRASE_SOLANA: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_SOLANA: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_SOLANA; - } break; - - case RECV_TXN_DISPLAY_ADDR_SOLANA: { - comm_reject_request(RECV_TXN_USER_VERIFIED_ADDRESS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - default: - break; - } - return; -} diff --git a/src/level_four/core/controller/receive_transaction_controller_eth.c b/src/level_four/core/controller/receive_transaction_controller_eth.c deleted file mode 100644 index 7049787f..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_eth.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @file receive_transaction_controller_eth.c - * @author Cypherock X1 Team - * @brief Receive transaction next controller for ETH. - * Handles post event (only next events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip32.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" -#include "harmony.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -extern Receive_Transaction_Data receive_transaction_data; -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -void receive_transaction_controller_eth() { - switch (flow_level.level_three) { - // TODO: Rename RECV_TXN_FIND_XPUB in all receive tasks to a relevant name - // (PROCESS_METADATA) - case RECV_TXN_FIND_XPUB_ETH: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_ETH; - } else { - flow_level.level_three = RECV_TXN_CHECK_PIN_ETH; - } - } break; - - case RECV_TXN_ENTER_PASSPHRASE_ETH: { - flow_level.level_three = RECV_TXN_CONFIRM_PASSPHRASE_ETH; - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_ETH: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = RECV_TXN_CHECK_PIN_ETH; - flow_level.level_one = 1; - } break; - - case RECV_TXN_CHECK_PIN_ETH: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PIN_ETH; - } else { - flow_level.level_three = RECV_TXN_TAP_CARD_ETH; - } - } break; - - case RECV_TXN_ENTER_PIN_ETH: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = RECV_TXN_TAP_CARD_ETH; - } break; - - case RECV_TXN_TAP_CARD_ETH: { - tap_card_data.desktop_control = true; - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_ETH: { - flow_level.level_three = RECV_TXN_READ_DEVICE_SHARE_ETH; - } break; - - case RECV_TXN_READ_DEVICE_SHARE_ETH: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = RECV_TXN_DERIVE_ADD_SCREEN_ETH; - break; - - case RECV_TXN_DERIVE_ADD_SCREEN_ETH: { - flow_level.level_three = RECV_TXN_DERIVE_ADD_ETH; - } break; - - case RECV_TXN_DERIVE_ADD_ETH: { - uint8_t secret[BLOCK_SIZE]; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - memzero(wallet_shamir_data.mnemonic_shares, - sizeof(wallet_shamir_data.mnemonic_shares)); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - HDNode node; - uint8_t seed[64]; - - memzero(seed, sizeof(seed)); - mnemonic_to_seed(mnemo, wallet_credential_data.passphrase, seed, NULL); - mnemonic_clear(); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - hdnode_from_seed(seed, sizeof(seed), SECP256K1_NAME, &node); - - hdnode_private_ckd( - &node, BYTE_ARRAY_TO_UINT32(receive_transaction_data.purpose)); - hdnode_private_ckd( - &node, BYTE_ARRAY_TO_UINT32(receive_transaction_data.coin_index)); - hdnode_private_ckd( - &node, BYTE_ARRAY_TO_UINT32(receive_transaction_data.account_index)); - - hdnode_fill_public_key(&node); - - hdnode_public_ckd( - &node, BYTE_ARRAY_TO_UINT32(receive_transaction_data.change_index)); - hdnode_fill_public_key(&node); - hdnode_public_ckd( - &node, BYTE_ARRAY_TO_UINT32(receive_transaction_data.address_index)); - hdnode_fill_public_key(&node); - hdnode_get_ethereum_pubkeyhash(&node, - receive_transaction_data.eth_pubkeyhash); - - flow_level.level_three = RECV_TXN_DISPLAY_ADDR_ETH; - } break; - - case RECV_TXN_DISPLAY_ADDR_ETH: { - uint64_t chain_id = receive_transaction_data.network_chain_id; - uint8_t data[1 + sizeof(receive_transaction_data.address) + - 1]; // confirm byte + address length + null byte - size_t datalen; - data[0] = 1; // confirmation byte - if (chain_id != HARMONY_MAINNET_CHAIN) { - memcpy(data + 1, - receive_transaction_data.eth_pubkeyhash, - sizeof(receive_transaction_data.eth_pubkeyhash)); - datalen = 1 + sizeof(receive_transaction_data.eth_pubkeyhash); - } else { - strncpy((char *)data + 1, - receive_transaction_data.address, - sizeof(data) - 1); - datalen = strnlen((char *)data, - sizeof(data)); // send excluding the null byte - } - transmit_data_to_app(RECV_TXN_USER_VERIFIED_ADDRESS, data, datalen); - reset_flow_level(); - } break; - - default: - break; - } - - return; -} diff --git a/src/level_four/core/controller/receive_transaction_controller_near.c b/src/level_four/core/controller/receive_transaction_controller_near.c deleted file mode 100644 index d657d358..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_near.c +++ /dev/null @@ -1,364 +0,0 @@ -/** - * @file receive_transaction_controller.c - * @author Cypherock X1 Team - * @brief Receive transaction next controller (for BTC). - * Handles post event (only next events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip32.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" -#include "near_context.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -extern Wallet_credential_data wallet_credential_data; - -extern Receive_Transaction_Data receive_transaction_data; -Coin_Specific_Data_Struct coin_specific_data; - -void receive_transaction_controller_near() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_NEAR: { - receive_transaction_data.near_acc_found = false; - - if (false && receive_transaction_data.near_account_type == 1) { - coin_specific_data.coin_type = COIN_TYPE_NEAR; - memcpy(coin_specific_data.wallet_id, - receive_transaction_data.wallet_id, - WALLET_ID_SIZE); - coin_specific_data.coin_data = - (uint8_t *)cy_malloc(NEAR_COIN_DATA_MAX_LEN); - uint16_t len = 0; - - get_coin_data(&coin_specific_data, NEAR_COIN_DATA_MAX_LEN, &len); - size_t acc_count = - near_get_account_ids_count(coin_specific_data.coin_data, len); - receive_transaction_data.near_acc_count = acc_count; - - char *acc_id[NEAR_REGISTERED_ACCOUNT_COUNT] = {0}; - - near_deserialize_account_ids( - coin_specific_data.coin_data, len, acc_id, acc_count); - - for (size_t i = 0; i < NEAR_REGISTERED_ACCOUNT_COUNT; i++) { - if (strcmp(acc_id[i], - receive_transaction_data.near_registered_account) == 0) { - receive_transaction_data.near_acc_found = true; - break; - } - } - } - - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_NEAR; - } else { - flow_level.level_three = RECV_TXN_CHECK_PIN_NEAR; - } - } break; - - case RECV_TXN_ENTER_PASSPHRASE_NEAR: { - flow_level.level_three = RECV_TXN_CONFIRM_PASSPHRASE_NEAR; - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_NEAR: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = RECV_TXN_CHECK_PIN_NEAR; - flow_level.level_one = 1; - } break; - - case RECV_TXN_CHECK_PIN_NEAR: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PIN_NEAR; - } else { - flow_level.level_three = RECV_TXN_TAP_CARD_NEAR; - } - } break; - - case RECV_TXN_ENTER_PIN_NEAR: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - - flow_level.level_three = RECV_TXN_TAP_CARD_NEAR; - } break; - - case RECV_TXN_TAP_CARD_NEAR: { - tap_card_data.desktop_control = true; - // TODO: Shorten func name - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_NEAR: { - flow_level.level_three = RECV_TXN_READ_DEVICE_SHARE_NEAR; - if (!receive_transaction_data.near_acc_found && - receive_transaction_data.near_account_type == 1) - transmit_one_byte(RECV_TXN_XPUBS_EXISTS_ON_DEVICE, 1); - } break; - - case RECV_TXN_READ_DEVICE_SHARE_NEAR: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = RECV_TXN_DERIVE_ADD_SCREEN_NEAR; - break; - - case RECV_TXN_DERIVE_ADD_SCREEN_NEAR: { - flow_level.level_three = RECV_TXN_DERIVE_ADD_NEAR; - } break; - - case RECV_TXN_DERIVE_ADD_NEAR: { - // TODO: Extract common part i.e. secret recreation and public key - // derication - uint8_t secret[BLOCK_SIZE] = {0}; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - memzero(wallet_shamir_data.share_encryption_data, - sizeof(wallet_shamir_data.share_encryption_data)); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - HDNode node; - uint8_t seed[64] = {0}; - - memzero(seed, sizeof(seed)); - - mnemonic_to_seed(mnemo, wallet_credential_data.passphrase, seed, NULL); - mnemonic_clear(); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - - uint32_t path[] = { - BYTE_ARRAY_TO_UINT32(receive_transaction_data.purpose), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.coin_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.account_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.change_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.address_index), - }; - derive_hdnode_from_path(path, 5, ED25519_NAME, seed, &node); - memzero(path, sizeof(path)); - memzero(receive_transaction_data.near_pubkey, - sizeof(receive_transaction_data.near_pubkey)); - memcpy(receive_transaction_data.near_pubkey, - node.public_key + 1, - 32 * sizeof(uint8_t)); - - if (receive_transaction_data.near_account_type == 0 || - receive_transaction_data.near_acc_found) { - flow_level.level_three = RECV_TXN_DISPLAY_ADDR_NEAR; - instruction_scr_destructor(); - } else { - flow_level.level_three = RECV_TXN_WAIT_FOR_LINK_NEAR; - } - } break; - - case RECV_TXN_WAIT_FOR_LINK_NEAR: { - uint8_t *data = NULL; - uint16_t size = 0; - if (get_usb_msg_by_cmd_type( - RECV_TXN_USER_VERIFIED_ACCOUNT, &data, &size)) { - flow_level.level_three = RECV_TXN_DISPLAY_ACC_NEAR; - clear_message_received_data(); - instruction_scr_destructor(); - } - } break; - - case RECV_TXN_DISPLAY_ACC_NEAR: { - flow_level.level_three = RECV_TXN_DISPLAY_ADDR_NEAR; - } break; - - case RECV_TXN_DISPLAY_ADDR_NEAR: { - flow_level.level_three = RECV_TXN_FINAL_SCREEN_NEAR; - - uint8_t data[1 + sizeof(receive_transaction_data.near_pubkey)] = {0}; - data[0] = 1; // confirmation byte - - if (receive_transaction_data.near_account_type == 1 && - !receive_transaction_data.near_acc_found) { - if (receive_transaction_data.near_acc_count < - NEAR_REGISTERED_ACCOUNT_COUNT) { - uint16_t len = 0; - memzero(coin_specific_data.coin_data, NEAR_COIN_DATA_MAX_LEN); - get_coin_data(&coin_specific_data, NEAR_COIN_DATA_MAX_LEN, &len); - - char *acc_id[NEAR_REGISTERED_ACCOUNT_COUNT] = {0}; - - near_deserialize_account_ids(coin_specific_data.coin_data, - len, - acc_id, - receive_transaction_data.near_acc_count); - - acc_id[receive_transaction_data.near_acc_count] = - receive_transaction_data.near_registered_account; - - uint8_t new_near_coin_data[NEAR_COIN_DATA_MAX_LEN] = {0}; - len = 0; - - near_serialize_account_ids( - (const char **)acc_id, - receive_transaction_data.near_acc_count + 1, - new_near_coin_data, - &len); - memcpy(coin_specific_data.coin_data, - new_near_coin_data, - NEAR_COIN_DATA_MAX_LEN); - - int status = set_coin_data(&coin_specific_data, len); - if (status != 0) { - comm_reject_request(COIN_SPECIFIC_DATA_ERROR, status); - reset_flow_level(); - return; - } - } else { - data[0] = 2; - flow_level.level_three = RECV_TXN_WAIT_FOR_REPLACE_NEAR_SCREEN; - } - } - - memcpy(data + 1, - receive_transaction_data.near_pubkey, - sizeof(receive_transaction_data.near_pubkey)); - transmit_data_to_app(RECV_TXN_USER_VERIFIED_ADDRESS, data, sizeof(data)); - } break; - - case RECV_TXN_WAIT_FOR_REPLACE_NEAR_SCREEN: { - flow_level.level_three = RECV_TXN_WAIT_FOR_REPLACE_NEAR; - } break; - - case RECV_TXN_WAIT_FOR_REPLACE_NEAR: { - uint8_t *data = NULL; - uint16_t size = 0; - if (get_usb_msg_by_cmd_type(RECV_TXN_REPLACE_ACCOUNT, &data, &size)) { - flow_level.level_three = RECV_TXN_SELECT_REPLACE_ACC_NEAR; - clear_message_received_data(); - instruction_scr_destructor(); - } - } break; - - case RECV_TXN_SELECT_REPLACE_ACC_NEAR: { - flow_level.level_three = RECV_TXN_VERIFY_SAVE_ACC_NEAR; - } break; - - case RECV_TXN_VERIFY_SAVE_ACC_NEAR: { - uint16_t filled_length = 0; - memzero(coin_specific_data.coin_data, NEAR_COIN_DATA_MAX_LEN); - - get_coin_data( - &coin_specific_data, NEAR_COIN_DATA_MAX_LEN, &filled_length); - size_t acc_count = near_get_account_ids_count( - coin_specific_data.coin_data, filled_length); - - char *acc_id[NEAR_REGISTERED_ACCOUNT_COUNT] = {0}; - - near_deserialize_account_ids( - coin_specific_data.coin_data, filled_length, acc_id, acc_count); - - acc_id[receive_transaction_data.near_acc_index] = - receive_transaction_data.near_registered_account; - - uint8_t new_near_coin_data[NEAR_COIN_DATA_MAX_LEN] = {0}; - filled_length = 0; - near_serialize_account_ids( - (const char **)acc_id, acc_count, new_near_coin_data, &filled_length); - memcpy(coin_specific_data.coin_data, - new_near_coin_data, - NEAR_COIN_DATA_MAX_LEN); - - int status = set_coin_data(&coin_specific_data, filled_length); - if (status != 0) { - comm_reject_request(COIN_SPECIFIC_DATA_ERROR, status); - reset_flow_level(); - return; - } - - transmit_one_byte_confirm(RECV_TXN_REPLACE_ACCOUNT); - reset_flow_level(); - } break; - - case RECV_TXN_FINAL_SCREEN_NEAR: { - reset_flow_level(); - } break; - - default: - break; - } - - return; -} diff --git a/src/level_four/core/controller/receive_transaction_controller_solana.c b/src/level_four/core/controller/receive_transaction_controller_solana.c deleted file mode 100644 index 397c5b16..00000000 --- a/src/level_four/core/controller/receive_transaction_controller_solana.c +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @file receive_transaction_controller_solana.c - * @author Cypherock X1 Team - * @brief Receive transaction next controller for SOLANA. - * Handles post event (only next events) operations for receive - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip32.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" - -extern Receive_Transaction_Data receive_transaction_data; -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -void receive_transaction_controller_solana() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_SOLANA: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PASSPHRASE_SOLANA; - } else { - flow_level.level_three = RECV_TXN_CHECK_PIN_SOLANA; - } - } break; - - case RECV_TXN_ENTER_PASSPHRASE_SOLANA: { - flow_level.level_three = RECV_TXN_CONFIRM_PASSPHRASE_SOLANA; - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_SOLANA: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = RECV_TXN_CHECK_PIN_SOLANA; - } break; - - case RECV_TXN_CHECK_PIN_SOLANA: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_ENTER_PIN_SOLANA; - } else { - flow_level.level_three = RECV_TXN_TAP_CARD_SOLANA; - } - } break; - - case RECV_TXN_ENTER_PIN_SOLANA: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = RECV_TXN_TAP_CARD_SOLANA; - } break; - - case RECV_TXN_TAP_CARD_SOLANA: { - tap_card_data.desktop_control = true; - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_SOLANA: { - flow_level.level_three = RECV_TXN_READ_DEVICE_SHARE_SOLANA; - } break; - - case RECV_TXN_READ_DEVICE_SHARE_SOLANA: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = RECV_TXN_DERIVE_ADD_SCREEN_SOLANA; - break; - - case RECV_TXN_DERIVE_ADD_SCREEN_SOLANA: { - flow_level.level_three = RECV_TXN_DERIVE_ADD_SOLANA; - } break; - - case RECV_TXN_DERIVE_ADD_SOLANA: { - uint8_t secret[BLOCK_SIZE]; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - memzero(wallet_shamir_data.mnemonic_shares, - sizeof(wallet_shamir_data.mnemonic_shares)); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - HDNode node; - uint8_t seed[64] = {0}; - - memzero(seed, sizeof(seed)); - - mnemonic_to_seed(mnemo, wallet_credential_data.passphrase, seed, NULL); - mnemonic_clear(); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - - uint32_t path[] = { - BYTE_ARRAY_TO_UINT32(receive_transaction_data.purpose), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.coin_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.account_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.change_index), - BYTE_ARRAY_TO_UINT32(receive_transaction_data.address_index), - }; - size_t depth = - sol_get_derivation_depth(receive_transaction_data.address_tag); - derive_hdnode_from_path(path, depth, ED25519_NAME, seed, &node); - size_t public_key_size = sizeof(receive_transaction_data.solana_address); - memzero(receive_transaction_data.solana_address, - sizeof(receive_transaction_data.solana_address)); - b58enc(receive_transaction_data.solana_address, - &public_key_size, - (char *)(node.public_key + 1), - 32); - memzero(path, sizeof(path)); - - flow_level.level_three = RECV_TXN_DISPLAY_ADDR_SOLANA; - } break; - - case RECV_TXN_DISPLAY_ADDR_SOLANA: { - uint8_t data[1 + sizeof(receive_transaction_data.solana_address)]; - data[0] = 1; // confirmation byte - memcpy(data + 1, - receive_transaction_data.solana_address, - sizeof(receive_transaction_data.solana_address)); - transmit_data_to_app(RECV_TXN_USER_VERIFIED_ADDRESS, data, sizeof(data)); - reset_flow_level(); - } break; - - default: - break; - } - - return; -} diff --git a/src/level_four/core/controller/send_transaction_controller_b_eth.c b/src/level_four/core/controller/send_transaction_controller_b_eth.c deleted file mode 100644 index c0bac96b..00000000 --- a/src/level_four/core/controller/send_transaction_controller_b_eth.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file send_transaction_controller_b_eth.c - * @author Cypherock X1 Team - * @brief Send transaction back controller for ETH. - * Handles post event (only back/cancel events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" - -extern Wallet_credential_data wallet_credential_data; -void send_transaction_controller_b_eth() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_ETH: { - comm_reject_request(SEND_TXN_REQ_UNSIGNED_TXN, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_TXN_NONCE_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 4); - reset_flow_level(); - counter.next_event_flag = true; - } - - case SEND_TXN_CALCULATE_AMOUNT_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 2); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: - case SEND_TXN_VERIFY_BLIND_SIGNING_ETH: - case SEND_TXN_VERIFY_DERIVATION_PATH: - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 2); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 3); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_DISPLAY_INFO_ETH: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 4); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_ENTER_PIN_ETH: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SEND_TXN_ENTER_PASSPHRASE_ETH: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_ETH: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = SEND_TXN_ENTER_PASSPHRASE_ETH; - } break; - - default: - break; - } -} \ No newline at end of file diff --git a/src/level_four/core/controller/send_transaction_controller_b_solana.c b/src/level_four/core/controller/send_transaction_controller_b_solana.c deleted file mode 100644 index f3cff547..00000000 --- a/src/level_four/core/controller/send_transaction_controller_b_solana.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file send_transaction_controller_b_solana.c - * @author Cypherock X1 Team - * @brief Send transaction back controller for SOLANA. - * Handles post event (only back/cancel events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" - -extern Wallet_credential_data wallet_credential_data; -void send_transaction_controller_b_solana() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_SOLANA: { - comm_reject_request(SEND_TXN_REQ_UNSIGNED_TXN, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_CALCULATE_AMOUNT_SOLANA: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 2); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SOLANA: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_SOLANA: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 2); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_SOLANA: { - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 3); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SEND_TXN_ENTER_PIN_SOLANA: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SEND_TXN_ENTER_PASSPHRASE_SOLANA: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_SOLANA: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = SEND_TXN_ENTER_PASSPHRASE_SOLANA; - } break; - - default: - break; - } -} \ No newline at end of file diff --git a/src/level_four/core/controller/send_transaction_controller_eth.c b/src/level_four/core/controller/send_transaction_controller_eth.c deleted file mode 100644 index 9af38ae6..00000000 --- a/src/level_four/core/controller/send_transaction_controller_eth.c +++ /dev/null @@ -1,267 +0,0 @@ -/** - * @file send_transaction_controller_eth.c - * @author Cypherock X1 Team - * @brief Send transaction next controller for ETH. - * Handles post event (only next events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -extern lv_task_t *timeout_task; - -evm_unsigned_txn eth_unsigned_txn_ptr = { - .nonce_size = {0}, - .nonce = {0}, - .gas_price_size = {0}, - .gas_price = {0}, - .gas_limit_size = {0}, - .gas_limit = {0}, - .to_address = {0}, - .value_size = {0}, - .value = {0}, - .data_size = 0, - .data = NULL, - .chain_id_size = {0}, - .chain_id = {0}, - .dummy_r = {0}, - .dummy_s = {0}, -}; -uint8_t *eth_unsigned_txn_byte_array = NULL; -uint16_t eth_unsigned_txn_len; - -extern ui_display_node *current_display_node; -extern bool evm_is_token_whitelisted; - -void send_transaction_controller_eth() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_ETH: { - uint8_t arr[3] = {0x01, 0x1f, 0x40}; - transmit_data_to_app(SEND_TXN_REQ_UNSIGNED_TXN, arr, sizeof(arr)); - flow_level.level_three = SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_ETH; - } break; - - case SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_ETH: { - uint8_t *data_array = NULL; - uint16_t msg_size = 0; - if (get_usb_msg_by_cmd_type( - SEND_TXN_UNSIGNED_TXN, &data_array, &msg_size)) { - eth_unsigned_txn_byte_array = (uint8_t *)cy_malloc(msg_size); - eth_unsigned_txn_len = msg_size; - memcpy(eth_unsigned_txn_byte_array, data_array, msg_size); - - clear_message_received_data(); - flow_level.level_three = SEND_TXN_UNSIGNED_TXN_RECEIVED_ETH; - } - } break; - - case SEND_TXN_VERIFY_BLIND_SIGNING_ETH: { - flow_level.level_three = SEND_TXN_VERIFY_DERIVATION_PATH; - } break; - - case SEND_TXN_VERIFY_DERIVATION_PATH: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH; - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH; - } break; - - case SEND_TXN_VERIFY_TXN_NONCE_ETH: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH; - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH: { - flow_level.level_three = SEND_TXN_CALCULATE_AMOUNT_ETH; - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_ETH: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_FEES_ETH; - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_ETH: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_ETH; - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_ETH: { - flow_level.level_three = SEND_TXN_DISPLAY_INFO_ETH; - } break; - - case SEND_TXN_DISPLAY_INFO_ETH: { - if (current_display_node == NULL) { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_ENTER_PASSPHRASE_ETH; - } else { - flow_level.level_three = SEND_TXN_CHECK_PIN_ETH; - } - } else { - current_display_node = current_display_node->next; - } - } break; - - case SEND_TXN_ENTER_PASSPHRASE_ETH: { - flow_level.level_three = SEND_TXN_CONFIRM_PASSPHRASE_ETH; - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_ETH: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SEND_TXN_CHECK_PIN_ETH; - } break; - - case SEND_TXN_CHECK_PIN_ETH: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_ENTER_PIN_ETH; - } else { - flow_level.level_three = SEND_TXN_TAP_CARD_ETH; - } - - } break; - - case SEND_TXN_ENTER_PIN_ETH: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SEND_TXN_TAP_CARD_ETH; - } break; - - case SEND_TXN_TAP_CARD_ETH: { - tap_card_data.desktop_control = true; - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case SEND_TXN_TAP_CARD_SEND_CMD_ETH: { - flow_level.level_three = SEND_TXN_READ_DEVICE_SHARE_ETH; - } break; - - case SEND_TXN_READ_DEVICE_SHARE_ETH: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = SEND_TXN_SIGN_TXN_ETH; - break; - - case SEND_TXN_SIGN_TXN_ETH: { - uint8_t secret[BLOCK_SIZE]; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - ASSERT(mnemo != NULL); - - uint8_t sig[65]; - sig_unsigned_byte_array( - eth_unsigned_txn_byte_array, - eth_unsigned_txn_len, - (const txn_metadata *)&var_send_transaction_data.transaction_metadata, - mnemo, - wallet_credential_data.passphrase, - sig); - transmit_data_to_app(SEND_TXN_SENDING_SIGNED_TXN, sig, 65); - mnemonic_clear(); - memzero(secret, sizeof(secret)); - memzero(wallet_shamir_data.mnemonic_shares, - sizeof(wallet_shamir_data.mnemonic_shares)); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - - flow_level.level_three = SEND_TXN_WAITING_SCREEN_ETH; - } break; - - case SEND_TXN_WAITING_SCREEN_ETH: - instruction_scr_destructor(); - lv_obj_clean(lv_scr_act()); - flow_level.level_three = SEND_TXN_FINAL_SCREEN_ETH; - break; - - case SEND_TXN_FINAL_SCREEN_ETH: - reset_flow_level(); - break; - - default: - break; - } -} diff --git a/src/level_four/core/controller/send_transaction_controller_solana.c b/src/level_four/core/controller/send_transaction_controller_solana.c deleted file mode 100644 index 66b932b2..00000000 --- a/src/level_four/core/controller/send_transaction_controller_solana.c +++ /dev/null @@ -1,282 +0,0 @@ -/** - * @file send_transaction_controller_solana.c - * @author Cypherock X1 Team - * @brief Send transaction next controller for SOLANA. - * Handles post event (only next events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -extern lv_task_t *timeout_task; - -solana_unsigned_txn solana_unsigned_txn_ptr; -uint8_t *solana_unsigned_txn_byte_array = NULL; -uint16_t solana_unsigned_txn_len; - -void send_transaction_controller_solana() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_SOLANA: { - uint8_t arr[3] = {0x01, 0x1f, 0x40}; - transmit_data_to_app(SEND_TXN_REQ_UNSIGNED_TXN, arr, sizeof(arr)); - flow_level.level_three = SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_SOLANA; - } break; - - case SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_SOLANA: { - uint8_t *data_array = NULL; - uint16_t msg_size = 0; - if (get_usb_msg_by_cmd_type( - SEND_TXN_UNSIGNED_TXN, &data_array, &msg_size)) { - solana_unsigned_txn_byte_array = (uint8_t *)cy_malloc(msg_size); - solana_unsigned_txn_len = msg_size; - memcpy(solana_unsigned_txn_byte_array, data_array, msg_size); - - int status = - solana_byte_array_to_unsigned_txn(solana_unsigned_txn_byte_array, - solana_unsigned_txn_len, - &solana_unsigned_txn_ptr); - - clear_message_received_data(); - flow_level.level_three = SEND_TXN_UNSIGNED_TXN_RECEIVED_SOLANA; - - if (status == SOL_OK) - status = solana_validate_unsigned_txn(&solana_unsigned_txn_ptr); - - if (status != SOL_OK) { - LOG_ERROR("Solana error code: %d", status); - instruction_scr_destructor(); - mark_error_screen(ui_text_worng_eth_transaction); - comm_reject_request(SEND_TXN_USER_VERIFIES_ADDRESS, 0); - reset_flow_level(); - } - } - } break; - - case SEND_TXN_UNSIGNED_TXN_RECEIVED_SOLANA: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_SOLANA; - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_SOLANA; - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SOLANA: { - flow_level.level_three = SEND_TXN_CALCULATE_AMOUNT_SOLANA; - } break; - - case SEND_TXN_CALCULATE_AMOUNT_SOLANA: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_AMOUNT_SOLANA; - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_SOLANA: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_FEES_SOLANA; - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_SOLANA: { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_SOLANA; - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_SOLANA: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_ENTER_PASSPHRASE_SOLANA; - } else { - flow_level.level_three = SEND_TXN_CHECK_PIN_SOLANA; - } - } break; - - case SEND_TXN_ENTER_PASSPHRASE_SOLANA: { - flow_level.level_three = SEND_TXN_CONFIRM_PASSPHRASE_SOLANA; - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_SOLANA: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SEND_TXN_CHECK_PIN_SOLANA; - } break; - - case SEND_TXN_CHECK_PIN_SOLANA: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_ENTER_PIN_SOLANA; - } else { - flow_level.level_three = SEND_TXN_TAP_CARD_SOLANA; - } - - } break; - - case SEND_TXN_ENTER_PIN_SOLANA: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SEND_TXN_TAP_CARD_SOLANA; - } break; - - case SEND_TXN_TAP_CARD_SOLANA: { - tap_card_data.desktop_control = true; - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case SEND_TXN_TAP_CARD_SEND_CMD_SOLANA: { - flow_level.level_three = SEND_TXN_UPDATE_BLOCKHASH_SOLANA; - uint8_t arr[1] = {1}; - transmit_data_to_app(SEND_TXN_UNSIGNED_TXN, arr, sizeof(arr)); - } break; - - case SEND_TXN_UPDATE_BLOCKHASH_SOLANA: { - uint8_t *blockhash_received = NULL; - uint16_t blockhash_msg_size = 0; - uint8_t solana_latest_blockhash[SOLANA_BLOCKHASH_LENGTH] = {0}; - - if (get_usb_msg_by_cmd_type(SEND_TXN_PRE_SIGNING_DATA, - &blockhash_received, - &blockhash_msg_size)) { - if (blockhash_msg_size != SOLANA_BLOCKHASH_LENGTH) { - comm_reject_invalid_cmd(); - reset_flow_level(); - } - memcpy(solana_latest_blockhash, - blockhash_received, - SOLANA_BLOCKHASH_LENGTH); - clear_message_received_data(); - - int status = solana_update_blockhash_in_byte_array( - solana_unsigned_txn_byte_array, solana_latest_blockhash); - if (status != SOL_OK) { - LOG_ERROR("SOL: %d", status); - comm_reject_request(SEND_TXN_PRE_SIGNING_DATA, 0); - reset_flow_level(); - } - flow_level.level_three = SEND_TXN_READ_DEVICE_SHARE_SOLANA; - } - - } break; - - case SEND_TXN_READ_DEVICE_SHARE_SOLANA: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = SEND_TXN_SIGN_TXN_SOLANA; - break; - - case SEND_TXN_SIGN_TXN_SOLANA: { - uint8_t secret[BLOCK_SIZE]; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - ASSERT(mnemo != NULL); - - uint8_t sig[64]; - solana_sig_unsigned_byte_array( - solana_unsigned_txn_byte_array, - solana_unsigned_txn_len, - (const txn_metadata *)&var_send_transaction_data.transaction_metadata, - mnemo, - wallet_credential_data.passphrase, - sig); - transmit_data_to_app(SEND_TXN_SENDING_SIGNED_TXN, sig, 64); - mnemonic_clear(); - memzero(secret, sizeof(secret)); - memzero(wallet_shamir_data.mnemonic_shares, - sizeof(wallet_shamir_data.mnemonic_shares)); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - - flow_level.level_three = SEND_TXN_WAITING_SCREEN_SOLANA; - } break; - - case SEND_TXN_WAITING_SCREEN_SOLANA: - instruction_scr_destructor(); - flow_level.level_three = SEND_TXN_FINAL_SCREEN_SOLANA; - break; - - case SEND_TXN_FINAL_SCREEN_SOLANA: - reset_flow_level(); - break; - - default: - break; - } -} diff --git a/src/level_four/core/controller/sign_message_controller_eth.c b/src/level_four/core/controller/sign_message_controller_eth.c deleted file mode 100644 index 73f1ffe5..00000000 --- a/src/level_four/core/controller/sign_message_controller_eth.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - * @file sign_message_controller_eth.c - * @author Cypherock X1 Team - * @brief Sign message next controller for ETH. - * Handles post event (only next events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "ui_confirmation.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -extern lv_task_t *timeout_task; - -extern MessageData msg_data; -extern ui_display_node *current_display_node; - -void sign_message_controller_eth() { - switch (flow_level.level_three) { - case SIGN_MSG_VERIFY_COIN_ETH: { - uint8_t arr[3] = {0x01, 0x1f, 0x40}; - transmit_data_to_app(SIGN_MSG_RAW_MSG, arr, sizeof(arr)); - flow_level.level_three = SIGN_MSG_RAW_MSG_WAIT_SCREEN_ETH; - eth_init_msg_data( - &msg_data); // initialize variables and decoding functions - } break; - - case SIGN_MSG_RAW_MSG_WAIT_SCREEN_ETH: { - uint8_t *data_array = NULL; - uint16_t msg_size = 0; - if (get_usb_msg_by_cmd_type(SIGN_MSG_RAW_MSG, &data_array, &msg_size)) { - int status = 0; - status = eth_byte_array_to_msg(data_array, msg_size, &msg_data); - - clear_message_received_data(); - flow_level.level_three = SIGN_MSG_DISPLAY_INFO_ETH; - - if (status != 0) { - instruction_scr_destructor(); - mark_error_screen(ui_text_worng_eth_transaction); - comm_reject_request(SIGN_MSG_START, 0); - reset_flow_level(); - } - - // eth_init_display_nodes(¤t_display_node, &msg_data); - ASSERT(current_display_node != NULL); - } - } break; - - case SIGN_MSG_DISPLAY_INFO_ETH: { - if (current_display_node == NULL) - flow_level.level_three = SIGN_MSG_CHECK_PASSPHRASE_ETH; - else - current_display_node = current_display_node->next; - } break; - - case SIGN_MSG_CHECK_PASSPHRASE_ETH: { - instruction_scr_destructor(); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - if (WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = SIGN_MSG_ENTER_PASSPHRASE_ETH; - } else { - flow_level.level_three = SIGN_MSG_CHECK_PIN_ETH; - } - } break; - - case SIGN_MSG_ENTER_PASSPHRASE_ETH: { - flow_level.level_three = SIGN_MSG_CONFIRM_PASSPHRASE_ETH; - } break; - - case SIGN_MSG_CONFIRM_PASSPHRASE_ETH: { - snprintf(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SIGN_MSG_CHECK_PIN_ETH; - } break; - - case SIGN_MSG_CHECK_PIN_ETH: { - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SIGN_MSG_ENTER_PIN_ETH; - } else { - flow_level.level_three = SIGN_MSG_TAP_CARD_ETH; - } - - } break; - - case SIGN_MSG_ENTER_PIN_ETH: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = SIGN_MSG_TAP_CARD_ETH; - } break; - - case SIGN_MSG_TAP_CARD_ETH: { - tap_card_data.desktop_control = true; - tap_threshold_cards_for_reconstruction_flow_controller(1); - } break; - - case SIGN_MSG_TAP_CARD_SEND_CMD_ETH: { - flow_level.level_three = SIGN_MSG_READ_DEVICE_SHARE_ETH; - } break; - - case SIGN_MSG_READ_DEVICE_SHARE_ETH: - wallet_shamir_data.share_x_coords[1] = 5; - get_flash_wallet_share_by_name((const char *)wallet.wallet_name, - wallet_shamir_data.mnemonic_shares[1]); - memcpy(wallet_shamir_data.share_encryption_data[1], - wallet_shamir_data.share_encryption_data[0], - PADDED_NONCE_SIZE + WALLET_MAC_SIZE); - flow_level.level_three = SIGN_MSG_SIGN_TXN_ETH; - break; - - case SIGN_MSG_SIGN_TXN_ETH: { - uint8_t secret[BLOCK_SIZE]; - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - decrypt_shares(); - recover_secret_from_shares(BLOCK_SIZE, - MINIMUM_NO_OF_SHARES, - wallet_shamir_data.mnemonic_shares, - wallet_shamir_data.share_x_coords, - secret); - mnemonic_clear(); - const char *mnemo = - mnemonic_from_data(secret, wallet.number_of_mnemonics * 4 / 3); - ASSERT(mnemo != NULL); - - uint8_t sig[65] = {0}; - - eth_sign_msg_data( - &msg_data, - (const txn_metadata *)&var_send_transaction_data.transaction_metadata, - mnemo, - wallet_credential_data.passphrase, - sig); - transmit_data_to_app(SIGN_MSG_SEND_SIG, sig, 65); - mnemonic_clear(); - memzero(secret, sizeof(secret)); - memzero(wallet_shamir_data.mnemonic_shares, - sizeof(wallet_shamir_data.mnemonic_shares)); - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - - flow_level.level_three = SIGN_MSG_WAITING_SCREEN_ETH; - } break; - - case SIGN_MSG_WAITING_SCREEN_ETH: - instruction_scr_destructor(); - lv_obj_clean(lv_scr_act()); - flow_level.level_three = SIGN_MSG_FINAL_SCREEN_ETH; - break; - - case SIGN_MSG_FINAL_SCREEN_ETH: - reset_flow_level(); - break; - - default: - break; - } -} diff --git a/src/level_four/core/controller/sign_messgae_controller_b_eth.c b/src/level_four/core/controller/sign_messgae_controller_b_eth.c deleted file mode 100644 index c4709fc0..00000000 --- a/src/level_four/core/controller/sign_messgae_controller_b_eth.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file sign_message_controller_b_eth.c - * @author Cypherock X1 Team - * @brief back controller for ETH. - * Handles post event (only back/cancel events) operations for send - *transaction flow initiated by desktop app. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "controller_level_four.h" - -extern Wallet_credential_data wallet_credential_data; -void sign_message_controller_b_eth() { - switch (flow_level.level_three) { - case SIGN_MSG_VERIFY_COIN_ETH: { - comm_reject_request(SIGN_MSG_START, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SIGN_MSG_DISPLAY_INFO_ETH: { - comm_reject_request(SIGN_MSG_START, 0); - reset_flow_level(); - counter.next_event_flag = true; - } break; - - case SIGN_MSG_ENTER_PIN_ETH: { - comm_reject_request(USER_REJECT_PIN_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SIGN_MSG_ENTER_PASSPHRASE_ETH: { - comm_reject_request(USER_REJECTED_PASSPHRASE_INPUT, 0); - reset_flow_level(); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - counter.next_event_flag = true; - } break; - - case SIGN_MSG_CONFIRM_PASSPHRASE_ETH: { - memzero(wallet_credential_data.passphrase, - sizeof(wallet_credential_data.passphrase)); - flow_level.level_three = SIGN_MSG_ENTER_PASSPHRASE_ETH; - } break; - - default: - break; - } -} \ No newline at end of file diff --git a/src/level_four/core/controller/verify_wallet_controller.c b/src/level_four/core/controller/verify_wallet_controller.c deleted file mode 100644 index 875fd514..00000000 --- a/src/level_four/core/controller/verify_wallet_controller.c +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file verify_wallet_controller.c - * @author Cypherock X1 Team - * @brief Verify wallet next controller. - * Handles post event (only next events) operations for verify wallet - *flow - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "card_action_controllers.h" -#include "card_flow_verify_wallet.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" -#include "flash_api.h" -#include "sha2.h" - -extern Wallet_credential_data wallet_credential_data; - -void verify_wallet_controller() { - switch (flow_level.level_three) { - case VERIFY_WALLET_START: - if (WALLET_IS_PIN_SET(wallet.wallet_info)) - flow_level.level_three = VERIFY_WALLET_PIN_INPUT; - else - flow_level.level_three = VERIFY_WALLET_TAP_CARDS_FLOW; - break; - - case VERIFY_WALLET_PIN_INPUT: - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet_credential_data.password_single_hash); - sha256_Raw(wallet_credential_data.password_single_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = VERIFY_WALLET_TAP_CARDS_FLOW; - break; - - case VERIFY_WALLET_TAP_CARDS_FLOW: - card_flow_verify_wallet(); - break; - - case VERIFY_WALLET_DATA: { - flow_level.level_three = (verify_card_share_data() == 1) - ? VERIFY_WALLET_SUCCESS - : VERIFY_WALLET_DELETE; - } break; - - case VERIFY_WALLET_SUCCESS: - reset_flow_level(); - break; - - case VERIFY_WALLET_DELETE: - mark_error_screen(ui_text_wallet_verification_failed_in_creation); - flow_level.level_three = 1; - break; - - default: - break; - } -} diff --git a/src/level_four/core/controller/verify_wallet_controller_b.c b/src/level_four/core/controller/verify_wallet_controller_b.c deleted file mode 100644 index 4ad05e20..00000000 --- a/src/level_four/core/controller/verify_wallet_controller_b.c +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file verify_wallet_controller_b.c - * @author Cypherock X1 Team - * @brief Verify wallet back controller. - * Handles post event (only back/cancel events) operations for verify - *wallet. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_level_four.h" - -void verify_wallet_controller_b() { - switch (flow_level.level_three) { - case VERIFY_WALLET_DELETE: { - reset_flow_level(); - break; - } - - default: - flow_level.level_three = VERIFY_WALLET_DELETE; - break; - } -} \ No newline at end of file diff --git a/src/level_four/core/controller/wallet_locked_controller.c b/src/level_four/core/controller/wallet_locked_controller.c deleted file mode 100644 index da5ca88a..00000000 --- a/src/level_four/core/controller/wallet_locked_controller.c +++ /dev/null @@ -1,186 +0,0 @@ -/** - * @file wallet_locked_controller.c - * @author Cypherock X1 Team - * @brief Wallet unlock flow controller. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ - -/***************************************************************************** - * INCLUDES - *****************************************************************************/ -#include "card_internal.h" -#include "card_unlock_wallet.h" -#include "card_utils.h" -#include "constant_texts.h" -#include "core_error.h" -#include "nfc.h" -#include "pow.h" -#include "pow_utilities.h" -#include "ui_screens.h" - -/***************************************************************************** - * EXTERN VARIABLES - *****************************************************************************/ - -/***************************************************************************** - * PRIVATE MACROS AND DEFINES - *****************************************************************************/ - -/***************************************************************************** - * PRIVATE TYPEDEFS - *****************************************************************************/ - -/***************************************************************************** - * STATIC FUNCTION PROTOTYPES - *****************************************************************************/ - -/***************************************************************************** - * STATIC VARIABLES - *****************************************************************************/ - -/***************************************************************************** - * GLOBAL VARIABLES - *****************************************************************************/ - -/***************************************************************************** - * STATIC FUNCTIONS - *****************************************************************************/ - -/***************************************************************************** - * GLOBAL FUNCTIONS - *****************************************************************************/ - -card_error_type_e card_unlock_wallet(const Wallet *wallet) { - card_error_type_e result = CARD_OPERATION_DEFAULT_INVALID; - card_operation_data_t card_data = {0}; - - char heading[50] = ""; - uint8_t wallet_index = 0xFF; - ASSERT(SUCCESS == - get_index_by_name((const char *)wallet->wallet_name, &wallet_index)); - - snprintf(heading, - sizeof(heading), - UI_TEXT_TAP_CARD, - decode_card_number(get_wallet_card_locked(wallet_index))); - instruction_scr_init(ui_text_place_card_below, heading); - - card_data.nfc_data.retries = 5; - card_data.nfc_data.init_session_keys = true; - while (1) { - card_data.nfc_data.acceptable_cards = get_wallet_card_locked(wallet_index); - memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); - card_data.nfc_data.tapped_card = 0; - - result = card_initialize_applet(&card_data); - - if (CARD_OPERATION_SUCCESS == card_data.error_type) { - card_data.nfc_data.status = - nfc_verify_challenge(wallet->wallet_name, - get_proof_of_work_nonce(), - wallet->password_double_hash); - - if (card_data.nfc_data.status == SW_NO_ERROR || - card_data.nfc_data.status == SW_WARNING_STATE_UNCHANGED) { - update_wallet_locked_flash((const char *)wallet->wallet_name, false); - buzzer_start(BUZZER_DURATION); - break; - } else { - card_handle_errors(&card_data); - if (POW_SW_CHALLENGE_FAILED == card_data.nfc_data.status) { - uint16_t bits = pow_count_set_bits( - get_wallet_by_index(wallet_index)->challenge.target); - LOG_CRITICAL("ex-pow-tg n: %d", bits); - log_hex_array( - "ex-pow-rn: ", - get_wallet_by_index(wallet_index)->challenge.random_number, - POW_RAND_NUMBER_SIZE); - } - } - } - - 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; - if (CARD_OPERATION_SUCCESS == indicate_card_error(error_msg)) { - // Re-render the instruction screen - instruction_scr_init(ui_text_place_card_below, heading); - continue; - } - } - - /** - * @brief For errors which lead to challenge failure or incorrect pin, we - * have to refetch the challenge which is performed subsequently in the same - * card tap session by the caller from user's perspective, so only for the - * condiion of `CARD_OPERATION_LOCKED_WALLET` we don't sound the buzzer as - * the card tap session has not completed. - */ - if (CARD_OPERATION_LOCKED_WALLET != card_data.error_type) { - buzzer_start(BUZZER_DURATION); - } - - result = handle_wallet_errors(&card_data, wallet); - if (CARD_OPERATION_SUCCESS != result) { - break; - } - - // If control reached here, it is an unrecoverable error, so break - result = card_data.error_type; - break; - } - - nfc_deselect_card(); - return result; -} \ No newline at end of file diff --git a/src/level_four/core/controller/wallet_locked_controller_b.c b/src/level_four/core/controller/wallet_locked_controller_b.c deleted file mode 100644 index e8b1543e..00000000 --- a/src/level_four/core/controller/wallet_locked_controller_b.c +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file wallet_locked_controller_b.c - * @author Cypherock X1 Team - * @brief Wallet unlock next controller. - * Handles post event (only back/cancel events) operations for unlock - *wallet. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_level_four.h" - -// wallet_locked_controller_b -void wallet_locked_controller_b() { - switch (flow_level.level_three) { - case WALLET_LOCKED_MESSAGE: { - reset_flow_level(); - counter.next_event_flag = true; - } break; - case WALLET_LOCKED_ENTER_PIN: { - reset_flow_level(); - counter.next_event_flag = true; - } break; - default: - break; - } -} \ No newline at end of file diff --git a/src/level_four/core/tasks/card_upgrade_tasks.c b/src/level_four/core/tasks/card_upgrade_tasks.c deleted file mode 100644 index 67a72e0c..00000000 --- a/src/level_four/core/tasks/card_upgrade_tasks.c +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file card_upgrade_tasks.c - * @author Cypherock X1 Team - * @brief Card upgrade task. - * This file contains the card upgrade task. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "tasks_level_four.h" -#include "ui_instruction.h" - -extern Flow_level flow_level; -extern Counter counter; -extern Wallet wallet; -void card_upgrade_task() { -#ifdef DEV_BUILD - switch (flow_level.level_three) { - case CARD_UPGRADE_TAP_CARD_MESSAGE: - instruction_scr_init(ui_text_tap_card_to_start, NULL); - mark_event_over(); - break; - - case CARD_UPGRADE_SELECT_CARD: - mark_event_over(); - break; - - case CARD_UPGRADE_FORWARD_MESSAGE: - mark_event_over(); - break; - - default: - break; - } -#endif -} diff --git a/src/level_four/core/tasks/initial_device_provision_tasks.c b/src/level_four/core/tasks/initial_device_provision_tasks.c deleted file mode 100644 index 6381db1d..00000000 --- a/src/level_four/core/tasks/initial_device_provision_tasks.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file initial_device_provision_tasks.c - * @author Cypherock X1 Team - * @brief Device provision task (initial). - * This file contains the implementation of the device provision task - *for initial application. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_level_four.h" -#include "tasks_level_four.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_menu.h" -#include "ui_message.h" - -void task_device_provision() { -#if X1WALLET_INITIAL - switch (flow_level.level_three) { - case GENERATE_PROVSION_DATA: { - ui_text_slideshow_init(ui_text_device_provisioning, 5, 500, false); - mark_event_over(); - } break; - - case PROVISION_STATUS_WAIT: - case PROVISION_SAVE_EXT_KEYS: { - mark_event_over(); - } break; - - case PROVISION_UNSUCCESSFUL: { - lv_obj_clean(lv_scr_act()); - delay_scr_init(ui_text_provision_fail, DELAY_TIME); - } break; - - default: - break; - } -#endif -} \ No newline at end of file diff --git a/src/level_four/core/tasks/receive_transaction_tasks_eth.c b/src/level_four/core/tasks/receive_transaction_tasks_eth.c deleted file mode 100644 index 35d8a8fd..00000000 --- a/src/level_four/core/tasks/receive_transaction_tasks_eth.c +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file receive_transaction_tasks_eth.c - * @author Cypherock X1 Team - * @brief Receive transaction task for ETH. - * This file contains the implementation of the receive transaction - *task for ETH. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "flash_api.h" -#include "harmony.h" -#include "segwit_addr.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_menu.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern Receive_Transaction_Data receive_transaction_data; - -void receive_transaction_tasks_eth() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_ETH: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PASSPHRASE_ETH: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = ADD_COINS_VERIFY; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_ETH: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case RECV_TXN_CHECK_PIN_ETH: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PIN_ETH: { - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - } break; - - case RECV_TXN_TAP_CARD_ETH: { - // TODO: Use tap_threshold_cards_for_reconstruction instead - retrieve_key_from_card(); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_ETH: { - mark_event_over(); - } break; - - case RECV_TXN_READ_DEVICE_SHARE_ETH: { - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_SCREEN_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_ETH: { - mark_event_over(); - } break; - - case RECV_TXN_DISPLAY_ADDR_ETH: { - instruction_scr_destructor(); - char display[70]; - char address_s[sizeof(receive_transaction_data.address)] = { - '0', 'x', '\0'}; - uint64_t chain_id = receive_transaction_data.network_chain_id; - if (chain_id != HARMONY_MAINNET_CHAIN) - byte_array_to_hex_string( - receive_transaction_data.eth_pubkeyhash, - sizeof(receive_transaction_data.eth_pubkeyhash), - address_s + 2, - sizeof(address_s) - 2); - else - bech32_addr_encode(address_s, - "one", - receive_transaction_data.eth_pubkeyhash, - sizeof(receive_transaction_data.eth_pubkeyhash)); - strncpy(receive_transaction_data.address, - address_s, - sizeof(receive_transaction_data.address)); - snprintf(display, sizeof(display), "%s%s", ui_text_20_spaces, address_s); - address_scr_init(ui_text_receive_on, display, true); // add 0x prefix - } break; - - default: - break; - } - - return; -} diff --git a/src/level_four/core/tasks/receive_transaction_tasks_near.c b/src/level_four/core/tasks/receive_transaction_tasks_near.c deleted file mode 100644 index e1dcfb43..00000000 --- a/src/level_four/core/tasks/receive_transaction_tasks_near.c +++ /dev/null @@ -1,247 +0,0 @@ -/** - * @file receive_transaction_tasks_near.c - * @author Cypherock X1 Team - * @brief Receive transaction for NEAR - * This file contains the implementation of the receive transaction for - *NEAR. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "flash_api.h" -#include "near_context.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_menu.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern lv_task_t *timeout_task; - -extern Receive_Transaction_Data receive_transaction_data; - -void receive_transaction_tasks_near() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PASSPHRASE_NEAR: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = ADD_COINS_VERIFY; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_NEAR: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case RECV_TXN_CHECK_PIN_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PIN_NEAR: { - // TODO: Redundant check - if (!WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = RECV_TXN_CHECK_PIN_NEAR; - break; - } - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - } break; - - case RECV_TXN_TAP_CARD_NEAR: { - // TODO: Shorten func name - tap_threshold_cards_for_reconstruction(); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_READ_DEVICE_SHARE_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_SCREEN_NEAR: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_WAIT_FOR_LINK_NEAR: { - instruction_scr_change_text(ui_text_waiting_for_desktop, true); - mark_event_over(); - } break; - - case RECV_TXN_DISPLAY_ACC_NEAR: { - char display[110]; - snprintf(display, - sizeof(display), - "%s%s%s", - ui_text_20_spaces, - ui_text_20_spaces, - receive_transaction_data.near_registered_account); - address_scr_init(ui_text_new_account_id, display, true); - } break; - - case RECV_TXN_DISPLAY_ADDR_NEAR: { - char display[110]; - char heading[20] = {0}; - snprintf(heading, sizeof(heading), "%s", ui_text_receive_on); - char address_s[2 * sizeof(receive_transaction_data.near_pubkey) + 1] = - "ed25519:"; - if (receive_transaction_data.near_account_type == 1) { - if (receive_transaction_data.near_acc_found) { - memcpy(address_s, - receive_transaction_data.near_registered_account, - sizeof(receive_transaction_data.near_registered_account)); - } else { - size_t sz = sizeof(address_s) - 8; - b58enc(address_s + 8, &sz, receive_transaction_data.near_pubkey, 32); - snprintf(heading, sizeof(heading), "%s", ui_text_new_public_key); - } - } else { - byte_array_to_hex_string(receive_transaction_data.near_pubkey, - sizeof(receive_transaction_data.near_pubkey), - address_s, - sizeof(address_s)); - } - snprintf(display, - sizeof(display), - "%s%s%s", - ui_text_20_spaces, - ui_text_20_spaces, - address_s); - - address_scr_init(heading, display, true); - - } break; - - case RECV_TXN_WAIT_FOR_REPLACE_NEAR_SCREEN: { - instruction_scr_init(ui_text_waiting_for_desktop, NULL); - mark_event_over(); - } break; - - case RECV_TXN_WAIT_FOR_REPLACE_NEAR: { - mark_event_over(); - } break; - - case RECV_TXN_SELECT_REPLACE_ACC_NEAR: { - char *acc_id[NEAR_REGISTERED_ACCOUNT_COUNT] = {0}; - - near_deserialize_account_ids(coin_specific_data.coin_data, - NEAR_COIN_DATA_MAX_LEN, - acc_id, - receive_transaction_data.near_acc_count); - - menu_init((const char **)acc_id, - NEAR_REGISTERED_ACCOUNT_COUNT, - ui_text_replace_account, - true); - - } break; - - case RECV_TXN_VERIFY_SAVE_ACC_NEAR: { - receive_transaction_data.near_acc_index = - flow_level.screen_input.list_choice - 1; - - char *acc_id[NEAR_REGISTERED_ACCOUNT_COUNT] = {0}; - - near_deserialize_account_ids(coin_specific_data.coin_data, - NEAR_COIN_DATA_MAX_LEN, - acc_id, - receive_transaction_data.near_acc_count); - - address_scr_init(ui_text_confirm_account, - acc_id[receive_transaction_data.near_acc_index], - false); - - } break; - - case RECV_TXN_FINAL_SCREEN_NEAR: { - // this exists to handle multiple exit points in near's receive flow - mark_event_over(); - } break; - - default: - break; - } - return; -} diff --git a/src/level_four/core/tasks/receive_transaction_tasks_solana.c b/src/level_four/core/tasks/receive_transaction_tasks_solana.c deleted file mode 100644 index cce3b367..00000000 --- a/src/level_four/core/tasks/receive_transaction_tasks_solana.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file receive_transaction_tasks_solana.c - * @author Cypherock X1 Team - * @brief Receive transaction task for SOLANA. - * This file contains the implementation of the receive transaction - *task for SOLANA. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "communication.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "flash_api.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_menu.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern Receive_Transaction_Data receive_transaction_data; - -void receive_transaction_tasks_solana() { - switch (flow_level.level_three) { - case RECV_TXN_FIND_XPUB_SOLANA: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PASSPHRASE_SOLANA: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = ADD_COINS_VERIFY; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - } break; - - case RECV_TXN_CONFIRM_PASSPHRASE_SOLANA: { - char display[65] = {0}; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case RECV_TXN_CHECK_PIN_SOLANA: { - mark_event_over(); - } break; - - case RECV_TXN_ENTER_PIN_SOLANA: { - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - } break; - - case RECV_TXN_TAP_CARD_SOLANA: { - retrieve_key_from_card(); - } break; - - case RECV_TXN_TAP_CARD_SEND_CMD_SOLANA: { - mark_event_over(); - } break; - - case RECV_TXN_READ_DEVICE_SHARE_SOLANA: { - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_SCREEN_SOLANA: { - instruction_scr_init(ui_text_processing, NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case RECV_TXN_DERIVE_ADD_SOLANA: { - mark_event_over(); - } break; - - case RECV_TXN_DISPLAY_ADDR_SOLANA: { - instruction_scr_destructor(); - char display[70] = {0}; - snprintf(display, - sizeof(display), - "%s%s", - ui_text_20_spaces, - receive_transaction_data.solana_address); - address_scr_init(ui_text_receive_on, display, true); - } break; - - default: - break; - } - - return; -} diff --git a/src/level_four/core/tasks/send_transaction_tasks_eth.c b/src/level_four/core/tasks/send_transaction_tasks_eth.c deleted file mode 100644 index ae068545..00000000 --- a/src/level_four/core/tasks/send_transaction_tasks_eth.c +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @file send_transaction_tasks_eth.c - * @author Cypherock X1 Team - * @brief Send transaction for ETH. - * This file contains functions to send transaction for ETH. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_level_four.h" -#include "eth.h" -#include "harmony.h" -#include "math.h" -#include "segwit_addr.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_message.h" -#include "ui_scroll_page.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern lv_task_t *timeout_task; -extern ui_display_node *current_display_node; - -void send_transaction_tasks_eth() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: { - char address[43]; - address[0] = '0'; - address[1] = 'x'; - char top_heading[55]; - char display[70]; - - instruction_scr_destructor(); - byte_array_to_hex_string(eth_unsigned_txn_ptr.to_address, - 20, - address + 2, - sizeof(address) - 2); - snprintf(top_heading, sizeof(top_heading), "%s", ui_text_verify_contract); - snprintf(display, sizeof(display), "%s%s", ui_text_20_spaces, address); - address_scr_init(top_heading, display, true); - } break; - - case SEND_TXN_VERIFY_TXN_NONCE_ETH: { - char nonce_hex_str[ETH_NONCE_SIZE_BYTES * 2 + 1] = {'\0'}; - uint8_t nonce_dec_str[ETH_NONCE_SIZE_BYTES * 3] = {0}; - uint16_t nonce_dec_len = sizeof(nonce_dec_str), nonce_hex_len; - int index, offset; - nonce_hex_len = - byte_array_to_hex_string(eth_unsigned_txn_ptr.nonce, - eth_unsigned_txn_ptr.nonce_size[0], - nonce_hex_str, - sizeof(nonce_hex_str)); - convertbase16tobase10( - nonce_hex_len - 1, nonce_hex_str, nonce_dec_str, nonce_dec_len); - // Loop till 2nd last index; to handle "0" nonce value by generalising for - // 1 digit nonce values - for (index = 0; index < nonce_dec_len - 1; index++) - if (nonce_dec_str[index] != 0) - break; - for (offset = index; index < nonce_dec_len; index++) - nonce_dec_str[index - offset] = nonce_dec_str[index] + '0'; - ASSERT((index > offset) && ((index - offset) < nonce_dec_len)); - nonce_dec_str[index - offset] = '\0'; - instruction_scr_destructor(); - address_scr_init("Verify nonce", (char *)nonce_dec_str, false); - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_ETH: { - instruction_scr_destructor(); - char address[43]; - address[0] = '0'; - address[1] = 'x'; - char top_heading[225]; - uint8_t address_bytes[20]; - char display[70]; - uint64_t chain_id = - var_send_transaction_data.transaction_metadata.network_chain_id; - uint8_t is_harmony_hrp = - var_send_transaction_data.transaction_metadata.is_harmony_address; - - instruction_scr_destructor(); - if (is_harmony_hrp == 0 || (chain_id != HARMONY_MAINNET_CHAIN)) - byte_array_to_hex_string(address_bytes, - sizeof(address_bytes), - address + 2, - sizeof(address) - 2); - else - bech32_addr_encode( - address, "one", address_bytes, sizeof(address_bytes)); - snprintf(top_heading, sizeof(top_heading), "%s", ""); - snprintf(display, sizeof(display), "%s%s", ui_text_20_spaces, address); - address_scr_init(top_heading, display, true); - } break; - - case SEND_TXN_CALCULATE_AMOUNT_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_ETH: { - char amount_string[65] = {'\0'}, amount_decimal_string[30] = {'\0'}; - char display[110] = {'\0'}; - memzero(amount_string, sizeof(amount_string)); - uint8_t len = 0, i = 0, j = 0; - - uint8_t decimal_val_s[ETH_VALUE_SIZE_BYTES * 3] = {0}; - if (sizeof(decimal_val_s) / sizeof(decimal_val_s[0]) > UINT8_MAX) { - LOG_ERROR("0xxx#"); - break; - } - const uint8_t dec_val_len = - sizeof(decimal_val_s) / - sizeof(decimal_val_s[0]); // logbase10(2pow256) roughly equals 78 - convertbase16tobase10(len, amount_string, decimal_val_s, dec_val_len); - bool pre_dec_digit = false, post_dec_digit = false; - uint8_t offset = 0; - log_hex_array("eth value: ", (uint8_t *)amount_string, len); - uint8_t point_index = dec_val_len - 0; - i = 0; - j = dec_val_len - 1; - - while (i <= j) { - if (i == point_index && post_dec_digit) { - if (!pre_dec_digit) { - offset += snprintf(amount_decimal_string + offset, - sizeof(amount_decimal_string) - offset, - "0"); - } - offset += snprintf(amount_decimal_string + offset, - sizeof(amount_decimal_string) - offset, - "."); - } - if (j >= point_index) { - if (!decimal_val_s[j] && !post_dec_digit) { - j--; - } else if (decimal_val_s[j]) { - post_dec_digit = true; - } - } - if (decimal_val_s[i] || i == point_index) { - pre_dec_digit = true; - } - if (pre_dec_digit || decimal_val_s[i]) { - // attach non zero leading value detected or decimal digits till - // j(should be the last non zero decimal digit index). - offset += snprintf(amount_decimal_string + offset, - sizeof(amount_decimal_string) - offset, - "%d", - decimal_val_s[i]); - } - i++; - } - if (!post_dec_digit && !pre_dec_digit) { - snprintf(amount_decimal_string, sizeof(amount_decimal_string) - 1, "0"); - } - - instruction_scr_destructor(); - confirm_scr_init(display); - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_ETH: { - char display[125] = {0}, fee[30] = {0}; - - instruction_scr_destructor(); - eth_get_fee_string(ð_unsigned_txn_ptr, fee, sizeof(fee), ETH_DECIMAL); - snprintf(display, sizeof(display), UI_TEXT_SEND_TXN_FEE, fee, ""); - confirm_scr_init(display); - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_DISPLAY_INFO_ETH: { - instruction_scr_destructor(); - if (current_display_node == NULL) - mark_event_over(); - else - ui_scrollable_page(current_display_node->title, - current_display_node->value, - MENU_SCROLL_HORIZONTAL, - false); - } break; - - case SEND_TXN_ENTER_PASSPHRASE_ETH: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_ETH; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_ETH: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case SEND_TXN_CHECK_PIN_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_ENTER_PIN_ETH: { - if (!WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_CHECK_PIN_ETH; - break; - } - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - - } break; - - case SEND_TXN_TAP_CARD_ETH: { - tap_threshold_cards_for_reconstruction(); - } break; - - case SEND_TXN_TAP_CARD_SEND_CMD_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_READ_DEVICE_SHARE_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_SIGN_TXN_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_WAITING_SCREEN_ETH: { - mark_event_over(); - } break; - - case SEND_TXN_FINAL_SCREEN_ETH: - delay_scr_init(ui_text_exported_signed_transaction_to_desktop, - DELAY_TIME); - CY_Reset_Not_Allow(true); - break; - - default: - break; - } -} diff --git a/src/level_four/core/tasks/send_transaction_tasks_solana.c b/src/level_four/core/tasks/send_transaction_tasks_solana.c deleted file mode 100644 index 874160d6..00000000 --- a/src/level_four/core/tasks/send_transaction_tasks_solana.c +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @file send_transaction_tasks_solana.c - * @author Cypherock X1 Team - * @brief Send transaction for SOLANA. - * This file contains functions to send transaction for SOLANA. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_level_four.h" -#include "int-util.h" -#include "math.h" -#include "solana.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_message.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern lv_task_t *timeout_task; - -void send_transaction_tasks_solana() { - switch (flow_level.level_three) { - case SEND_TXN_VERIFY_COIN_SOLANA: { - instruction_scr_init(ui_text_processing, NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_UNSIGNED_TXN_WAIT_SCREEN_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_UNSIGNED_TXN_RECEIVED_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_VERIFY_CONTRACT_ADDRESS: { - mark_event_over(); - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SOLANA: { - instruction_scr_destructor(); - char address[45] = {0}; - char top_heading[225] = {0}; - char display[70] = {0}; - - instruction_scr_destructor(); - size_t address_size = sizeof(address); - b58enc(address, - &address_size, - solana_unsigned_txn_ptr.instruction.program.transfer - .recipient_account, - SOLANA_ACCOUNT_ADDRESS_LENGTH); - snprintf(top_heading, sizeof(top_heading), "%s", ui_text_verify_address); - snprintf(display, sizeof(display), "%s%s", ui_text_20_spaces, address); - address_scr_init(top_heading, display, true); - } break; - - case SEND_TXN_CALCULATE_AMOUNT_SOLANA: { - instruction_scr_init(ui_text_processing, NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_VERIFY_RECEIPT_AMOUNT_SOLANA: { - char amount_string[40] = {'\0'}, amount_decimal_string[30] = {'\0'}; - char display[110] = {'\0'}; - uint8_t be_lamports[8] = {0}; - int i = 8; - while (i--) - be_lamports[i] = - solana_unsigned_txn_ptr.instruction.program.transfer.lamports >> - 8 * (7 - i); - byte_array_to_hex_string( - be_lamports, 8, amount_string, sizeof(amount_string)); - if (!convert_byte_array_to_decimal_string(16, - solana_get_decimal(), - amount_string, - amount_decimal_string, - sizeof(amount_decimal_string))) - break; - instruction_scr_destructor(); - snprintf(display, - sizeof(display), - UI_TEXT_VERIFY_AMOUNT, - amount_decimal_string, - ""); - confirm_scr_init(display); - } break; - - case SEND_TXN_VERIFY_RECEIPT_FEES_SOLANA: { - char amount_string[40] = {'\0'}, amount_decimal_string[30] = {'\0'}; - char display[110] = {'\0'}; - byte_array_to_hex_string((const uint8_t *)var_send_transaction_data - .transaction_metadata.transaction_fees, - 8, - amount_string, - sizeof(amount_string)); - uint8_t decimal_val_s[32 * 3] = {0}; - - if (sizeof(decimal_val_s) / sizeof(decimal_val_s[0]) > UINT8_MAX) { - LOG_ERROR("0xxx#"); - break; - } - - if (!convert_byte_array_to_decimal_string(16, - solana_get_decimal(), - amount_string, - amount_decimal_string, - sizeof(amount_decimal_string))) - break; - instruction_scr_destructor(); - snprintf(display, - sizeof(display), - UI_TEXT_VERIFY_AMOUNT, - amount_decimal_string, - ""); - confirm_scr_init(display); - } break; - - case SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_ENTER_PASSPHRASE_SOLANA: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = - SEND_TXN_VERIFY_RECEIPT_ADDRESS_SEND_CMD_SOLANA; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - - } break; - - case SEND_TXN_CONFIRM_PASSPHRASE_SOLANA: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case SEND_TXN_CHECK_PIN_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_ENTER_PIN_SOLANA: { - if (!WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SEND_TXN_CHECK_PIN_SOLANA; - break; - } - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - - } break; - - case SEND_TXN_TAP_CARD_SOLANA: { - tap_threshold_cards_for_reconstruction(); - } break; - - case SEND_TXN_TAP_CARD_SEND_CMD_SOLANA: { - instruction_scr_init(ui_text_processing, NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SEND_TXN_UPDATE_BLOCKHASH_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_READ_DEVICE_SHARE_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_SIGN_TXN_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_WAITING_SCREEN_SOLANA: { - mark_event_over(); - } break; - - case SEND_TXN_FINAL_SCREEN_SOLANA: - delay_scr_init(ui_text_exported_signed_transaction_to_desktop, - DELAY_TIME); - CY_Reset_Not_Allow(true); - break; - - default: - break; - } -} diff --git a/src/level_four/core/tasks/sign_message_tasks_eth.c b/src/level_four/core/tasks/sign_message_tasks_eth.c deleted file mode 100644 index 8f25ccac..00000000 --- a/src/level_four/core/tasks/sign_message_tasks_eth.c +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file sign_message_tasks_eth.c - * @author Cypherock X1 Team - * @brief Sign message for ETH. - * This file contains functions to send transaction for ETH. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_level_four.h" -#include "int-util.h" -#include "math.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_message.h" -#include "ui_scroll_page.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -extern lv_task_t *timeout_task; -extern ui_display_node *current_display_node; - -void sign_message_tasks_eth() { - switch (flow_level.level_three) { - case SIGN_MSG_VERIFY_COIN_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SIGN_MSG_RAW_MSG_WAIT_SCREEN_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_DISPLAY_INFO_ETH: { - instruction_scr_destructor(); - if (current_display_node == NULL) - mark_event_over(); - else - ui_scrollable_page(current_display_node->title, - current_display_node->value, - MENU_SCROLL_HORIZONTAL, - false); - } break; - - case SIGN_MSG_CHECK_PASSPHRASE_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_ENTER_PASSPHRASE_ETH: { - if (!WALLET_IS_PASSPHRASE_SET(wallet.wallet_info)) { - flow_level.level_three = SIGN_MSG_CHECK_PIN_ETH; - break; - } - input_text_init(PASSPHRASE, - 26, - ui_text_enter_passphrase, - 0, - DATA_TYPE_PASSPHRASE, - 64); - - } break; - - case SIGN_MSG_CONFIRM_PASSPHRASE_ETH: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_passphrase, display, false); - memzero(display, sizeof(display)); - } break; - - case SIGN_MSG_CHECK_PIN_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_ENTER_PIN_ETH: { - if (!WALLET_IS_PIN_SET(wallet.wallet_info)) { - flow_level.level_three = SIGN_MSG_CHECK_PIN_ETH; - break; - } - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - - } break; - - case SIGN_MSG_TAP_CARD_ETH: { - tap_threshold_cards_for_reconstruction(); - } break; - - case SIGN_MSG_TAP_CARD_SEND_CMD_ETH: { - instruction_scr_init("", NULL); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case SIGN_MSG_READ_DEVICE_SHARE_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_SIGN_TXN_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_WAITING_SCREEN_ETH: { - mark_event_over(); - } break; - - case SIGN_MSG_FINAL_SCREEN_ETH: - delay_scr_init(ui_text_exported_signed_transaction_to_desktop, - DELAY_TIME); - CY_Reset_Not_Allow(true); - break; - - default: - break; - } -} diff --git a/src/level_four/core/tasks/tasks_level_four.h b/src/level_four/core/tasks/tasks_level_four.h deleted file mode 100644 index d3ba89b5..00000000 --- a/src/level_four/core/tasks/tasks_level_four.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file tasks_level_four.h - * @author Cypherock X1 Team - * @brief Header for level four tasks. - * This file contains all the functions prototypes for level four - * tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ -#ifndef TASKS_LEVEL_FOUR_H -#define TASKS_LEVEL_FOUR_H - -#pragma once - -#include "coin_utils.h" -#include "controller_main.h" -#include "eth.h" -#include "tasks.h" - -extern evm_unsigned_txn eth_unsigned_txn_ptr; -extern uint8_t challenge_no[32]; - -/** - * @brief This task is executed for processing and signing unsigned transaction - * of Ethereum. - * @details - * - * @see - * @since v1.0.0 - */ -void send_transaction_tasks_eth(); - -/** - * @brief This task is executed for processing and signing unsigned transaction - * of Ethereum. - * - */ -void sign_message_tasks_eth(); - -/** - * @brief This task is executed for processing and signing unsigned transaction. - */ -void send_transaction_tasks_solana(); - -/** - * @brief This task is executed for generating address using xpub for Ethereum. - * @details - * - * @see - * @since v1.0.0 - */ -void receive_transaction_tasks_eth(); - -/** - * @brief This task is executed for handling near registered accounts and - * generating near implicit account. - * @details - * - * @see - * @since v1.0.0 - */ -void receive_transaction_tasks_near(); - -/** - * @brief This task is executed for generating solana address using the public - * key - * @details - * - * @see - * @since v1.0.0 - */ -void receive_transaction_tasks_solana(); - -/** - * @brief This task is executed for verifying wallet added or restored - * on the device and cards. - * @details - * - * @see - * @since v1.0.0 - */ -void verify_wallet_tasks(); - -/** - * @brief Device provision task handler - * @details - * - * @see - * @since v1.0.0 - */ -void task_device_provision(); - -/** - * @brief This task is executed when the name of a wallet is clicked - * and it is locked. - * @details - * - * @see - * @since v1.0.0 - */ -void wallet_locked_task(); - -/** - * @brief This task is executed for verifying card. - * @details - * - * @see - * @since v1.0.0 - */ -void verify_card_task(); - -/** - * @brief This task is executed for upgrading cards. - * @details - * - * @see - * @since v1.0.0 - */ -void card_upgrade_task(); - -#endif \ No newline at end of file diff --git a/src/level_four/core/tasks/verify_wallet_task.c b/src/level_four/core/tasks/verify_wallet_task.c deleted file mode 100644 index 81018b3b..00000000 --- a/src/level_four/core/tasks/verify_wallet_task.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file verify_wallet_task.c - * @author Cypherock X1 Team - * @brief Verify wallet task. - * This file contains the implementation of the verify wallet task. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip39.h" -#include "controller_main.h" -#include "flash_api.h" -#include "shamir_wrapper.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_list.h" -#include "ui_message.h" -#include "ui_multi_instruction.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -extern Wallet_shamir_data wallet_shamir_data; -extern Wallet_credential_data wallet_credential_data; - -void verify_wallet_tasks() { - switch (flow_level.level_three) { - case VERIFY_WALLET_START: - mark_event_over(); - break; - - case VERIFY_WALLET_PIN_INPUT: - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - break; - - case VERIFY_WALLET_TAP_CARDS_FLOW: - tap_cards_for_verification_flow(); - break; - - case VERIFY_WALLET_DATA: { - instruction_scr_init(ui_text_processing, ""); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - } break; - - case VERIFY_WALLET_SUCCESS: { - instruction_scr_destructor(); - const char *messages[6] = { - ui_text_verification_is_now_complete_messages[0], - ui_text_verification_is_now_complete_messages[1], - ui_text_verification_is_now_complete_messages[2], - ui_text_verification_is_now_complete_messages[4], - ui_text_verification_is_now_complete_messages[5], - NULL}; - uint8_t count = 5; - - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - messages[3] = ui_text_verification_is_now_complete_messages[3]; - messages[4] = ui_text_verification_is_now_complete_messages[4]; - messages[5] = ui_text_verification_is_now_complete_messages[5]; - count = 6; - } - - multi_instruction_init(messages, count, DELAY_LONG_STRING, true); - } break; - - case VERIFY_WALLET_DELETE: - instruction_scr_destructor(); - address_scr_init(ui_text_verification_cancelled, - (char *)ui_text_delete_this_wallet, - false); - break; - - default: - break; - } -} diff --git a/src/level_four/core/tasks/wallet_locked_tasks.c b/src/level_four/core/tasks/wallet_locked_tasks.c deleted file mode 100644 index 1ef6b66d..00000000 --- a/src/level_four/core/tasks/wallet_locked_tasks.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * @file wallet_locked_tasks.c - * @author Cypherock X1 Team - * @brief Wallet unlock task. - * This file contains the implementation of wallet unlock task. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "pow.h" -#include "pow_utilities.h" -#include "tasks_level_four.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_text_slideshow.h" - -extern Flow_level flow_level; -extern Counter counter; -extern Wallet wallet; -extern char *ALPHA_NUMERIC; - -void wallet_locked_task() { - switch (flow_level.level_three) { - case WALLET_LOCKED_MESSAGE: { - char slideshow[2][MAX_NUM_OF_CHARS_IN_A_SLIDE]; - uint8_t wallet_index; - - get_index_by_name((const char *)wallet.wallet_name, &wallet_index); - - convert_secs_to_time(get_wallet_time_to_unlock(wallet_index), - (char *)wallet.wallet_name, - slideshow[0]); - snprintf(slideshow[1], - sizeof(slideshow[1]), - "Multiple incorrect attempts may block %s", - wallet.wallet_name); - char *temp[3] = { - slideshow[0], (char *)ui_text_do_not_detach_device, slideshow[1]}; - ui_text_slideshow_init((const char **)temp, 3, DELAY_TIME, false); - start_proof_of_work_task((const char *)wallet.wallet_name); - - } break; - - case WALLET_LOCKED_ENTER_PIN: - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - break; - - case WALLET_LOCKED_TAP_CARD_FRONTEND: { - Flash_Wallet *flash_wallet; - get_flash_wallet_by_name((const char *)wallet.wallet_name, &flash_wallet); - - char msg[32]; - snprintf(msg, - sizeof(msg), - UI_TEXT_TAP_CARD, - decode_card_number(flash_wallet->challenge.card_locked)); - - instruction_scr_init(msg, NULL); - mark_event_over(); - } break; - - case WALLET_LOCKED_TAP_CARD_BACKEND: - mark_event_over(); - break; - - case WALLET_LOCKED_SUCCESS: { - char msg[50]; - snprintf(msg, - sizeof(msg), - "Correct PIN! %s is now unlocked", - wallet.wallet_name); - delay_scr_init(msg, DELAY_TIME); - } break; - - default: - break; - } -} \ No newline at end of file diff --git a/src/level_four/tap_cards/controller/card_action_controllers.h b/src/level_four/tap_cards/controller/card_action_controllers.h deleted file mode 100644 index 682fbc99..00000000 --- a/src/level_four/tap_cards/controller/card_action_controllers.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @file card_action_controllers.h - * @author Cypherock X1 Team - * @brief Header for card action controllers. - * This file contains the declaration of the card action controllers. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ -#ifndef CONTROLLER_CARD_ACTIONS -#define CONTROLLER_CARD_ACTIONS -#include - -void readback_share_from_card(uint8_t xcor); - -int verify_card_share_data(); - -#endif \ No newline at end of file diff --git a/src/level_four/tap_cards/controller/controller_tap_cards.c b/src/level_four/tap_cards/controller/controller_tap_cards.c deleted file mode 100644 index dcf1c57a..00000000 --- a/src/level_four/tap_cards/controller/controller_tap_cards.c +++ /dev/null @@ -1,305 +0,0 @@ -/** - * @file controller_tap_cards.c - * @author Cypherock X1 Team - * @brief Tap card next controller. - * This file contains the functions to control the tap card next - *controller. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_tap_cards.h" - -#include "app_error.h" -#include "nfc.h" -#include "tasks.h" -#include "ui_instruction.h" - -NFC_connection_data tap_card_data; - -bool tap_card_applet_connection() { - uint8_t acceptable_cards; - tap_card_data.recovery_mode = 0; - if (tap_card_data.desktop_control) { - nfc_set_early_exit_handler(&cy_exit_flow); - CY_Reset_Not_Allow(false); - } else { - nfc_set_early_exit_handler(NULL); - } - if (!tap_card_data.card_absent_retries) { - tap_card_data.card_absent_retries = 100; - } - - while (1) { - if (nfc_select_card() != - STM_SUCCESS) // Stuck here until card is detected - return false; - - instruction_scr_change_text(ui_text_card_detected, true); - - acceptable_cards = tap_card_data.acceptable_cards; - tap_card_data.status = nfc_select_applet(tap_card_data.family_id, - &tap_card_data.acceptable_cards, - NULL, - tap_card_data.card_key_id, - &tap_card_data.recovery_mode); - - /* Card is in recovery mode. This is a critical situation. Instruct user to - * safely recover/export wallets to different set of cards in limited - * attempts. NOTE: Errors such as invalid card & invalid family id have - * higher priority than this. - */ - if (tap_card_data.recovery_mode == 1) - mark_error_screen(ui_critical_card_health_migrate_data); - - /* The tapped_card information should be persistent, as it is used at later - * stage in the flow For example, in the second half of card-verification, - * the card tapped in first half becomes the acceptable card for that half. - * It is the knowledge of previous round of card tapping, hence it's update - * should happen only here or at the fresh start of a card tap flow. */ - tap_card_data.tapped_card = - (acceptable_cards ^ tap_card_data.acceptable_cards); - - if (tap_card_data.status == SW_NO_ERROR) { -#if X1WALLET_MAIN - tap_card_data.keystore_index = - get_paired_card_index(tap_card_data.card_key_id); - if (false) { - tap_card_take_to_pairing(); - return false; - } -#endif - const uint8_t *pairing_key = - get_keystore_pairing_key(tap_card_data.keystore_index); - if (tap_card_data.keystore_index >= 0) - init_session_keys(pairing_key, pairing_key + 32, NULL); - return true; - } else if (tap_card_data.status == SW_CONDITIONS_NOT_SATISFIED) { - mark_error_screen(ui_text_wrong_card_sequence); - } else if (tap_card_data.status == SW_FILE_INVALID) { - mark_error_screen(ui_text_family_id_mismatch); - } else if (tap_card_data.status == SW_FILE_NOT_FOUND) { - mark_error_screen(ui_text_corrupted_card_contact_support); - reset_flow_level(); - } else if (tap_card_data.status == SW_INCOMPATIBLE_APPLET) { - mark_error_screen(ui_text_incompatible_card_version); - reset_flow_level(); - } else { - tap_card_data.tapped_card = 0; - tap_card_data.acceptable_cards = acceptable_cards; - if ((tap_card_data.status == NFC_CARD_ABSENT) || - (nfc_diagnose_card_presence() != 0)) { - instruction_scr_change_text(ui_text_card_removed_fast, true); - if ((!--tap_card_data.card_absent_retries)) { - tap_card_data.status = NFC_CARD_ABSENT; - mark_error_screen(ui_text_card_freq_discon_fault); - } - } else if (!(--tap_card_data.retries)) { - mark_error_screen(ui_text_unknown_error_contact_support); - reset_flow_level(); - } else if ((tap_card_data.status & NFC_ERROR_BASE) == NFC_ERROR_BASE) { - instruction_scr_change_text(ui_text_card_align_with_device_screen, - true); - nfc_deselect_card(); - } - } - LOG_ERROR("err (0x%04X)\n", tap_card_data.status); - - if (flow_level.show_error_screen) { - buzzer_start(BUZZER_DURATION); - if (counter.level != - LEVEL_ONE) { // flow not reset, we wanna retry after prompting user - flow_level.level_three = tap_card_data.lvl3_retry_point; - flow_level.level_four = tap_card_data.lvl4_retry_point; - } else { // flow is reset, convey to desktop if needed - if (tap_card_data.desktop_control) - comm_reject_request(tap_card_data.active_cmd_type, 0); - } - instruction_scr_destructor(); - return false; - } - } -} - -bool tap_card_handle_applet_errors() { - LOG_ERROR("err (0x%04X)\n", tap_card_data.status); - switch (tap_card_data.status) { - case SW_NO_ERROR: - return true; - case SW_SECURITY_CONDITIONS_NOT_SATISFIED: - mark_error_screen(ui_text_security_conditions_not_met); - reset_flow_level(); - break; - case SW_NOT_PAIRED: - invalidate_keystore(); - tap_card_take_to_pairing(); - return true; - case SW_CONDITIONS_NOT_SATISFIED: - break; - case SW_WRONG_DATA: - mark_error_screen(ui_text_card_invalid_apdu_length); - reset_flow_level(); - break; - case SW_FILE_FULL: - mark_error_screen(ui_text_card_is_full); - reset_flow_level(); - break; - case SW_RECORD_NOT_FOUND: - tap_card_data.active_cmd_type = WALLET_DOES_NOT_EXISTS_ON_CARD; - mark_error_screen(ui_text_wallet_doesnt_exists_on_this_card); - reset_flow_level(); - break; - case SW_TRANSACTION_EXCEPTION: - mark_error_screen(ui_text_card_transaction_exception); - reset_flow_level(); - break; - case SW_NULL_POINTER_EXCEPTION: - mark_error_screen(ui_text_card_null_pointer_exception); - reset_flow_level(); - break; - case SW_OUT_OF_BOUNDARY: - mark_error_screen(ui_text_card_out_of_boundary_exception); - reset_flow_level(); - break; - case SW_INVALID_INS: - mark_error_screen(ui_text_card_error_contact_support); - reset_flow_level(); - break; - case SW_INS_BLOCKED: - mark_error_screen(ui_critical_card_health_migrate_data); - reset_flow_level(); - break; - default: - if ((tap_card_data.status & 0xFF00) == POW_SW_WALLET_LOCKED) { - uint8_t target[SHA256_SIZE], random_number[POW_RAND_NUMBER_SIZE]; - - tap_card_data.status = - nfc_get_challenge(wallet.wallet_name, target, random_number); - - mark_error_screen(ui_text_wrong_wallet_is_now_locked); - // if (tap_card_data.status == SW_NO_ERROR) - // add_challenge_flash((const char *)wallet.wallet_name, - // target, - // random_number, - // tap_card_data.tapped_card); - tap_card_data.lvl3_retry_point = WALLET_LOCKED_MESSAGE; - flow_level.level_one = LEVEL_TWO_OLD_WALLET; - flow_level.level_two = LEVEL_THREE_WALLET_LOCKED; - decrease_level_counter(); - if (tap_card_data.desktop_control) { - comm_reject_request(WALLET_IS_LOCKED, 0); - CY_Set_External_Triggered(false); - } - } else if ((tap_card_data.status & 0xFF00) == SW_CORRECT_LENGTH_00) { - char error_text[40]; - snprintf(error_text, - sizeof(error_text), - "Incorrect PIN!\n%d attempt(s) remaining", - tap_card_data.status & 0xFF); - mark_error_screen(error_text); - tap_card_data.lvl3_retry_point = flow_level.level_three - 1; - tap_card_data.lvl4_retry_point = 1; - } else if ((tap_card_data.status & 0xFF00) == SW_CRYPTO_EXCEPTION) { - mark_error_screen(ui_text_card_crypto_exception); - reset_flow_level(); - } else { - tap_card_data.tapped_card = 0; - if ((tap_card_data.status == NFC_CARD_ABSENT) || - (nfc_diagnose_card_presence() != 0)) { - instruction_scr_change_text(ui_text_card_removed_fast, true); - if ((!--tap_card_data.card_absent_retries)) { - tap_card_data.status = NFC_CARD_ABSENT; - mark_error_screen(ui_text_card_freq_discon_fault); - } - } else if (!(--tap_card_data.retries)) { - mark_error_screen(ui_text_unknown_error_contact_support); - reset_flow_level(); - } else if ((tap_card_data.status & NFC_ERROR_BASE) == NFC_ERROR_BASE) { - instruction_scr_change_text(ui_text_card_align_with_device_screen, - true); - nfc_deselect_card(); - } - } - break; - } - - if (flow_level.show_error_screen) { - buzzer_start(BUZZER_DURATION); - if (counter.level != - LEVEL_ONE) { // flow not reset, we want to retry after prompting user - flow_level.level_three = tap_card_data.lvl3_retry_point; - flow_level.level_four = tap_card_data.lvl4_retry_point; - } else { // flow is reset, convey to desktop if needed - if (tap_card_data.desktop_control) - comm_reject_request(tap_card_data.active_cmd_type, 0); - } - instruction_scr_destructor(); - return true; - } - - // probably comm failure; guess is NFC teardown; reconnect with applet - // silently retry to connect; can't connect here, cards_state is important - return false; -} - -void tap_card_take_to_pairing() { -#if X1WALLET_MAIN - buzzer_start(BUZZER_DURATION); - mark_error_screen(ui_text_device_and_card_not_paired); - reset_flow_level(); - counter.level = LEVEL_THREE; - flow_level.level_one = LEVEL_TWO_ADVANCED_SETTINGS; - if (tap_card_data.desktop_control) - comm_reject_request(tap_card_data.active_cmd_type, 0); - instruction_scr_destructor(); -#endif -} diff --git a/src/level_four/tap_cards/controller/controller_tap_cards.h b/src/level_four/tap_cards/controller/controller_tap_cards.h deleted file mode 100644 index 78228113..00000000 --- a/src/level_four/tap_cards/controller/controller_tap_cards.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file controller_tap_cards.h - * @author Cypherock X1 Team - * @brief Header for tap card controllers. - * This file contains the declaration of the tap card controllers. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef CONTROLLER_TAP_CARDS_H -#define CONTROLLER_TAP_CARDS_H - -#include "buzzer.h" -#include "controller_main.h" -#include "nfc.h" -#include "sha2.h" -#include "stdbool.h" - -/** - * @brief - * @details - * - * @see - * @since v1.0.0 - * - * @note - */ -typedef struct NFC_connection_data { - uint8_t desktop_control; // TODO: Remove deprecated - uint8_t active_cmd_type; // TODO: Remove deprecated - int8_t keystore_index; - uint8_t acceptable_cards; - uint8_t tapped_card; - uint8_t lvl3_retry_point; // TODO: Remove deprecated - uint8_t lvl4_retry_point; // TODO: Remove deprecated - uint8_t resume_point; // TODO: Remove deprecated - uint8_t retries; - uint8_t family_id[FAMILY_ID_SIZE + - 2]; // TODO: Review(need to find reason for extra byte) - uint8_t card_key_id[4]; - bool pairing_error; - uint8_t recovery_mode; - uint8_t card_absent_retries; - uint8_t *card_version; - bool init_session_keys; - ISO7816 status; -} NFC_connection_data; - -extern NFC_connection_data tap_card_data; - -/** - * @brief Identifies a JavaCard in the field and triggers handshake and X1 - * Applet invocation. - * @details The function handles the JavaCard identification and handshake with - * the X1 Applet. It also identifies certain states of the card and triggers the - * appropriate action if possible. Other critical errors are handled and - * reported in the UI.
This function is responsible for initializing the - * NFC SecureChannel session with the appropriate IV and key.
For scenarios - * like using a X1 Card from a different set or not using the requested card, - * the function informs the user about the situation and continues to retry. - * This happens without any limit on the retry attempts.
If the X1 Card is - * absent right after the handshake, then the user is asked to tap and hold till - * a feedback is received from the buzzer. - * - * @return bool true, false - * @retval true if the card is identified and the handshake is successful. - * @retval false if the card is not identified or the handshake fails. - * - * @see NFC_connection_data, nfc_select_card(), nfc_select_applet(), - * tap_card_handle_applet_errors() - * @since v1.0.0 - * - * @note The tap_card_data structure needs to be initialized accordingly before - * calling this function. - */ -bool tap_card_applet_connection(); - -/** - * @brief A common handler for the X1 Applet and the NFC communication errors. - * @details This is a one place error handler. The application can make a call - * to this for handling the errors, if the application does not receive an - * expected response from the X1 Applet.
The function checks the status - * member of tap_card_data for the error code. This function is supposed to be - * called after making a call to any of the nfc functions. Based on the status, - * the function performs the appropriate action which can be either displaying - * a message to the user, or exiting the process, or retrying or a combination - * of these.
For certain types of errors, the function decrements its retry - * counter. If the counter is zero, then the function exits the process and the - * non-critical error is now considered as critical which is indicated by true. - * - * @return boolean true, false - * @retval true if the error is handled. Application need not retry. - * @retval false if the error is not critical. Application can retry right away. - * - * @see NFC_connection_data, nfc_select_card(), nfc_select_applet(), - * tap_card_applet_connection() - * @since v1.0.0 - * - * @note The tap_card_data structure should be used to store the errors. - * Otherwise the behavior is undefined. - */ -bool tap_card_handle_applet_errors(); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_cards_for_write_and_verify_flow_controller(); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_threshold_cards_for_reconstruction_flow_controller(uint8_t threshold); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void delete_from_cards_controller(); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void controller_update_card_id(); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void retrieve_key_from_card_flow_controller(); - -/** - * @brief - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_card_take_to_pairing(); - -#endif diff --git a/src/level_four/tap_cards/controller/retrieve_key_from_card_controllers.c b/src/level_four/tap_cards/controller/retrieve_key_from_card_controllers.c deleted file mode 100644 index eadf4287..00000000 --- a/src/level_four/tap_cards/controller/retrieve_key_from_card_controllers.c +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file retrieve_key_from_card_controllers.c - * @author Cypherock X1 Team - * @brief Retrieve key from card. - * This file contains the functions to retrieve the key from the card. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "apdu.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "flash_api.h" -#include "nfc.h" -#include "tasks.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern int error_occurred_remaining_tries; -extern Wallet_shamir_data wallet_shamir_data; - -static void _tap_card_backend(uint8_t xcor); -static void _handle_retrieve_wallet_success(uint8_t xcor); - -void retrieve_key_from_card_flow_controller() { - switch (flow_level.level_four) { - case TAP_CARD_ONE_FRONTEND: - tap_card_data.tapped_card = 0; - flow_level.level_four = TAP_CARD_ONE_BACKEND; - break; - - case TAP_CARD_ONE_BACKEND: - _tap_card_backend(0); - break; - default: - break; - } -} - -static void _tap_card_backend(uint8_t xcor) { - tap_card_data.retries = 5; - - while (!CY_Read_Reset_Flow()) { - tap_card_data.acceptable_cards = 15; - memcpy(tap_card_data.family_id, get_family_id(), FAMILY_ID_SIZE); - tap_card_data.lvl3_retry_point = flow_level.level_three; - tap_card_data.lvl4_retry_point = flow_level.level_four - 1; - if (xcor == 0) - tap_card_data.tapped_card = 0; - if (!tap_card_applet_connection()) - return; - tap_card_data.status = nfc_retrieve_wallet(&wallet); - - if (tap_card_data.status == SW_NO_ERROR) { - _handle_retrieve_wallet_success(xcor); - buzzer_start(BUZZER_DURATION); - instruction_scr_destructor(); - break; - } else if (tap_card_handle_applet_errors()) { - break; - } - } -} - -static void _handle_retrieve_wallet_success(uint8_t xcor) { - memcpy(wallet_shamir_data.mnemonic_shares[xcor], - wallet.wallet_share_with_mac_and_nonce, - BLOCK_SIZE); - memzero(wallet.wallet_share_with_mac_and_nonce, - sizeof(wallet.wallet_share_with_mac_and_nonce)); - - wallet_shamir_data.share_x_coords[xcor] = wallet.xcor; - - flow_level.level_three++; - flow_level.level_four = 1; -} diff --git a/src/level_four/tap_cards/controller/tap_one_card_controllers.c b/src/level_four/tap_cards/controller/tap_one_card_controllers.c deleted file mode 100644 index d9422f5a..00000000 --- a/src/level_four/tap_cards/controller/tap_one_card_controllers.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file tap_one_card_controllers.c - * @author Cypherock X1 Team - * @brief Tap one card controller. - * This file contains the implementation of the tap one card - *controllers. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "apdu.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "flash_api.h" -#include "nfc.h" -#include "pow_utilities.h" -#include "tasks.h" -#include "ui_delay.h" -#include "ui_instruction.h" -#include "utils.h" - -void controller_update_card_id() { - switch (flow_level.level_three) { - case 1: - flow_level.level_three++; - break; - - case 2: - flow_level.level_three++; - break; - - case 3: { - uint8_t send_apdu[10] = {0x00, 0xC7, 0x00, 0x00, 0x05}; - hex_string_to_byte_array( - flow_level.screen_input.input_text, 2 * CARD_ID_SIZE, send_apdu + 5); - - uint8_t recv_apdu[255]; - uint16_t recv_len = 236; - while (1) { - // todo log - nfc_select_card(); // Stuck here until card is detected - // todo log - uint8_t no_restrictions[6] = {DEFAULT_VALUE_IN_FLASH, - DEFAULT_VALUE_IN_FLASH, - DEFAULT_VALUE_IN_FLASH, - DEFAULT_VALUE_IN_FLASH}; - uint8_t all_cards = 15; - nfc_select_applet(no_restrictions, &all_cards, NULL, NULL, NULL); - - if (nfc_exchange_apdu( - send_apdu, sizeof(send_apdu), recv_apdu, &recv_len) == - STM_SUCCESS) { - flow_level.level_three++; - break; - } - } - lv_obj_clean(lv_scr_act()); - } break; - case 4: - reset_flow_level(); - break; - default: - break; - } -} diff --git a/src/level_four/tap_cards/tasks/reconstruct_from_four_cards_to_verify_tasks.c b/src/level_four/tap_cards/tasks/reconstruct_from_four_cards_to_verify_tasks.c deleted file mode 100644 index a03f3c14..00000000 --- a/src/level_four/tap_cards/tasks/reconstruct_from_four_cards_to_verify_tasks.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file reconstruct_from_four_cards_to_verify_tasks.c - * @author Cypherock X1 Team - * @brief Reconstruct from all cards. - * This file contains the implementation of the function to perform the - * reconstruction of the secret from the four shares of the cards. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_main.h" -#include "stdint.h" -#include "tasks.h" -#include "tasks_tap_cards.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -void tap_cards_for_verification_flow() { - char display[40]; - - switch (flow_level.level_four) { - case TAP_CARD_ONE_FRONTEND: - case TAP_CARD_TWO_FRONTEND: - case TAP_CARD_THREE_FRONTEND: - case TAP_CARD_FOUR_FRONTEND: - snprintf(display, - sizeof(display), - UI_TEXT_TAP_CARD, - ((flow_level.level_four - 1) >> 1) + 1); - instruction_scr_init(ui_text_place_card_below, display); - mark_event_over(); - break; - - case TAP_CARD_ONE_BACKEND: - case TAP_CARD_TWO_BACKEND: - case TAP_CARD_THREE_BACKEND: - case TAP_CARD_FOUR_BACKEND: - mark_event_over(); - break; - - default: - message_scr_init(ui_text_something_went_wrong); - break; - } -} diff --git a/src/level_four/tap_cards/tasks/reconstruct_from_threshold_cards_tasks.c b/src/level_four/tap_cards/tasks/reconstruct_from_threshold_cards_tasks.c deleted file mode 100644 index 07837e5d..00000000 --- a/src/level_four/tap_cards/tasks/reconstruct_from_threshold_cards_tasks.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file reconstruct_from_threshold_cards_tasks.c - * @author Cypherock X1 Team - * @brief Reconstruct from threshold. - * Short description of the file - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_main.h" -#include "tasks.h" -#include "tasks_tap_cards.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -void tap_threshold_cards_for_reconstruction() { -} diff --git a/src/level_four/tap_cards/tasks/retrieve_key_from_card_tasks.c b/src/level_four/tap_cards/tasks/retrieve_key_from_card_tasks.c deleted file mode 100644 index f1f8c455..00000000 --- a/src/level_four/tap_cards/tasks/retrieve_key_from_card_tasks.c +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file retrieve_key_from_card_tasks.c - * @author Cypherock X1 Team - * @brief Retrieve key task. - * This file contains the retrieve key task. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_main.h" -#include "tasks.h" -#include "tasks_tap_cards.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -void retrieve_key_from_card() { - switch (flow_level.level_four) { - case TAP_CARD_ONE_FRONTEND: - instruction_scr_init(ui_text_tap_1_2_cards, NULL); - mark_event_over(); - break; - - case TAP_CARD_ONE_BACKEND: - mark_event_over(); - break; - - default: - break; - } -} diff --git a/src/level_four/tap_cards/tasks/tap_one_card_tasks.c b/src/level_four/tap_cards/tasks/tap_one_card_tasks.c deleted file mode 100644 index ebe34e50..00000000 --- a/src/level_four/tap_cards/tasks/tap_one_card_tasks.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file tap_one_card_tasks.c - * @author Cypherock X1 Team - * @brief Tap one card task. - * This file contains the implementation of the tap one card tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "apdu.h" -#include "buzzer.h" -#include "communication.h" -#include "constant_texts.h" -#include "controller_main.h" -#include "flash_api.h" -#include "flash_if.h" -#include "nfc.h" -#include "pow_utilities.h" -#include "tasks.h" -#include "tasks_tap_cards.h" -#include "ui_delay.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_message.h" -#include "utils.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *HEX; - -void tasks_update_card_id() { - switch (flow_level.level_three) { - case 1: { - input_text_init(HEX, 0, ui_text_family_id_hex, 10, DATA_TYPE_TEXT, 8); - } - - break; - - case 2: { - instruction_scr_init(ui_text_tap_a_card, NULL); - mark_event_over(); - } break; - - case 3: { - mark_event_over(); - } break; - - case 4: - message_scr_init(ui_text_successfull); - break; - - default: - break; - } -} diff --git a/src/level_four/tap_cards/tasks/tasks_tap_cards.h b/src/level_four/tap_cards/tasks/tasks_tap_cards.h deleted file mode 100644 index e9b8fe66..00000000 --- a/src/level_four/tap_cards/tasks/tasks_tap_cards.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file tasks_tap_cards.h - * @author Cypherock X1 Team - * @brief Header for tap card tasks. - * This file contains all the functions prototypes for the tap card - * tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef TASKS_TAP_CARDS_H -#define TASKS_TAP_CARDS_H - -/** - * @brief Task for writing on the card flow , used to add wallet or restore - * wallet on cards - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_cards_for_write_flow(); - -/** - * @brief Task for verification of the card - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_cards_for_verification_flow(); - -/** - * @brief Task to retrieve wallet from card - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tap_threshold_cards_for_reconstruction(); - -/** - * @brief Task to update card id - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void tasks_update_card_id(); - -/** - * @brief Task to retrieve key from id - * @details - * - * @param - * - * @return - * @retval - * - * @see - * @since v1.0.0 - * - * @note - */ -void retrieve_key_from_card(); - -#endif \ No newline at end of file diff --git a/src/level_four/tap_cards/tasks/write_to_cards_tasks.c b/src/level_four/tap_cards/tasks/write_to_cards_tasks.c deleted file mode 100644 index 12f1a290..00000000 --- a/src/level_four/tap_cards/tasks/write_to_cards_tasks.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file write_to_cards_tasks.c - * @author Cypherock X1 Team - * @brief Write to cards. - * This file contains the task handler to write to cards. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_main.h" -#include "flash_api.h" -#include "nfc.h" -#include "stdint.h" -#include "tasks.h" -#include "tasks_tap_cards.h" -#include "ui_instruction.h" -#include "ui_message.h" - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -void tap_cards_for_write_flow() { - switch (flow_level.level_four) { - case CARD_ONE_FRONTEND: - case CARD_TWO_FRONTEND: - case CARD_THREE_FRONTEND: - case CARD_FOUR_FRONTEND: { - char display[40]; - snprintf(display, - sizeof(display), - UI_TEXT_TAP_CARD, - ((flow_level.level_four - 1) / 3) + 1); - instruction_scr_init(ui_text_place_card_below, display); - mark_event_over(); - } break; - - case CARD_ONE_READBACK: - case CARD_TWO_READBACK: - case CARD_THREE_READBACK: - case CARD_FOUR_READBACK: { - char display[40]; - instruction_scr_destructor(); - snprintf(display, - sizeof(display), - UI_TEXT_TAP_CARD, - flow_level.level_four / 3); - instruction_scr_init(ui_text_place_card_below, display); - if (nfc_wait_for_card(DEFAULT_NFC_TG_INIT_TIME) != STM_SUCCESS) - instruction_scr_change_text(ui_text_card_removed_fast, true); - } - case CARD_ONE_WRITE: - case CARD_TWO_WRITE: - case CARD_THREE_WRITE: - case CARD_FOUR_WRITE: - mark_event_over(); - break; - - default: - LOG_CRITICAL("xx30"); - reset_flow_level(); - message_scr_init(ui_text_something_went_wrong); - break; - } -} diff --git a/src/level_three/add_wallet/controller/controller_add_wallet.h b/src/level_three/add_wallet/controller/controller_add_wallet.h deleted file mode 100644 index 3992d6e7..00000000 --- a/src/level_three/add_wallet/controller/controller_add_wallet.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file controller_add_wallet.h - * @author Cypherock X1 Team - * @brief Header for add wallet controllers. - * Houses the declarations of controllers for add wallet tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef CONTROLLER_ADD_WALLET_H -#define CONTROLLER_ADD_WALLET_H - -#include "controller_main.h" - -/** - * @brief Controller to add arbitrary data wallet flow - * @details - * - * @see - * @since v1.0.0 - */ -void arbitrary_data_controller(); - -/** - * @brief Back button controller for arbitrary data wallet flow - * @details - * - * @see - * @since v1.0.0 - */ -void arbitrary_data_controller_b(); - -#endif \ No newline at end of file diff --git a/src/level_three/add_wallet/controller/controller_arbitrary_data.c b/src/level_three/add_wallet/controller/controller_arbitrary_data.c deleted file mode 100644 index 7d328f13..00000000 --- a/src/level_three/add_wallet/controller/controller_arbitrary_data.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * @file controller_arbitrary_data.c - * @author Cypherock X1 Team - * @brief Arbitrary data next controller. - * Handles post event (only next events) operations for arbitrary data - *flow. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "bip39.h" -#include "card_action_controllers.h" -#include "card_flow_create_wallet.h" -#include "constant_texts.h" -#include "controller_add_wallet.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "sha2.h" -#include "shamir_wrapper.h" -#include "tasks.h" -#include "ui_message.h" -#include "wallet_utilities.h" - -extern Wallet_credential_data wallet_credential_data; -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; - -extern Flash_Wallet wallet_for_flash; -extern char arbitrary_data[4096 / 8 + 1]; - -#ifdef USE_ARBITRARY_DATA -static void restore_wallet_enter_mnemonics_flow_controller() { - if (flow_level.level_four <= wallet.number_of_mnemonics) { - snprintf( - wallet_credential_data.mnemonics[flow_level.level_four - 1], - sizeof(wallet_credential_data.mnemonics[flow_level.level_four - 1]), - "%s", - mnemonic_get_word(flow_level.screen_input.list_choice)); - flow_level.level_four++; - } else { - flow_level.level_three++; - } -} -#endif - -void arbitrary_data_controller() { - switch (flow_level.level_three) { - case ARBITRARY_DATA_NAME_INPUT: { - flow_level.level_three = ARBITRARY_DATA_NAME_CONFIRM; - } break; - case ARBITRARY_DATA_NAME_CONFIRM: { - uint8_t dummy; - if (get_index_by_name(flow_level.screen_input.input_text, &dummy) == - SUCCESS_) { - // wallet already exists - mark_error_screen(ui_text_wallet_name_exists); - } else { - flow_level.level_three = RESTORE_WALLET_PIN_INSTRUCTIONS_1; - snprintf((char *)wallet_for_flash.wallet_name, - sizeof(wallet_for_flash.wallet_name), - "%s", - flow_level.screen_input.input_text); - snprintf((char *)wallet.wallet_name, - sizeof(wallet.wallet_name), - "%s", - flow_level.screen_input.input_text); - } - } break; - case RESTORE_WALLET_PIN_INSTRUCTIONS_1: { - flow_level.level_three = RESTORE_WALLET_PIN_INSTRUCTIONS_2; - } break; - - case RESTORE_WALLET_PIN_INSTRUCTIONS_2: { - flow_level.level_three = ARBITRARY_DATA_SKIP_PIN; - } break; - - case ARBITRARY_DATA_SKIP_PIN: { - flow_level.level_three = ARBITRARY_DATA_PIN_INPUT; - WALLET_SET_PIN(wallet_for_flash.wallet_info); - WALLET_SET_PIN(wallet.wallet_info); - } break; - - case ARBITRARY_DATA_PIN_INPUT: { - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - wallet.password_double_hash); - sha256_Raw(wallet.password_double_hash, - SHA256_DIGEST_LENGTH, - wallet.password_double_hash); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - flow_level.level_three = ARBITRARY_DATA_PIN_CONFIRM; - } break; - - case ARBITRARY_DATA_PIN_CONFIRM: { - uint8_t CONFIDENTIAL temp[SHA256_DIGEST_LENGTH] = {0}; - - ASSERT(temp != NULL); - sha256_Raw((uint8_t *)flow_level.screen_input.input_text, - strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)), - temp); - sha256_Raw(temp, SHA256_DIGEST_LENGTH, temp); - if (memcmp(wallet.password_double_hash, temp, SHA256_DIGEST_LENGTH) == - 0) { - flow_level.level_three = ARBITRARY_DATA_ENTER_DATA_INSTRUCTION; - } else { - mark_error_screen(ui_text_pin_incorrect_re_enter); - flow_level.level_three = ARBITRARY_DATA_PIN_INPUT; - } - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - memzero(temp, sizeof(temp)); - } break; - - case ARBITRARY_DATA_ENTER_DATA_INSTRUCTION: { - flow_level.level_three = ARBITRARY_DATA_ENTER_DATA; - - } break; - - case ARBITRARY_DATA_ENTER_DATA: { - flow_level.level_three = ARBITRARY_DATA_CONFIRM_DATA; - } break; - - case ARBITRARY_DATA_CONFIRM_DATA: { - flow_level.level_three = ARBITRARY_DATA_CREATING_WAIT_SCREEN; - } break; - - case ARBITRARY_DATA_CREATING_WAIT_SCREEN: { - flow_level.level_three = ARBITRARY_DATA_CREATE; - } break; - - case ARBITRARY_DATA_CREATE: { - uint8_t wallet_index, temp_wallet_id[WALLET_ID_SIZE]; - - sha256_Raw((const uint8_t *)arbitrary_data, - strnlen(arbitrary_data, sizeof(arbitrary_data)), - temp_wallet_id); - sha256_Raw(temp_wallet_id, SHA256_DIGEST_LENGTH, temp_wallet_id); - - if ((get_first_matching_index_by_id(temp_wallet_id, &wallet_index) == - DOESNT_EXIST)) { - memcpy(wallet_for_flash.wallet_id, temp_wallet_id, WALLET_ID_SIZE); - memcpy(wallet.wallet_id, wallet_for_flash.wallet_id, WALLET_ID_SIZE); - wallet.arbitrary_data_size = - strnlen(arbitrary_data, sizeof(arbitrary_data)); - WALLET_SET_ARBITRARY_DATA(wallet.wallet_info); - WALLET_SET_ARBITRARY_DATA(wallet_for_flash.wallet_info); - - convert_to_shares(wallet.arbitrary_data_size, - (uint8_t *)arbitrary_data, - wallet.total_number_of_shares, - wallet.minimum_number_of_shares, - wallet_shamir_data.arbitrary_data_shares); - memzero(arbitrary_data, sizeof(arbitrary_data)); - flow_level.level_three = ARBITRARY_DATA_TAP_CARDS; - flow_level.level_four = 1; - flow_level.level_five = 1; - } else { - mark_error_screen(ui_text_wallet_with_same_mnemo_exists); - flow_level.level_three = ARBITRARY_DATA_ENTER_DATA_INSTRUCTION; - flow_level.level_four = 1; - flow_level.level_five = 1; - } - } break; - - case ARBITRARY_DATA_TAP_CARDS: - card_flow_create_wallet(); - break; - - case ARBITRARY_DATA_VERIFY_SHARES: - flow_level.level_three = verify_card_share_data() == 1 - ? ARBITRARY_DATA_SUCCESS_MESSAGE - : ARBITRARY_DATA_FAILED_MESSAGE; - memzero(wallet.password_double_hash, sizeof(wallet.password_double_hash)); - memzero(wallet.wallet_share_with_mac_and_nonce, - sizeof(wallet.wallet_share_with_mac_and_nonce)); - memzero(wallet.arbitrary_data_share, sizeof(wallet.arbitrary_data_share)); - memzero(wallet.checksum, sizeof(wallet.checksum)); - memzero(wallet.key, sizeof(wallet.key)); - memzero(wallet.beneficiary_key, sizeof(wallet.beneficiary_key)); - memzero(wallet.iv_for_beneficiary_key, - sizeof(wallet.iv_for_beneficiary_key)); - break; - - case ARBITRARY_DATA_SUCCESS_MESSAGE: - reset_flow_level(); - break; - - case ARBITRARY_DATA_FAILED_MESSAGE: - flow_level.level_one = LEVEL_TWO_OLD_WALLET; - flow_level.level_three = 1; - flow_level.level_four = 1; - break; - - default: - message_scr_init(ui_text_something_went_wrong); - reset_flow_level(); - break; - } - return; -} diff --git a/src/level_three/add_wallet/controller/controller_arbitrary_data_b.c b/src/level_three/add_wallet/controller/controller_arbitrary_data_b.c deleted file mode 100644 index c24f7c2c..00000000 --- a/src/level_three/add_wallet/controller/controller_arbitrary_data_b.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file controller_arbitrary_data_b.c - * @author Cypherock X1 Team - * @brief Arbitrary data back controller. - * Handles post event (only back/cancel events) operations for - *arbitrary data flow. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_add_wallet.h" -#include "controller_main.h" -// Atul #include "crys_hash.h" -#include "flash_api.h" -#include "tasks.h" - -extern Flash_Wallet wallet_for_flash; - -void arbitrary_data_controller_b() { - switch (flow_level.level_three) { - case ARBITRARY_DATA_NAME_CONFIRM: { - flow_level.level_three = ARBITRARY_DATA_NAME_INPUT; - } break; - - case ARBITRARY_DATA_SKIP_PIN: { - flow_level.level_three = ARBITRARY_DATA_ENTER_DATA_INSTRUCTION; - WALLET_UNSET_PIN(wallet_for_flash.wallet_info); - WALLET_UNSET_PIN(wallet.wallet_info); - } break; - case ARBITRARY_DATA_PIN_INPUT: { - flow_level.level_three = ARBITRARY_DATA_SKIP_PIN; - } break; - case ARBITRARY_DATA_PIN_CONFIRM: { - flow_level.level_three = ARBITRARY_DATA_PIN_INPUT; - } break; - - case ARBITRARY_DATA_ENTER_DATA: { - flow_level.level_three = ARBITRARY_DATA_PIN_INPUT; - } break; - - case ARBITRARY_DATA_CONFIRM_DATA: { - flow_level.level_three = ARBITRARY_DATA_ENTER_DATA_INSTRUCTION; - } break; - - default: { - reset_flow_level(); - } - } -} \ No newline at end of file diff --git a/src/level_three/add_wallet/tasks/tasks_add_wallet.h b/src/level_three/add_wallet/tasks/tasks_add_wallet.h deleted file mode 100644 index 0a6d6248..00000000 --- a/src/level_three/add_wallet/tasks/tasks_add_wallet.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file tasks_add_wallet.h - * @author Cypherock X1 Team - * @brief Header for add wallet tasks. - * This file contains all the functions prototypes for the add wallet - * tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ -/** - * @file task_new_wallet.h - * @author your name (you@domain.com) - * @brief - * @version 0.1 - * @date 2020-05-27 - * - * @copyright Copyright (c) 2020 - * - */ - -#ifndef TASKS_ADD_WALLET_H -#define TASKS_ADD_WALLET_H - -#include "controller_main.h" -#include "tasks.h" - -/** - * @brief Task to create a wallet to add arbitrary data - * @details - * - * @see - * @since v1.0.0 - */ -void tasks_arbitrary_data(); - -#endif \ No newline at end of file diff --git a/src/level_three/add_wallet/tasks/tasks_arbitrary_data.c b/src/level_three/add_wallet/tasks/tasks_arbitrary_data.c deleted file mode 100644 index 22652334..00000000 --- a/src/level_three/add_wallet/tasks/tasks_arbitrary_data.c +++ /dev/null @@ -1,226 +0,0 @@ -/** - * @file tasks_arbitrary_data.c - * @author Cypherock X1 Team - * @brief Arbitrary data tasks. - * This file contains the implementation of the tasks that are used to - *create arbitrary data. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "constant_texts.h" -#include "controller_main.h" -#include "shamir_wrapper.h" -#include "stdint.h" -#include "tasks.h" -#include "tasks_add_wallet.h" -#include "tasks_tap_cards.h" -#include "ui_address.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_input_mnemonics.h" -#include "ui_input_text.h" -#include "ui_instruction.h" -#include "ui_list.h" -#include "ui_menu.h" -#include "ui_message.h" -#include "ui_multi_instruction.h" -#include "ui_text_slideshow.h" -#include "wallet.h" - -extern char arbitrary_data[4096 / 8 + 1]; - -extern char *ALPHABET; -extern char *ALPHA_NUMERIC; -extern char *NUMBERS; -extern char *PASSPHRASE; - -#ifdef USE_ARBITRARY_DATA -static void restore_wallet_enter_mnemonics_flow() { - if (flow_level.level_four <= wallet.number_of_mnemonics) { - char heading[20]; - snprintf( - heading, sizeof(heading), UI_TEXT_ENTER_WORD, flow_level.level_four); - ui_mnem_init(heading); - } else { - // todo check if mnemonics is correct - mark_event_over(); - } -} -#endif - -void tasks_arbitrary_data() { - if (flow_level.show_error_screen) { - message_scr_init(flow_level.error_screen_text); - return; - } - - switch (flow_level.level_three) { - case ARBITRARY_DATA_NAME_INPUT: { - input_text_init(WALLET_NAME_CHARSET, - 0, - ui_text_enter_wallet_name, - 2, - DATA_TYPE_TEXT, - 15); - } break; - - case ARBITRARY_DATA_NAME_CONFIRM: { - char display[65]; - snprintf( - display, sizeof(display), "%s", flow_level.screen_input.input_text); - address_scr_init(ui_text_confirm_wallet_name, display, false); - } break; - - case RESTORE_WALLET_PIN_INSTRUCTIONS_1: { - char display[65]; - if (strnlen(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)) <= 15) - snprintf( - display, sizeof(display), UI_TEXT_PIN_INS1, wallet.wallet_name); - else - snprintf(display, sizeof(display), UI_TEXT_PIN_INS1, "this wallet"); - delay_scr_init(display, DELAY_TIME); - } break; - - case RESTORE_WALLET_PIN_INSTRUCTIONS_2: { - delay_scr_init(ui_wallet_pin_instruction_2, DELAY_TIME); - } break; - - case ARBITRARY_DATA_SKIP_PIN: { - confirm_scr_init(ui_text_do_you_want_to_set_pin); - confirm_scr_focus_cancel(); - } break; - - case ARBITRARY_DATA_PIN_INPUT: { - input_text_init( - ALPHA_NUMERIC, 26, ui_text_enter_pin, 4, DATA_TYPE_PIN, 8); - } break; - - case ARBITRARY_DATA_PIN_CONFIRM: { - input_text_init( - ALPHA_NUMERIC, 26, ui_text_confirm_pin, 4, DATA_TYPE_PIN, 8); - } break; - - case ARBITRARY_DATA_ENTER_DATA_INSTRUCTION: { - message_scr_init(ui_text_now_enter_your_data); - - } break; - - case ARBITRARY_DATA_ENTER_DATA: { - input_text_init( - PASSPHRASE, 26, ui_text_enter_data, 0, DATA_TYPE_PASSPHRASE, 255); - } break; - - case ARBITRARY_DATA_CONFIRM_DATA: { - snprintf(arbitrary_data, - sizeof(arbitrary_data), - "%s", - flow_level.screen_input.input_text); - memzero(flow_level.screen_input.input_text, - sizeof(flow_level.screen_input.input_text)); - address_scr_init(ui_text_confirm_data, arbitrary_data, false); - } break; - - case ARBITRARY_DATA_CREATING_WAIT_SCREEN: { - instruction_scr_init(ui_text_processing, NULL); - mark_event_over(); - } break; - - case ARBITRARY_DATA_CREATE: { - instruction_scr_destructor(); - mark_event_over(); - } break; - - case ARBITRARY_DATA_TAP_CARDS: { - tap_cards_for_write_flow(); - } break; - - case ARBITRARY_DATA_VERIFY_SHARES: - instruction_scr_init(ui_text_processing, ""); - instruction_scr_change_text(ui_text_processing, true); - BSP_DelayMs(DELAY_SHORT); - mark_event_over(); - break; - - case ARBITRARY_DATA_SUCCESS_MESSAGE: { - instruction_scr_destructor(); - const char *messages[6] = { - ui_text_verification_is_now_complete_messages[0], - ui_text_verification_is_now_complete_messages[1], - ui_text_verification_is_now_complete_messages[2], - ui_text_verification_is_now_complete_messages[4], - ui_text_verification_is_now_complete_messages[5], - NULL}; - uint8_t count = 5; - - if (WALLET_IS_PIN_SET(wallet.wallet_info)) { - messages[3] = ui_text_verification_is_now_complete_messages[3]; - messages[4] = ui_text_verification_is_now_complete_messages[4]; - messages[5] = ui_text_verification_is_now_complete_messages[5]; - count = 6; - } - - multi_instruction_init(messages, count, DELAY_LONG_STRING, true); - } break; - - case ARBITRARY_DATA_FAILED_MESSAGE: { - instruction_scr_destructor(); - message_scr_init(ui_text_creation_failed_delete_wallet); - } break; - - default: { - message_scr_init(ui_text_something_went_wrong); - } break; - } - return; -} diff --git a/src/level_three/advanced_settings/controller/advanced_settings_controller.c b/src/level_three/advanced_settings/controller/advanced_settings_controller.c deleted file mode 100644 index ffcd0f6e..00000000 --- a/src/level_three/advanced_settings/controller/advanced_settings_controller.c +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file advanced_settings_controller.c - * @author Cypherock X1 Team - * @brief Advanced settings next controller. - * Handles post event (only next events) operations for advanced - *settings flow. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include - -#include "application_startup.h" -#include "controller_advanced_settings.h" -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "tasks.h" - -extern lv_task_t *timeout_task; - -void level_three_advanced_settings_controller() { - switch (flow_level.level_two) { -#if X1WALLET_MAIN -#ifdef DEV_BUILD - case LEVEL_THREE_UPDATE_CARD_ID: { - controller_update_card_id(); - } break; - - case LEVEL_THREE_CARD_UPGRADE: - card_upgrade_controller(); - break; -#endif -#endif -#if X1WALLET_INITIAL - case LEVEL_THREE_START_DEVICE_PROVISION: { - device_provision_controller(); - } break; -#elif X1WALLET_MAIN -#else -#error Specify what to build (X1WALLET_INITIAL or X1WALLET_MAIN) -#endif - default: - break; - } -} diff --git a/src/level_three/advanced_settings/controller/controller_advanced_settings.h b/src/level_three/advanced_settings/controller/controller_advanced_settings.h deleted file mode 100644 index 77d0f032..00000000 --- a/src/level_three/advanced_settings/controller/controller_advanced_settings.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file controller_advanced_settings.h - * @author Cypherock X1 Team - * @brief Header for advanced settings controller. - * This file contains the prototypes of the functions used to control - * the advanced settings. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef CONTROLLER_ADV_SETTINGS_H -#define CONTROLLER_ADV_SETTINGS_H - -#pragma once - -#include "controller_main.h" -#include "tasks.h" - -/** - * @brief Controller for post-event processing of advanced settings tasks. - * @details This function is used to control the flow of the advanced settings - * controller and is responsible for transition from one state to an appropriate - * state based on the user's input (as communication via lvgl's UI components). - * - * @see LEVEL_THREE_ADVANCED_SETTINGS_TASKS, initial_verify_card_controller(), - * level_three_advanced_settings_tasks(), - * get_usb_msg_by_cmd_type(), device_provision_controller(), - * tap_card_pair_card_controller() - * @since v1.0.0 - */ -void level_three_advanced_settings_controller(); - -#endif \ No newline at end of file diff --git a/src/level_three/advanced_settings/tasks/advanced_settings_tasks.c b/src/level_three/advanced_settings/tasks/advanced_settings_tasks.c deleted file mode 100644 index b80a28fa..00000000 --- a/src/level_three/advanced_settings/tasks/advanced_settings_tasks.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file advanced_settings_tasks.c - * @author Cypherock X1 Team - * @brief Advanced settings task. - * This file contains the pre-processing & rendering of the advanced - *settings task. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "board.h" -#include "constant_texts.h" -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_tap_cards.h" -#include "tasks.h" -#include "tasks_level_four.h" -#include "tasks_tap_cards.h" -#include "ui_confirmation.h" -#include "ui_delay.h" -#include "ui_instruction.h" -#include "ui_message.h" -#include "ui_multi_instruction.h" -#include "utils.h" - -extern lv_task_t *timeout_task; - -extern const char *GIT_REV; -extern const char *GIT_TAG; -extern const char *GIT_BRANCH; - -void level_three_advanced_settings_tasks() { - switch (flow_level.level_two) { -#if X1WALLET_MAIN -#ifdef DEV_BUILD - case LEVEL_THREE_UPDATE_CARD_ID: { - tasks_update_card_id(); - } break; - - case LEVEL_THREE_CARD_UPGRADE: - card_upgrade_task(); - break; -#endif -#endif -#if X1WALLET_INITIAL - case LEVEL_THREE_START_DEVICE_PROVISION: { - task_device_provision(); - } break; -#elif X1WALLET_MAIN -#else -#error Specify what to build (X1WALLET_INITIAL or X1WALLET_MAIN) -#endif - default: - break; - } -} diff --git a/src/level_three/advanced_settings/tasks/tasks_advanced_settings.h b/src/level_three/advanced_settings/tasks/tasks_advanced_settings.h deleted file mode 100644 index 73a60d04..00000000 --- a/src/level_three/advanced_settings/tasks/tasks_advanced_settings.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file tasks_advanced_settings.h - * @author Cypherock X1 Team - * @brief Header for advanced settings tasks. - * This file contains the prototypes of the functions used to manage - * the advanced settings tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef TASKS_ADVANCED_SETTINGS_H -#define TASKS_ADVANCED_SETTINGS_H - -#pragma once - -#include "controller_main.h" -#include "tasks.h" - -/** - * @brief This function is used to manage the pre-processing & rendering in - * advanced settings tasks. - * @details All the settings features are managed here. Some of the desktop - * triggered requests are also managed here such as export of logs, firmware - * upgrade, card verification along with card pairing. - * - * @see LEVEL_THREE_ADVANCED_SETTINGS_TASKS, initial_verify_card_task(), - * verify_card_task(), task_device_provision() - * @since v1.0.0 - */ -void level_three_advanced_settings_tasks(); - -#endif \ No newline at end of file diff --git a/src/level_three/old_wallet/controller/controller_old_wallet.c b/src/level_three/old_wallet/controller/controller_old_wallet.c deleted file mode 100644 index 533909d6..00000000 --- a/src/level_three/old_wallet/controller/controller_old_wallet.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file controller_old_wallet.c - * @author Cypherock X1 Team - * @brief Old wallet next controller. - * Handles post event (only next events) operations for old wallet - *flow. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_old_wallet.h" - -#include "controller_level_four.h" -#include "controller_main.h" -#include "tasks.h" - -void level_three_old_wallet_controller() { -#if X1WALLET_MAIN == 1 - switch (flow_level.level_two) { - case LEVEL_THREE_SEND_TRANSACTION_ETH: { - send_transaction_controller_eth(); - } break; - - case LEVEL_THREE_SIGN_MESSAGE_ETH: { - sign_message_controller_eth(); - } break; - - case LEVEL_THREE_SEND_TRANSACTION_SOLANA: { - send_transaction_controller_solana(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_ETH: { - receive_transaction_controller_eth(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_NEAR: { - receive_transaction_controller_near(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_SOLANA: { - receive_transaction_controller_solana(); - } break; - - case LEVEL_THREE_WALLET_LOCKED: { - // wallet_locked_controller(); - } break; - - case LEVEL_THREE_VERIFY_WALLET: { - verify_wallet_controller(); - } break; - case LEVEL_THREE_SYNC_WALLET: { - } break; - default: - break; - } - return; -#endif -} diff --git a/src/level_three/old_wallet/controller/controller_old_wallet.h b/src/level_three/old_wallet/controller/controller_old_wallet.h deleted file mode 100644 index f1aeb49f..00000000 --- a/src/level_three/old_wallet/controller/controller_old_wallet.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file controller_old_wallet.h - * @author Cypherock X1 Team - * @brief Header for old wallet controller. - * This file contains the old wallet controller. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef CONTROLLER_OLD_WALLET_H -#define CONTROLLER_OLD_WALLET_H - -#pragma once - -#include "controller_main.h" - -/** - * @brief Controller to handle post event processing of the delete wallet flow. - * @details The function deletes the wallet from the device removing both the - * basic information along with the device's share. - * - * @see DELETE_WALLET_TASKS, delete_from_cards_controller(), - * delete_wallet_share_from_sec_flash(), delete_wallet_from_flash(), - * delete_wallet_task() - * @since v1.0.0 - * - * @note The wallet entry is erased only after the wallet has been deleted from - * all the cards. - */ -void delete_wallet_controller(); - -/** - * @brief Controller to branch through the application state for processing the - * exact active flow. - * @details This controller is only responsible for branching through the - * application state and processing the exact active flow. No actual processing - * is done here. - * - * @see LEVEL_THREE_OLD_WALLET_TASKS, view_seed_controller(), - * delete_wallet_controller(), export_wallet_controller(), - * add_coin_controller(), send_transaction_controller_eth(), - * receive_transaction_controller_eth(), wallet_locked_controller(), - * verify_wallet_controller(), level_three_old_wallet_tasks() - * @since v1.0.0 - */ -void level_three_old_wallet_controller(); - -/** - * @brief Back button controller for level three old wallet flow. - * @details This controller is only responsible for branching through the - * application state and processing the exact active flow. No actual processing - * is done here. - * - * @see LEVEL_THREE_OLD_WALLET_TASKS, - * verify_wallet_controller_b(), wallet_locked_controller_b(), - * receive_transaction_controller_b_eth(), - * send_transaction_controller_b_eth(), - * level_three_old_wallet_tasks() - * @since v1.0.0 - */ -void level_three_old_wallet_controller_b(); - -#endif \ No newline at end of file diff --git a/src/level_three/old_wallet/controller/controller_old_wallet_b.c b/src/level_three/old_wallet/controller/controller_old_wallet_b.c deleted file mode 100644 index 87f2721d..00000000 --- a/src/level_three/old_wallet/controller/controller_old_wallet_b.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file controller_old_wallet_b.c - * @author Cypherock X1 Team - * @brief Old wallet back controller. - * Handles post event (only back/cancel events) operations for old - *wallet flow. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "controller_level_four.h" -#include "controller_main.h" -#include "controller_old_wallet.h" -#include "tasks.h" - -void level_three_old_wallet_controller_b() { - switch (flow_level.level_two) { - case LEVEL_THREE_SEND_TRANSACTION_ETH: { - send_transaction_controller_b_eth(); - } break; - - case LEVEL_THREE_SIGN_MESSAGE_ETH: { - sign_message_controller_b_eth(); - } break; - - case LEVEL_THREE_SEND_TRANSACTION_SOLANA: { - send_transaction_controller_b_solana(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_ETH: { - receive_transaction_controller_b_eth(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_NEAR: { - receive_transaction_controller_b_near(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_SOLANA: { - receive_transaction_controller_b_solana(); - } break; - - case LEVEL_THREE_WALLET_LOCKED: { - wallet_locked_controller_b(); - break; - } - - case LEVEL_THREE_VERIFY_WALLET: { - verify_wallet_controller_b(); - } break; - - case LEVEL_THREE_SYNC_WALLET: { - } break; - - default: - break; - } - return; -} diff --git a/src/level_three/old_wallet/tasks/tasks_old_wallet.c b/src/level_three/old_wallet/tasks/tasks_old_wallet.c deleted file mode 100644 index 3f94096a..00000000 --- a/src/level_three/old_wallet/tasks/tasks_old_wallet.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file tasks_old_wallet.c - * @author Cypherock X1 Team - * @brief Old wallet task. - * Handles pre-processing & display updates for old wallet tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - ****************************************************************************** - * @attention - * - * (c) Copyright 2022 by HODL TECH PTE LTD - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject - * to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * "Commons Clause" License Condition v1.0 - * - * The Software is provided to you by the Licensor under the License, - * as defined below, subject to the following condition. - * - * Without limiting other conditions in the License, the grant of - * rights under the License will not include, and the License does not - * grant to you, the right to Sell the Software. - * - * For purposes of the foregoing, "Sell" means practicing any or all - * of the rights granted to you under the License to provide to third - * parties, for a fee or other consideration (including without - * limitation fees for hosting or consulting/ support services related - * to the Software), a product or service whose value derives, entirely - * or substantially, from the functionality of the Software. Any license - * notice or attribution required by the License must also include - * this Commons Clause License Condition notice. - * - * Software: All X1Wallet associated files. - * License: MIT - * Licensor: HODL TECH PTE LTD - * - ****************************************************************************** - */ -#include "tasks_old_wallet.h" - -#include "constant_texts.h" -#include "controller_main.h" -#include "tasks.h" -#include "tasks_level_four.h" - -void level_three_old_wallet_tasks() { - // Check if desktop sent an abort command (view seed and delete wallet are not - // initiated by desktop, therefore excluded here) - if (flow_level.level_two != LEVEL_THREE_WALLET_LOCKED && - flow_level.level_two != LEVEL_THREE_VERIFY_WALLET && - CY_Read_Reset_Flow()) { - mark_error_screen(ui_text_aborted); - reset_flow_level(); - return; - } - - switch (flow_level.level_two) { - case LEVEL_THREE_SEND_TRANSACTION_ETH: { - send_transaction_tasks_eth(); - } break; - - case LEVEL_THREE_SIGN_MESSAGE_ETH: { - sign_message_tasks_eth(); - } break; - - case LEVEL_THREE_SEND_TRANSACTION_SOLANA: { - send_transaction_tasks_solana(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_ETH: { - receive_transaction_tasks_eth(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_NEAR: { - receive_transaction_tasks_near(); - } break; - - case LEVEL_THREE_RECEIVE_TRANSACTION_SOLANA: { - receive_transaction_tasks_solana(); - } break; - - case LEVEL_THREE_WALLET_LOCKED: - wallet_locked_task(); - break; - - case LEVEL_THREE_VERIFY_WALLET: - verify_wallet_tasks(); - break; - case LEVEL_THREE_SYNC_WALLET: { - } break; - default: - break; - } - return; -} diff --git a/src/level_three/old_wallet/tasks/tasks_old_wallet.h b/src/level_three/old_wallet/tasks/tasks_old_wallet.h deleted file mode 100644 index fb288760..00000000 --- a/src/level_three/old_wallet/tasks/tasks_old_wallet.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file tasks_old_wallet.h - * @author Cypherock X1 Team - * @brief Header for old wallet tasks. - * This file contains all the prototypes for the old wallet tasks. - * @copyright Copyright (c) 2022 HODL TECH PTE LTD - *
You may obtain a copy of license at https://mitcc.org/ - * - */ - -#ifndef TASKS_OLD_WALLET_H -#define TASKS_OLD_WALLET_H - -#pragma once - -#include "controller_main.h" - -/** - * @brief Handles all the possible operations on the old wallets. - * @details This function handles all the possible operations on the old wallets - * such as view seed, delete/unlock/verify wallet and other desktop triggered - * operations such export wallet, send/receive transactions. - * - * @see view_seed_task(), wallet_locked_task(), - * verify_wallet_task(), - * send_transaction_tasks_eth(), receive_transaction_tasks_eth(), - * LEVEL_THREE_OLD_WALLET_TASKS, Flow_level.level_two, - * level_three_old_wallet_controller_b() level_three_old_wallet_controller() - * @since v1.0.0 - */ -void level_three_old_wallet_tasks(); - -#endif \ No newline at end of file From c8e13d08bd0b924c1b33bc91649be8ae33a98afd Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Mon, 4 Mar 2024 18:16:54 +0530 Subject: [PATCH 06/32] chore (build): Update includes --- apps/btc_family/btc_pub_key.c | 3 + apps/btc_family/btc_txn.c | 3 + apps/btc_family/btc_xpub.c | 1 + apps/evm_family/evm_helpers.c | 1 + apps/evm_family/evm_txn_helpers.c | 1 + apps/evm_family/evm_typed_data_helper.c | 1 + apps/evm_family/evm_user_verification.c | 1 + apps/manager_app/device_authentication_api.c | 3 +- apps/manager_app/device_authentication_api.h | 29 +++ apps/manager_app/get_device_info.c | 4 +- .../user_interface/ui_input_mnemonics.c | 2 + common/libraries/util/utils.c | 3 +- common/startup/application_startup.c | 74 ++++++- common/startup/application_startup.h | 23 +++ src/card_operations/card_internal.c | 2 - src/card_operations/card_internal.h | 31 ++- src/card_operations/card_pair.c | 52 ++++- src/card_operations/card_read_verify_shares.c | 2 + src/card_operations/card_unlock_wallet.c | 186 ++++++++++++++++++ src/card_operations/card_utils.c | 1 - src/card_operations/card_utils.h | 1 - src/controller_main.c | 3 - src/controller_main.h | 1 - src/wallet/create_new_wallet_flow.c | 2 + src/wallet/reconstruct_wallet_flow.c | 1 + src/wallet/restore_seed_phrase_flow.c | 1 + src/wallet/view_seed_flow.c | 2 + src/wallet/wallet_unlock_flow.c | 1 + 28 files changed, 418 insertions(+), 17 deletions(-) create mode 100644 src/card_operations/card_unlock_wallet.c diff --git a/apps/btc_family/btc_pub_key.c b/apps/btc_family/btc_pub_key.c index f79ff2d6..6c56aac1 100644 --- a/apps/btc_family/btc_pub_key.c +++ b/apps/btc_family/btc_pub_key.c @@ -60,9 +60,12 @@ * INCLUDES *****************************************************************************/ +#include "bip32.h" #include "btc_api.h" #include "btc_helpers.h" #include "btc_priv.h" +#include "coin_utils.h" +#include "curves.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" #include "ui_core_confirm.h" diff --git a/apps/btc_family/btc_txn.c b/apps/btc_family/btc_txn.c index a7fde492..608fdfe1 100644 --- a/apps/btc_family/btc_txn.c +++ b/apps/btc_family/btc_txn.c @@ -60,12 +60,15 @@ * INCLUDES *****************************************************************************/ +#include "bip32.h" #include "btc_api.h" #include "btc_helpers.h" #include "btc_priv.h" #include "btc_script.h" #include "btc_txn_helpers.h" +#include "coin_utils.h" #include "constant_texts.h" +#include "curves.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" #include "ui_core_confirm.h" diff --git a/apps/btc_family/btc_xpub.c b/apps/btc_family/btc_xpub.c index b3e7e028..cbee4740 100644 --- a/apps/btc_family/btc_xpub.c +++ b/apps/btc_family/btc_xpub.c @@ -63,6 +63,7 @@ #include "btc_api.h" #include "btc_helpers.h" #include "btc_priv.h" +#include "curves.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" #include "ui_core_confirm.h" diff --git a/apps/evm_family/evm_helpers.c b/apps/evm_family/evm_helpers.c index 0485b043..d42efcb7 100644 --- a/apps/evm_family/evm_helpers.c +++ b/apps/evm_family/evm_helpers.c @@ -62,6 +62,7 @@ #include "evm_helpers.h" +#include "eth.h" #include "evm_priv.h" #include "evm_txn_helpers.h" #include "evm_typed_data_helper.h" diff --git a/apps/evm_family/evm_txn_helpers.c b/apps/evm_family/evm_txn_helpers.c index 2a310f2e..56825591 100644 --- a/apps/evm_family/evm_txn_helpers.c +++ b/apps/evm_family/evm_txn_helpers.c @@ -63,6 +63,7 @@ #include "evm_txn_helpers.h" +#include "eth.h" #include "evm_priv.h" #include "int-util.h" diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index d70485e9..4807a9b7 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -64,6 +64,7 @@ #include "coin_utils.h" #include "eip712_utils.h" +#include "eth.h" #include "evm_priv.h" /***************************************************************************** diff --git a/apps/evm_family/evm_user_verification.c b/apps/evm_family/evm_user_verification.c index fedbc1cf..e998fc3c 100644 --- a/apps/evm_family/evm_user_verification.c +++ b/apps/evm_family/evm_user_verification.c @@ -64,6 +64,7 @@ #include "address.h" #include "constant_texts.h" +#include "eth.h" #include "evm_api.h" #include "evm_priv.h" #include "ui_core_confirm.h" diff --git a/apps/manager_app/device_authentication_api.c b/apps/manager_app/device_authentication_api.c index 0493db3e..aebd73dc 100644 --- a/apps/manager_app/device_authentication_api.c +++ b/apps/manager_app/device_authentication_api.c @@ -57,9 +57,9 @@ */ #include "atca_host.h" #include "board.h" -#include "controller_level_four.h" #include "cryptoauthlib.h" #include "curves.h" +#include "flash_api.h" #include "nist256p1.h" #include "sec_flash.h" #include "string.h" @@ -67,6 +67,7 @@ #include "stm32l4xx_it.h" #endif +#include "atca_basic.h" #include "device_authentication_api.h" #define SIGNATURE_SIZE 64 diff --git a/apps/manager_app/device_authentication_api.h b/apps/manager_app/device_authentication_api.h index 7588cdd0..9aa62793 100644 --- a/apps/manager_app/device_authentication_api.h +++ b/apps/manager_app/device_authentication_api.h @@ -17,16 +17,45 @@ *****************************************************************************/ #include +#include "atca_iface.h" +#include "atca_status.h" #include "stddef.h" #include "stdint.h" /***************************************************************************** * MACROS AND DEFINES *****************************************************************************/ +#define DEFAULT_ATECC_RETRIES 5 +#define DEVICE_SERIAL_SIZE 32 /***************************************************************************** * TYPEDEFS *****************************************************************************/ +typedef enum { + slot_0_unused = 0U, + slot_1_unused = 1U, + slot_2_auth_key = 2U, + slot_3_nfc_pair_key = 3U, + slot_4_unused = 4U, + slot_5_challenge = 5U, + slot_6_io_key = 6U, + slot_7_unused = 7U, + slot_8_serial = 8U, + slot_9_unused = 9U, + slot_10_unused = 10U, + slot_11_unused = 11U, + slot_12_unused = 12U, + slot_13_unused = 13U, + slot_14_unused = 14U, + slot_15_unused = 15U +} atecc_slot_define_t; +typedef struct { + uint8_t device_serial[DEVICE_SERIAL_SIZE], retries; + ATCA_STATUS status; + ATCAIfaceCfg *cfg_atecc608a_iface; +} atecc_data_t; + +extern atecc_data_t atecc_data; /***************************************************************************** * EXPORTED VARIABLES diff --git a/apps/manager_app/get_device_info.c b/apps/manager_app/get_device_info.c index 793a33ef..5194066f 100644 --- a/apps/manager_app/get_device_info.c +++ b/apps/manager_app/get_device_info.c @@ -60,7 +60,9 @@ * INCLUDES *****************************************************************************/ -#include "controller_level_four.h" +#include "application_startup.h" +#include "atca_status.h" +#include "device_authentication_api.h" #include "flash_api.h" #include "manager_api.h" #include "manager_app.h" diff --git a/common/interfaces/user_interface/ui_input_mnemonics.c b/common/interfaces/user_interface/ui_input_mnemonics.c index d9b499b2..0f343a9e 100644 --- a/common/interfaces/user_interface/ui_input_mnemonics.c +++ b/common/interfaces/user_interface/ui_input_mnemonics.c @@ -58,7 +58,9 @@ */ #include "ui_input_mnemonics.h" +#include "bip39.h" #include "ui_events_priv.h" + static void ui_mnem_create(); static void refresh_screen_texts(); static void shrink(); diff --git a/common/libraries/util/utils.c b/common/libraries/util/utils.c index 2729cf60..4b5ac82c 100644 --- a/common/libraries/util/utils.c +++ b/common/libraries/util/utils.c @@ -65,12 +65,13 @@ #include "assert_conf.h" #include "bip32.h" #include "bip39.h" -#include "controller_level_four.h" #include "crypto_random.h" #include "cryptoauthlib.h" #include "curves.h" +#include "device_authentication_api.h" #include "logger.h" #include "lv_font.h" +#include "lv_txt.h" #include "sha2.h" #include "wallet.h" diff --git a/common/startup/application_startup.c b/common/startup/application_startup.c index f07a8ef4..3d179075 100644 --- a/common/startup/application_startup.c +++ b/common/startup/application_startup.c @@ -69,11 +69,10 @@ */ #include "application_startup.h" -#include "controller_level_four.h" -#include "controller_tap_cards.h" #include "core_error.h" #include "core_flow_init.h" #include "cryptoauthlib.h" +#include "device_authentication_api.h" #include "flash_api.h" #include "flash_if.h" #include "logger.h" @@ -85,6 +84,7 @@ #include "sys_state.h" #include "systick_timer.h" #include "ui_screens.h" + #ifdef DEV_BUILD #include "dev_utils.h" #endif @@ -456,6 +456,76 @@ void device_hardware_check() { #endif } +uint32_t get_device_serial() { + atecc_data.retries = DEFAULT_ATECC_RETRIES; + bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); + + NVIC_DisableIRQ(OTG_FS_IRQn); + do { + atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); + atecc_data.status = atcab_read_zone(ATCA_ZONE_DATA, + slot_8_serial, + 0, + 0, + atecc_data.device_serial, + DEVICE_SERIAL_SIZE); + } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); + if (usb_irq_enable_on_entry == true) + NVIC_EnableIRQ(OTG_FS_IRQn); + + if (atecc_data.status == ATCA_SUCCESS) { + if (0 != memcmp(atecc_data.device_serial + 8, (void *)UID_BASE, 12)) { + return 1; + } else { + return SUCCESS; + } + } + return atecc_data.status; +} + +provision_status_t check_provision_status() { + uint8_t cfg[128]; + memset(cfg, 0, 128); + atecc_data.retries = DEFAULT_ATECC_RETRIES; + + bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); + NVIC_DisableIRQ(OTG_FS_IRQn); + do { + atecc_data.status = atcab_init(atecc_data.cfg_atecc608a_iface); + atecc_data.status = atcab_read_config_zone(cfg); + } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); + if (usb_irq_enable_on_entry == true) + NVIC_EnableIRQ(OTG_FS_IRQn); + + if (atecc_data.status != ATCA_SUCCESS) { + LOG_CRITICAL("xxx30: %d", atecc_data.status); + return -1; + } + + if (cfg[86] == 0x00 && + cfg[87] == 0x00) { // config zone and data zones are locked + + if (cfg[88] == 0xBF && + cfg[89] == + 0xFE) { // device serial and IO key are programmed and locked + return provision_incomplete; + + } else if ((cfg[88] & ATECC_CFG_88_MASK) == 0x00 && + (cfg[89] & ATECC_CFG_89_MASK) == + 0x00) { // private key slots are locked + return provision_complete; + } else if ((cfg[88] & ATECC_CFG_88_MASK_OLD_PROV) == 0x00 && + (cfg[89] & ATECC_CFG_89_MASK) == + 0x00) { // NFC private key slot not locked + return provision_v1_complete; + } else { + return provision_empty; + } + } else { + return provision_empty; + } +} + void device_provision_check() { #if USE_SIMULATOR == 0 const char *msg = NULL; diff --git a/common/startup/application_startup.h b/common/startup/application_startup.h index e6022756..e23a6801 100644 --- a/common/startup/application_startup.h +++ b/common/startup/application_startup.h @@ -54,6 +54,18 @@ /// Interval defined for user inactivity in a flow in milli seconds #define INACTIVITY_TIME (300 * 1000) +#define ATECC_CFG_88_MASK 0x4C +#define ATECC_CFG_89_MASK 0x01 + +#define ATECC_CFG_88_MASK_OLD_PROV 44 + +typedef enum { + provision_empty = 0, + provision_incomplete = 1, + provision_complete = 2, + provision_v1_complete = 3 +} provision_status_t; + extern uint8_t device_auth_flag; extern bool main_app_ready; @@ -183,6 +195,17 @@ bool fault_in_prev_boot(); */ void handle_fault_in_prev_boot(); +/** + * @brief fetch device serial and check if UID in the serial matches MCU UID + * or not + * @details + * + * @return uint32_t device serial fetch status or failure status + * @retval 0 fetched successfully + * @retval 1 device UID doesn't match with serial UID + */ +uint32_t get_device_serial(); + /** * @brief Detect hardware related faults * diff --git a/src/card_operations/card_internal.c b/src/card_operations/card_internal.c index c866807d..c81ebab2 100644 --- a/src/card_operations/card_internal.c +++ b/src/card_operations/card_internal.c @@ -62,9 +62,7 @@ *****************************************************************************/ #include "card_internal.h" -#include "apdu.h" #include "app_error.h" -#include "buzzer.h" #include "core_error.h" #include "events.h" #include "nfc.h" diff --git a/src/card_operations/card_internal.h b/src/card_operations/card_internal.h index e4ccbfd7..ac60bb15 100644 --- a/src/card_operations/card_internal.h +++ b/src/card_operations/card_internal.h @@ -13,10 +13,10 @@ /***************************************************************************** * INCLUDES *****************************************************************************/ +#include "apdu.h" +#include "buzzer.h" #include "card_operation_typedefs.h" -/* TODO: Remove the include and move required struct with cleanup*/ -#include "controller_tap_cards.h" /***************************************************************************** * MACROS AND DEFINES *****************************************************************************/ @@ -24,6 +24,33 @@ /***************************************************************************** * TYPEDEFS *****************************************************************************/ + +/** + * @brief + * @details + * + * @see + * @since v1.0.0 + * + * @note + */ +typedef struct NFC_connection_data { + uint8_t desktop_control; + int8_t keystore_index; + uint8_t acceptable_cards; + uint8_t tapped_card; + uint8_t retries; + uint8_t family_id[FAMILY_ID_SIZE + + 2]; // TODO: Review(need to find reason for extra byte) + uint8_t card_key_id[4]; + bool pairing_error; + uint8_t recovery_mode; + uint8_t card_absent_retries; + uint8_t *card_version; + bool init_session_keys; + ISO7816 status; +} NFC_connection_data; + typedef struct card_operation_data { NFC_connection_data nfc_data; const char *error_message; /** Error message to be displayed for user action diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 7094fc73..79ff528b 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -66,13 +66,17 @@ #include "bip32.h" #include "card_internal.h" #include "card_utils.h" -#include "controller_level_four.h" #include "core_error.h" #include "curves.h" #include "nist256p1.h" #include "ui_instruction.h" #include "utils.h" - +#if USE_SIMULATOR == 0 +#include "stm32l4xx_it.h" +#endif +#include "atca_basic.h" +#include "device_authentication_api.h" +#include "nfc.h" /***************************************************************************** * EXTERN VARIABLES *****************************************************************************/ @@ -163,6 +167,50 @@ static void init_and_pair_card(card_operation_data_t *card_data, /***************************************************************************** * STATIC FUNCTIONS *****************************************************************************/ + +static uint8_t atecc_nfc_sign_hash(const uint8_t *hash, uint8_t *sign) { + atecc_data.retries = DEFAULT_ATECC_RETRIES; + + bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); + NVIC_DisableIRQ(OTG_FS_IRQn); + do { + if (atecc_data.status != ATCA_SUCCESS) + LOG_CRITICAL("PAIR SG: %04x, count:%d", + atecc_data.status, + DEFAULT_ATECC_RETRIES - atecc_data.retries); + atcab_init(atecc_data.cfg_atecc608a_iface); + atecc_data.status = atcab_sign(slot_3_nfc_pair_key, hash, sign); + } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); + if (usb_irq_enable_on_entry == true) + NVIC_EnableIRQ(OTG_FS_IRQn); + + return atecc_data.status; +} + +static uint8_t atecc_nfc_ecdh(const uint8_t *pub_key, uint8_t *shared_secret) { + uint8_t io_key[IO_KEY_SIZE]; + atecc_data.retries = DEFAULT_ATECC_RETRIES; + + if (get_io_protection_key(io_key) != SUCCESS_) + return -1; + + bool usb_irq_enable_on_entry = NVIC_GetEnableIRQ(OTG_FS_IRQn); + NVIC_DisableIRQ(OTG_FS_IRQn); + do { + if (atecc_data.status != ATCA_SUCCESS) + LOG_CRITICAL("ECDH: %04x, count:%d", + atecc_data.status, + DEFAULT_ATECC_RETRIES - atecc_data.retries); + atcab_init(atecc_data.cfg_atecc608a_iface); + atecc_data.status = + atcab_ecdh_ioenc(slot_3_nfc_pair_key, pub_key, shared_secret, io_key); + } while (atecc_data.status != ATCA_SUCCESS && --atecc_data.retries); + if (usb_irq_enable_on_entry == true) + NVIC_EnableIRQ(OTG_FS_IRQn); + + return atecc_data.status; +} + static uint32_t pair_card_preprocess(card_pairing_data_t *pair_data) { uint8_t digest[64] = {0}, sig[65] = {0}; uint8_t invalid_self_keypath[8] = {DEFAULT_VALUE_IN_FLASH, diff --git a/src/card_operations/card_read_verify_shares.c b/src/card_operations/card_read_verify_shares.c index efeec3b7..cbdb16a4 100644 --- a/src/card_operations/card_read_verify_shares.c +++ b/src/card_operations/card_read_verify_shares.c @@ -60,12 +60,14 @@ /***************************************************************************** * INCLUDES *****************************************************************************/ +#include "bip39.h" #include "card_internal.h" #include "card_operation_typedefs.h" #include "card_read_verify_share.h" #include "card_utils.h" #include "flash_api.h" #include "nfc.h" +#include "options.h" #include "shamir_wrapper.h" #include "ui_instruction.h" #include "wallet.h" diff --git a/src/card_operations/card_unlock_wallet.c b/src/card_operations/card_unlock_wallet.c new file mode 100644 index 00000000..044d532a --- /dev/null +++ b/src/card_operations/card_unlock_wallet.c @@ -0,0 +1,186 @@ +/** + * @file card_unlock_wallet.c + * @author Cypherock X1 Team + * @brief Wallet unlock flow controller + * @copyright Copyright (c) 2023 HODL TECH PTE LTD + *
You may obtain a copy of license at https://mitcc.org/ + * + ****************************************************************************** + * @attention + * + * (c) Copyright 2023 by HODL TECH PTE LTD + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * "Commons Clause" License Condition v1.0 + * + * The Software is provided to you by the Licensor under the License, + * as defined below, subject to the following condition. + * + * Without limiting other conditions in the License, the grant of + * rights under the License will not include, and the License does not + * grant to you, the right to Sell the Software. + * + * For purposes of the foregoing, "Sell" means practicing any or all + * of the rights granted to you under the License to provide to third + * parties, for a fee or other consideration (including without + * limitation fees for hosting or consulting/ support services related + * to the Software), a product or service whose value derives, entirely + * or substantially, from the functionality of the Software. Any license + * notice or attribution required by the License must also include + * this Commons Clause License Condition notice. + * + * Software: All X1Wallet associated files. + * License: MIT + * Licensor: HODL TECH PTE LTD + * + ****************************************************************************** + */ + +/***************************************************************************** + * INCLUDES + *****************************************************************************/ + +#include "card_unlock_wallet.h" + +#include "buzzer.h" +#include "card_internal.h" +#include "card_utils.h" +#include "nfc.h" +#include "pow_utilities.h" +#include "ui_instruction.h" + +/***************************************************************************** + * EXTERN VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * PRIVATE MACROS AND DEFINES + *****************************************************************************/ + +/***************************************************************************** + * PRIVATE TYPEDEFS + *****************************************************************************/ + +/***************************************************************************** + * STATIC FUNCTION PROTOTYPES + *****************************************************************************/ + +/***************************************************************************** + * STATIC VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * GLOBAL VARIABLES + *****************************************************************************/ + +/***************************************************************************** + * STATIC FUNCTIONS + *****************************************************************************/ + +/***************************************************************************** + * GLOBAL FUNCTIONS + *****************************************************************************/ + +card_error_type_e card_unlock_wallet(const Wallet *wallet) { + card_error_type_e result = CARD_OPERATION_DEFAULT_INVALID; + card_operation_data_t card_data = {0}; + + char heading[50] = ""; + uint8_t wallet_index = 0xFF; + ASSERT(SUCCESS == + get_index_by_name((const char *)wallet->wallet_name, &wallet_index)); + + snprintf(heading, + sizeof(heading), + UI_TEXT_TAP_CARD, + decode_card_number(get_wallet_card_locked(wallet_index))); + instruction_scr_init(ui_text_place_card_below, heading); + + card_data.nfc_data.retries = 5; + card_data.nfc_data.init_session_keys = true; + while (1) { + card_data.nfc_data.acceptable_cards = get_wallet_card_locked(wallet_index); + memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); + card_data.nfc_data.tapped_card = 0; + + result = card_initialize_applet(&card_data); + + if (CARD_OPERATION_SUCCESS == card_data.error_type) { + card_data.nfc_data.status = + nfc_verify_challenge(wallet->wallet_name, + get_proof_of_work_nonce(), + wallet->password_double_hash); + + if (card_data.nfc_data.status == SW_NO_ERROR || + card_data.nfc_data.status == SW_WARNING_STATE_UNCHANGED) { + update_wallet_locked_flash((const char *)wallet->wallet_name, false); + buzzer_start(BUZZER_DURATION); + break; + } else { + card_handle_errors(&card_data); + if (POW_SW_CHALLENGE_FAILED == card_data.nfc_data.status) { + uint16_t bits = pow_count_set_bits( + get_wallet_by_index(wallet_index)->challenge.target); + LOG_CRITICAL("ex-pow-tg n: %d", bits); + log_hex_array( + "ex-pow-rn: ", + get_wallet_by_index(wallet_index)->challenge.random_number, + POW_RAND_NUMBER_SIZE); + } + } + } + + 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; + if (CARD_OPERATION_SUCCESS == indicate_card_error(error_msg)) { + // Re-render the instruction screen + instruction_scr_init(ui_text_place_card_below, heading); + continue; + } + } + + /** + * @brief For errors which lead to challenge failure or incorrect pin, we + * have to refetch the challenge which is performed subsequently in the same + * card tap session by the caller from user's perspective, so only for the + * condiion of `CARD_OPERATION_LOCKED_WALLET` we don't sound the buzzer as + * the card tap session has not completed. + */ + if (CARD_OPERATION_LOCKED_WALLET != card_data.error_type) { + buzzer_start(BUZZER_DURATION); + } + + result = handle_wallet_errors(&card_data, wallet); + if (CARD_OPERATION_SUCCESS != result) { + break; + } + + // If control reached here, it is an unrecoverable error, so break + result = card_data.error_type; + break; + } + + nfc_deselect_card(); + return result; +} \ No newline at end of file diff --git a/src/card_operations/card_utils.c b/src/card_operations/card_utils.c index 111c4c91..049e6264 100644 --- a/src/card_operations/card_utils.c +++ b/src/card_operations/card_utils.c @@ -64,7 +64,6 @@ #include "card_internal.h" #include "constant_texts.h" -#include "controller_tap_cards.h" #include "events.h" #include "ui_instruction.h" #include "ui_message.h" diff --git a/src/card_operations/card_utils.h b/src/card_operations/card_utils.h index 271832b5..051073de 100644 --- a/src/card_operations/card_utils.h +++ b/src/card_operations/card_utils.h @@ -14,7 +14,6 @@ * INCLUDES *****************************************************************************/ #include "card_internal.h" -#include "controller_tap_cards.h" #include "stdbool.h" /***************************************************************************** diff --git a/src/controller_main.c b/src/controller_main.c index ae4392b8..18aa7b87 100644 --- a/src/controller_main.c +++ b/src/controller_main.c @@ -92,7 +92,6 @@ #include "chacha20poly1305.h" #include "communication.h" #include "constant_texts.h" -#include "controller_level_four.h" #include "cryptoauthlib.h" #include "etc.h" #include "eth.h" @@ -141,8 +140,6 @@ char arbitrary_data[4096 / 8 + 1]; // TODO: Variable required for code compilation: Delete after all coins are // ported -Send_Transaction_Data var_send_transaction_data = {0}; -Receive_Transaction_Data receive_transaction_data = {0}; /** * @brief Global Flow_level instance. diff --git a/src/controller_main.h b/src/controller_main.h index f438cb4a..4e50a4f7 100644 --- a/src/controller_main.h +++ b/src/controller_main.h @@ -43,7 +43,6 @@ #include "sha2.h" #include "sys_state.h" #include "tasks.h" -#include "tasks_level_four.h" #include "utils.h" #include "wallet.h" diff --git a/src/wallet/create_new_wallet_flow.c b/src/wallet/create_new_wallet_flow.c index b455012e..d1bac129 100644 --- a/src/wallet/create_new_wallet_flow.c +++ b/src/wallet/create_new_wallet_flow.c @@ -61,12 +61,14 @@ *****************************************************************************/ #include "create_new_wallet_flow.h" +#include "bip39.h" #include "card_flow_create_wallet.h" #include "constant_texts.h" #include "core_error.h" #include "crypto_random.h" #include "flash_api.h" #include "flash_if.h" +#include "options.h" #include "sha2.h" #include "shamir_wrapper.h" #include "ui_core_confirm.h" diff --git a/src/wallet/reconstruct_wallet_flow.c b/src/wallet/reconstruct_wallet_flow.c index a9a84487..72231c01 100644 --- a/src/wallet/reconstruct_wallet_flow.c +++ b/src/wallet/reconstruct_wallet_flow.c @@ -61,6 +61,7 @@ *****************************************************************************/ #include "reconstruct_wallet_flow.h" +#include "bip39.h" #include "card_flow_reconstruct_wallet.h" #include "common_error.h" #include "constant_texts.h" diff --git a/src/wallet/restore_seed_phrase_flow.c b/src/wallet/restore_seed_phrase_flow.c index c7d1b4b6..39ab4ca1 100644 --- a/src/wallet/restore_seed_phrase_flow.c +++ b/src/wallet/restore_seed_phrase_flow.c @@ -62,6 +62,7 @@ #include "constant_texts.h" #include "core_error.h" #include "flash_if.h" +#include "options.h" #include "sha2.h" #include "shamir_wrapper.h" #include "ui_core_confirm.h" diff --git a/src/wallet/view_seed_flow.c b/src/wallet/view_seed_flow.c index 6b9316de..ce97c63c 100644 --- a/src/wallet/view_seed_flow.c +++ b/src/wallet/view_seed_flow.c @@ -59,8 +59,10 @@ /***************************************************************************** * INCLUDES *****************************************************************************/ +#include "bip32.h" #include "constant_texts.h" #include "core_error.h" +#include "options.h" #include "reconstruct_wallet_flow.h" #include "ui_core_confirm.h" #include "ui_multi_instruction.h" diff --git a/src/wallet/wallet_unlock_flow.c b/src/wallet/wallet_unlock_flow.c index 0d9c39df..323c84ab 100644 --- a/src/wallet/wallet_unlock_flow.c +++ b/src/wallet/wallet_unlock_flow.c @@ -62,6 +62,7 @@ #include "wallet_unlock_flow.h" #include "card_operations.h" +#include "card_unlock_wallet.h" #include "constant_texts.h" #include "core_error.h" #include "flash_api.h" From d4bca9928a1dce496c64c735b5a1722c8e86a309 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Mon, 4 Mar 2024 18:26:54 +0530 Subject: [PATCH 07/32] chore (build): Added missing struct --- src/controller_main.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/controller_main.h b/src/controller_main.h index 4e50a4f7..aff31708 100644 --- a/src/controller_main.h +++ b/src/controller_main.h @@ -249,6 +249,19 @@ extern Wallet wallet; extern lv_task_t *address_timeout_task; extern uint32_t inactivity_counter; +#pragma pack(push, 1) +typedef struct Provision_Data_Struct { + uint8_t device_private_key[32]; + uint8_t device_public_key[ECDSA_PUB_KEY_SIZE]; + uint8_t self_key_path[FS_KEYSTORE_KEYPATH_LEN]; + uint8_t priv_key[FS_KEYSTORE_PRIVKEY_LEN]; + uint8_t card_root_xpub[FS_KEYSTORE_XPUB_LEN]; +} Provision_Data_struct; +#pragma pack(pop) + +extern Provision_Data_struct provision_keys_data; +extern uint8_t provision_date[4]; + /** * @brief Get the Global Flash_Wallet instance. * From c8b6e33a5951d08a4288adf90cc5543bc9d85b1a Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 5 Mar 2024 15:17:08 +0530 Subject: [PATCH 08/32] chore (build): Provision extern removed --- src/controller_main.c | 3 +++ src/controller_main.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controller_main.c b/src/controller_main.c index 18aa7b87..2334a6bb 100644 --- a/src/controller_main.c +++ b/src/controller_main.c @@ -166,6 +166,9 @@ Flash_Wallet wallet_for_flash; MessageData msg_data; ui_display_node *current_display_node = NULL; +uint8_t provision_date[4]; +Provision_Data_struct provision_keys_data; + Flash_Wallet *get_flash_wallet() { ASSERT((&wallet_for_flash) != NULL); diff --git a/src/controller_main.h b/src/controller_main.h index aff31708..3d5d057c 100644 --- a/src/controller_main.h +++ b/src/controller_main.h @@ -259,9 +259,6 @@ typedef struct Provision_Data_Struct { } Provision_Data_struct; #pragma pack(pop) -extern Provision_Data_struct provision_keys_data; -extern uint8_t provision_date[4]; - /** * @brief Get the Global Flash_Wallet instance. * From 7d4616c533c406b05f284d11e6980d106f64419b Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 5 Mar 2024 16:22:04 +0530 Subject: [PATCH 09/32] chore (build): Removed redundant includes --- apps/evm_family/evm_helpers.c | 1 - apps/evm_family/evm_priv.h | 1 + apps/evm_family/evm_txn_helpers.c | 1 - apps/evm_family/evm_typed_data_helper.c | 1 - apps/evm_family/evm_user_verification.c | 1 - common/coin_support/coin_utils.h | 1 + 6 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/evm_family/evm_helpers.c b/apps/evm_family/evm_helpers.c index d42efcb7..0485b043 100644 --- a/apps/evm_family/evm_helpers.c +++ b/apps/evm_family/evm_helpers.c @@ -62,7 +62,6 @@ #include "evm_helpers.h" -#include "eth.h" #include "evm_priv.h" #include "evm_txn_helpers.h" #include "evm_typed_data_helper.h" diff --git a/apps/evm_family/evm_priv.h b/apps/evm_family/evm_priv.h index 01bdc4e6..95f37f27 100644 --- a/apps/evm_family/evm_priv.h +++ b/apps/evm_family/evm_priv.h @@ -15,6 +15,7 @@ * INCLUDES *****************************************************************************/ +#include "eth.h" #include "events.h" #include "evm_api.h" #include "evm_context.h" diff --git a/apps/evm_family/evm_txn_helpers.c b/apps/evm_family/evm_txn_helpers.c index 56825591..2a310f2e 100644 --- a/apps/evm_family/evm_txn_helpers.c +++ b/apps/evm_family/evm_txn_helpers.c @@ -63,7 +63,6 @@ #include "evm_txn_helpers.h" -#include "eth.h" #include "evm_priv.h" #include "int-util.h" diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index 4807a9b7..d70485e9 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -64,7 +64,6 @@ #include "coin_utils.h" #include "eip712_utils.h" -#include "eth.h" #include "evm_priv.h" /***************************************************************************** diff --git a/apps/evm_family/evm_user_verification.c b/apps/evm_family/evm_user_verification.c index e998fc3c..fedbc1cf 100644 --- a/apps/evm_family/evm_user_verification.c +++ b/apps/evm_family/evm_user_verification.c @@ -64,7 +64,6 @@ #include "address.h" #include "constant_texts.h" -#include "eth.h" #include "evm_api.h" #include "evm_priv.h" #include "ui_core_confirm.h" diff --git a/common/coin_support/coin_utils.h b/common/coin_support/coin_utils.h index 397e65e2..5a5832f0 100644 --- a/common/coin_support/coin_utils.h +++ b/common/coin_support/coin_utils.h @@ -53,6 +53,7 @@ #define DASH_COIN_VERSION 0x00000000 /// ETHEREUM coin index +#define ETHEREUM_COIN_INDEX 0x8000003C #define ETHEREUM ETHEREUM_COIN_INDEX /// NEAR coin index From f80e7468c34bb9138caad32e4f1b1222bfd209ac Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Wed, 6 Mar 2024 17:11:10 +0530 Subject: [PATCH 10/32] chore (build): Added prototypes --- common/startup/application_startup.h | 12 +++++++++++ src/card_operations/card_internal.h | 1 - src/card_operations/card_pair.c | 31 ++++++++++++++++++++++++++++ src/card_operations/check_pairing.c | 1 - 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/common/startup/application_startup.h b/common/startup/application_startup.h index e23a6801..3aae7a16 100644 --- a/common/startup/application_startup.h +++ b/common/startup/application_startup.h @@ -195,6 +195,18 @@ bool fault_in_prev_boot(); */ void handle_fault_in_prev_boot(); +/** + * @brief + * @details + * + * @return uint8_t Provision status of the device + * @retval 0 Not provisioned + * @retval 1 Semi-provisioned (serial and IO-Protection Key present) + * @retval 2 Fully provisioned + * @retval 3 External auth configuration + */ +provision_status_t check_provision_status(); + /** * @brief fetch device serial and check if UID in the serial matches MCU UID * or not diff --git a/src/card_operations/card_internal.h b/src/card_operations/card_internal.h index ac60bb15..254bb1f8 100644 --- a/src/card_operations/card_internal.h +++ b/src/card_operations/card_internal.h @@ -35,7 +35,6 @@ * @note */ typedef struct NFC_connection_data { - uint8_t desktop_control; int8_t keystore_index; uint8_t acceptable_cards; uint8_t tapped_card; diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 79ff528b..14251195 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -99,6 +99,37 @@ typedef struct card_pairing_data { * STATIC FUNCTION PROTOTYPES *****************************************************************************/ +/** + * @brief Request ATECC to generate signature on the hash with private available + * on SLOT-3 + * @details + * + * @param [in] hash - hash to be signed + * @param [out] sign - signature generated + * + * @return ATCA_SUCCESS on success, otherwise an error code. + * + * @see atcab_init(), atcab_sign(), ATCAIfaceCfg, cfg_atecc608a_iface + * @since v1.0.0 + */ +static uint8_t atecc_nfc_sign_hash(const uint8_t *hash, uint8_t *sign); + +/** + * @brief Request ATECC to perform ECDH operation on pub_key with private key + * from SLOT-3 + * @details + * + * @param [in] pub_key - public key to be used for ECDH + * @param [out] shared_secret - shared secret generated + * + * @return ATCA_SUCCESS on success, otherwise an error code. + * + * @see atcab_init(), atcab_ecdh(), atcab_ecdh_ioenc(), ATCAIfaceCfg, + * cfg_atecc608a_iface + * @since v1.0.0 + */ +static uint8_t atecc_nfc_ecdh(const uint8_t *pub_key, uint8_t *shared_secret); + /***************************************************************************** * STATIC VARIABLES *****************************************************************************/ diff --git a/src/card_operations/check_pairing.c b/src/card_operations/check_pairing.c index b16cd645..d887457f 100644 --- a/src/card_operations/check_pairing.c +++ b/src/card_operations/check_pairing.c @@ -104,7 +104,6 @@ static void init_tap_card_data(NFC_connection_data *connection_data); static void init_tap_card_data(NFC_connection_data *connection_data) { memset(connection_data, 0, sizeof(NFC_connection_data)); connection_data->retries = 5; - connection_data->desktop_control = false; connection_data->acceptable_cards = ACCEPTABLE_CARDS_ALL; memset(connection_data->family_id, 0xff, sizeof(connection_data->family_id)); memset(connection_data->card_key_id, 0, sizeof(connection_data->card_key_id)); From 551bcc1f782595dd005ce5014796bdc4a3292b4d Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:18:51 +0530 Subject: [PATCH 11/32] fix (app): Handle device auth state change in-between onboarding Fixes https://app.clickup.com/t/9002019994/PRF-7078 --- common/core/core_flow_init.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/common/core/core_flow_init.c b/common/core/core_flow_init.c index 07fed66d..afecb734 100644 --- a/common/core/core_flow_init.c +++ b/common/core/core_flow_init.c @@ -125,8 +125,17 @@ engine_ctx_t core_step_engine_ctx = { engine_ctx_t *get_core_flow_ctx(void) { engine_reset_flow(&core_step_engine_ctx); + const manager_onboarding_step_t step = onboarding_get_last_step(); /// Check if onboarding is complete or not - if (MANAGER_ONBOARDING_STEP_COMPLETE != onboarding_get_last_step()) { + if (MANAGER_ONBOARDING_STEP_COMPLETE != step) { + // reset partial-onboarding if auth flag is reset (which can happen via + // secure-bootloader). Refer PRF-7078 + if (MANAGER_ONBOARDING_STEP_VIRGIN_DEVICE < step && + DEVICE_NOT_AUTHENTICATED == get_auth_state()) { + // bypass onboarding_set_step_done as we want to force reset + save_onboarding_step(MANAGER_ONBOARDING_STEP_VIRGIN_DEVICE); + } + // Skip onbaording for infield devices with pairing and/or wallets count is // greater than zero if ((get_wallet_count() > 0) || (get_keystore_used_count() > 0)) { From 632bd344009702a5a4057ffb69b7b5e7f06c88ea Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 13:44:27 +0530 Subject: [PATCH 12/32] feat (debug): Add unit tests debug --- .vscode/launch.json | 20 ++++++++++++++++++++ .vscode/tasks.json | 12 +++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7ce14a4c..d5c93d4c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,6 +25,26 @@ ], "preLaunchTask": "build-simulator" }, + { + "name": "Simulator Debug Unit Tests", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceRoot}/bin/Cypherock_Simulator", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceRoot}/bin", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "build-simulator-units-tests" + }, { "name": "Main Debug [Launch]", "cwd": "${workspaceRoot}", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1f6aced1..1a27525d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,7 +14,17 @@ ], "group": "build" }, - + { + "label": "build-simulator-units-tests", + "type": "shell", + "command": "utilities/build.sh", + "args": [ + "-tunit_tests", + "-fmain", + "-psimulator", + ], + "group": "build" + }, { "label": "build-device", "type": "shell", From 2f4bb15da85de27af8c337e382bd4cb7a82f3fab Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 16:12:31 +0530 Subject: [PATCH 13/32] chore (evm): Domain-only and empty unit tests added --- tests/apps/evm_app/evm_sign_msg_tests.c | 108 ++++++++++++++++++++++++ tests/unit_test_lists.c | 3 + 2 files changed, 111 insertions(+) diff --git a/tests/apps/evm_app/evm_sign_msg_tests.c b/tests/apps/evm_app/evm_sign_msg_tests.c index 4fe0678c..afb1f0ac 100644 --- a/tests/apps/evm_app/evm_sign_msg_tests.c +++ b/tests/apps/evm_app/evm_sign_msg_tests.c @@ -98,6 +98,114 @@ TEST_TEAR_DOWN(evm_sign_msg_test) { ctx.msg_data = NULL; } +TEST(evm_sign_msg_test, evm_sign_msg_test_empty_typed_data_hash) { + evm_query_t query = { + .which_request = 3, + .sign_msg = { + .which_request = 1, + .initiate = {.derivation_path_count = 5, + .derivation_path = {NON_SEGWIT, ETHEREUM, BITCOIN, 0, 0}, + .wallet_id = {}, + .message_type = EVM_SIGN_MSG_TYPE_SIGN_TYPED_DATA, + .total_msg_size = 121}}}; + uint8_t buffer[1024]; + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + uint8_t expected_digest[SHA256_DIGEST_LENGTH] = { + 48, 26, 80, 178, 145, 211, 60, 225, 232, 233, 6, + 78, 63, 106, 108, 81, 217, 2, 236, 34, 137, 43, + 80, 213, 138, 191, 99, 87, 198, 164, 85, 65}; + + // Set init query to ctx buffer + memcpy(&ctx.init, + &query.sign_msg.initiate, + sizeof(evm_sign_msg_initiate_request_t)); + + // Prepare typed data from msg_data + char *string = + "0a3a0a06646f6d61696e1007220c454950373132446f6d61696e322020bcc3f8105eea47" + "d067386e42e60246e89393cd61c512edd1e87688890fb914123b0a076d65737361676510" + "07220c454950373132446f6d61696e322020bcc3f8105eea47d067386e42e60246e89393" + "cd61c512edd1e87688890fb914"; + ctx.msg_data = buffer; + hex_string_to_byte_array(string, ctx.init.total_msg_size * 2, buffer); + pb_istream_t istream = + pb_istream_from_buffer(ctx.msg_data, ctx.init.total_msg_size); + bool result = + pb_decode(&istream, EVM_SIGN_TYPED_DATA_STRUCT_FIELDS, &(ctx.typed_data)); + +#ifdef EVM_SIGN_TYPED_DATA_DISPLAY_TEST + // Display the typed data + ui_display_node *display_node = NULL; + evm_init_typed_data_display_node(&display_node, &(ctx.typed_data)); + while (NULL != display_node) { + core_scroll_page(display_node->title, display_node->value, evm_send_error); + display_node = display_node->next; + } +#endif + TEST_ASSERT_TRUE(result); + TEST_ASSERT_TRUE(evm_get_msg_data_digest(&ctx, digest)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_digest, digest, SHA256_DIGEST_LENGTH); + + pb_release(EVM_SIGN_TYPED_DATA_STRUCT_FIELDS, &(ctx.typed_data)); +} + +TEST(evm_sign_msg_test, evm_sign_msg_test_domain_only_typed_data_hash) { + evm_query_t query = { + .which_request = 3, + .sign_msg = { + .which_request = 1, + .initiate = {.derivation_path_count = 5, + .derivation_path = {NON_SEGWIT, ETHEREUM, BITCOIN, 0, 0}, + .wallet_id = {}, + .message_type = EVM_SIGN_MSG_TYPE_SIGN_TYPED_DATA, + .total_msg_size = 355}}}; + uint8_t buffer[1024]; + uint8_t digest[SHA256_DIGEST_LENGTH] = {0}; + uint8_t expected_digest[SHA256_DIGEST_LENGTH] = { + 116, 118, 39, 55, 210, 218, 151, 77, 201, 234, 163, + 106, 199, 100, 63, 130, 38, 147, 175, 116, 232, 98, + 80, 99, 235, 157, 156, 36, 198, 0, 10, 52}; + + // Set init query to ctx buffer + memcpy(&ctx.init, + &query.sign_msg.initiate, + sizeof(evm_sign_msg_initiate_request_t)); + + // Prepare typed data from msg_data + char *string = + "0aa3020a06646f6d61696e10071805220c454950373132446f6d61696e3220d87cd6ef79" + "d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac564723a1a0a046e616d6510" + "0318062206737472696e672a065472657a6f723a220a0776657273696f6e1003180b2206" + "737472696e672a0b546573742076302e302e303a360a07636861696e4964182022077569" + "6e743235362a200000000000000000000000000000000000000000000000000000000000" + "0000013a360a11766572696679696e67436f6e7472616374100518142207616464726573" + "732a14cccccccccccccccccccccccccccccccccccccccc3a350a0473616c741002182022" + "07627974657333322a200123456789abcdef0123456789abcdef0123456789abcdef0123" + "456789abcdef123b0a076d6573736167651007220c454950373132446f6d61696e3220d8" + "7cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472"; + ctx.msg_data = buffer; + hex_string_to_byte_array(string, ctx.init.total_msg_size * 2, buffer); + pb_istream_t istream = + pb_istream_from_buffer(ctx.msg_data, ctx.init.total_msg_size); + bool result = + pb_decode(&istream, EVM_SIGN_TYPED_DATA_STRUCT_FIELDS, &(ctx.typed_data)); + +#ifdef EVM_SIGN_TYPED_DATA_DISPLAY_TEST + // Display the typed data + ui_display_node *display_node = NULL; + evm_init_typed_data_display_node(&display_node, &(ctx.typed_data)); + while (NULL != display_node) { + core_scroll_page(display_node->title, display_node->value, evm_send_error); + display_node = display_node->next; + } +#endif + TEST_ASSERT_TRUE(result); + TEST_ASSERT_TRUE(evm_get_msg_data_digest(&ctx, digest)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_digest, digest, SHA256_DIGEST_LENGTH); + + pb_release(EVM_SIGN_TYPED_DATA_STRUCT_FIELDS, &(ctx.typed_data)); +} + TEST(evm_sign_msg_test, evm_sign_msg_test_typed_data_hash) { evm_query_t query = { .which_request = 3, diff --git a/tests/unit_test_lists.c b/tests/unit_test_lists.c index 48e47355..182410b2 100644 --- a/tests/unit_test_lists.c +++ b/tests/unit_test_lists.c @@ -185,6 +185,9 @@ TEST_GROUP_RUNNER(evm_txn_test) { } TEST_GROUP_RUNNER(evm_sign_msg_test) { + RUN_TEST_CASE(evm_sign_msg_test, evm_sign_msg_test_empty_typed_data_hash); + RUN_TEST_CASE(evm_sign_msg_test, + evm_sign_msg_test_domain_only_typed_data_hash); RUN_TEST_CASE(evm_sign_msg_test, evm_sign_msg_test_typed_data_hash); RUN_TEST_CASE(evm_sign_msg_test, evm_sign_msg_test_personal_sign_hash); RUN_TEST_CASE(evm_sign_msg_test, evm_sign_msg_test_eth_sign_hash); From 7e9613b2e20632655f0e577bbe2fa7770d959f25 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 16:13:54 +0530 Subject: [PATCH 14/32] fix (evm): Added domain and message only checks --- apps/evm_family/evm_typed_data_helper.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index d70485e9..5e78a6a5 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -178,7 +178,14 @@ bool evm_get_typed_struct_data_digest( uint8_t *data = NULL; uint16_t data_size = 0, offset = 0; - data_size = sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1 + HASH_SIZE * 2; + data_size = sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; + if (0 < (unsigned int)(typed_data->domain).size) { + data_size += HASH_SIZE; + } + if (0 < (unsigned int)(typed_data->message).size) { + data_size += HASH_SIZE; + } + data = malloc(data_size); ASSERT(NULL != data); memzero(data, data_size); @@ -187,9 +194,17 @@ bool evm_get_typed_struct_data_digest( sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1); offset += sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; - eip712_status = hash_struct(&(typed_data->domain), data + offset); + if (0 < (unsigned int)(typed_data->domain).size) { + eip712_status = hash_struct(&(typed_data->domain), data + offset); + } else { + eip712_status = 0; + } offset += HASH_SIZE; - eip712_status |= hash_struct(&(typed_data->message), data + offset); + if (0 < (unsigned int)(typed_data->message).size) { + eip712_status |= hash_struct(&(typed_data->message), data + offset); + } else { + eip712_status |= 0; + } if (EIP712_OK == eip712_status) { keccak_256(data, data_size, digest_out); From 6420e013e142b620d3bcec66530e6751ee99cc1c Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 18:09:19 +0530 Subject: [PATCH 15/32] chore: Added special char for passphrase --- common/interfaces/user_interface/ui_common.c | 4 ++-- common/interfaces/user_interface/ui_input_text.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/interfaces/user_interface/ui_common.c b/common/interfaces/user_interface/ui_common.c index 321247bf..d1032ac9 100644 --- a/common/interfaces/user_interface/ui_common.c +++ b/common/interfaces/user_interface/ui_common.c @@ -64,8 +64,8 @@ const char *ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ALPHA_NUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const char *NUMBERS = "0123456789"; const char *HEX = "0123456789ABCDEF"; -const char *PASSPHRASE = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "; +const char *PASSPHRASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0" + "123456789 !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; /// Global callback method called when an event is marked over void (*ui_mark_event_over)(); diff --git a/common/interfaces/user_interface/ui_input_text.h b/common/interfaces/user_interface/ui_input_text.h index 3daa998d..262c030b 100644 --- a/common/interfaces/user_interface/ui_input_text.h +++ b/common/interfaces/user_interface/ui_input_text.h @@ -16,7 +16,7 @@ #define MAX_INPUT_SIZE \ 10 // This is the max number of characters that can be shown in a screen -#define MAX_CHARACTER_INPUT_LIST 80 +#define MAX_CHARACTER_INPUT_LIST 100 #define MAX_PIN_SIZE 8 #define MAX_PASSPHRASE_SIZE 63 #define MAX_ARRAY_SIZE 512 From 68f47bfa03a9b174db4fffacd006452583c9b214 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 18:30:31 +0530 Subject: [PATCH 16/32] chore: Update confirm texts --- src/constant_texts.c | 6 +++++- src/settings/factory_reset.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/constant_texts.c b/src/constant_texts.c index ef97a6c9..8bd625ee 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -136,7 +136,8 @@ const char *ui_text_factory_reset_instruction = "You will need 2 cards to perform factory reset\nMake sure at least 2 " "cards are accessible\nDo you want to proceed?"; const char *ui_text_confirm_factory_reset = - "This will erase all wallets from device. Confirm?"; + "This will erase all wallets from device\nYour device will reset to " + "factory default settings.\nConfirm?"; const char *ui_text_erasing = "Factory reset done Device will restart"; const char *ui_text_reset_exit[NUMBER_OF_SLIDES_FACTORY_RESET_EXIT] = { "Exiting without factory reset", @@ -160,6 +161,9 @@ const char *ui_text_syncing_complete = "wallet(s) synced"; const char *ui_text_clear_device_data_instruction = "You will need 2 cards to perform clear device data\nMake sure at least 2 " "cards are accessible\nDo you want to proceed?"; +const char *ui_text_confirm_clear_device_data = + "This will erase all wallets from device\nYour device will reset and go to " + "main menu.\nConfirm?"; const char *ui_text_erasing_device_data = "Device data cleared Device will restart"; const char diff --git a/src/settings/factory_reset.c b/src/settings/factory_reset.c index 51c83156..5c0e4bb0 100644 --- a/src/settings/factory_reset.c +++ b/src/settings/factory_reset.c @@ -339,7 +339,7 @@ void clear_device_data(void) { return; } - if (!core_scroll_page(NULL, ui_text_confirm_factory_reset, NULL)) { + if (!core_scroll_page(NULL, ui_text_confirm_clear_device_data, NULL)) { return; } From 7fcb6eafab4fdd5fcb9cc71d743b327881f80134 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 12 Mar 2024 18:35:17 +0530 Subject: [PATCH 17/32] chore (fix): Update confirm texts --- src/constant_texts.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constant_texts.h b/src/constant_texts.h index f659f1fb..539ba359 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -132,6 +132,7 @@ extern const char *ui_text_syncing_complete; // Clear user data text extern const char *ui_text_clear_device_data_instruction; +extern const char *ui_text_confirm_clear_device_data; extern const char *ui_text_erasing_device_data; extern const char *ui_text_clear_wallet_data_exit[NUMBER_OF_SLIDES_FACTORY_RESET_EXIT]; From 73983a09488dee14a27d7c7ce0f6d6b9de209f70 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Wed, 13 Mar 2024 18:14:11 +0530 Subject: [PATCH 18/32] chore: Removed typecast --- apps/evm_family/evm_typed_data_helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index 5e78a6a5..b4d5462c 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -179,10 +179,10 @@ bool evm_get_typed_struct_data_digest( uint16_t data_size = 0, offset = 0; data_size = sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; - if (0 < (unsigned int)(typed_data->domain).size) { + if (0 < typed_data->domain.size) { data_size += HASH_SIZE; } - if (0 < (unsigned int)(typed_data->message).size) { + if (0 < typed_data->message.size) { data_size += HASH_SIZE; } @@ -194,13 +194,13 @@ bool evm_get_typed_struct_data_digest( sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1); offset += sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; - if (0 < (unsigned int)(typed_data->domain).size) { + if (0 < typed_data->domain.size) { eip712_status = hash_struct(&(typed_data->domain), data + offset); } else { eip712_status = 0; } offset += HASH_SIZE; - if (0 < (unsigned int)(typed_data->message).size) { + if (0 < typed_data->message.size) { eip712_status |= hash_struct(&(typed_data->message), data + offset); } else { eip712_status |= 0; From 140692e97257aa97514b334a0a267dff42515514 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Sat, 16 Mar 2024 18:42:35 +0530 Subject: [PATCH 19/32] feat(font): Added verdana font for symbols --- common/interfaces/user_interface/ui_common.c | 2 +- common/lv_conf.h | 5 +- common/lvgl/src/lv_font/lv_font.h | 4 + common/lvgl/src/lv_font/lv_font.mk | 1 + common/lvgl/src/lv_font/lv_font_verdana_11.c | 1436 ++++++++++++++++++ 5 files changed, 1445 insertions(+), 3 deletions(-) create mode 100644 common/lvgl/src/lv_font/lv_font_verdana_11.c diff --git a/common/interfaces/user_interface/ui_common.c b/common/interfaces/user_interface/ui_common.c index d1032ac9..e52a1b75 100644 --- a/common/interfaces/user_interface/ui_common.c +++ b/common/interfaces/user_interface/ui_common.c @@ -65,7 +65,7 @@ const char *ALPHA_NUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const char *NUMBERS = "0123456789"; const char *HEX = "0123456789ABCDEF"; const char *PASSPHRASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0" - "123456789 !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; + "123456789 !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; /// Global callback method called when an event is marked over void (*ui_mark_event_over)(); diff --git a/common/lv_conf.h b/common/lv_conf.h index eb4d7f83..c1e0926c 100644 --- a/common/lv_conf.h +++ b/common/lv_conf.h @@ -266,10 +266,11 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i /* Robot fonts with bpp = 4 * https://fonts.google.com/specimen/Roboto */ -#define LV_FONT_ROBOTO_12 1 +#define LV_FONT_ROBOTO_12 0 #define LV_FONT_ROBOTO_16 0 #define LV_FONT_ROBOTO_22 0 #define LV_FONT_ROBOTO_28 0 +#define LV_FONT_VERDANA_11 1 /*Pixel perfect monospace font * http://pelulamu.net/unscii/ */ @@ -284,7 +285,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font) LV_FONT_DECLARE(my_logo) LV_FONT_DECLARE(nfc_logo) /*Always set a default font from the built-in fonts*/ -#define LV_FONT_DEFAULT &lv_font_roboto_12 +#define LV_FONT_DEFAULT &lv_font_verdana_11 /* Enable it if you have fonts with a lot of characters. * The limit depends on the font size, font face and bpp diff --git a/common/lvgl/src/lv_font/lv_font.h b/common/lvgl/src/lv_font/lv_font.h index e639a54a..07a26353 100644 --- a/common/lvgl/src/lv_font/lv_font.h +++ b/common/lvgl/src/lv_font/lv_font.h @@ -138,6 +138,10 @@ LV_FONT_DECLARE(lv_font_roboto_28) LV_FONT_DECLARE(lv_font_unscii_8) #endif +#if LV_FONT_VERDANA_11 +LV_FONT_DECLARE(lv_font_verdana_11) +#endif + /*Declare the custom (user defined) fonts*/ #ifdef LV_FONT_CUSTOM_DECLARE LV_FONT_CUSTOM_DECLARE diff --git a/common/lvgl/src/lv_font/lv_font.mk b/common/lvgl/src/lv_font/lv_font.mk index 9f7918cf..c8b95eba 100644 --- a/common/lvgl/src/lv_font/lv_font.mk +++ b/common/lvgl/src/lv_font/lv_font.mk @@ -4,6 +4,7 @@ SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_12.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_16.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_22.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_28.c +SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_verdana_11.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_unscii_8.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/my_logo.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/nfc_logo.c diff --git a/common/lvgl/src/lv_font/lv_font_verdana_11.c b/common/lvgl/src/lv_font/lv_font_verdana_11.c new file mode 100644 index 00000000..e89860b7 --- /dev/null +++ b/common/lvgl/src/lv_font/lv_font_verdana_11.c @@ -0,0 +1,1436 @@ +/******************************************************************************* + * Size: 11 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 11 --font verdana.ttf -r 0x20-0x7F --font FontAwesome.ttf -r 61441,61448,61451,61452,61453,61457,61459,61460,61461,61465,61468,61473,61478,61479,61480,61502,61504,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62099 --format lvgl -o lv_font_verdana_11.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_VERDANA_11 +#define LV_FONT_VERDANA_11 1 +#endif + +#if LV_FONT_VERDANA_11 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x6c, 0x6b, 0x5b, 0x5a, 0x5a, 0x26, 0x1, 0x6b, + + /* U+0022 "\"" */ + 0xf, 0xf, 0x10, 0xf0, 0xe0, 0xc, 0xc, 0x0, + 0x0, 0x0, + + /* U+0023 "#" */ + 0x0, 0x1a, 0xb, 0x0, 0x5, 0x62, 0x80, 0x3b, + 0xec, 0xdc, 0xa0, 0xa, 0xa, 0x0, 0x0, 0xa0, + 0xb0, 0xa, 0xcd, 0xbd, 0xb3, 0x8, 0x26, 0x40, + 0x0, 0xb0, 0x91, 0x0, + + /* U+0024 "$" */ + 0x0, 0xa, 0x0, 0x0, 0x3b, 0xec, 0x90, 0xe, + 0x2a, 0x4, 0x0, 0xf3, 0xa0, 0x0, 0x4, 0xcf, + 0xb5, 0x0, 0x0, 0xa3, 0xe2, 0x13, 0xa, 0xd, + 0x11, 0xcc, 0xeb, 0x50, 0x0, 0xa, 0x0, 0x0, + 0x0, 0xa0, 0x0, + + /* U+0025 "%" */ + 0x7, 0xbc, 0x20, 0xa, 0x30, 0x0, 0x1d, 0x5, + 0x90, 0x3a, 0x0, 0x0, 0x2c, 0x3, 0xb0, 0xb2, + 0x0, 0x0, 0xd, 0x6, 0x94, 0x92, 0xbb, 0x40, + 0x5, 0xba, 0x1c, 0x1b, 0x31, 0xd0, 0x0, 0x0, + 0x49, 0xe, 0x10, 0xe0, 0x0, 0x0, 0xc1, 0xc, + 0x20, 0xd0, 0x0, 0x5, 0x80, 0x4, 0xaa, 0x50, + + /* U+0026 "&" */ + 0x4, 0xbb, 0xa0, 0x0, 0x0, 0xe2, 0xd, 0x40, + 0x0, 0xd, 0x61, 0xd1, 0x0, 0x0, 0x3f, 0xd3, + 0x1b, 0x0, 0x1d, 0x29, 0xa2, 0xc0, 0x5, 0xc0, + 0x9, 0xd8, 0x0, 0x3e, 0x10, 0x1e, 0xb0, 0x0, + 0x6c, 0xaa, 0x27, 0xc0, + + /* U+0027 "'" */ + 0x1f, 0x0, 0xf0, 0xd, 0x0, 0x0, + + /* U+0028 "(" */ + 0x0, 0x6b, 0x0, 0x1e, 0x10, 0x9, 0x70, 0x0, + 0xd2, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, 0xd, + 0x10, 0x0, 0x97, 0x0, 0x1, 0xd0, 0x0, 0x6, + 0xb0, + + /* U+0029 ")" */ + 0xb, 0x60, 0x0, 0x1d, 0x10, 0x0, 0x78, 0x0, + 0x2, 0xd0, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, + 0x2d, 0x0, 0x7, 0x80, 0x1, 0xe1, 0x0, 0xb6, + 0x0, + + /* U+002A "*" */ + 0x1, 0xa, 0x1, 0x0, 0x98, 0xb8, 0x90, 0x0, + 0x8f, 0x80, 0x0, 0xa5, 0xa5, 0xa0, 0x0, 0x8, + 0x0, 0x0, + + /* U+002B "+" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0xe, 0x0, 0xb, 0xdd, 0xfd, 0xdb, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, + 0x0, + + /* U+002C "," */ + 0x2, 0x70, 0x8, 0xa0, 0xc, 0x30, 0x1c, 0x0, + + /* U+002D "-" */ + 0x2f, 0xff, 0x20, + + /* U+002E "." */ + 0x44, 0xaa, + + /* U+002F "/" */ + 0x0, 0x0, 0x86, 0x0, 0x0, 0xd0, 0x0, 0x5, + 0x90, 0x0, 0xb, 0x30, 0x0, 0x2c, 0x0, 0x0, + 0x86, 0x0, 0x0, 0xd0, 0x0, 0x5, 0x90, 0x0, + 0xc, 0x20, 0x0, 0x6, 0x0, 0x0, + + /* U+0030 "0" */ + 0x2, 0xce, 0xc2, 0x0, 0xd5, 0x5, 0xc0, 0x2f, + 0x0, 0xe, 0x13, 0xd0, 0x0, 0xd3, 0x3d, 0x0, + 0xd, 0x32, 0xe0, 0x0, 0xe2, 0xd, 0x50, 0x5d, + 0x0, 0x2c, 0xdc, 0x20, + + /* U+0031 "1" */ + 0x0, 0xd3, 0x5, 0xdf, 0x30, 0x0, 0xd3, 0x0, + 0xd, 0x30, 0x0, 0xd3, 0x0, 0xd, 0x30, 0x0, + 0xd3, 0x6, 0xcf, 0xda, + + /* U+0032 "2" */ + 0xa, 0xee, 0xc2, 0x0, 0x60, 0x7, 0xc0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x9, 0x90, 0x0, 0x7, + 0xc0, 0x0, 0x7, 0xc1, 0x0, 0xa, 0xa0, 0x0, + 0x2, 0xfe, 0xee, 0xe4, + + /* U+0033 "3" */ + 0x8, 0xde, 0xd5, 0x0, 0x50, 0x4, 0xe0, 0x0, + 0x0, 0x6b, 0x0, 0x3, 0xed, 0x20, 0x0, 0x0, + 0x4e, 0x0, 0x0, 0x0, 0xf1, 0x15, 0x0, 0x6e, + 0x0, 0xbe, 0xec, 0x30, + + /* U+0034 "4" */ + 0x0, 0x2, 0xf4, 0x0, 0x1, 0xdd, 0x40, 0x0, + 0xb4, 0xc4, 0x0, 0x97, 0xc, 0x40, 0x6a, 0x0, + 0xc4, 0x8, 0xdd, 0xdf, 0xd6, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0xc, 0x40, + + /* U+0035 "5" */ + 0xaf, 0xee, 0xe2, 0xa6, 0x0, 0x0, 0xa6, 0x0, + 0x0, 0xae, 0xec, 0x40, 0x0, 0x5, 0xf0, 0x0, + 0x0, 0xe2, 0x50, 0x5, 0xe0, 0xbe, 0xec, 0x30, + + /* U+0036 "6" */ + 0x0, 0x5d, 0xe9, 0x0, 0x7c, 0x20, 0x0, 0xf, + 0x20, 0x0, 0x2, 0xfa, 0xdd, 0x50, 0x3e, 0x10, + 0x2e, 0x22, 0xe0, 0x0, 0xb5, 0xd, 0x50, 0x1e, + 0x20, 0x2b, 0xdc, 0x40, + + /* U+0037 "7" */ + 0x2e, 0xee, 0xef, 0x40, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x79, 0x0, 0x0, 0x1e, 0x10, 0x0, 0x9, + 0x80, 0x0, 0x2, 0xe1, 0x0, 0x0, 0xa7, 0x0, + 0x0, 0x3e, 0x0, 0x0, + + /* U+0038 "8" */ + 0x4, 0xcc, 0xc4, 0x0, 0xf1, 0x2, 0xf0, 0xf, + 0x40, 0x1f, 0x0, 0x5f, 0xbb, 0x40, 0xc, 0x43, + 0xac, 0x4, 0xc0, 0x0, 0xd4, 0x2e, 0x20, 0x1e, + 0x20, 0x5c, 0xcc, 0x40, + + /* U+0039 "9" */ + 0x4, 0xdd, 0xb2, 0x2, 0xe2, 0x5, 0xc0, 0x5b, + 0x0, 0xe, 0x22, 0xe2, 0x1, 0xe3, 0x5, 0xdd, + 0xaf, 0x20, 0x0, 0x2, 0xe0, 0x0, 0x1, 0xc6, + 0x0, 0x9e, 0xd5, 0x0, + + /* U+003A ":" */ + 0x2f, 0x21, 0x71, 0x0, 0x0, 0x0, 0x17, 0x12, + 0xf2, + + /* U+003B ";" */ + 0x2f, 0x21, 0x71, 0x0, 0x0, 0x0, 0x7, 0x31, + 0xf1, 0x5a, 0xa, 0x30, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x18, 0xd5, 0x3, + 0xac, 0x60, 0x8, 0xf5, 0x0, 0x0, 0x6, 0xda, + 0x30, 0x0, 0x0, 0x4b, 0xc4, 0x0, 0x0, 0x2, + 0x40, + + /* U+003D "=" */ + 0x9d, 0xdd, 0xdd, 0x90, 0x0, 0x0, 0x0, 0x9d, + 0xdd, 0xdd, 0x90, + + /* U+003E ">" */ + 0x20, 0x0, 0x0, 0x5, 0xd8, 0x10, 0x0, 0x0, + 0x6c, 0xa3, 0x0, 0x0, 0x5, 0xf8, 0x0, 0x3a, + 0xc6, 0x4, 0xcb, 0x40, 0x0, 0x42, 0x0, 0x0, + 0x0, + + /* U+003F "?" */ + 0x1c, 0xee, 0x80, 0x3, 0x1, 0xd4, 0x0, 0x0, + 0xc4, 0x0, 0x8, 0xc0, 0x0, 0xb8, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x10, 0x0, 0x0, 0xd4, 0x0, + + /* U+0040 "@" */ + 0x0, 0x7, 0xbb, 0xb9, 0x10, 0x0, 0xb, 0x50, + 0x0, 0x2c, 0x20, 0x8, 0x42, 0xcc, 0xc8, 0x2a, + 0x0, 0xc0, 0xb4, 0x5, 0x80, 0xc0, 0xb, 0xd, + 0x0, 0x58, 0xb, 0x0, 0xc0, 0xa5, 0x8, 0x80, + 0xb0, 0x8, 0x51, 0xab, 0x7b, 0x95, 0x0, 0xb, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x5, 0xbb, 0xb5, + 0x0, 0x0, + + /* U+0041 "A" */ + 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x7a, 0xf0, 0x0, + 0x0, 0xd3, 0xb6, 0x0, 0x3, 0xd0, 0x6b, 0x0, + 0x9, 0x80, 0x1f, 0x10, 0xe, 0xee, 0xef, 0x70, + 0x5c, 0x0, 0x5, 0xd0, 0xa6, 0x0, 0x0, 0xe3, + + /* U+0042 "B" */ + 0xee, 0xee, 0xa0, 0xe, 0x20, 0xd, 0x50, 0xe2, + 0x1, 0xd2, 0xe, 0xdd, 0xfc, 0x20, 0xe2, 0x0, + 0x6d, 0xe, 0x20, 0x0, 0xf0, 0xe2, 0x0, 0x6d, + 0xe, 0xee, 0xeb, 0x20, + + /* U+0043 "C" */ + 0x0, 0x7d, 0xee, 0x91, 0x9, 0xb1, 0x1, 0x73, + 0x2f, 0x10, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x5c, 0x0, 0x0, 0x0, 0x2f, 0x10, 0x0, 0x0, + 0xa, 0xb1, 0x1, 0x73, 0x0, 0x8d, 0xee, 0x91, + + /* U+0044 "D" */ + 0xee, 0xee, 0x91, 0xe, 0x20, 0x17, 0xe1, 0xe2, + 0x0, 0x9, 0x8e, 0x20, 0x0, 0x5c, 0xe2, 0x0, + 0x5, 0xce, 0x20, 0x0, 0x98, 0xe2, 0x0, 0x7e, + 0x1e, 0xee, 0xe9, 0x10, + + /* U+0045 "E" */ + 0xee, 0xee, 0xe5, 0xe2, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0xee, 0xee, 0xe4, 0xe2, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xee, 0xee, 0xe5, + + /* U+0046 "F" */ + 0xee, 0xee, 0xe2, 0xe2, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0xee, 0xee, 0x80, 0xe2, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x7d, 0xee, 0xb4, 0x9, 0xc2, 0x0, 0x48, + 0x2f, 0x10, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x5c, 0x0, 0x6e, 0xeb, 0x2f, 0x10, 0x0, 0x5c, + 0x9, 0xc2, 0x0, 0x6c, 0x0, 0x6c, 0xed, 0xb4, + + /* U+0048 "H" */ + 0xe2, 0x0, 0xe, 0x3e, 0x20, 0x0, 0xe3, 0xe2, + 0x0, 0xe, 0x3e, 0xee, 0xee, 0xf3, 0xe2, 0x0, + 0xe, 0x3e, 0x20, 0x0, 0xe3, 0xe2, 0x0, 0xe, + 0x3e, 0x20, 0x0, 0xe3, + + /* U+0049 "I" */ + 0x3d, 0xfb, 0x3, 0xd0, 0x3, 0xd0, 0x3, 0xd0, + 0x3, 0xd0, 0x3, 0xd0, 0x3, 0xd0, 0x3d, 0xfb, + + /* U+004A "J" */ + 0x9, 0xdf, 0x0, 0x1f, 0x0, 0x1f, 0x0, 0x1f, + 0x0, 0x1f, 0x0, 0x1f, 0x0, 0x4d, 0xae, 0xd4, + + /* U+004B "K" */ + 0xe2, 0x0, 0x6c, 0xe, 0x20, 0x5d, 0x10, 0xe2, + 0x4d, 0x10, 0xe, 0x6e, 0x20, 0x0, 0xed, 0xe6, + 0x0, 0xe, 0x32, 0xe4, 0x0, 0xe2, 0x3, 0xe3, + 0xe, 0x20, 0x5, 0xe2, + + /* U+004C "L" */ + 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xee, 0xee, 0xe2, + + /* U+004D "M" */ + 0xec, 0x0, 0x8, 0xf3, 0xed, 0x30, 0xd, 0xe3, + 0xe5, 0xb0, 0x77, 0xd3, 0xe1, 0xc3, 0xd0, 0xd3, + 0xe1, 0x5e, 0x80, 0xd3, 0xe1, 0xb, 0x10, 0xd3, + 0xe1, 0x0, 0x0, 0xd3, 0xe1, 0x0, 0x0, 0xd3, + + /* U+004E "N" */ + 0xee, 0x0, 0xd, 0x2e, 0xa8, 0x0, 0xd2, 0xe2, + 0xe1, 0xd, 0x2e, 0x18, 0x90, 0xd2, 0xe1, 0x1e, + 0x2d, 0x2e, 0x10, 0x7a, 0xd2, 0xe1, 0x0, 0xee, + 0x2e, 0x10, 0x6, 0xf2, + + /* U+004F "O" */ + 0x0, 0x8e, 0xed, 0x40, 0x0, 0xaa, 0x10, 0x3e, + 0x40, 0x2f, 0x0, 0x0, 0x5c, 0x4, 0xc0, 0x0, + 0x2, 0xf0, 0x4c, 0x0, 0x0, 0x2f, 0x2, 0xf0, + 0x0, 0x5, 0xd0, 0xa, 0xa1, 0x3, 0xe4, 0x0, + 0x8, 0xee, 0xd5, 0x0, + + /* U+0050 "P" */ + 0xee, 0xed, 0x50, 0xe2, 0x3, 0xf1, 0xe2, 0x0, + 0xd4, 0xe2, 0x5, 0xe1, 0xee, 0xeb, 0x30, 0xe2, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x8e, 0xed, 0x40, 0x0, 0xaa, 0x10, 0x3e, + 0x40, 0x2f, 0x0, 0x0, 0x5c, 0x4, 0xc0, 0x0, + 0x2, 0xf0, 0x4c, 0x0, 0x0, 0x2f, 0x2, 0xf0, + 0x0, 0x5, 0xc0, 0xa, 0xa1, 0x3, 0xe5, 0x0, + 0x8, 0xee, 0xf5, 0x0, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0x0, 0x0, 0x7e, 0xe2, + + /* U+0052 "R" */ + 0xee, 0xed, 0x60, 0xe, 0x20, 0x2f, 0x20, 0xe2, + 0x0, 0xd4, 0xe, 0x20, 0x4e, 0x0, 0xed, 0xee, + 0x20, 0xe, 0x20, 0xc7, 0x0, 0xe2, 0x1, 0xe5, + 0xe, 0x20, 0x2, 0xe4, + + /* U+0053 "S" */ + 0x3, 0xce, 0xec, 0x41, 0xf3, 0x0, 0x45, 0x2f, + 0x0, 0x0, 0x0, 0xbe, 0x97, 0x20, 0x0, 0x37, + 0x9e, 0x70, 0x0, 0x0, 0x4d, 0x38, 0x10, 0x9, + 0xa1, 0xae, 0xed, 0x90, + + /* U+0054 "T" */ + 0xee, 0xef, 0xee, 0xb0, 0x2, 0xe0, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2, 0xe0, 0x0, + + /* U+0055 "U" */ + 0xf, 0x0, 0x0, 0xf1, 0xf, 0x0, 0x0, 0xf1, + 0xf, 0x0, 0x0, 0xf1, 0xf, 0x0, 0x0, 0xf1, + 0xf, 0x0, 0x0, 0xf1, 0xf, 0x10, 0x0, 0xf0, + 0xa, 0x80, 0x8, 0xb0, 0x1, 0xae, 0xeb, 0x10, + + /* U+0056 "V" */ + 0xa7, 0x0, 0x0, 0xe3, 0x5d, 0x0, 0x3, 0xd0, + 0xe, 0x20, 0x9, 0x70, 0x9, 0x80, 0xe, 0x10, + 0x3, 0xe0, 0x5b, 0x0, 0x0, 0xd3, 0xa6, 0x0, + 0x0, 0x7a, 0xe0, 0x0, 0x0, 0x2f, 0xa0, 0x0, + + /* U+0057 "W" */ + 0x5b, 0x0, 0x3f, 0x10, 0xc, 0x31, 0xf0, 0x7, + 0xe5, 0x0, 0xf0, 0xd, 0x30, 0xb6, 0x90, 0x4b, + 0x0, 0x97, 0xd, 0xd, 0x8, 0x70, 0x5, 0xb3, + 0xa0, 0xc1, 0xc3, 0x0, 0x1f, 0x76, 0x8, 0x6e, + 0x0, 0x0, 0xce, 0x20, 0x4d, 0xa0, 0x0, 0x8, + 0xe0, 0x0, 0xf6, 0x0, + + /* U+0058 "X" */ + 0x3e, 0x10, 0x5, 0xc0, 0x8, 0xa0, 0x1e, 0x20, + 0x0, 0xd4, 0xa6, 0x0, 0x0, 0x3f, 0xb0, 0x0, + 0x0, 0x3e, 0xc0, 0x0, 0x0, 0xd3, 0xb7, 0x0, + 0x9, 0x80, 0x1e, 0x20, 0x4d, 0x0, 0x6, 0xc0, + + /* U+0059 "Y" */ + 0xa8, 0x0, 0xb, 0x61, 0xe2, 0x5, 0xc0, 0x6, + 0xb0, 0xd2, 0x0, 0xc, 0xc8, 0x0, 0x0, 0x4f, + 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2, 0xe0, 0x0, + + /* U+005A "Z" */ + 0x2e, 0xee, 0xef, 0xc0, 0x0, 0x0, 0xd5, 0x0, + 0x0, 0xa8, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x4d, + 0x10, 0x0, 0x2e, 0x20, 0x0, 0xd, 0x50, 0x0, + 0x5, 0xfe, 0xee, 0xed, + + /* U+005B "[" */ + 0xbc, 0xc0, 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, + 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, + 0xb3, 0x0, 0xbc, 0xc0, + + /* U+005C "\\" */ + 0x68, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x50, + 0x0, 0x3, 0xb0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x68, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x50, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x60, + + /* U+005D "]" */ + 0xc, 0xcb, 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, + 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, + 0x0, 0x3b, 0xc, 0xcb, + + /* U+005E "^" */ + 0x0, 0x4f, 0x40, 0x0, 0x1d, 0x3d, 0x10, 0xc, + 0x40, 0x4c, 0x9, 0x70, 0x0, 0x79, + + /* U+005F "_" */ + 0xa, 0xaa, 0xaa, 0xaa, 0x0, + + /* U+0060 "`" */ + 0xc, 0x50, 0x2, 0xc0, + + /* U+0061 "a" */ + 0xb, 0xed, 0xb1, 0x2, 0x0, 0x88, 0x5, 0xac, + 0xda, 0x4d, 0x20, 0x5a, 0x5a, 0x0, 0x8a, 0xb, + 0xcc, 0xba, + + /* U+0062 "b" */ + 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf8, 0xee, + 0x50, 0xf5, 0x3, 0xe0, 0xf0, 0x0, 0xd3, 0xf0, + 0x0, 0xd3, 0xf0, 0x4, 0xd0, 0xfb, 0xdc, 0x30, + + /* U+0063 "c" */ + 0x4, 0xcd, 0xd4, 0x1e, 0x20, 0x13, 0x5a, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x1e, 0x20, 0x13, 0x4, + 0xdd, 0xd4, + + /* U+0064 "d" */ + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x2d, 0x4, 0xde, + 0xcd, 0x1e, 0x30, 0x3d, 0x5b, 0x0, 0x2d, 0x5a, + 0x0, 0x2d, 0x2e, 0x0, 0x4d, 0x6, 0xdb, 0xad, + + /* U+0065 "e" */ + 0x4, 0xcc, 0xc3, 0x1, 0xc1, 0x3, 0xd0, 0x5e, + 0xcc, 0xcd, 0x5, 0xb0, 0x0, 0x0, 0x1e, 0x40, + 0x5, 0x0, 0x4c, 0xdd, 0x90, + + /* U+0066 "f" */ + 0x5, 0xdd, 0x20, 0xe1, 0x0, 0x8f, 0xdb, 0x0, + 0xf1, 0x0, 0xf, 0x10, 0x0, 0xf1, 0x0, 0xf, + 0x10, 0x0, 0xf1, 0x0, + + /* U+0067 "g" */ + 0x4, 0xde, 0xcd, 0x1e, 0x30, 0x3d, 0x5b, 0x0, + 0x2d, 0x5a, 0x0, 0x2d, 0x2e, 0x10, 0x6d, 0x7, + 0xed, 0xac, 0x1, 0x0, 0x69, 0xa, 0xed, 0xa1, + + /* U+0068 "h" */ + 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf7, 0xde, + 0x50, 0xf5, 0x3, 0xe0, 0xf0, 0x0, 0xf0, 0xf0, + 0x0, 0xf0, 0xf0, 0x0, 0xf0, 0xf0, 0x0, 0xf0, + + /* U+0069 "i" */ + 0x1f, 0x10, 0x0, 0xf, 0x0, 0xf0, 0xf, 0x0, + 0xf0, 0xf, 0x0, 0xf0, + + /* U+006A "j" */ + 0x0, 0x4d, 0x0, 0x0, 0x6, 0xdc, 0x0, 0x3c, + 0x0, 0x3c, 0x0, 0x3c, 0x0, 0x3c, 0x0, 0x3c, + 0x0, 0x6b, 0x4e, 0xd3, + + /* U+006B "k" */ + 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x8, + 0xb0, 0xf0, 0x7b, 0x0, 0xf8, 0xb0, 0x0, 0xfa, + 0xe3, 0x0, 0xf0, 0x4e, 0x20, 0xf0, 0x5, 0xd1, + + /* U+006C "l" */ + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + + /* U+006D "m" */ + 0xf9, 0xcd, 0x6a, 0xcd, 0x2f, 0x30, 0x4e, 0x20, + 0x6a, 0xf0, 0x2, 0xd0, 0x4, 0xbf, 0x0, 0x2e, + 0x0, 0x4c, 0xf0, 0x2, 0xe0, 0x4, 0xcf, 0x0, + 0x2e, 0x0, 0x4c, + + /* U+006E "n" */ + 0xf9, 0xcd, 0x50, 0xf3, 0x2, 0xe0, 0xf0, 0x0, + 0xf0, 0xf0, 0x0, 0xf0, 0xf0, 0x0, 0xf0, 0xf0, + 0x0, 0xf0, + + /* U+006F "o" */ + 0x4, 0xdd, 0xb1, 0x1, 0xe2, 0x6, 0xc0, 0x5a, + 0x0, 0xf, 0x5, 0xa0, 0x0, 0xf0, 0x1e, 0x10, + 0x6c, 0x0, 0x5d, 0xdb, 0x20, + + /* U+0070 "p" */ + 0xf9, 0xbd, 0x50, 0xf2, 0x1, 0xe0, 0xf0, 0x0, + 0xc3, 0xf0, 0x0, 0xd3, 0xf0, 0x4, 0xd0, 0xfc, + 0xec, 0x30, 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x4, 0xde, 0xcd, 0x1e, 0x20, 0x3d, 0x5b, 0x0, + 0x2d, 0x5a, 0x0, 0x2d, 0x2e, 0x10, 0x6d, 0x6, + 0xed, 0x9d, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x2d, + + /* U+0072 "r" */ + 0xf7, 0xeb, 0xf6, 0x0, 0xf0, 0x0, 0xf0, 0x0, + 0xf0, 0x0, 0xf0, 0x0, + + /* U+0073 "s" */ + 0x9, 0xdd, 0xb0, 0x4c, 0x0, 0x30, 0x2e, 0x96, + 0x10, 0x1, 0x59, 0xe1, 0x32, 0x0, 0xd3, 0x3c, + 0xdd, 0x70, + + /* U+0074 "t" */ + 0x7, 0x0, 0x0, 0xf0, 0x0, 0x8f, 0xdd, 0x10, + 0xf0, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, 0xe, + 0x20, 0x0, 0x6e, 0xd1, + + /* U+0075 "u" */ + 0xf, 0x0, 0xf, 0xf, 0x0, 0xf, 0xf, 0x0, + 0xf, 0xf, 0x0, 0xf, 0xf, 0x10, 0x4f, 0x6, + 0xdc, 0x9f, + + /* U+0076 "v" */ + 0x79, 0x0, 0x1e, 0x1, 0xe0, 0x7, 0x90, 0xa, + 0x60, 0xd2, 0x0, 0x4c, 0x3c, 0x0, 0x0, 0xdc, + 0x50, 0x0, 0x7, 0xe0, 0x0, + + /* U+0077 "w" */ + 0x6a, 0x1, 0xf1, 0x9, 0x62, 0xd0, 0x6d, 0x70, + 0xc2, 0xd, 0x1b, 0x4c, 0xe, 0x0, 0x96, 0xc0, + 0xc5, 0xa0, 0x5, 0xe7, 0x7, 0xe5, 0x0, 0x1f, + 0x20, 0x1f, 0x10, + + /* U+0078 "x" */ + 0x4e, 0x10, 0x5c, 0x0, 0x8b, 0x2d, 0x10, 0x0, + 0xbe, 0x30, 0x0, 0xb, 0xe4, 0x0, 0x7, 0x93, + 0xe1, 0x4, 0xd0, 0x7, 0xc0, + + /* U+0079 "y" */ + 0x7a, 0x0, 0x1e, 0x1, 0xe1, 0x8, 0x80, 0x9, + 0x70, 0xe1, 0x0, 0x2e, 0x6a, 0x0, 0x0, 0xbf, + 0x30, 0x0, 0x6, 0xc0, 0x0, 0x0, 0xb5, 0x0, + 0x0, 0x2e, 0x0, 0x0, + + /* U+007A "z" */ + 0x5d, 0xdd, 0xf3, 0x0, 0x8, 0x90, 0x0, 0x5c, + 0x0, 0x2, 0xd1, 0x0, 0xd, 0x40, 0x0, 0x7f, + 0xdd, 0xd4, + + /* U+007B "{" */ + 0x0, 0x5, 0xcb, 0x0, 0xe, 0x10, 0x0, 0xf, + 0x0, 0x0, 0x6a, 0x0, 0x1e, 0xb0, 0x0, 0x0, + 0x78, 0x0, 0x0, 0xe, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x4, 0xcb, + + /* U+007C "|" */ + 0xff, 0xff, 0xff, 0xff, 0xff, + + /* U+007D "}" */ + 0xbc, 0x50, 0x0, 0x1, 0xe0, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0xc, 0xe0, 0x0, + 0x97, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x0, + 0x2, 0xd0, 0x0, 0xbc, 0x40, 0x0, + + /* U+007E "~" */ + 0x2c, 0xc3, 0x0, 0xcb, 0x32, 0xd2, 0x3b, 0xd0, + 0x3, 0xcc, 0x20, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x4, 0x95, 0x0, 0x1, 0x6b, + 0xff, 0xfa, 0x0, 0xd, 0xff, 0xff, 0xfa, 0x0, + 0xd, 0xff, 0xfe, 0xaa, 0x0, 0xd, 0xc8, 0x30, + 0x2a, 0x0, 0xc, 0x0, 0x0, 0x2a, 0x0, 0xc, + 0x0, 0x26, 0x6a, 0x0, 0xc, 0x2, 0xff, 0xfa, + 0x6c, 0xcd, 0x0, 0xae, 0xc3, 0xef, 0xfd, 0x0, + 0x0, 0x0, 0x16, 0x61, 0x0, 0x0, 0x0, + + /* U+F008 "" */ + 0x8c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc6, 0xd0, 0xd0, + 0x0, 0x0, 0x3b, 0xc, 0xd1, 0xd0, 0x0, 0x0, + 0x2b, 0x1c, 0xfb, 0xf0, 0x0, 0x0, 0x2e, 0xcc, + 0xc0, 0xc0, 0x0, 0x0, 0x2a, 0xc, 0xfc, 0xfd, + 0xcc, 0xcc, 0xdf, 0xdc, 0xc0, 0xc0, 0x0, 0x0, + 0x2a, 0xc, 0xfc, 0xf0, 0x0, 0x0, 0x2f, 0xdc, + 0xd0, 0xd0, 0x0, 0x0, 0x2b, 0xc, 0xd0, 0xd1, + 0x0, 0x0, 0x3b, 0x1c, 0x8c, 0xcc, 0xcc, 0xcc, + 0xcc, 0xc6, + + /* U+F00B "" */ + 0x56, 0x60, 0x56, 0x66, 0x66, 0x5f, 0xff, 0x3f, + 0xff, 0xff, 0xff, 0xdf, 0xe1, 0xdf, 0xff, 0xff, + 0xd3, 0x54, 0x4, 0x55, 0x55, 0x53, 0xff, 0xf3, + 0xff, 0xff, 0xff, 0xfc, 0xed, 0x1d, 0xee, 0xee, + 0xec, 0x45, 0x50, 0x45, 0x55, 0x55, 0x4f, 0xff, + 0x3f, 0xff, 0xff, 0xff, 0xef, 0xf1, 0xef, 0xff, + 0xff, 0xe0, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xd0, 0x0, 0x0, 0x0, 0x4f, 0xfe, + 0x10, 0xbe, 0x20, 0x4f, 0xfe, 0x20, 0x1f, 0xfe, + 0x6f, 0xfe, 0x20, 0x0, 0x4f, 0xff, 0xfe, 0x20, + 0x0, 0x0, 0x4f, 0xfe, 0x20, 0x0, 0x0, 0x0, + 0x4c, 0x20, 0x0, 0x0, + + /* U+F00D "" */ + 0x0, 0x0, 0x0, 0x10, 0xc, 0xe2, 0x6, 0xf7, + 0x2f, 0xfe, 0x7f, 0xfc, 0x5, 0xff, 0xff, 0xd1, + 0x0, 0x9f, 0xff, 0x30, 0x6, 0xff, 0xff, 0xe2, + 0x3f, 0xfd, 0x6f, 0xfd, 0xb, 0xd1, 0x5, 0xf6, + 0x0, 0x0, 0x0, 0x0, + + /* U+F011 "" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xf7, + 0x0, 0x0, 0x4, 0xa1, 0xf8, 0x68, 0x0, 0x2f, + 0xd1, 0xf8, 0x7f, 0x80, 0xaf, 0x11, 0xf8, 0xa, + 0xf1, 0xea, 0x0, 0xe5, 0x4, 0xf5, 0xfa, 0x0, + 0x0, 0x3, 0xf5, 0xce, 0x0, 0x0, 0x8, 0xf2, + 0x4f, 0xa0, 0x0, 0x5f, 0xa0, 0x8, 0xff, 0xcd, + 0xfd, 0x10, 0x0, 0x3a, 0xdc, 0x70, 0x0, + + /* U+F013 "" */ + 0x0, 0x3, 0xd6, 0x0, 0x0, 0x9, 0xba, 0xfc, + 0x9b, 0x0, 0xe, 0xff, 0xff, 0xff, 0x20, 0xa, + 0xfd, 0x5b, 0xfc, 0x0, 0xff, 0xf4, 0x0, 0xff, + 0xf3, 0xff, 0xf3, 0x0, 0xff, 0xf3, 0x1a, 0xfc, + 0x39, 0xfd, 0x20, 0xd, 0xff, 0xff, 0xff, 0x20, + 0xa, 0xdb, 0xfd, 0xbd, 0x10, 0x0, 0x4, 0xf7, + 0x0, 0x0, + + /* U+F014 "" */ + 0x0, 0x28, 0x97, 0x0, 0x0, 0xb, 0x53, 0x95, + 0x0, 0xde, 0xcc, 0xcc, 0xcf, 0x73, 0x90, 0x1, + 0x0, 0xc0, 0x39, 0xa3, 0xb7, 0x4c, 0x3, 0x9a, + 0x3b, 0x84, 0xc0, 0x39, 0xa3, 0xb8, 0x4c, 0x3, + 0x98, 0x29, 0x63, 0xc0, 0x39, 0x0, 0x0, 0xc, + 0x0, 0xac, 0xcc, 0xcc, 0x60, + + /* U+F015 "" */ + 0x0, 0x0, 0xaa, 0x1c, 0x80, 0x0, 0x1, 0xca, + 0xad, 0xfa, 0x0, 0x3, 0xe9, 0xdd, 0x8f, 0xa0, + 0x5, 0xe9, 0xff, 0xfe, 0x8e, 0x70, 0x88, 0xff, + 0xff, 0xff, 0x89, 0x0, 0xaf, 0xfa, 0xaf, 0xfa, + 0x0, 0xa, 0xff, 0x11, 0xff, 0xa0, 0x0, 0x9f, + 0xf1, 0x1f, 0xf9, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x99, 0x20, 0x0, 0x0, 0x0, 0x1f, + 0xf4, 0x0, 0x0, 0x0, 0x1, 0xff, 0x40, 0x0, + 0x0, 0x3, 0x5f, 0xf7, 0x40, 0x0, 0x0, 0xbf, + 0xff, 0xfd, 0x10, 0x0, 0x0, 0xaf, 0xfd, 0x10, + 0x0, 0x35, 0x53, 0x9c, 0x35, 0x54, 0xf, 0xff, + 0xf3, 0x2d, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xfa, + 0xdd, 0x3e, 0xff, 0xff, 0xff, 0xef, 0xe2, + + /* U+F01C "" */ + 0x6, 0xff, 0xff, 0xfc, 0x0, 0xd, 0x83, 0x33, + 0x4f, 0x40, 0x4f, 0x0, 0x0, 0x9, 0xb0, 0xb9, + 0x0, 0x0, 0x2, 0xf2, 0xfa, 0x82, 0x0, 0x78, + 0xf6, 0xff, 0xfb, 0x57, 0xff, 0xf6, 0xff, 0xff, + 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, + + /* U+F021 "" */ + 0x0, 0x4, 0x65, 0x10, 0x0, 0x2, 0xdf, 0xff, + 0xf8, 0xa6, 0x1e, 0xe6, 0x24, 0xbf, 0xf7, 0x9f, + 0x30, 0x0, 0xaf, 0xf7, 0x65, 0x0, 0x0, 0x77, + 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf5, + 0x0, 0x6, 0xf2, 0xff, 0xd0, 0x0, 0x4f, 0xb0, + 0xfc, 0xff, 0xcd, 0xfd, 0x10, 0x50, 0x4a, 0xdb, + 0x70, 0x0, + + /* U+F026 "" */ + 0x0, 0x1, 0x50, 0x1, 0xdb, 0x67, 0xdf, 0xbf, + 0xff, 0xfb, 0xff, 0xff, 0xba, 0xbf, 0xfb, 0x0, + 0x3f, 0xb0, 0x0, 0x38, + + /* U+F027 "" */ + 0x0, 0x1, 0x50, 0x0, 0x0, 0x1d, 0xb0, 0x0, + 0x67, 0xdf, 0xb1, 0x10, 0xff, 0xff, 0xb2, 0xc0, + 0xff, 0xff, 0xb0, 0xd0, 0xab, 0xff, 0xb3, 0x40, + 0x0, 0x3f, 0xb0, 0x0, 0x0, 0x3, 0x80, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, + 0x0, 0xc5, 0x0, 0x0, 0xc, 0xb0, 0x73, 0xb4, + 0x4, 0x5c, 0xfb, 0x12, 0xc3, 0xc0, 0xff, 0xff, + 0xb3, 0xc4, 0x8a, 0x1f, 0xff, 0xfb, 0xc, 0x39, + 0x92, 0xcc, 0xff, 0xb3, 0x59, 0x5c, 0x0, 0x5, + 0xfb, 0x8, 0x95, 0x90, 0x0, 0x5, 0xa0, 0x16, + 0xc0, 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, + + /* U+F03E "" */ + 0x6a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0xd2, 0x22, + 0x22, 0x22, 0x22, 0x2c, 0xc3, 0xfa, 0x0, 0x0, + 0x0, 0xc, 0xc4, 0xfc, 0x0, 0x1c, 0x40, 0xc, + 0xc0, 0x31, 0x1, 0xdf, 0xf4, 0xc, 0xc0, 0x1a, + 0x3d, 0xff, 0xff, 0x2c, 0xc1, 0xdf, 0xff, 0xff, + 0xff, 0x3c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x3c, + 0xc1, 0x33, 0x33, 0x33, 0x33, 0xc, 0x9c, 0xcc, + 0xcc, 0xcc, 0xcc, 0xc6, + + /* U+F040 "" */ + 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x3, + 0xff, 0x60, 0x0, 0x0, 0x47, 0xbf, 0xf2, 0x0, + 0x4, 0xdd, 0x7b, 0xc0, 0x0, 0x4d, 0xcf, 0xf6, + 0x0, 0x4, 0xdc, 0xff, 0xc0, 0x0, 0x4e, 0xcf, + 0xfc, 0x0, 0x0, 0xd4, 0xff, 0xc0, 0x0, 0x0, + 0xf7, 0x7c, 0x0, 0x0, 0x0, 0xcc, 0xa0, 0x0, + 0x0, 0x0, + + /* U+F048 "" */ + 0x63, 0x0, 0x1, 0x1f, 0x90, 0x1, 0xc4, 0xf9, + 0x1, 0xcf, 0x4f, 0x91, 0xcf, 0xf4, 0xfa, 0xcf, + 0xff, 0x4f, 0xdf, 0xff, 0xf4, 0xf9, 0x5f, 0xff, + 0x4f, 0x90, 0x5f, 0xf4, 0xf9, 0x0, 0x5f, 0x4e, + 0x80, 0x0, 0x54, + + /* U+F04B "" */ + 0x81, 0x0, 0x0, 0x0, 0xf, 0xe7, 0x0, 0x0, + 0x0, 0xff, 0xfd, 0x50, 0x0, 0xf, 0xff, 0xff, + 0xc3, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x2f, 0xff, + 0xff, 0xff, 0xc3, 0xff, 0xff, 0xfe, 0x60, 0xf, + 0xff, 0xf7, 0x0, 0x0, 0xff, 0x91, 0x0, 0x0, + 0xa, 0x20, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x67, 0x76, 0x4, 0x77, 0x70, 0xff, 0xfe, 0xb, + 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xff, + 0xfe, 0xb, 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, + 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xff, 0xfe, + 0xb, 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, + 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xef, 0xfd, 0xa, + 0xff, 0xf2, + + /* U+F04D "" */ + 0x67, 0x77, 0x77, 0x77, 0x72, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, + 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, + 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0xff, 0xff, 0xff, 0xff, 0xf6, 0xef, 0xff, 0xff, + 0xff, 0xf5, + + /* U+F051 "" */ + 0x11, 0x0, 0x2, 0x70, 0x3d, 0x10, 0x7, 0xf1, + 0x3f, 0xd1, 0x7, 0xf1, 0x3f, 0xfd, 0x17, 0xf1, + 0x3f, 0xff, 0xd9, 0xf1, 0x3f, 0xff, 0xfd, 0xf1, + 0x3f, 0xff, 0x77, 0xf1, 0x3f, 0xf7, 0x7, 0xf1, + 0x3f, 0x70, 0x7, 0xf1, 0x27, 0x0, 0x6, 0xe0, + + /* U+F052 "" */ + 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xc, + 0xff, 0x40, 0x0, 0x0, 0xc, 0xff, 0xff, 0x40, + 0x0, 0xc, 0xff, 0xff, 0xff, 0x40, 0xa, 0xdd, + 0xdd, 0xdd, 0xdd, 0x20, 0x55, 0x55, 0x55, 0x55, + 0x51, 0xf, 0xff, 0xff, 0xff, 0xff, 0x60, 0xff, + 0xff, 0xff, 0xff, 0xf6, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xa0, + 0x0, 0x1, 0xdf, 0xf2, 0x0, 0x1d, 0xff, 0x40, + 0x1, 0xdf, 0xf4, 0x0, 0xd, 0xff, 0x40, 0x0, + 0x8, 0xff, 0x90, 0x0, 0x0, 0x8f, 0xf9, 0x0, + 0x0, 0x8, 0xff, 0x90, 0x0, 0x0, 0x8f, 0xf2, + 0x0, 0x0, 0x7, 0x50, + + /* U+F054 "" */ + 0x0, 0x0, 0x0, 0x0, 0xcb, 0x0, 0x0, 0x4f, + 0xfb, 0x0, 0x0, 0x6f, 0xfb, 0x0, 0x0, 0x6f, + 0xfb, 0x0, 0x0, 0x6f, 0xfa, 0x0, 0xb, 0xff, + 0x60, 0xb, 0xff, 0x60, 0xb, 0xff, 0x60, 0x4, + 0xff, 0x60, 0x0, 0x6, 0x50, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x7, 0xa3, 0x0, 0x0, 0x0, 0xdf, 0x80, + 0x0, 0x0, 0xd, 0xf8, 0x0, 0x6, 0x88, 0xef, + 0xc8, 0x83, 0xff, 0xff, 0xff, 0xff, 0xac, 0xdd, + 0xff, 0xed, 0xd7, 0x0, 0xd, 0xf8, 0x0, 0x0, + 0x0, 0xdf, 0x80, 0x0, 0x0, 0xc, 0xf6, 0x0, + 0x0, + + /* U+F068 "" */ + 0x46, 0x66, 0x66, 0x66, 0x2f, 0xff, 0xff, 0xff, + 0xfa, 0xdf, 0xff, 0xff, 0xff, 0x80, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0x50, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x1, 0xea, 0xa, 0xe1, 0x0, + 0x0, 0x0, 0x8f, 0xa0, 0xaf, 0x80, 0x0, 0x0, + 0x2f, 0xfb, 0xb, 0xff, 0x10, 0x0, 0xa, 0xff, + 0xfc, 0xff, 0xfa, 0x0, 0x3, 0xff, 0xfb, 0xb, + 0xff, 0xf3, 0x0, 0xbf, 0xff, 0xe9, 0xef, 0xff, + 0xb0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xb0, 0xff, 0xc3, 0x7, 0xdf, 0xff, + 0xb9, 0xae, 0xe7, 0xfc, 0xac, 0xf6, 0x0, 0x29, + 0xfb, 0x0, 0x56, 0x0, 0x0, 0x8f, 0x30, 0x0, + 0x0, 0x0, 0x1e, 0xb8, 0x0, 0x45, 0x8, 0x8d, + 0xf7, 0xfb, 0x8b, 0xf5, 0xff, 0xd4, 0x9, 0xff, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x20, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x6, + 0xfc, 0x10, 0x0, 0x0, 0x6, 0xff, 0xfc, 0x10, + 0x0, 0x6, 0xff, 0xcf, 0xfc, 0x10, 0x6, 0xff, + 0xb0, 0x4f, 0xfc, 0x11, 0xff, 0xa0, 0x0, 0x4f, + 0xf8, 0x5, 0xa0, 0x0, 0x0, 0x4a, 0x0, + + /* U+F078 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x20, + 0x0, 0x8, 0xe2, 0x1e, 0xfe, 0x20, 0x8, 0xff, + 0x70, 0x3e, 0xfe, 0x28, 0xff, 0x90, 0x0, 0x3e, + 0xff, 0xff, 0x90, 0x0, 0x0, 0x3e, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x3e, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x0, 0x0, 0x11, 0x11, 0x0, 0x0, 0x5, + 0xd1, 0xdf, 0xff, 0xff, 0x10, 0x3, 0xff, 0xc2, + 0x88, 0x8c, 0xf1, 0x0, 0xef, 0xff, 0x80, 0x0, + 0x8f, 0x10, 0x1, 0x8f, 0x20, 0x0, 0x19, 0xf3, + 0x0, 0x7, 0xf1, 0x0, 0xe, 0xff, 0xf7, 0x0, + 0x7f, 0x99, 0x98, 0x3f, 0xfb, 0x0, 0x7, 0xff, + 0xff, 0xf7, 0x5c, 0x0, + + /* U+F07B "" */ + 0x4a, 0xa9, 0x10, 0x0, 0x0, 0xe, 0xff, 0xfa, + 0x11, 0x11, 0x0, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x9f, 0xff, 0xff, 0xff, + 0xfc, 0x0, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xc0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xc0, 0x0, + 0x0, 0x9, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x78, + 0xff, 0xa7, 0x10, 0x0, 0x0, 0x1f, 0xf4, 0x0, + 0x0, 0x0, 0x1, 0xff, 0x40, 0x0, 0x4, 0x55, + 0x29, 0xa2, 0x55, 0x50, 0xff, 0xfe, 0x99, 0xcf, + 0xff, 0x3f, 0xff, 0xff, 0xff, 0x8c, 0xc3, 0xac, + 0xcc, 0xcc, 0xcc, 0xcc, 0x10, + + /* U+F095 "" */ + 0x29, 0x10, 0x0, 0x0, 0xc, 0xfa, 0x0, 0x0, + 0x0, 0xff, 0xf0, 0x0, 0x0, 0xc, 0xf3, 0x0, + 0x0, 0x0, 0x5f, 0x70, 0x0, 0x0, 0x0, 0xcf, + 0x40, 0x0, 0x0, 0x1, 0xdf, 0x73, 0xfa, 0x10, + 0x1, 0xcf, 0xff, 0xf9, 0x0, 0x0, 0x5c, 0xfc, + 0x20, + + /* U+F0C4 "" */ + 0x6, 0xcb, 0x40, 0x0, 0x0, 0x0, 0xf, 0x44, + 0xc4, 0x0, 0x6, 0x67, 0xd, 0x70, 0x59, 0x4, + 0x61, 0x63, 0x2, 0xcf, 0xfa, 0x72, 0x17, 0x10, + 0x0, 0x1, 0x1b, 0x53, 0xa0, 0x0, 0x2, 0xde, + 0xf8, 0x97, 0x7, 0x10, 0xe, 0x60, 0x58, 0x4, + 0x71, 0x53, 0xf, 0x44, 0xd3, 0x0, 0x6, 0x77, + 0x6, 0xcb, 0x30, 0x0, 0x0, 0x0, + + /* U+F0C5 "" */ + 0x0, 0x8, 0xaa, 0x80, 0x0, 0x0, 0xc, 0xe2, + 0x2d, 0x0, 0x0, 0xc, 0x8c, 0x0, 0xc0, 0x0, + 0xb, 0xb1, 0xc0, 0xc, 0xef, 0xfe, 0xeb, 0xb8, + 0x4, 0xcd, 0x0, 0xcc, 0x0, 0x4, 0xb1, 0xd0, + 0xc, 0xc0, 0x0, 0xec, 0xc9, 0x0, 0xcc, 0x0, + 0x1b, 0x0, 0x0, 0xc, 0xdc, 0xcd, 0xb0, 0x0, + 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, + 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, 0xb, 0xcc, + 0xcc, 0xca, + + /* U+F0C7 "" */ + 0xac, 0xcc, 0xcc, 0xb4, 0x0, 0xc7, 0xfc, 0xb, + 0x3d, 0x50, 0xc7, 0xfc, 0xb, 0x10, 0xb4, 0xc6, + 0xff, 0xbe, 0x0, 0x29, 0xc0, 0x1, 0x10, 0x0, + 0x2a, 0xc0, 0x0, 0x0, 0x0, 0x2a, 0xc5, 0xdc, + 0xcc, 0xcd, 0x2a, 0xc7, 0x40, 0x0, 0xe, 0x2a, + 0xc7, 0x40, 0x0, 0xe, 0x2a, 0xac, 0xcc, 0xcc, + 0xcc, 0xc6, + + /* U+F0E7 "" */ + 0x0, 0xbd, 0x90, 0x0, 0xf, 0xf6, 0x0, 0x4, + 0xff, 0x11, 0x10, 0x8f, 0xed, 0xf4, 0xc, 0xff, + 0xfd, 0x0, 0x96, 0x6f, 0x50, 0x0, 0x8, 0xd0, + 0x0, 0x0, 0xc6, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x3, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x19, + 0xf6, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xfc, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xf5, 0x0, 0x0, 0xdf, + 0xff, 0xff, 0x80, 0x0, 0xe, 0xff, 0xff, 0xf9, + 0x0, 0x1, 0xff, 0xff, 0xff, 0xc0, 0x0, 0x7f, + 0xff, 0xff, 0xff, 0x20, 0x2f, 0xff, 0xff, 0xff, + 0xfc, 0x8, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x1, 0xcf, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x82, + 0x0, 0x0, + + /* U+F11C "" */ + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc9, 0xc3, 0x25, + 0x22, 0x51, 0x33, 0x1c, 0xc2, 0x13, 0x12, 0x30, + 0x29, 0x3c, 0xc5, 0xc2, 0x86, 0x29, 0x4d, 0x2c, + 0xc2, 0x15, 0x55, 0x55, 0x33, 0x1c, 0xc3, 0x26, + 0x77, 0x77, 0x33, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xc9, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x1, 0x87, 0x0, 0x0, 0x1, + 0x8f, 0xf3, 0x0, 0x1, 0x8f, 0xff, 0xb0, 0x1, + 0x8f, 0xff, 0xff, 0x30, 0xc, 0xdd, 0xdf, 0xfb, + 0x0, 0x0, 0x0, 0x1f, 0xf3, 0x0, 0x0, 0x0, + 0x1f, 0xb0, 0x0, 0x0, 0x0, 0x1f, 0x30, 0x0, + 0x0, 0x0, 0x8, 0x0, 0x0, + + /* U+F15B "" */ + 0x23, 0x33, 0x31, 0x0, 0x0, 0xff, 0xff, 0xf8, + 0x70, 0x0, 0xff, 0xff, 0xf8, 0xbb, 0x0, 0xff, + 0xff, 0xf8, 0xaf, 0xa0, 0xff, 0xff, 0xfb, 0x44, + 0x41, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, + 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xbc, + 0xcc, 0xcc, 0xcc, 0xc3, + + /* U+F1EB "" */ + 0x0, 0x4, 0x9b, 0xca, 0x72, 0x0, 0x0, 0x5d, + 0xff, 0xdc, 0xef, 0xfa, 0x10, 0x7f, 0xe6, 0x35, + 0x64, 0x39, 0xfe, 0x12, 0x93, 0xbf, 0xff, 0xff, + 0x74, 0x80, 0x0, 0xef, 0x94, 0x35, 0xcf, 0x60, + 0x0, 0x3, 0x28, 0xff, 0xc4, 0x50, 0x0, 0x0, + 0x3, 0xfc, 0xae, 0xb0, 0x0, 0x0, 0x0, 0x1, + 0x48, 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0x0, 0x0, + + /* U+F240 "" */ + 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, + 0x44, 0x44, 0x44, 0x44, 0x42, 0xa2, 0xc7, 0xff, + 0xff, 0xff, 0xff, 0xf9, 0x9a, 0xc7, 0xff, 0xff, + 0xff, 0xff, 0xf9, 0xc, 0xc7, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0xc, 0xc7, 0xff, 0xff, 0xff, 0xff, + 0xf9, 0x7b, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x64, + 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+F241 "" */ + 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, + 0x44, 0x44, 0x44, 0x41, 0x0, 0xa2, 0xc7, 0xff, + 0xff, 0xff, 0xf4, 0x0, 0x9a, 0xc7, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xff, + 0xf4, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x7b, 0xc3, 0x66, 0x66, 0x66, 0x61, 0x0, + 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+F242 "" */ + 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, + 0x44, 0x44, 0x40, 0x0, 0x0, 0xa2, 0xc7, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x9a, 0xc7, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x7b, 0xc3, 0x66, 0x66, 0x60, 0x0, 0x0, + 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+F243 "" */ + 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, + 0x44, 0x20, 0x0, 0x0, 0x0, 0xa2, 0xc7, 0xff, + 0xa0, 0x0, 0x0, 0x0, 0x9a, 0xc7, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0xc, 0xc7, 0xff, 0xa0, 0x0, + 0x0, 0x0, 0xc, 0xc7, 0xff, 0xa0, 0x0, 0x0, + 0x0, 0x7b, 0xc3, 0x66, 0x40, 0x0, 0x0, 0x0, + 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+F244 "" */ + 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9a, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+F293 "" */ + 0x0, 0x0, 0x22, 0x0, 0x0, 0x7, 0xfe, 0xfe, + 0x50, 0x5, 0xff, 0x98, 0xff, 0x30, 0xcf, 0xf9, + 0x18, 0xfa, 0xf, 0xb4, 0x89, 0x1d, 0xd1, 0xff, + 0x90, 0x1a, 0xff, 0x1f, 0xff, 0x23, 0xff, 0xf1, + 0xff, 0x44, 0x44, 0xfe, 0xe, 0xba, 0x97, 0x2d, + 0xc0, 0xaf, 0xf9, 0x1d, 0xf8, 0x2, 0xef, 0xad, + 0xfd, 0x10, 0x2, 0x9b, 0xb8, 0x10 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 62, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 69, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 8, .adv_w = 81, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 18, .adv_w = 144, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 46, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81, .adv_w = 189, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 129, .adv_w = 128, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 165, .adv_w = 47, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 171, .adv_w = 80, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 196, .adv_w = 80, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 221, .adv_w = 112, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 239, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 264, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 272, .adv_w = 80, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 275, .adv_w = 64, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 277, .adv_w = 80, .box_w = 6, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 307, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 335, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 355, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 383, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 411, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 439, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 463, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 491, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 519, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 547, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 575, .adv_w = 80, .box_w = 3, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 584, .adv_w = 80, .box_w = 3, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 596, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 621, .adv_w = 144, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 632, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 657, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 681, .adv_w = 176, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 731, .adv_w = 120, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 763, .adv_w = 121, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 791, .adv_w = 123, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 823, .adv_w = 136, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 851, .adv_w = 111, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 875, .adv_w = 101, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 899, .adv_w = 136, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 931, .adv_w = 132, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 959, .adv_w = 74, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 975, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 991, .adv_w = 122, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1019, .adv_w = 98, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1043, .adv_w = 148, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1075, .adv_w = 132, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1103, .adv_w = 139, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1139, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1163, .adv_w = 139, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1208, .adv_w = 122, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1236, .adv_w = 120, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1264, .adv_w = 108, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1292, .adv_w = 129, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1324, .adv_w = 120, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1356, .adv_w = 174, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1400, .adv_w = 121, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1432, .adv_w = 108, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1460, .adv_w = 121, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1488, .adv_w = 80, .box_w = 4, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1508, .adv_w = 80, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1538, .adv_w = 80, .box_w = 4, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1558, .adv_w = 144, .box_w = 7, .box_h = 4, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 1572, .adv_w = 112, .box_w = 9, .box_h = 1, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 1577, .adv_w = 112, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 1581, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1599, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1623, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1641, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1665, .adv_w = 105, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1686, .adv_w = 62, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1706, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1730, .adv_w = 111, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1754, .adv_w = 48, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1766, .adv_w = 61, .box_w = 4, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 1786, .adv_w = 104, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1810, .adv_w = 48, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1818, .adv_w = 171, .box_w = 9, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1845, .adv_w = 111, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1863, .adv_w = 107, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1884, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1908, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1932, .adv_w = 75, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1944, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1962, .adv_w = 69, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1982, .adv_w = 111, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2000, .adv_w = 104, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2021, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2048, .adv_w = 104, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2069, .adv_w = 104, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2097, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2115, .adv_w = 112, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2145, .adv_w = 80, .box_w = 1, .box_h = 10, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 2150, .adv_w = 112, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 2180, .adv_w = 144, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 2191, .adv_w = 151, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2246, .adv_w = 189, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2312, .adv_w = 176, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2362, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2406, .adv_w = 138, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2442, .adv_w = 151, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2497, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2547, .adv_w = 138, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2592, .adv_w = 163, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2636, .adv_w = 163, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2691, .adv_w = 151, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2731, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2781, .adv_w = 75, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2801, .adv_w = 113, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2833, .adv_w = 163, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2888, .adv_w = 189, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2948, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2998, .adv_w = 101, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3033, .adv_w = 138, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3078, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3128, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3178, .adv_w = 101, .box_w = 8, .box_h = 10, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 3218, .adv_w = 151, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 3262, .adv_w = 126, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3306, .adv_w = 126, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3345, .adv_w = 138, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3386, .adv_w = 138, .box_w = 9, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 3400, .adv_w = 176, .box_w = 13, .box_h = 11, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 3472, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3533, .adv_w = 176, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3572, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3616, .adv_w = 189, .box_w = 13, .box_h = 8, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 3668, .adv_w = 163, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3718, .adv_w = 163, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3779, .adv_w = 138, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3820, .adv_w = 176, .box_w = 12, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 3874, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3940, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3990, .adv_w = 88, .box_w = 7, .box_h = 11, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 4029, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4095, .adv_w = 189, .box_w = 12, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4137, .adv_w = 138, .box_w = 10, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 4182, .adv_w = 151, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4242, .adv_w = 201, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4301, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4357, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4413, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4469, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4525, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4581, .adv_w = 151, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -2} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13, + 0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d, + 0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52, + 0x53, 0x66, 0x67, 0x70, 0x73, 0x76, 0x77, 0x78, + 0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xf2, + 0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, 0x242, + 0x243, 0x292 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 61441, .range_length = 659, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 2, 3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 6, 7, 0, 8, + 0, 0, 9, 10, 11, 12, 0, 0, + 13, 14, 15, 16, 17, 18, 10, 19, + 20, 21, 22, 23, 0, 0, 0, 0, + 0, 0, 24, 25, 26, 0, 27, 28, + 0, 29, 0, 0, 30, 0, 29, 29, + 31, 25, 0, 32, 0, 33, 0, 34, + 35, 36, 37, 38, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = +{ + 0, 0, 0, 1, 0, 0, 0, 0, + 2, 0, 3, 4, 0, 5, 6, 7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 8, 0, 0, 0, + 9, 0, 10, 0, 11, 0, 0, 0, + 11, 0, 12, 13, 0, 0, 0, 0, + 14, 0, 0, 0, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 3, 3, 0, + 0, 0, 23, 0, 24, 25, 26, 0, + 27, 0, 0, 0, 0, 0, 28, 28, + 26, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, -3, -9, 0, -2, -13, 0, -4, + -4, -7, -12, -3, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -3, + -2, -4, -3, -3, 0, 0, 0, 0, + -11, -14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, -10, -1, -5, -4, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -1, -4, -3, 0, -4, 0, + 0, 0, 0, 0, -2, 1, -2, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, -4, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, 0, -2, -1, + -2, -2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -26, 0, + -26, -5, 5, -9, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, + -9, 0, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -2, 0, -2, 0, 0, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 0, 0, 0, 0, 0, 0, + 0, -2, 0, 0, 0, 0, 0, 0, + 0, 0, -5, 0, 0, -6, 0, 0, + 0, 0, 0, 0, -4, -7, -6, 0, + -7, 0, 0, -10, 0, 0, 0, -14, + 0, 0, 0, 0, -2, 0, 9, -2, + 0, -15, 0, -9, -9, 0, -14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -9, 0, 0, -9, 0, + 0, 0, 0, 0, -3, 0, -3, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, -1, -2, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -26, 0, -26, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, -4, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3, 0, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, 0, 0, -2, 0, + -3, 0, 0, -4, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, -5, 0, + 0, 0, 0, 0, -2, 0, -2, 0, + 0, -2, 0, 0, 0, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -3, -2, 0, -3, 0, 0, 0, + 0, 0, -25, -13, -25, -17, 5, -10, + -3, 0, 0, -4, -1, -6, 0, 0, + 0, 0, 0, 0, -21, -19, 0, -19, + -18, 0, 0, -17, -15, 0, -17, -17, + -17, 0, -17, -15, 0, 0, 0, 0, + -25, -4, -25, -7, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -9, 0, 0, -9, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + -6, 0, 0, 0, 0, 0, -25, -4, + -19, -7, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -9, 0, 0, -9, 0, 0, 0, -5, + 0, 0, -5, 0, 0, 0, -6, 0, + 0, 0, 0, 0, 0, -7, 0, 0, + 0, 0, -1, 0, 0, -1, 0, 0, + 0, 0, 0, 0, 0, 0, -4, 0, + 0, -5, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, -7, 0, 0, 0, + 0, 0, -25, -12, -25, -17, 0, -7, + 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, -12, 0, -10, -11, + -11, -9, -11, -9, -9, 0, -9, -9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, 0, 0, -2, 0, + 0, -2, 0, 0, 0, 0, 0, 0, + 0, -1, -4, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, -3, 0, + -6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1, -1, 0, -1, 0, + 0, 0, 0, 0, -3, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 9, 4, -11, -4, + -10, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -1, 0, -2, 0, 0, 0, + 0, 0, 0, -9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, 0, -2, + -1, 0, 0, 0, 0, 0, -25, -2, + -25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + 0, 0, -15, -3, -15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, -2, -6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -1, -2, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -16, -3, -16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -3, -2, + -1, -2, -1, 0, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, -1, -1, + -1, 0, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 38, + .right_class_cnt = 38, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LV_VERSION_CHECK(8, 0, 0) +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 1, + .bitmap_format = 0, +#if LV_VERSION_CHECK(8, 0, 0) + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LV_VERSION_CHECK(8, 0, 0) +const lv_font_t lv_font_verdana_11 = { +#else +lv_font_t lv_font_verdana_11 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 12, /*The maximum line height required by the font*/ + .base_line = 2, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + + + +#endif /*#if LV_FONT_VERDANA_11*/ From 136e8aa3940cf6b8cc686d231deac987a65b0944 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 19 Mar 2024 14:12:33 +0530 Subject: [PATCH 20/32] chore: Removed verdana --- common/lv_conf.h | 7 +- common/lvgl/src/lv_font/lv_font.h | 4 - common/lvgl/src/lv_font/lv_font.mk | 1 - common/lvgl/src/lv_font/lv_font_verdana_11.c | 1436 ------------------ 4 files changed, 4 insertions(+), 1444 deletions(-) delete mode 100644 common/lvgl/src/lv_font/lv_font_verdana_11.c diff --git a/common/lv_conf.h b/common/lv_conf.h index c1e0926c..3936af94 100644 --- a/common/lv_conf.h +++ b/common/lv_conf.h @@ -37,6 +37,8 @@ #define LV_COLOR_DEPTH 1 #endif +#define LV_SUBPX_BGR 1 + /* Swap the 2 bytes of RGB565 color. * Useful if the display has a 8 bit interface (e.g. SPI)*/ #define LV_COLOR_16_SWAP 0 @@ -266,11 +268,10 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i /* Robot fonts with bpp = 4 * https://fonts.google.com/specimen/Roboto */ -#define LV_FONT_ROBOTO_12 0 +#define LV_FONT_ROBOTO_12 1 #define LV_FONT_ROBOTO_16 0 #define LV_FONT_ROBOTO_22 0 #define LV_FONT_ROBOTO_28 0 -#define LV_FONT_VERDANA_11 1 /*Pixel perfect monospace font * http://pelulamu.net/unscii/ */ @@ -285,7 +286,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font) LV_FONT_DECLARE(my_logo) LV_FONT_DECLARE(nfc_logo) /*Always set a default font from the built-in fonts*/ -#define LV_FONT_DEFAULT &lv_font_verdana_11 +#define LV_FONT_DEFAULT &lv_font_roboto_12 /* Enable it if you have fonts with a lot of characters. * The limit depends on the font size, font face and bpp diff --git a/common/lvgl/src/lv_font/lv_font.h b/common/lvgl/src/lv_font/lv_font.h index 07a26353..e639a54a 100644 --- a/common/lvgl/src/lv_font/lv_font.h +++ b/common/lvgl/src/lv_font/lv_font.h @@ -138,10 +138,6 @@ LV_FONT_DECLARE(lv_font_roboto_28) LV_FONT_DECLARE(lv_font_unscii_8) #endif -#if LV_FONT_VERDANA_11 -LV_FONT_DECLARE(lv_font_verdana_11) -#endif - /*Declare the custom (user defined) fonts*/ #ifdef LV_FONT_CUSTOM_DECLARE LV_FONT_CUSTOM_DECLARE diff --git a/common/lvgl/src/lv_font/lv_font.mk b/common/lvgl/src/lv_font/lv_font.mk index c8b95eba..9f7918cf 100644 --- a/common/lvgl/src/lv_font/lv_font.mk +++ b/common/lvgl/src/lv_font/lv_font.mk @@ -4,7 +4,6 @@ SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_12.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_16.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_22.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_roboto_28.c -SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_verdana_11.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/lv_font_unscii_8.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/my_logo.c SRC_FILES += $(OLED_DIR)/lvgl/src/lv_font/nfc_logo.c diff --git a/common/lvgl/src/lv_font/lv_font_verdana_11.c b/common/lvgl/src/lv_font/lv_font_verdana_11.c deleted file mode 100644 index e89860b7..00000000 --- a/common/lvgl/src/lv_font/lv_font_verdana_11.c +++ /dev/null @@ -1,1436 +0,0 @@ -/******************************************************************************* - * Size: 11 px - * Bpp: 4 - * Opts: --no-compress --no-prefilter --bpp 4 --size 11 --font verdana.ttf -r 0x20-0x7F --font FontAwesome.ttf -r 61441,61448,61451,61452,61453,61457,61459,61460,61461,61465,61468,61473,61478,61479,61480,61502,61504,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62099 --format lvgl -o lv_font_verdana_11.c --force-fast-kern-format - ******************************************************************************/ - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -#ifndef LV_FONT_VERDANA_11 -#define LV_FONT_VERDANA_11 1 -#endif - -#if LV_FONT_VERDANA_11 - -/*----------------- - * BITMAPS - *----------------*/ - -/*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { - /* U+0020 " " */ - - /* U+0021 "!" */ - 0x6c, 0x6b, 0x5b, 0x5a, 0x5a, 0x26, 0x1, 0x6b, - - /* U+0022 "\"" */ - 0xf, 0xf, 0x10, 0xf0, 0xe0, 0xc, 0xc, 0x0, - 0x0, 0x0, - - /* U+0023 "#" */ - 0x0, 0x1a, 0xb, 0x0, 0x5, 0x62, 0x80, 0x3b, - 0xec, 0xdc, 0xa0, 0xa, 0xa, 0x0, 0x0, 0xa0, - 0xb0, 0xa, 0xcd, 0xbd, 0xb3, 0x8, 0x26, 0x40, - 0x0, 0xb0, 0x91, 0x0, - - /* U+0024 "$" */ - 0x0, 0xa, 0x0, 0x0, 0x3b, 0xec, 0x90, 0xe, - 0x2a, 0x4, 0x0, 0xf3, 0xa0, 0x0, 0x4, 0xcf, - 0xb5, 0x0, 0x0, 0xa3, 0xe2, 0x13, 0xa, 0xd, - 0x11, 0xcc, 0xeb, 0x50, 0x0, 0xa, 0x0, 0x0, - 0x0, 0xa0, 0x0, - - /* U+0025 "%" */ - 0x7, 0xbc, 0x20, 0xa, 0x30, 0x0, 0x1d, 0x5, - 0x90, 0x3a, 0x0, 0x0, 0x2c, 0x3, 0xb0, 0xb2, - 0x0, 0x0, 0xd, 0x6, 0x94, 0x92, 0xbb, 0x40, - 0x5, 0xba, 0x1c, 0x1b, 0x31, 0xd0, 0x0, 0x0, - 0x49, 0xe, 0x10, 0xe0, 0x0, 0x0, 0xc1, 0xc, - 0x20, 0xd0, 0x0, 0x5, 0x80, 0x4, 0xaa, 0x50, - - /* U+0026 "&" */ - 0x4, 0xbb, 0xa0, 0x0, 0x0, 0xe2, 0xd, 0x40, - 0x0, 0xd, 0x61, 0xd1, 0x0, 0x0, 0x3f, 0xd3, - 0x1b, 0x0, 0x1d, 0x29, 0xa2, 0xc0, 0x5, 0xc0, - 0x9, 0xd8, 0x0, 0x3e, 0x10, 0x1e, 0xb0, 0x0, - 0x6c, 0xaa, 0x27, 0xc0, - - /* U+0027 "'" */ - 0x1f, 0x0, 0xf0, 0xd, 0x0, 0x0, - - /* U+0028 "(" */ - 0x0, 0x6b, 0x0, 0x1e, 0x10, 0x9, 0x70, 0x0, - 0xd2, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, 0xd, - 0x10, 0x0, 0x97, 0x0, 0x1, 0xd0, 0x0, 0x6, - 0xb0, - - /* U+0029 ")" */ - 0xb, 0x60, 0x0, 0x1d, 0x10, 0x0, 0x78, 0x0, - 0x2, 0xd0, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, - 0x2d, 0x0, 0x7, 0x80, 0x1, 0xe1, 0x0, 0xb6, - 0x0, - - /* U+002A "*" */ - 0x1, 0xa, 0x1, 0x0, 0x98, 0xb8, 0x90, 0x0, - 0x8f, 0x80, 0x0, 0xa5, 0xa5, 0xa0, 0x0, 0x8, - 0x0, 0x0, - - /* U+002B "+" */ - 0x0, 0x7, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, - 0xe, 0x0, 0xb, 0xdd, 0xfd, 0xdb, 0x0, 0xe, - 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, - 0x0, - - /* U+002C "," */ - 0x2, 0x70, 0x8, 0xa0, 0xc, 0x30, 0x1c, 0x0, - - /* U+002D "-" */ - 0x2f, 0xff, 0x20, - - /* U+002E "." */ - 0x44, 0xaa, - - /* U+002F "/" */ - 0x0, 0x0, 0x86, 0x0, 0x0, 0xd0, 0x0, 0x5, - 0x90, 0x0, 0xb, 0x30, 0x0, 0x2c, 0x0, 0x0, - 0x86, 0x0, 0x0, 0xd0, 0x0, 0x5, 0x90, 0x0, - 0xc, 0x20, 0x0, 0x6, 0x0, 0x0, - - /* U+0030 "0" */ - 0x2, 0xce, 0xc2, 0x0, 0xd5, 0x5, 0xc0, 0x2f, - 0x0, 0xe, 0x13, 0xd0, 0x0, 0xd3, 0x3d, 0x0, - 0xd, 0x32, 0xe0, 0x0, 0xe2, 0xd, 0x50, 0x5d, - 0x0, 0x2c, 0xdc, 0x20, - - /* U+0031 "1" */ - 0x0, 0xd3, 0x5, 0xdf, 0x30, 0x0, 0xd3, 0x0, - 0xd, 0x30, 0x0, 0xd3, 0x0, 0xd, 0x30, 0x0, - 0xd3, 0x6, 0xcf, 0xda, - - /* U+0032 "2" */ - 0xa, 0xee, 0xc2, 0x0, 0x60, 0x7, 0xc0, 0x0, - 0x0, 0x3e, 0x0, 0x0, 0x9, 0x90, 0x0, 0x7, - 0xc0, 0x0, 0x7, 0xc1, 0x0, 0xa, 0xa0, 0x0, - 0x2, 0xfe, 0xee, 0xe4, - - /* U+0033 "3" */ - 0x8, 0xde, 0xd5, 0x0, 0x50, 0x4, 0xe0, 0x0, - 0x0, 0x6b, 0x0, 0x3, 0xed, 0x20, 0x0, 0x0, - 0x4e, 0x0, 0x0, 0x0, 0xf1, 0x15, 0x0, 0x6e, - 0x0, 0xbe, 0xec, 0x30, - - /* U+0034 "4" */ - 0x0, 0x2, 0xf4, 0x0, 0x1, 0xdd, 0x40, 0x0, - 0xb4, 0xc4, 0x0, 0x97, 0xc, 0x40, 0x6a, 0x0, - 0xc4, 0x8, 0xdd, 0xdf, 0xd6, 0x0, 0x0, 0xc4, - 0x0, 0x0, 0xc, 0x40, - - /* U+0035 "5" */ - 0xaf, 0xee, 0xe2, 0xa6, 0x0, 0x0, 0xa6, 0x0, - 0x0, 0xae, 0xec, 0x40, 0x0, 0x5, 0xf0, 0x0, - 0x0, 0xe2, 0x50, 0x5, 0xe0, 0xbe, 0xec, 0x30, - - /* U+0036 "6" */ - 0x0, 0x5d, 0xe9, 0x0, 0x7c, 0x20, 0x0, 0xf, - 0x20, 0x0, 0x2, 0xfa, 0xdd, 0x50, 0x3e, 0x10, - 0x2e, 0x22, 0xe0, 0x0, 0xb5, 0xd, 0x50, 0x1e, - 0x20, 0x2b, 0xdc, 0x40, - - /* U+0037 "7" */ - 0x2e, 0xee, 0xef, 0x40, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0x79, 0x0, 0x0, 0x1e, 0x10, 0x0, 0x9, - 0x80, 0x0, 0x2, 0xe1, 0x0, 0x0, 0xa7, 0x0, - 0x0, 0x3e, 0x0, 0x0, - - /* U+0038 "8" */ - 0x4, 0xcc, 0xc4, 0x0, 0xf1, 0x2, 0xf0, 0xf, - 0x40, 0x1f, 0x0, 0x5f, 0xbb, 0x40, 0xc, 0x43, - 0xac, 0x4, 0xc0, 0x0, 0xd4, 0x2e, 0x20, 0x1e, - 0x20, 0x5c, 0xcc, 0x40, - - /* U+0039 "9" */ - 0x4, 0xdd, 0xb2, 0x2, 0xe2, 0x5, 0xc0, 0x5b, - 0x0, 0xe, 0x22, 0xe2, 0x1, 0xe3, 0x5, 0xdd, - 0xaf, 0x20, 0x0, 0x2, 0xe0, 0x0, 0x1, 0xc6, - 0x0, 0x9e, 0xd5, 0x0, - - /* U+003A ":" */ - 0x2f, 0x21, 0x71, 0x0, 0x0, 0x0, 0x17, 0x12, - 0xf2, - - /* U+003B ";" */ - 0x2f, 0x21, 0x71, 0x0, 0x0, 0x0, 0x7, 0x31, - 0xf1, 0x5a, 0xa, 0x30, - - /* U+003C "<" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x18, 0xd5, 0x3, - 0xac, 0x60, 0x8, 0xf5, 0x0, 0x0, 0x6, 0xda, - 0x30, 0x0, 0x0, 0x4b, 0xc4, 0x0, 0x0, 0x2, - 0x40, - - /* U+003D "=" */ - 0x9d, 0xdd, 0xdd, 0x90, 0x0, 0x0, 0x0, 0x9d, - 0xdd, 0xdd, 0x90, - - /* U+003E ">" */ - 0x20, 0x0, 0x0, 0x5, 0xd8, 0x10, 0x0, 0x0, - 0x6c, 0xa3, 0x0, 0x0, 0x5, 0xf8, 0x0, 0x3a, - 0xc6, 0x4, 0xcb, 0x40, 0x0, 0x42, 0x0, 0x0, - 0x0, - - /* U+003F "?" */ - 0x1c, 0xee, 0x80, 0x3, 0x1, 0xd4, 0x0, 0x0, - 0xc4, 0x0, 0x8, 0xc0, 0x0, 0xb8, 0x0, 0x0, - 0xa2, 0x0, 0x0, 0x10, 0x0, 0x0, 0xd4, 0x0, - - /* U+0040 "@" */ - 0x0, 0x7, 0xbb, 0xb9, 0x10, 0x0, 0xb, 0x50, - 0x0, 0x2c, 0x20, 0x8, 0x42, 0xcc, 0xc8, 0x2a, - 0x0, 0xc0, 0xb4, 0x5, 0x80, 0xc0, 0xb, 0xd, - 0x0, 0x58, 0xb, 0x0, 0xc0, 0xa5, 0x8, 0x80, - 0xb0, 0x8, 0x51, 0xab, 0x7b, 0x95, 0x0, 0xb, - 0x60, 0x0, 0x0, 0x0, 0x0, 0x5, 0xbb, 0xb5, - 0x0, 0x0, - - /* U+0041 "A" */ - 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x7a, 0xf0, 0x0, - 0x0, 0xd3, 0xb6, 0x0, 0x3, 0xd0, 0x6b, 0x0, - 0x9, 0x80, 0x1f, 0x10, 0xe, 0xee, 0xef, 0x70, - 0x5c, 0x0, 0x5, 0xd0, 0xa6, 0x0, 0x0, 0xe3, - - /* U+0042 "B" */ - 0xee, 0xee, 0xa0, 0xe, 0x20, 0xd, 0x50, 0xe2, - 0x1, 0xd2, 0xe, 0xdd, 0xfc, 0x20, 0xe2, 0x0, - 0x6d, 0xe, 0x20, 0x0, 0xf0, 0xe2, 0x0, 0x6d, - 0xe, 0xee, 0xeb, 0x20, - - /* U+0043 "C" */ - 0x0, 0x7d, 0xee, 0x91, 0x9, 0xb1, 0x1, 0x73, - 0x2f, 0x10, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, - 0x5c, 0x0, 0x0, 0x0, 0x2f, 0x10, 0x0, 0x0, - 0xa, 0xb1, 0x1, 0x73, 0x0, 0x8d, 0xee, 0x91, - - /* U+0044 "D" */ - 0xee, 0xee, 0x91, 0xe, 0x20, 0x17, 0xe1, 0xe2, - 0x0, 0x9, 0x8e, 0x20, 0x0, 0x5c, 0xe2, 0x0, - 0x5, 0xce, 0x20, 0x0, 0x98, 0xe2, 0x0, 0x7e, - 0x1e, 0xee, 0xe9, 0x10, - - /* U+0045 "E" */ - 0xee, 0xee, 0xe5, 0xe2, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0xee, 0xee, 0xe4, 0xe2, 0x0, 0x0, 0xe2, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xee, 0xee, 0xe5, - - /* U+0046 "F" */ - 0xee, 0xee, 0xe2, 0xe2, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0xee, 0xee, 0x80, 0xe2, 0x0, 0x0, 0xe2, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, - - /* U+0047 "G" */ - 0x0, 0x7d, 0xee, 0xb4, 0x9, 0xc2, 0x0, 0x48, - 0x2f, 0x10, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, - 0x5c, 0x0, 0x6e, 0xeb, 0x2f, 0x10, 0x0, 0x5c, - 0x9, 0xc2, 0x0, 0x6c, 0x0, 0x6c, 0xed, 0xb4, - - /* U+0048 "H" */ - 0xe2, 0x0, 0xe, 0x3e, 0x20, 0x0, 0xe3, 0xe2, - 0x0, 0xe, 0x3e, 0xee, 0xee, 0xf3, 0xe2, 0x0, - 0xe, 0x3e, 0x20, 0x0, 0xe3, 0xe2, 0x0, 0xe, - 0x3e, 0x20, 0x0, 0xe3, - - /* U+0049 "I" */ - 0x3d, 0xfb, 0x3, 0xd0, 0x3, 0xd0, 0x3, 0xd0, - 0x3, 0xd0, 0x3, 0xd0, 0x3, 0xd0, 0x3d, 0xfb, - - /* U+004A "J" */ - 0x9, 0xdf, 0x0, 0x1f, 0x0, 0x1f, 0x0, 0x1f, - 0x0, 0x1f, 0x0, 0x1f, 0x0, 0x4d, 0xae, 0xd4, - - /* U+004B "K" */ - 0xe2, 0x0, 0x6c, 0xe, 0x20, 0x5d, 0x10, 0xe2, - 0x4d, 0x10, 0xe, 0x6e, 0x20, 0x0, 0xed, 0xe6, - 0x0, 0xe, 0x32, 0xe4, 0x0, 0xe2, 0x3, 0xe3, - 0xe, 0x20, 0x5, 0xe2, - - /* U+004C "L" */ - 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, - 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xee, 0xee, 0xe2, - - /* U+004D "M" */ - 0xec, 0x0, 0x8, 0xf3, 0xed, 0x30, 0xd, 0xe3, - 0xe5, 0xb0, 0x77, 0xd3, 0xe1, 0xc3, 0xd0, 0xd3, - 0xe1, 0x5e, 0x80, 0xd3, 0xe1, 0xb, 0x10, 0xd3, - 0xe1, 0x0, 0x0, 0xd3, 0xe1, 0x0, 0x0, 0xd3, - - /* U+004E "N" */ - 0xee, 0x0, 0xd, 0x2e, 0xa8, 0x0, 0xd2, 0xe2, - 0xe1, 0xd, 0x2e, 0x18, 0x90, 0xd2, 0xe1, 0x1e, - 0x2d, 0x2e, 0x10, 0x7a, 0xd2, 0xe1, 0x0, 0xee, - 0x2e, 0x10, 0x6, 0xf2, - - /* U+004F "O" */ - 0x0, 0x8e, 0xed, 0x40, 0x0, 0xaa, 0x10, 0x3e, - 0x40, 0x2f, 0x0, 0x0, 0x5c, 0x4, 0xc0, 0x0, - 0x2, 0xf0, 0x4c, 0x0, 0x0, 0x2f, 0x2, 0xf0, - 0x0, 0x5, 0xd0, 0xa, 0xa1, 0x3, 0xe4, 0x0, - 0x8, 0xee, 0xd5, 0x0, - - /* U+0050 "P" */ - 0xee, 0xed, 0x50, 0xe2, 0x3, 0xf1, 0xe2, 0x0, - 0xd4, 0xe2, 0x5, 0xe1, 0xee, 0xeb, 0x30, 0xe2, - 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, 0x0, 0x0, - - /* U+0051 "Q" */ - 0x0, 0x8e, 0xed, 0x40, 0x0, 0xaa, 0x10, 0x3e, - 0x40, 0x2f, 0x0, 0x0, 0x5c, 0x4, 0xc0, 0x0, - 0x2, 0xf0, 0x4c, 0x0, 0x0, 0x2f, 0x2, 0xf0, - 0x0, 0x5, 0xc0, 0xa, 0xa1, 0x3, 0xe5, 0x0, - 0x8, 0xee, 0xf5, 0x0, 0x0, 0x0, 0x1f, 0x10, - 0x0, 0x0, 0x0, 0x7e, 0xe2, - - /* U+0052 "R" */ - 0xee, 0xed, 0x60, 0xe, 0x20, 0x2f, 0x20, 0xe2, - 0x0, 0xd4, 0xe, 0x20, 0x4e, 0x0, 0xed, 0xee, - 0x20, 0xe, 0x20, 0xc7, 0x0, 0xe2, 0x1, 0xe5, - 0xe, 0x20, 0x2, 0xe4, - - /* U+0053 "S" */ - 0x3, 0xce, 0xec, 0x41, 0xf3, 0x0, 0x45, 0x2f, - 0x0, 0x0, 0x0, 0xbe, 0x97, 0x20, 0x0, 0x37, - 0x9e, 0x70, 0x0, 0x0, 0x4d, 0x38, 0x10, 0x9, - 0xa1, 0xae, 0xed, 0x90, - - /* U+0054 "T" */ - 0xee, 0xef, 0xee, 0xb0, 0x2, 0xe0, 0x0, 0x0, - 0x2e, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, - 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, - 0x0, 0x2, 0xe0, 0x0, - - /* U+0055 "U" */ - 0xf, 0x0, 0x0, 0xf1, 0xf, 0x0, 0x0, 0xf1, - 0xf, 0x0, 0x0, 0xf1, 0xf, 0x0, 0x0, 0xf1, - 0xf, 0x0, 0x0, 0xf1, 0xf, 0x10, 0x0, 0xf0, - 0xa, 0x80, 0x8, 0xb0, 0x1, 0xae, 0xeb, 0x10, - - /* U+0056 "V" */ - 0xa7, 0x0, 0x0, 0xe3, 0x5d, 0x0, 0x3, 0xd0, - 0xe, 0x20, 0x9, 0x70, 0x9, 0x80, 0xe, 0x10, - 0x3, 0xe0, 0x5b, 0x0, 0x0, 0xd3, 0xa6, 0x0, - 0x0, 0x7a, 0xe0, 0x0, 0x0, 0x2f, 0xa0, 0x0, - - /* U+0057 "W" */ - 0x5b, 0x0, 0x3f, 0x10, 0xc, 0x31, 0xf0, 0x7, - 0xe5, 0x0, 0xf0, 0xd, 0x30, 0xb6, 0x90, 0x4b, - 0x0, 0x97, 0xd, 0xd, 0x8, 0x70, 0x5, 0xb3, - 0xa0, 0xc1, 0xc3, 0x0, 0x1f, 0x76, 0x8, 0x6e, - 0x0, 0x0, 0xce, 0x20, 0x4d, 0xa0, 0x0, 0x8, - 0xe0, 0x0, 0xf6, 0x0, - - /* U+0058 "X" */ - 0x3e, 0x10, 0x5, 0xc0, 0x8, 0xa0, 0x1e, 0x20, - 0x0, 0xd4, 0xa6, 0x0, 0x0, 0x3f, 0xb0, 0x0, - 0x0, 0x3e, 0xc0, 0x0, 0x0, 0xd3, 0xb7, 0x0, - 0x9, 0x80, 0x1e, 0x20, 0x4d, 0x0, 0x6, 0xc0, - - /* U+0059 "Y" */ - 0xa8, 0x0, 0xb, 0x61, 0xe2, 0x5, 0xc0, 0x6, - 0xb0, 0xd2, 0x0, 0xc, 0xc8, 0x0, 0x0, 0x4f, - 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, - 0x0, 0x2, 0xe0, 0x0, - - /* U+005A "Z" */ - 0x2e, 0xee, 0xef, 0xc0, 0x0, 0x0, 0xd5, 0x0, - 0x0, 0xa8, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x4d, - 0x10, 0x0, 0x2e, 0x20, 0x0, 0xd, 0x50, 0x0, - 0x5, 0xfe, 0xee, 0xed, - - /* U+005B "[" */ - 0xbc, 0xc0, 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, - 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, 0xb3, 0x0, - 0xb3, 0x0, 0xbc, 0xc0, - - /* U+005C "\\" */ - 0x68, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x50, - 0x0, 0x3, 0xb0, 0x0, 0x0, 0xc2, 0x0, 0x0, - 0x68, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, 0x50, - 0x0, 0x2, 0xc0, 0x0, 0x0, 0x60, - - /* U+005D "]" */ - 0xc, 0xcb, 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, - 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, 0x0, 0x3b, - 0x0, 0x3b, 0xc, 0xcb, - - /* U+005E "^" */ - 0x0, 0x4f, 0x40, 0x0, 0x1d, 0x3d, 0x10, 0xc, - 0x40, 0x4c, 0x9, 0x70, 0x0, 0x79, - - /* U+005F "_" */ - 0xa, 0xaa, 0xaa, 0xaa, 0x0, - - /* U+0060 "`" */ - 0xc, 0x50, 0x2, 0xc0, - - /* U+0061 "a" */ - 0xb, 0xed, 0xb1, 0x2, 0x0, 0x88, 0x5, 0xac, - 0xda, 0x4d, 0x20, 0x5a, 0x5a, 0x0, 0x8a, 0xb, - 0xcc, 0xba, - - /* U+0062 "b" */ - 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf8, 0xee, - 0x50, 0xf5, 0x3, 0xe0, 0xf0, 0x0, 0xd3, 0xf0, - 0x0, 0xd3, 0xf0, 0x4, 0xd0, 0xfb, 0xdc, 0x30, - - /* U+0063 "c" */ - 0x4, 0xcd, 0xd4, 0x1e, 0x20, 0x13, 0x5a, 0x0, - 0x0, 0x5a, 0x0, 0x0, 0x1e, 0x20, 0x13, 0x4, - 0xdd, 0xd4, - - /* U+0064 "d" */ - 0x0, 0x0, 0x2d, 0x0, 0x0, 0x2d, 0x4, 0xde, - 0xcd, 0x1e, 0x30, 0x3d, 0x5b, 0x0, 0x2d, 0x5a, - 0x0, 0x2d, 0x2e, 0x0, 0x4d, 0x6, 0xdb, 0xad, - - /* U+0065 "e" */ - 0x4, 0xcc, 0xc3, 0x1, 0xc1, 0x3, 0xd0, 0x5e, - 0xcc, 0xcd, 0x5, 0xb0, 0x0, 0x0, 0x1e, 0x40, - 0x5, 0x0, 0x4c, 0xdd, 0x90, - - /* U+0066 "f" */ - 0x5, 0xdd, 0x20, 0xe1, 0x0, 0x8f, 0xdb, 0x0, - 0xf1, 0x0, 0xf, 0x10, 0x0, 0xf1, 0x0, 0xf, - 0x10, 0x0, 0xf1, 0x0, - - /* U+0067 "g" */ - 0x4, 0xde, 0xcd, 0x1e, 0x30, 0x3d, 0x5b, 0x0, - 0x2d, 0x5a, 0x0, 0x2d, 0x2e, 0x10, 0x6d, 0x7, - 0xed, 0xac, 0x1, 0x0, 0x69, 0xa, 0xed, 0xa1, - - /* U+0068 "h" */ - 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf7, 0xde, - 0x50, 0xf5, 0x3, 0xe0, 0xf0, 0x0, 0xf0, 0xf0, - 0x0, 0xf0, 0xf0, 0x0, 0xf0, 0xf0, 0x0, 0xf0, - - /* U+0069 "i" */ - 0x1f, 0x10, 0x0, 0xf, 0x0, 0xf0, 0xf, 0x0, - 0xf0, 0xf, 0x0, 0xf0, - - /* U+006A "j" */ - 0x0, 0x4d, 0x0, 0x0, 0x6, 0xdc, 0x0, 0x3c, - 0x0, 0x3c, 0x0, 0x3c, 0x0, 0x3c, 0x0, 0x3c, - 0x0, 0x6b, 0x4e, 0xd3, - - /* U+006B "k" */ - 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x8, - 0xb0, 0xf0, 0x7b, 0x0, 0xf8, 0xb0, 0x0, 0xfa, - 0xe3, 0x0, 0xf0, 0x4e, 0x20, 0xf0, 0x5, 0xd1, - - /* U+006C "l" */ - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - - /* U+006D "m" */ - 0xf9, 0xcd, 0x6a, 0xcd, 0x2f, 0x30, 0x4e, 0x20, - 0x6a, 0xf0, 0x2, 0xd0, 0x4, 0xbf, 0x0, 0x2e, - 0x0, 0x4c, 0xf0, 0x2, 0xe0, 0x4, 0xcf, 0x0, - 0x2e, 0x0, 0x4c, - - /* U+006E "n" */ - 0xf9, 0xcd, 0x50, 0xf3, 0x2, 0xe0, 0xf0, 0x0, - 0xf0, 0xf0, 0x0, 0xf0, 0xf0, 0x0, 0xf0, 0xf0, - 0x0, 0xf0, - - /* U+006F "o" */ - 0x4, 0xdd, 0xb1, 0x1, 0xe2, 0x6, 0xc0, 0x5a, - 0x0, 0xf, 0x5, 0xa0, 0x0, 0xf0, 0x1e, 0x10, - 0x6c, 0x0, 0x5d, 0xdb, 0x20, - - /* U+0070 "p" */ - 0xf9, 0xbd, 0x50, 0xf2, 0x1, 0xe0, 0xf0, 0x0, - 0xc3, 0xf0, 0x0, 0xd3, 0xf0, 0x4, 0xd0, 0xfc, - 0xec, 0x30, 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, - - /* U+0071 "q" */ - 0x4, 0xde, 0xcd, 0x1e, 0x20, 0x3d, 0x5b, 0x0, - 0x2d, 0x5a, 0x0, 0x2d, 0x2e, 0x10, 0x6d, 0x6, - 0xed, 0x9d, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x2d, - - /* U+0072 "r" */ - 0xf7, 0xeb, 0xf6, 0x0, 0xf0, 0x0, 0xf0, 0x0, - 0xf0, 0x0, 0xf0, 0x0, - - /* U+0073 "s" */ - 0x9, 0xdd, 0xb0, 0x4c, 0x0, 0x30, 0x2e, 0x96, - 0x10, 0x1, 0x59, 0xe1, 0x32, 0x0, 0xd3, 0x3c, - 0xdd, 0x70, - - /* U+0074 "t" */ - 0x7, 0x0, 0x0, 0xf0, 0x0, 0x8f, 0xdd, 0x10, - 0xf0, 0x0, 0xf, 0x0, 0x0, 0xf0, 0x0, 0xe, - 0x20, 0x0, 0x6e, 0xd1, - - /* U+0075 "u" */ - 0xf, 0x0, 0xf, 0xf, 0x0, 0xf, 0xf, 0x0, - 0xf, 0xf, 0x0, 0xf, 0xf, 0x10, 0x4f, 0x6, - 0xdc, 0x9f, - - /* U+0076 "v" */ - 0x79, 0x0, 0x1e, 0x1, 0xe0, 0x7, 0x90, 0xa, - 0x60, 0xd2, 0x0, 0x4c, 0x3c, 0x0, 0x0, 0xdc, - 0x50, 0x0, 0x7, 0xe0, 0x0, - - /* U+0077 "w" */ - 0x6a, 0x1, 0xf1, 0x9, 0x62, 0xd0, 0x6d, 0x70, - 0xc2, 0xd, 0x1b, 0x4c, 0xe, 0x0, 0x96, 0xc0, - 0xc5, 0xa0, 0x5, 0xe7, 0x7, 0xe5, 0x0, 0x1f, - 0x20, 0x1f, 0x10, - - /* U+0078 "x" */ - 0x4e, 0x10, 0x5c, 0x0, 0x8b, 0x2d, 0x10, 0x0, - 0xbe, 0x30, 0x0, 0xb, 0xe4, 0x0, 0x7, 0x93, - 0xe1, 0x4, 0xd0, 0x7, 0xc0, - - /* U+0079 "y" */ - 0x7a, 0x0, 0x1e, 0x1, 0xe1, 0x8, 0x80, 0x9, - 0x70, 0xe1, 0x0, 0x2e, 0x6a, 0x0, 0x0, 0xbf, - 0x30, 0x0, 0x6, 0xc0, 0x0, 0x0, 0xb5, 0x0, - 0x0, 0x2e, 0x0, 0x0, - - /* U+007A "z" */ - 0x5d, 0xdd, 0xf3, 0x0, 0x8, 0x90, 0x0, 0x5c, - 0x0, 0x2, 0xd1, 0x0, 0xd, 0x40, 0x0, 0x7f, - 0xdd, 0xd4, - - /* U+007B "{" */ - 0x0, 0x5, 0xcb, 0x0, 0xe, 0x10, 0x0, 0xf, - 0x0, 0x0, 0x6a, 0x0, 0x1e, 0xb0, 0x0, 0x0, - 0x78, 0x0, 0x0, 0xe, 0x0, 0x0, 0xf, 0x0, - 0x0, 0xd, 0x10, 0x0, 0x4, 0xcb, - - /* U+007C "|" */ - 0xff, 0xff, 0xff, 0xff, 0xff, - - /* U+007D "}" */ - 0xbc, 0x50, 0x0, 0x1, 0xe0, 0x0, 0x0, 0xf0, - 0x0, 0x0, 0xb5, 0x0, 0x0, 0xc, 0xe0, 0x0, - 0x97, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x0, - 0x2, 0xd0, 0x0, 0xbc, 0x40, 0x0, - - /* U+007E "~" */ - 0x2c, 0xc3, 0x0, 0xcb, 0x32, 0xd2, 0x3b, 0xd0, - 0x3, 0xcc, 0x20, - - /* U+F001 "" */ - 0x0, 0x0, 0x0, 0x4, 0x95, 0x0, 0x1, 0x6b, - 0xff, 0xfa, 0x0, 0xd, 0xff, 0xff, 0xfa, 0x0, - 0xd, 0xff, 0xfe, 0xaa, 0x0, 0xd, 0xc8, 0x30, - 0x2a, 0x0, 0xc, 0x0, 0x0, 0x2a, 0x0, 0xc, - 0x0, 0x26, 0x6a, 0x0, 0xc, 0x2, 0xff, 0xfa, - 0x6c, 0xcd, 0x0, 0xae, 0xc3, 0xef, 0xfd, 0x0, - 0x0, 0x0, 0x16, 0x61, 0x0, 0x0, 0x0, - - /* U+F008 "" */ - 0x8c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc6, 0xd0, 0xd0, - 0x0, 0x0, 0x3b, 0xc, 0xd1, 0xd0, 0x0, 0x0, - 0x2b, 0x1c, 0xfb, 0xf0, 0x0, 0x0, 0x2e, 0xcc, - 0xc0, 0xc0, 0x0, 0x0, 0x2a, 0xc, 0xfc, 0xfd, - 0xcc, 0xcc, 0xdf, 0xdc, 0xc0, 0xc0, 0x0, 0x0, - 0x2a, 0xc, 0xfc, 0xf0, 0x0, 0x0, 0x2f, 0xdc, - 0xd0, 0xd0, 0x0, 0x0, 0x2b, 0xc, 0xd0, 0xd1, - 0x0, 0x0, 0x3b, 0x1c, 0x8c, 0xcc, 0xcc, 0xcc, - 0xcc, 0xc6, - - /* U+F00B "" */ - 0x56, 0x60, 0x56, 0x66, 0x66, 0x5f, 0xff, 0x3f, - 0xff, 0xff, 0xff, 0xdf, 0xe1, 0xdf, 0xff, 0xff, - 0xd3, 0x54, 0x4, 0x55, 0x55, 0x53, 0xff, 0xf3, - 0xff, 0xff, 0xff, 0xfc, 0xed, 0x1d, 0xee, 0xee, - 0xec, 0x45, 0x50, 0x45, 0x55, 0x55, 0x4f, 0xff, - 0x3f, 0xff, 0xff, 0xff, 0xef, 0xf1, 0xef, 0xff, - 0xff, 0xe0, - - /* U+F00C "" */ - 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x0, 0x4f, 0xd0, 0x0, 0x0, 0x0, 0x4f, 0xfe, - 0x10, 0xbe, 0x20, 0x4f, 0xfe, 0x20, 0x1f, 0xfe, - 0x6f, 0xfe, 0x20, 0x0, 0x4f, 0xff, 0xfe, 0x20, - 0x0, 0x0, 0x4f, 0xfe, 0x20, 0x0, 0x0, 0x0, - 0x4c, 0x20, 0x0, 0x0, - - /* U+F00D "" */ - 0x0, 0x0, 0x0, 0x10, 0xc, 0xe2, 0x6, 0xf7, - 0x2f, 0xfe, 0x7f, 0xfc, 0x5, 0xff, 0xff, 0xd1, - 0x0, 0x9f, 0xff, 0x30, 0x6, 0xff, 0xff, 0xe2, - 0x3f, 0xfd, 0x6f, 0xfd, 0xb, 0xd1, 0x5, 0xf6, - 0x0, 0x0, 0x0, 0x0, - - /* U+F011 "" */ - 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0xf7, - 0x0, 0x0, 0x4, 0xa1, 0xf8, 0x68, 0x0, 0x2f, - 0xd1, 0xf8, 0x7f, 0x80, 0xaf, 0x11, 0xf8, 0xa, - 0xf1, 0xea, 0x0, 0xe5, 0x4, 0xf5, 0xfa, 0x0, - 0x0, 0x3, 0xf5, 0xce, 0x0, 0x0, 0x8, 0xf2, - 0x4f, 0xa0, 0x0, 0x5f, 0xa0, 0x8, 0xff, 0xcd, - 0xfd, 0x10, 0x0, 0x3a, 0xdc, 0x70, 0x0, - - /* U+F013 "" */ - 0x0, 0x3, 0xd6, 0x0, 0x0, 0x9, 0xba, 0xfc, - 0x9b, 0x0, 0xe, 0xff, 0xff, 0xff, 0x20, 0xa, - 0xfd, 0x5b, 0xfc, 0x0, 0xff, 0xf4, 0x0, 0xff, - 0xf3, 0xff, 0xf3, 0x0, 0xff, 0xf3, 0x1a, 0xfc, - 0x39, 0xfd, 0x20, 0xd, 0xff, 0xff, 0xff, 0x20, - 0xa, 0xdb, 0xfd, 0xbd, 0x10, 0x0, 0x4, 0xf7, - 0x0, 0x0, - - /* U+F014 "" */ - 0x0, 0x28, 0x97, 0x0, 0x0, 0xb, 0x53, 0x95, - 0x0, 0xde, 0xcc, 0xcc, 0xcf, 0x73, 0x90, 0x1, - 0x0, 0xc0, 0x39, 0xa3, 0xb7, 0x4c, 0x3, 0x9a, - 0x3b, 0x84, 0xc0, 0x39, 0xa3, 0xb8, 0x4c, 0x3, - 0x98, 0x29, 0x63, 0xc0, 0x39, 0x0, 0x0, 0xc, - 0x0, 0xac, 0xcc, 0xcc, 0x60, - - /* U+F015 "" */ - 0x0, 0x0, 0xaa, 0x1c, 0x80, 0x0, 0x1, 0xca, - 0xad, 0xfa, 0x0, 0x3, 0xe9, 0xdd, 0x8f, 0xa0, - 0x5, 0xe9, 0xff, 0xfe, 0x8e, 0x70, 0x88, 0xff, - 0xff, 0xff, 0x89, 0x0, 0xaf, 0xfa, 0xaf, 0xfa, - 0x0, 0xa, 0xff, 0x11, 0xff, 0xa0, 0x0, 0x9f, - 0xf1, 0x1f, 0xf9, 0x0, - - /* U+F019 "" */ - 0x0, 0x0, 0x99, 0x20, 0x0, 0x0, 0x0, 0x1f, - 0xf4, 0x0, 0x0, 0x0, 0x1, 0xff, 0x40, 0x0, - 0x0, 0x3, 0x5f, 0xf7, 0x40, 0x0, 0x0, 0xbf, - 0xff, 0xfd, 0x10, 0x0, 0x0, 0xaf, 0xfd, 0x10, - 0x0, 0x35, 0x53, 0x9c, 0x35, 0x54, 0xf, 0xff, - 0xf3, 0x2d, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xfa, - 0xdd, 0x3e, 0xff, 0xff, 0xff, 0xef, 0xe2, - - /* U+F01C "" */ - 0x6, 0xff, 0xff, 0xfc, 0x0, 0xd, 0x83, 0x33, - 0x4f, 0x40, 0x4f, 0x0, 0x0, 0x9, 0xb0, 0xb9, - 0x0, 0x0, 0x2, 0xf2, 0xfa, 0x82, 0x0, 0x78, - 0xf6, 0xff, 0xfb, 0x57, 0xff, 0xf6, 0xff, 0xff, - 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, - - /* U+F021 "" */ - 0x0, 0x4, 0x65, 0x10, 0x0, 0x2, 0xdf, 0xff, - 0xf8, 0xa6, 0x1e, 0xe6, 0x24, 0xbf, 0xf7, 0x9f, - 0x30, 0x0, 0xaf, 0xf7, 0x65, 0x0, 0x0, 0x77, - 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf5, - 0x0, 0x6, 0xf2, 0xff, 0xd0, 0x0, 0x4f, 0xb0, - 0xfc, 0xff, 0xcd, 0xfd, 0x10, 0x50, 0x4a, 0xdb, - 0x70, 0x0, - - /* U+F026 "" */ - 0x0, 0x1, 0x50, 0x1, 0xdb, 0x67, 0xdf, 0xbf, - 0xff, 0xfb, 0xff, 0xff, 0xba, 0xbf, 0xfb, 0x0, - 0x3f, 0xb0, 0x0, 0x38, - - /* U+F027 "" */ - 0x0, 0x1, 0x50, 0x0, 0x0, 0x1d, 0xb0, 0x0, - 0x67, 0xdf, 0xb1, 0x10, 0xff, 0xff, 0xb2, 0xc0, - 0xff, 0xff, 0xb0, 0xd0, 0xab, 0xff, 0xb3, 0x40, - 0x0, 0x3f, 0xb0, 0x0, 0x0, 0x3, 0x80, 0x0, - - /* U+F028 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, - 0x0, 0xc5, 0x0, 0x0, 0xc, 0xb0, 0x73, 0xb4, - 0x4, 0x5c, 0xfb, 0x12, 0xc3, 0xc0, 0xff, 0xff, - 0xb3, 0xc4, 0x8a, 0x1f, 0xff, 0xfb, 0xc, 0x39, - 0x92, 0xcc, 0xff, 0xb3, 0x59, 0x5c, 0x0, 0x5, - 0xfb, 0x8, 0x95, 0x90, 0x0, 0x5, 0xa0, 0x16, - 0xc0, 0x0, 0x0, 0x0, 0x1, 0x70, 0x0, - - /* U+F03E "" */ - 0x6a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0xd2, 0x22, - 0x22, 0x22, 0x22, 0x2c, 0xc3, 0xfa, 0x0, 0x0, - 0x0, 0xc, 0xc4, 0xfc, 0x0, 0x1c, 0x40, 0xc, - 0xc0, 0x31, 0x1, 0xdf, 0xf4, 0xc, 0xc0, 0x1a, - 0x3d, 0xff, 0xff, 0x2c, 0xc1, 0xdf, 0xff, 0xff, - 0xff, 0x3c, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x3c, - 0xc1, 0x33, 0x33, 0x33, 0x33, 0xc, 0x9c, 0xcc, - 0xcc, 0xcc, 0xcc, 0xc6, - - /* U+F040 "" */ - 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x3, - 0xff, 0x60, 0x0, 0x0, 0x47, 0xbf, 0xf2, 0x0, - 0x4, 0xdd, 0x7b, 0xc0, 0x0, 0x4d, 0xcf, 0xf6, - 0x0, 0x4, 0xdc, 0xff, 0xc0, 0x0, 0x4e, 0xcf, - 0xfc, 0x0, 0x0, 0xd4, 0xff, 0xc0, 0x0, 0x0, - 0xf7, 0x7c, 0x0, 0x0, 0x0, 0xcc, 0xa0, 0x0, - 0x0, 0x0, - - /* U+F048 "" */ - 0x63, 0x0, 0x1, 0x1f, 0x90, 0x1, 0xc4, 0xf9, - 0x1, 0xcf, 0x4f, 0x91, 0xcf, 0xf4, 0xfa, 0xcf, - 0xff, 0x4f, 0xdf, 0xff, 0xf4, 0xf9, 0x5f, 0xff, - 0x4f, 0x90, 0x5f, 0xf4, 0xf9, 0x0, 0x5f, 0x4e, - 0x80, 0x0, 0x54, - - /* U+F04B "" */ - 0x81, 0x0, 0x0, 0x0, 0xf, 0xe7, 0x0, 0x0, - 0x0, 0xff, 0xfd, 0x50, 0x0, 0xf, 0xff, 0xff, - 0xc3, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x2f, 0xff, - 0xff, 0xff, 0xc3, 0xff, 0xff, 0xfe, 0x60, 0xf, - 0xff, 0xf7, 0x0, 0x0, 0xff, 0x91, 0x0, 0x0, - 0xa, 0x20, 0x0, 0x0, 0x0, - - /* U+F04C "" */ - 0x67, 0x76, 0x4, 0x77, 0x70, 0xff, 0xfe, 0xb, - 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xff, - 0xfe, 0xb, 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, - 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xff, 0xfe, - 0xb, 0xff, 0xf3, 0xff, 0xfe, 0xb, 0xff, 0xf3, - 0xff, 0xfe, 0xb, 0xff, 0xf3, 0xef, 0xfd, 0xa, - 0xff, 0xf2, - - /* U+F04D "" */ - 0x67, 0x77, 0x77, 0x77, 0x72, 0xff, 0xff, 0xff, - 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, - 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, - 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, - 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, - 0xff, 0xff, 0xff, 0xff, 0xf6, 0xef, 0xff, 0xff, - 0xff, 0xf5, - - /* U+F051 "" */ - 0x11, 0x0, 0x2, 0x70, 0x3d, 0x10, 0x7, 0xf1, - 0x3f, 0xd1, 0x7, 0xf1, 0x3f, 0xfd, 0x17, 0xf1, - 0x3f, 0xff, 0xd9, 0xf1, 0x3f, 0xff, 0xfd, 0xf1, - 0x3f, 0xff, 0x77, 0xf1, 0x3f, 0xf7, 0x7, 0xf1, - 0x3f, 0x70, 0x7, 0xf1, 0x27, 0x0, 0x6, 0xe0, - - /* U+F052 "" */ - 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xc, - 0xff, 0x40, 0x0, 0x0, 0xc, 0xff, 0xff, 0x40, - 0x0, 0xc, 0xff, 0xff, 0xff, 0x40, 0xa, 0xdd, - 0xdd, 0xdd, 0xdd, 0x20, 0x55, 0x55, 0x55, 0x55, - 0x51, 0xf, 0xff, 0xff, 0xff, 0xff, 0x60, 0xff, - 0xff, 0xff, 0xff, 0xf6, - - /* U+F053 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xa0, - 0x0, 0x1, 0xdf, 0xf2, 0x0, 0x1d, 0xff, 0x40, - 0x1, 0xdf, 0xf4, 0x0, 0xd, 0xff, 0x40, 0x0, - 0x8, 0xff, 0x90, 0x0, 0x0, 0x8f, 0xf9, 0x0, - 0x0, 0x8, 0xff, 0x90, 0x0, 0x0, 0x8f, 0xf2, - 0x0, 0x0, 0x7, 0x50, - - /* U+F054 "" */ - 0x0, 0x0, 0x0, 0x0, 0xcb, 0x0, 0x0, 0x4f, - 0xfb, 0x0, 0x0, 0x6f, 0xfb, 0x0, 0x0, 0x6f, - 0xfb, 0x0, 0x0, 0x6f, 0xfa, 0x0, 0xb, 0xff, - 0x60, 0xb, 0xff, 0x60, 0xb, 0xff, 0x60, 0x4, - 0xff, 0x60, 0x0, 0x6, 0x50, 0x0, 0x0, - - /* U+F067 "" */ - 0x0, 0x7, 0xa3, 0x0, 0x0, 0x0, 0xdf, 0x80, - 0x0, 0x0, 0xd, 0xf8, 0x0, 0x6, 0x88, 0xef, - 0xc8, 0x83, 0xff, 0xff, 0xff, 0xff, 0xac, 0xdd, - 0xff, 0xed, 0xd7, 0x0, 0xd, 0xf8, 0x0, 0x0, - 0x0, 0xdf, 0x80, 0x0, 0x0, 0xc, 0xf6, 0x0, - 0x0, - - /* U+F068 "" */ - 0x46, 0x66, 0x66, 0x66, 0x2f, 0xff, 0xff, 0xff, - 0xfa, 0xdf, 0xff, 0xff, 0xff, 0x80, - - /* U+F071 "" */ - 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x5f, 0x50, 0x0, 0x0, 0x0, 0x0, 0xd, - 0xfd, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xf7, - 0x0, 0x0, 0x0, 0x1, 0xea, 0xa, 0xe1, 0x0, - 0x0, 0x0, 0x8f, 0xa0, 0xaf, 0x80, 0x0, 0x0, - 0x2f, 0xfb, 0xb, 0xff, 0x10, 0x0, 0xa, 0xff, - 0xfc, 0xff, 0xfa, 0x0, 0x3, 0xff, 0xfb, 0xb, - 0xff, 0xf3, 0x0, 0xbf, 0xff, 0xe9, 0xef, 0xff, - 0xb0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, - - /* U+F074 "" */ - 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x0, 0x5, 0xb0, 0xff, 0xc3, 0x7, 0xdf, 0xff, - 0xb9, 0xae, 0xe7, 0xfc, 0xac, 0xf6, 0x0, 0x29, - 0xfb, 0x0, 0x56, 0x0, 0x0, 0x8f, 0x30, 0x0, - 0x0, 0x0, 0x1e, 0xb8, 0x0, 0x45, 0x8, 0x8d, - 0xf7, 0xfb, 0x8b, 0xf5, 0xff, 0xd4, 0x9, 0xff, - 0xff, 0xc0, 0x0, 0x0, 0x0, 0x6, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x20, 0x0, - - /* U+F077 "" */ - 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x6, - 0xfc, 0x10, 0x0, 0x0, 0x6, 0xff, 0xfc, 0x10, - 0x0, 0x6, 0xff, 0xcf, 0xfc, 0x10, 0x6, 0xff, - 0xb0, 0x4f, 0xfc, 0x11, 0xff, 0xa0, 0x0, 0x4f, - 0xf8, 0x5, 0xa0, 0x0, 0x0, 0x4a, 0x0, - - /* U+F078 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0x20, - 0x0, 0x8, 0xe2, 0x1e, 0xfe, 0x20, 0x8, 0xff, - 0x70, 0x3e, 0xfe, 0x28, 0xff, 0x90, 0x0, 0x3e, - 0xff, 0xff, 0x90, 0x0, 0x0, 0x3e, 0xff, 0x90, - 0x0, 0x0, 0x0, 0x3e, 0x90, 0x0, 0x0, 0x0, - 0x0, 0x10, 0x0, 0x0, - - /* U+F079 "" */ - 0x0, 0x0, 0x0, 0x11, 0x11, 0x0, 0x0, 0x5, - 0xd1, 0xdf, 0xff, 0xff, 0x10, 0x3, 0xff, 0xc2, - 0x88, 0x8c, 0xf1, 0x0, 0xef, 0xff, 0x80, 0x0, - 0x8f, 0x10, 0x1, 0x8f, 0x20, 0x0, 0x19, 0xf3, - 0x0, 0x7, 0xf1, 0x0, 0xe, 0xff, 0xf7, 0x0, - 0x7f, 0x99, 0x98, 0x3f, 0xfb, 0x0, 0x7, 0xff, - 0xff, 0xf7, 0x5c, 0x0, - - /* U+F07B "" */ - 0x4a, 0xa9, 0x10, 0x0, 0x0, 0xe, 0xff, 0xfa, - 0x11, 0x11, 0x0, 0xff, 0xff, 0xff, 0xff, 0xfd, - 0xf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xf3, 0x9f, 0xff, 0xff, 0xff, - 0xfc, 0x0, - - /* U+F093 "" */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, - 0xc0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xc0, 0x0, - 0x0, 0x9, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x78, - 0xff, 0xa7, 0x10, 0x0, 0x0, 0x1f, 0xf4, 0x0, - 0x0, 0x0, 0x1, 0xff, 0x40, 0x0, 0x4, 0x55, - 0x29, 0xa2, 0x55, 0x50, 0xff, 0xfe, 0x99, 0xcf, - 0xff, 0x3f, 0xff, 0xff, 0xff, 0x8c, 0xc3, 0xac, - 0xcc, 0xcc, 0xcc, 0xcc, 0x10, - - /* U+F095 "" */ - 0x29, 0x10, 0x0, 0x0, 0xc, 0xfa, 0x0, 0x0, - 0x0, 0xff, 0xf0, 0x0, 0x0, 0xc, 0xf3, 0x0, - 0x0, 0x0, 0x5f, 0x70, 0x0, 0x0, 0x0, 0xcf, - 0x40, 0x0, 0x0, 0x1, 0xdf, 0x73, 0xfa, 0x10, - 0x1, 0xcf, 0xff, 0xf9, 0x0, 0x0, 0x5c, 0xfc, - 0x20, - - /* U+F0C4 "" */ - 0x6, 0xcb, 0x40, 0x0, 0x0, 0x0, 0xf, 0x44, - 0xc4, 0x0, 0x6, 0x67, 0xd, 0x70, 0x59, 0x4, - 0x61, 0x63, 0x2, 0xcf, 0xfa, 0x72, 0x17, 0x10, - 0x0, 0x1, 0x1b, 0x53, 0xa0, 0x0, 0x2, 0xde, - 0xf8, 0x97, 0x7, 0x10, 0xe, 0x60, 0x58, 0x4, - 0x71, 0x53, 0xf, 0x44, 0xd3, 0x0, 0x6, 0x77, - 0x6, 0xcb, 0x30, 0x0, 0x0, 0x0, - - /* U+F0C5 "" */ - 0x0, 0x8, 0xaa, 0x80, 0x0, 0x0, 0xc, 0xe2, - 0x2d, 0x0, 0x0, 0xc, 0x8c, 0x0, 0xc0, 0x0, - 0xb, 0xb1, 0xc0, 0xc, 0xef, 0xfe, 0xeb, 0xb8, - 0x4, 0xcd, 0x0, 0xcc, 0x0, 0x4, 0xb1, 0xd0, - 0xc, 0xc0, 0x0, 0xec, 0xc9, 0x0, 0xcc, 0x0, - 0x1b, 0x0, 0x0, 0xc, 0xdc, 0xcd, 0xb0, 0x0, - 0x0, 0xc0, 0x0, 0x1b, 0x0, 0x0, 0xc, 0x0, - 0x1, 0xb0, 0x0, 0x0, 0xc0, 0x0, 0xb, 0xcc, - 0xcc, 0xca, - - /* U+F0C7 "" */ - 0xac, 0xcc, 0xcc, 0xb4, 0x0, 0xc7, 0xfc, 0xb, - 0x3d, 0x50, 0xc7, 0xfc, 0xb, 0x10, 0xb4, 0xc6, - 0xff, 0xbe, 0x0, 0x29, 0xc0, 0x1, 0x10, 0x0, - 0x2a, 0xc0, 0x0, 0x0, 0x0, 0x2a, 0xc5, 0xdc, - 0xcc, 0xcd, 0x2a, 0xc7, 0x40, 0x0, 0xe, 0x2a, - 0xc7, 0x40, 0x0, 0xe, 0x2a, 0xac, 0xcc, 0xcc, - 0xcc, 0xc6, - - /* U+F0E7 "" */ - 0x0, 0xbd, 0x90, 0x0, 0xf, 0xf6, 0x0, 0x4, - 0xff, 0x11, 0x10, 0x8f, 0xed, 0xf4, 0xc, 0xff, - 0xfd, 0x0, 0x96, 0x6f, 0x50, 0x0, 0x8, 0xd0, - 0x0, 0x0, 0xc6, 0x0, 0x0, 0xe, 0x0, 0x0, - 0x3, 0x70, 0x0, 0x0, 0x10, 0x0, 0x0, - - /* U+F0F3 "" */ - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x19, - 0xf6, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xfc, 0x0, - 0x0, 0xa, 0xff, 0xff, 0xf5, 0x0, 0x0, 0xdf, - 0xff, 0xff, 0x80, 0x0, 0xe, 0xff, 0xff, 0xf9, - 0x0, 0x1, 0xff, 0xff, 0xff, 0xc0, 0x0, 0x7f, - 0xff, 0xff, 0xff, 0x20, 0x2f, 0xff, 0xff, 0xff, - 0xfc, 0x8, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, - 0x1, 0xcf, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x82, - 0x0, 0x0, - - /* U+F11C "" */ - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc9, 0xc3, 0x25, - 0x22, 0x51, 0x33, 0x1c, 0xc2, 0x13, 0x12, 0x30, - 0x29, 0x3c, 0xc5, 0xc2, 0x86, 0x29, 0x4d, 0x2c, - 0xc2, 0x15, 0x55, 0x55, 0x33, 0x1c, 0xc3, 0x26, - 0x77, 0x77, 0x33, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, - 0xcc, 0xc9, - - /* U+F124 "" */ - 0x0, 0x0, 0x0, 0x1, 0x87, 0x0, 0x0, 0x1, - 0x8f, 0xf3, 0x0, 0x1, 0x8f, 0xff, 0xb0, 0x1, - 0x8f, 0xff, 0xff, 0x30, 0xc, 0xdd, 0xdf, 0xfb, - 0x0, 0x0, 0x0, 0x1f, 0xf3, 0x0, 0x0, 0x0, - 0x1f, 0xb0, 0x0, 0x0, 0x0, 0x1f, 0x30, 0x0, - 0x0, 0x0, 0x8, 0x0, 0x0, - - /* U+F15B "" */ - 0x23, 0x33, 0x31, 0x0, 0x0, 0xff, 0xff, 0xf8, - 0x70, 0x0, 0xff, 0xff, 0xf8, 0xbb, 0x0, 0xff, - 0xff, 0xf8, 0xaf, 0xa0, 0xff, 0xff, 0xfb, 0x44, - 0x41, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, - 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, - 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, - 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xbc, - 0xcc, 0xcc, 0xcc, 0xc3, - - /* U+F1EB "" */ - 0x0, 0x4, 0x9b, 0xca, 0x72, 0x0, 0x0, 0x5d, - 0xff, 0xdc, 0xef, 0xfa, 0x10, 0x7f, 0xe6, 0x35, - 0x64, 0x39, 0xfe, 0x12, 0x93, 0xbf, 0xff, 0xff, - 0x74, 0x80, 0x0, 0xef, 0x94, 0x35, 0xcf, 0x60, - 0x0, 0x3, 0x28, 0xff, 0xc4, 0x50, 0x0, 0x0, - 0x3, 0xfc, 0xae, 0xb0, 0x0, 0x0, 0x0, 0x1, - 0x48, 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, - 0x0, 0x0, 0x0, - - /* U+F240 "" */ - 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, - 0x44, 0x44, 0x44, 0x44, 0x42, 0xa2, 0xc7, 0xff, - 0xff, 0xff, 0xff, 0xf9, 0x9a, 0xc7, 0xff, 0xff, - 0xff, 0xff, 0xf9, 0xc, 0xc7, 0xff, 0xff, 0xff, - 0xff, 0xf9, 0xc, 0xc7, 0xff, 0xff, 0xff, 0xff, - 0xf9, 0x7b, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x64, - 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, - - /* U+F241 "" */ - 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, - 0x44, 0x44, 0x44, 0x41, 0x0, 0xa2, 0xc7, 0xff, - 0xff, 0xff, 0xf4, 0x0, 0x9a, 0xc7, 0xff, 0xff, - 0xff, 0xf4, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xff, - 0xf4, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xff, 0xf4, - 0x0, 0x7b, 0xc3, 0x66, 0x66, 0x66, 0x61, 0x0, - 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, - - /* U+F242 "" */ - 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, - 0x44, 0x44, 0x40, 0x0, 0x0, 0xa2, 0xc7, 0xff, - 0xff, 0xf0, 0x0, 0x0, 0x9a, 0xc7, 0xff, 0xff, - 0xf0, 0x0, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xf0, - 0x0, 0x0, 0xc, 0xc7, 0xff, 0xff, 0xf0, 0x0, - 0x0, 0x7b, 0xc3, 0x66, 0x66, 0x60, 0x0, 0x0, - 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, - - /* U+F243 "" */ - 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc2, - 0x44, 0x20, 0x0, 0x0, 0x0, 0xa2, 0xc7, 0xff, - 0xa0, 0x0, 0x0, 0x0, 0x9a, 0xc7, 0xff, 0xa0, - 0x0, 0x0, 0x0, 0xc, 0xc7, 0xff, 0xa0, 0x0, - 0x0, 0x0, 0xc, 0xc7, 0xff, 0xa0, 0x0, 0x0, - 0x0, 0x7b, 0xc3, 0x66, 0x40, 0x0, 0x0, 0x0, - 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, - - /* U+F244 "" */ - 0xac, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0xc0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, 0xc0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x9a, 0xc0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x7b, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xa2, 0xbc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, - - /* U+F293 "" */ - 0x0, 0x0, 0x22, 0x0, 0x0, 0x7, 0xfe, 0xfe, - 0x50, 0x5, 0xff, 0x98, 0xff, 0x30, 0xcf, 0xf9, - 0x18, 0xfa, 0xf, 0xb4, 0x89, 0x1d, 0xd1, 0xff, - 0x90, 0x1a, 0xff, 0x1f, 0xff, 0x23, 0xff, 0xf1, - 0xff, 0x44, 0x44, 0xfe, 0xe, 0xba, 0x97, 0x2d, - 0xc0, 0xaf, 0xf9, 0x1d, 0xf8, 0x2, 0xef, 0xad, - 0xfd, 0x10, 0x2, 0x9b, 0xb8, 0x10 -}; - - -/*--------------------- - * GLYPH DESCRIPTION - *--------------------*/ - -static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { - {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 62, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 0, .adv_w = 69, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 8, .adv_w = 81, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 18, .adv_w = 144, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 46, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 81, .adv_w = 189, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 129, .adv_w = 128, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 165, .adv_w = 47, .box_w = 3, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 171, .adv_w = 80, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 196, .adv_w = 80, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 221, .adv_w = 112, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 239, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 264, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 272, .adv_w = 80, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 275, .adv_w = 64, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 277, .adv_w = 80, .box_w = 6, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 307, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 335, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 355, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 383, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 411, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 439, .adv_w = 112, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 463, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 491, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 519, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 547, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 575, .adv_w = 80, .box_w = 3, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 584, .adv_w = 80, .box_w = 3, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 596, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 621, .adv_w = 144, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 632, .adv_w = 144, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 657, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 681, .adv_w = 176, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 731, .adv_w = 120, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 763, .adv_w = 121, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 791, .adv_w = 123, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 823, .adv_w = 136, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 851, .adv_w = 111, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 875, .adv_w = 101, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 899, .adv_w = 136, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 931, .adv_w = 132, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 959, .adv_w = 74, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 975, .adv_w = 80, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 991, .adv_w = 122, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1019, .adv_w = 98, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1043, .adv_w = 148, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1075, .adv_w = 132, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1103, .adv_w = 139, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1139, .adv_w = 106, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1163, .adv_w = 139, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1208, .adv_w = 122, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1236, .adv_w = 120, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1264, .adv_w = 108, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1292, .adv_w = 129, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1324, .adv_w = 120, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1356, .adv_w = 174, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1400, .adv_w = 121, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1432, .adv_w = 108, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1460, .adv_w = 121, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1488, .adv_w = 80, .box_w = 4, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 1508, .adv_w = 80, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1538, .adv_w = 80, .box_w = 4, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1558, .adv_w = 144, .box_w = 7, .box_h = 4, .ofs_x = 1, .ofs_y = 4}, - {.bitmap_index = 1572, .adv_w = 112, .box_w = 9, .box_h = 1, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 1577, .adv_w = 112, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 7}, - {.bitmap_index = 1581, .adv_w = 106, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1599, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1623, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1641, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1665, .adv_w = 105, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1686, .adv_w = 62, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1706, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1730, .adv_w = 111, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1754, .adv_w = 48, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1766, .adv_w = 61, .box_w = 4, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 1786, .adv_w = 104, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1810, .adv_w = 48, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1818, .adv_w = 171, .box_w = 9, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1845, .adv_w = 111, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1863, .adv_w = 107, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1884, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 1908, .adv_w = 110, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1932, .adv_w = 75, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 1944, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1962, .adv_w = 69, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1982, .adv_w = 111, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2000, .adv_w = 104, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2021, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2048, .adv_w = 104, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2069, .adv_w = 104, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2097, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2115, .adv_w = 112, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2145, .adv_w = 80, .box_w = 1, .box_h = 10, .ofs_x = 2, .ofs_y = -2}, - {.bitmap_index = 2150, .adv_w = 112, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 2180, .adv_w = 144, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, - {.bitmap_index = 2191, .adv_w = 151, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2246, .adv_w = 189, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 2312, .adv_w = 176, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2362, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2406, .adv_w = 138, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2442, .adv_w = 151, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2497, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2547, .adv_w = 138, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2592, .adv_w = 163, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2636, .adv_w = 163, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2691, .adv_w = 151, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2731, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2781, .adv_w = 75, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2801, .adv_w = 113, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 2833, .adv_w = 163, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2888, .adv_w = 189, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2948, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 2998, .adv_w = 101, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3033, .adv_w = 138, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3078, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3128, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3178, .adv_w = 101, .box_w = 8, .box_h = 10, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 3218, .adv_w = 151, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 3262, .adv_w = 126, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3306, .adv_w = 126, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3345, .adv_w = 138, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3386, .adv_w = 138, .box_w = 9, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 3400, .adv_w = 176, .box_w = 13, .box_h = 11, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 3472, .adv_w = 176, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3533, .adv_w = 176, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3572, .adv_w = 176, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3616, .adv_w = 189, .box_w = 13, .box_h = 8, .ofs_x = -1, .ofs_y = 0}, - {.bitmap_index = 3668, .adv_w = 163, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3718, .adv_w = 163, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3779, .adv_w = 138, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 3820, .adv_w = 176, .box_w = 12, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 3874, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 3940, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 3990, .adv_w = 88, .box_w = 7, .box_h = 11, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 4029, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 4095, .adv_w = 189, .box_w = 12, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4137, .adv_w = 138, .box_w = 10, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, - {.bitmap_index = 4182, .adv_w = 151, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 4242, .adv_w = 201, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4301, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4357, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4413, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4469, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4525, .adv_w = 226, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 4581, .adv_w = 151, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -2} -}; - -/*--------------------- - * CHARACTER MAPPING - *--------------------*/ - -static const uint16_t unicode_list_1[] = { - 0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13, - 0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d, - 0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52, - 0x53, 0x66, 0x67, 0x70, 0x73, 0x76, 0x77, 0x78, - 0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, 0xf2, - 0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, 0x241, 0x242, - 0x243, 0x292 -}; - -/*Collect the unicode lists and glyph_id offsets*/ -static const lv_font_fmt_txt_cmap_t cmaps[] = -{ - { - .range_start = 32, .range_length = 95, .glyph_id_start = 1, - .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY - }, - { - .range_start = 61441, .range_length = 659, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY - } -}; - -/*----------------- - * KERNING - *----------------*/ - - -/*Map glyph_ids to kern left classes*/ -static const uint8_t kern_left_class_mapping[] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 2, 3, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4, 5, 6, 7, 0, 8, - 0, 0, 9, 10, 11, 12, 0, 0, - 13, 14, 15, 16, 17, 18, 10, 19, - 20, 21, 22, 23, 0, 0, 0, 0, - 0, 0, 24, 25, 26, 0, 27, 28, - 0, 29, 0, 0, 30, 0, 29, 29, - 31, 25, 0, 32, 0, 33, 0, 34, - 35, 36, 37, 38, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -/*Map glyph_ids to kern right classes*/ -static const uint8_t kern_right_class_mapping[] = -{ - 0, 0, 0, 1, 0, 0, 0, 0, - 2, 0, 3, 4, 0, 5, 6, 7, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 8, 0, 0, 0, - 9, 0, 10, 0, 11, 0, 0, 0, - 11, 0, 12, 13, 0, 0, 0, 0, - 14, 0, 0, 0, 15, 16, 17, 18, - 19, 20, 21, 22, 0, 3, 3, 0, - 0, 0, 23, 0, 24, 25, 26, 0, - 27, 0, 0, 0, 0, 0, 28, 28, - 26, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -/*Kern values between classes*/ -static const int8_t kern_class_values[] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -4, - 0, -3, -9, 0, -2, -13, 0, -4, - -4, -7, -12, -3, -2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -3, - -2, -4, -3, -3, 0, 0, 0, 0, - -11, -14, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -4, - 0, 0, 0, 0, 0, 0, 0, 0, - -1, -10, -1, -5, -4, 0, -7, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -2, -1, -4, -3, 0, -4, 0, - 0, 0, 0, 0, -2, 1, -2, 0, - 0, 0, 0, 0, 0, 0, 0, -5, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -4, 0, -4, 0, 0, 0, 0, 0, - 0, 0, 0, -4, 0, 0, -2, -1, - -2, -2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -26, 0, - -26, -5, 5, -9, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 0, 0, - -9, 0, 0, -4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -2, 0, -2, 0, 0, -1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -9, 0, 0, 0, 0, 0, 0, - 0, -2, 0, 0, 0, 0, 0, 0, - 0, 0, -5, 0, 0, -6, 0, 0, - 0, 0, 0, 0, -4, -7, -6, 0, - -7, 0, 0, -10, 0, 0, 0, -14, - 0, 0, 0, 0, -2, 0, 9, -2, - 0, -15, 0, -9, -9, 0, -14, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -9, 0, 0, -9, 0, - 0, 0, 0, 0, -3, 0, -3, 0, - 0, 0, 0, 0, 0, 0, 0, -4, - 0, 0, 0, -1, -2, -2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -26, 0, -26, 0, 0, -4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, -4, 0, 0, -4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -3, 0, -3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -9, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -5, 0, 0, 0, 0, -2, 0, - -3, 0, 0, -4, 0, 0, 0, 0, - 0, 0, -2, 0, 0, 0, -5, 0, - 0, 0, 0, 0, -2, 0, -2, 0, - 0, -2, 0, 0, 0, 0, -2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -3, -2, 0, -3, 0, 0, 0, - 0, 0, -25, -13, -25, -17, 5, -10, - -3, 0, 0, -4, -1, -6, 0, 0, - 0, 0, 0, 0, -21, -19, 0, -19, - -18, 0, 0, -17, -15, 0, -17, -17, - -17, 0, -17, -15, 0, 0, 0, 0, - -25, -4, -25, -7, 0, -5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -9, 0, 0, -9, 0, 0, - 0, 0, 0, 0, -5, 0, 0, 0, - -6, 0, 0, 0, 0, 0, -25, -4, - -19, -7, 0, -4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -9, 0, 0, -9, 0, 0, 0, -5, - 0, 0, -5, 0, 0, 0, -6, 0, - 0, 0, 0, 0, 0, -7, 0, 0, - 0, 0, -1, 0, 0, -1, 0, 0, - 0, 0, 0, 0, 0, 0, -4, 0, - 0, -5, 0, 0, 0, 0, 0, 0, - -3, 0, 0, 0, -7, 0, 0, 0, - 0, 0, -25, -12, -25, -17, 0, -7, - 0, 0, 0, -2, 0, 0, 0, 0, - 0, 0, 0, 0, -12, 0, -10, -11, - -11, -9, -11, -9, -9, 0, -9, -9, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -5, 0, 0, 0, 0, -2, 0, - 0, -2, 0, 0, 0, 0, 0, 0, - 0, -1, -4, 0, 0, -5, 0, 0, - 0, 0, 0, 0, 0, 0, -3, 0, - -6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -1, -1, 0, -1, 0, - 0, 0, 0, 0, -3, 0, -2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -12, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 9, 4, -11, -4, - -10, 0, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -2, -1, 0, -2, 0, 0, 0, - 0, 0, 0, -9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -3, 0, -2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -1, 0, -2, - -1, 0, 0, 0, 0, 0, -25, -2, - -25, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -1, 0, 0, 0, - 0, 0, -15, -3, -15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -3, 0, 0, -2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -6, -2, -6, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -2, -1, -2, -1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -16, -3, -16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -3, -2, - -1, -2, -1, 0, -1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -2, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -1, -1, -1, - -1, 0, -1, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; - - -/*Collect the kern class' data in one place*/ -static const lv_font_fmt_txt_kern_classes_t kern_classes = -{ - .class_pair_values = kern_class_values, - .left_class_mapping = kern_left_class_mapping, - .right_class_mapping = kern_right_class_mapping, - .left_class_cnt = 38, - .right_class_cnt = 38, -}; - -/*-------------------- - * ALL CUSTOM DATA - *--------------------*/ - -#if LV_VERSION_CHECK(8, 0, 0) -/*Store all the custom data of the font*/ -static lv_font_fmt_txt_glyph_cache_t cache; -static const lv_font_fmt_txt_dsc_t font_dsc = { -#else -static lv_font_fmt_txt_dsc_t font_dsc = { -#endif - .glyph_bitmap = glyph_bitmap, - .glyph_dsc = glyph_dsc, - .cmaps = cmaps, - .kern_dsc = &kern_classes, - .kern_scale = 16, - .cmap_num = 2, - .bpp = 4, - .kern_classes = 1, - .bitmap_format = 0, -#if LV_VERSION_CHECK(8, 0, 0) - .cache = &cache -#endif -}; - - -/*----------------- - * PUBLIC FONT - *----------------*/ - -/*Initialize a public general font descriptor*/ -#if LV_VERSION_CHECK(8, 0, 0) -const lv_font_t lv_font_verdana_11 = { -#else -lv_font_t lv_font_verdana_11 = { -#endif - .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ - .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ - .line_height = 12, /*The maximum line height required by the font*/ - .base_line = 2, /*Baseline measured from the bottom of the line*/ -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - .subpx = LV_FONT_SUBPX_NONE, -#endif -#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 - .underline_position = -1, - .underline_thickness = 1, -#endif - .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ -}; - - - -#endif /*#if LV_FONT_VERDANA_11*/ From a9271aad69e64108337387e1248ddf5f927e5819 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 19 Mar 2024 17:16:08 +0530 Subject: [PATCH 21/32] feat: Added special characters --- common/lv_conf.h | 2 +- common/lvgl/src/lv_font/lv_font_roboto_12.c | 1529 ++++++++----------- 2 files changed, 608 insertions(+), 923 deletions(-) diff --git a/common/lv_conf.h b/common/lv_conf.h index 3936af94..7f44e363 100644 --- a/common/lv_conf.h +++ b/common/lv_conf.h @@ -283,7 +283,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ * LV_FONT_DECLARE(my_font_2) */ -#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font) LV_FONT_DECLARE(my_logo) LV_FONT_DECLARE(nfc_logo) +#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(nfc_logo) LV_FONT_DECLARE(special_char) /*Always set a default font from the built-in fonts*/ #define LV_FONT_DEFAULT &lv_font_roboto_12 diff --git a/common/lvgl/src/lv_font/lv_font_roboto_12.c b/common/lvgl/src/lv_font/lv_font_roboto_12.c index 98e23dc7..4865d002 100644 --- a/common/lvgl/src/lv_font/lv_font_roboto_12.c +++ b/common/lvgl/src/lv_font/lv_font_roboto_12.c @@ -1,11 +1,15 @@ -#include "lvgl/lvgl.h" - /******************************************************************************* * Size: 12 px * Bpp: 1 - * Opts: + * Opts: --no-compress --no-prefilter --bpp 1 --size 12 --font Roboto-Regular.woff -r 0x41-0x5A,0x61-0x7A --font Roboto-Regular.woff -r 0x30-0x39 --font verdana.ttf -r 0x20-0x2F,0x3A-0x40,0x5B-0x60,0x7B-0x7F --font FontAwesome.ttf -r 61441,61448,61451,61452,61453,61457,61459,61460,61461,61465,61468,61473,61478,61479,61480,61502,61504,61512,61515,61516,61517,61521,61522,61523,61524,61536,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62099,62087,62189 --font fa.woff -r 62212,62218,62810,63426,63650 -o lv_font_roboto_12 --format lvgl --force-fast-kern-format ******************************************************************************/ +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + #ifndef LV_FONT_ROBOTO_12 #define LV_FONT_ROBOTO_12 1 #endif @@ -17,515 +21,520 @@ *----------------*/ /*Store the image of the glyphs*/ -static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { - /* U+20 " " */ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ 0x0, - /* U+21 "!" */ + /* U+0021 "!" */ 0xfc, 0x80, - /* U+22 "\"" */ - 0xfc, + /* U+0022 "\"" */ + 0xaa, 0xa0, - /* U+23 "#" */ - 0x28, 0xaf, 0xd2, 0x4b, 0xf5, 0x14, 0x50, + /* U+0023 "#" */ + 0x14, 0x14, 0x7f, 0x24, 0x28, 0x28, 0xfe, 0x48, + 0x48, - /* U+24 "$" */ - 0x23, 0xa7, 0x18, 0x30, 0xc1, 0x8c, 0x5c, 0x40, + /* U+0024 "$" */ + 0x21, 0xfa, 0x68, 0xe0, 0xf2, 0x49, 0xf8, 0x82, + 0x0, - /* U+25 "%" */ - 0x60, 0x94, 0x94, 0x68, 0x10, 0x16, 0x29, 0x29, - 0x6, + /* U+0025 "%" */ + 0x61, 0x12, 0x22, 0x48, 0x49, 0x6, 0x4c, 0x12, + 0x42, 0x48, 0x89, 0x10, 0xc0, - /* U+26 "&" */ - 0x30, 0x91, 0x23, 0x86, 0x1a, 0xa3, 0x44, 0x7c, + /* U+0026 "&" */ + 0x30, 0x24, 0x12, 0xe, 0x5, 0x24, 0x52, 0x19, + 0x8c, 0x79, 0x0, - /* U+27 "'" */ + /* U+0027 "'" */ 0xe0, - /* U+28 "(" */ - 0x29, 0x49, 0x24, 0x91, 0x22, + /* U+0028 "(" */ + 0x24, 0x48, 0x88, 0x88, 0x84, 0x42, - /* U+29 ")" */ - 0x89, 0x12, 0x49, 0x25, 0x28, + /* U+0029 ")" */ + 0x42, 0x21, 0x11, 0x11, 0x12, 0x24, - /* U+2A "*" */ - 0x21, 0x3e, 0xc5, 0x0, + /* U+002A "*" */ + 0x25, 0x5d, 0xf2, 0x0, - /* U+2B "+" */ - 0x20, 0x82, 0x3f, 0x20, 0x82, 0x0, + /* U+002B "+" */ + 0x10, 0x20, 0x47, 0xf1, 0x2, 0x4, 0x0, - /* U+2C "," */ - 0x54, + /* U+002C "," */ + 0x7a, - /* U+2D "-" */ - 0xe0, + /* U+002D "-" */ + 0xf0, - /* U+2E "." */ + /* U+002E "." */ 0x80, - /* U+2F "/" */ - 0x10, 0x84, 0x42, 0x11, 0x8, 0x44, 0x0, + /* U+002F "/" */ + 0x8, 0xc4, 0x22, 0x10, 0x88, 0x42, 0x21, 0x0, - /* U+30 "0" */ + /* U+0030 "0" */ 0x74, 0xe3, 0x18, 0xc6, 0x3b, 0x70, - /* U+31 "1" */ + /* U+0031 "1" */ 0x3c, 0x92, 0x49, 0x20, - /* U+32 "2" */ + /* U+0032 "2" */ 0x74, 0x62, 0x11, 0x11, 0x88, 0xf8, - /* U+33 "3" */ + /* U+0033 "3" */ 0x74, 0x42, 0x13, 0x4, 0x31, 0x70, - /* U+34 "4" */ + /* U+0034 "4" */ 0x8, 0x62, 0x8a, 0x4b, 0x2f, 0xc2, 0x8, - /* U+35 "5" */ - 0xfc, 0x21, 0xe1, 0x86, 0x31, 0x70, + /* U+0035 "5" */ + 0xfc, 0x21, 0xe1, 0x86, 0x33, 0x70, - /* U+36 "6" */ + /* U+0036 "6" */ 0x32, 0x21, 0xe8, 0xc6, 0x39, 0x70, - /* U+37 "7" */ + /* U+0037 "7" */ 0xfc, 0x10, 0x82, 0x10, 0x43, 0x8, 0x20, - /* U+38 "8" */ + /* U+0038 "8" */ 0x74, 0x63, 0x17, 0x46, 0x31, 0x70, - /* U+39 "9" */ + /* U+0039 "9" */ 0x74, 0xe3, 0x18, 0xbc, 0x22, 0x60, - /* U+3A ":" */ + /* U+003A ":" */ 0x82, - /* U+3B ";" */ - 0x87, + /* U+003B ";" */ + 0x40, 0x15, 0x60, - /* U+3C "<" */ - 0x9, 0xb1, 0xc3, 0x84, + /* U+003C "<" */ + 0x6, 0x33, 0x87, 0x3, 0x80, 0xc0, 0x0, - /* U+3D "=" */ - 0xf8, 0x1, 0xf0, + /* U+003D "=" */ + 0xfe, 0x0, 0x7, 0xf0, - /* U+3E ">" */ - 0x83, 0x6, 0x7e, 0x40, + /* U+003E ">" */ + 0xc0, 0x60, 0x38, 0x73, 0x98, 0x0, 0x0, - /* U+3F "?" */ - 0x72, 0x42, 0x11, 0x10, 0x80, 0x20, + /* U+003F "?" */ + 0xf4, 0x42, 0x11, 0x10, 0x80, 0x20, - /* U+40 "@" */ - 0x1e, 0x8, 0x64, 0xa, 0x39, 0x92, 0x64, 0x99, - 0x26, 0x5b, 0x9b, 0x90, 0x6, 0x0, 0xf8, + /* U+0040 "@" */ + 0x1e, 0x18, 0x65, 0xea, 0x89, 0xa2, 0x68, 0x9a, + 0x25, 0x7e, 0x60, 0x7, 0x80, - /* U+41 "A" */ + /* U+0041 "A" */ 0x18, 0x18, 0x18, 0x24, 0x24, 0x64, 0x7e, 0x42, 0xc2, - /* U+42 "B" */ + /* U+0042 "B" */ 0xfa, 0x18, 0x61, 0xfa, 0x18, 0x61, 0xf8, - /* U+43 "C" */ + /* U+0043 "C" */ 0x39, 0x18, 0x60, 0x82, 0x8, 0x51, 0x38, - /* U+44 "D" */ + /* U+0044 "D" */ 0xf2, 0x28, 0x61, 0x86, 0x18, 0x62, 0xf0, - /* U+45 "E" */ + /* U+0045 "E" */ 0xfc, 0x21, 0xf, 0xc2, 0x10, 0xf8, - /* U+46 "F" */ + /* U+0046 "F" */ 0xfc, 0x21, 0xf, 0xc2, 0x10, 0x80, - /* U+47 "G" */ + /* U+0047 "G" */ 0x3c, 0x8e, 0x4, 0x8, 0xf0, 0x60, 0xa1, 0x3c, - /* U+48 "H" */ + /* U+0048 "H" */ 0x83, 0x6, 0xc, 0x1f, 0xf0, 0x60, 0xc1, 0x82, - /* U+49 "I" */ + /* U+0049 "I" */ 0xff, 0x80, - /* U+4A "J" */ + /* U+004A "J" */ 0x8, 0x42, 0x10, 0x86, 0x31, 0x70, - /* U+4B "K" */ + /* U+004B "K" */ 0x8e, 0x29, 0x28, 0xe2, 0x49, 0xa2, 0x84, - /* U+4C "L" */ + /* U+004C "L" */ 0x84, 0x21, 0x8, 0x42, 0x10, 0xf8, - /* U+4D "M" */ + /* U+004D "M" */ 0xc3, 0xc3, 0xc3, 0xa5, 0xa5, 0xa5, 0x99, 0x99, 0x99, - /* U+4E "N" */ + /* U+004E "N" */ 0x83, 0x87, 0x8d, 0x99, 0x33, 0x63, 0xc3, 0x82, - /* U+4F "O" */ + /* U+004F "O" */ 0x38, 0x8a, 0xc, 0x18, 0x30, 0x60, 0xa2, 0x38, - /* U+50 "P" */ + /* U+0050 "P" */ 0xfa, 0x18, 0x61, 0xfa, 0x8, 0x20, 0x80, - /* U+51 "Q" */ + /* U+0051 "Q" */ 0x38, 0x8a, 0xc, 0x18, 0x30, 0x60, 0xa2, 0x3c, 0xc, - /* U+52 "R" */ - 0xfa, 0x18, 0x61, 0xfa, 0x28, 0xa1, 0x84, + /* U+0052 "R" */ + 0xfa, 0x18, 0x61, 0xfa, 0x68, 0xa1, 0x84, - /* U+53 "S" */ - 0x7a, 0x38, 0x70, 0x30, 0x38, 0x71, 0x78, + /* U+0053 "S" */ + 0x7a, 0x38, 0x70, 0x30, 0x38, 0x61, 0x78, - /* U+54 "T" */ + /* U+0054 "T" */ 0xfe, 0x20, 0x40, 0x81, 0x2, 0x4, 0x8, 0x10, - /* U+55 "U" */ + /* U+0055 "U" */ 0x86, 0x18, 0x61, 0x86, 0x18, 0x73, 0x78, - /* U+56 "V" */ + /* U+0056 "V" */ 0xc2, 0x85, 0x1a, 0x22, 0x45, 0x8a, 0xc, 0x18, - /* U+57 "W" */ + /* U+0057 "W" */ 0xc4, 0x53, 0x14, 0xa5, 0x2b, 0x4a, 0x8c, 0xa3, 0x18, 0xc6, 0x31, 0x0, - /* U+58 "X" */ + /* U+0058 "X" */ 0x42, 0xc8, 0xb0, 0xc1, 0x7, 0xb, 0x32, 0x42, - /* U+59 "Y" */ + /* U+0059 "Y" */ 0xc6, 0x89, 0xb1, 0x42, 0x82, 0x4, 0x8, 0x10, - /* U+5A "Z" */ + /* U+005A "Z" */ 0xfc, 0x30, 0x84, 0x30, 0x84, 0x30, 0xfc, - /* U+5B "[" */ - 0xea, 0xaa, 0xaa, 0xc0, + /* U+005B "[" */ + 0xf2, 0x49, 0x24, 0x92, 0x70, - /* U+5C "\\" */ - 0x82, 0x10, 0xc2, 0x10, 0x42, 0x10, 0x40, + /* U+005C "\\" */ + 0x41, 0x4, 0x8, 0x20, 0x81, 0x4, 0x8, 0x20, + 0x81, - /* U+5D "]" */ - 0xd5, 0x55, 0x55, 0xc0, + /* U+005D "]" */ + 0xe4, 0x92, 0x49, 0x24, 0xf0, - /* U+5E "^" */ - 0x21, 0x14, 0xa5, 0x0, + /* U+005E "^" */ + 0x18, 0x38, 0x24, 0x42, 0xc2, - /* U+5F "_" */ - 0xf8, + /* U+005F "_" */ + 0xff, - /* U+60 "`" */ - 0x4c, + /* U+0060 "`" */ + 0x94, - /* U+61 "a" */ + /* U+0061 "a" */ 0x74, 0x42, 0xf8, 0xc5, 0xe0, - /* U+62 "b" */ + /* U+0062 "b" */ 0x84, 0x21, 0xe9, 0xc6, 0x31, 0x9f, 0x80, - /* U+63 "c" */ - 0x7b, 0x28, 0x20, 0x83, 0x27, 0x0, + /* U+0063 "c" */ + 0x76, 0x61, 0x8, 0x65, 0xc0, - /* U+64 "d" */ + /* U+0064 "d" */ 0x8, 0x42, 0xfc, 0xc6, 0x31, 0xcb, 0xc0, - /* U+65 "e" */ - 0x76, 0x63, 0xf8, 0x65, 0xc0, + /* U+0065 "e" */ + 0x73, 0x28, 0xbf, 0x83, 0x27, 0x80, - /* U+66 "f" */ + /* U+0066 "f" */ 0x34, 0x4f, 0x44, 0x44, 0x44, - /* U+67 "g" */ - 0x7e, 0x63, 0x18, 0xe5, 0xe1, 0x9b, 0x80, + /* U+0067 "g" */ + 0x7e, 0x63, 0x18, 0xe5, 0xe1, 0x8b, 0x80, - /* U+68 "h" */ + /* U+0068 "h" */ 0x84, 0x21, 0xe8, 0xc6, 0x31, 0x8c, 0x40, - /* U+69 "i" */ + /* U+0069 "i" */ 0xbf, 0x80, - /* U+6A "j" */ + /* U+006A "j" */ 0x45, 0x55, 0x57, - /* U+6B "k" */ + /* U+006B "k" */ 0x84, 0x21, 0x2b, 0x73, 0x94, 0x94, 0x40, - /* U+6C "l" */ + /* U+006C "l" */ 0xff, 0xc0, - /* U+6D "m" */ + /* U+006D "m" */ 0xf7, 0x44, 0x62, 0x31, 0x18, 0x8c, 0x46, 0x22, - /* U+6E "n" */ + /* U+006E "n" */ 0xf4, 0x63, 0x18, 0xc6, 0x20, - /* U+6F "o" */ + /* U+006F "o" */ 0x7b, 0x38, 0x61, 0x87, 0x37, 0x80, - /* U+70 "p" */ + /* U+0070 "p" */ 0xf4, 0xe3, 0x18, 0xcf, 0xd0, 0x84, 0x0, - /* U+71 "q" */ + /* U+0071 "q" */ 0x7e, 0x63, 0x18, 0xe5, 0xe1, 0x8, 0x40, - /* U+72 "r" */ + /* U+0072 "r" */ 0xf2, 0x49, 0x20, - /* U+73 "s" */ + /* U+0073 "s" */ 0x74, 0x60, 0xe0, 0xc5, 0xc0, - /* U+74 "t" */ + /* U+0074 "t" */ 0x4b, 0xa4, 0x92, 0x60, - /* U+75 "u" */ + /* U+0075 "u" */ 0x8c, 0x63, 0x18, 0xc5, 0xe0, - /* U+76 "v" */ + /* U+0076 "v" */ 0x89, 0x24, 0x94, 0x30, 0xc2, 0x0, - /* U+77 "w" */ + /* U+0077 "w" */ 0x88, 0xa4, 0x95, 0x4a, 0xa5, 0x51, 0x10, 0x88, - /* U+78 "x" */ + /* U+0078 "x" */ 0x49, 0x23, 0xc, 0x31, 0x24, 0x80, - /* U+79 "y" */ + /* U+0079 "y" */ 0x89, 0x24, 0x94, 0x30, 0xc3, 0x8, 0x23, 0x0, - /* U+7A "z" */ + /* U+007A "z" */ 0xf8, 0xc4, 0x44, 0x63, 0xe0, - /* U+7B "{" */ - 0x29, 0x24, 0xa2, 0x49, 0x22, + /* U+007B "{" */ + 0x19, 0x8, 0x42, 0x32, 0xc, 0x21, 0x8, 0x30, - /* U+7C "|" */ - 0xff, 0xe0, + /* U+007C "|" */ + 0xff, 0xf0, - /* U+7D "}" */ - 0x89, 0x24, 0x8a, 0x49, 0x28, + /* U+007D "}" */ + 0xc1, 0x8, 0x42, 0x18, 0x26, 0x21, 0x9, 0x80, - /* U+7E "~" */ - 0x65, 0x2a, 0x70, + /* U+007E "~" */ + 0x71, 0x99, 0x8e, /* U+F001 "" */ - 0x0, 0x70, 0x3f, 0x1f, 0xf1, 0xfb, 0x1c, 0x31, - 0x83, 0x18, 0x31, 0x83, 0x19, 0xf7, 0x9f, 0xf8, - 0x47, 0x0, + 0x0, 0x0, 0xf1, 0xfc, 0x7f, 0x1e, 0x44, 0x11, + 0x4, 0x47, 0x13, 0xfc, 0x6f, 0x0, /* U+F008 "" */ - 0xbf, 0xde, 0x7, 0xa0, 0x5e, 0x7, 0xbf, 0xde, - 0x7, 0xa0, 0x5e, 0x7, 0xbf, 0xd0, + 0xff, 0xfc, 0x82, 0x64, 0x13, 0xe0, 0xf9, 0x4, + 0xc8, 0x27, 0xff, 0xf2, 0x9, 0xf0, 0x7c, 0x82, + 0x64, 0x13, 0xff, 0xf0, /* U+F00B "" */ - 0xf7, 0xf7, 0xbf, 0xfd, 0xfe, 0x0, 0xf, 0x7f, - 0x7b, 0xff, 0xdf, 0xc0, 0x0, 0xf7, 0xf7, 0xbf, - 0xfd, 0xfc, + 0xef, 0xfe, 0xff, 0x0, 0xe, 0xff, 0xef, 0xf0, + 0x0, 0x0, 0xe, 0xff, 0xef, 0xf0, /* U+F00C "" */ - 0x0, 0x20, 0x7, 0x0, 0xe4, 0x1c, 0xe3, 0x87, - 0x70, 0x3e, 0x1, 0xc0, 0x8, 0x0, + 0x0, 0x80, 0x74, 0x3b, 0x9c, 0xfe, 0x1f, 0x3, + 0x80, 0x40, /* U+F00D "" */ - 0xc3, 0xe7, 0x7e, 0x3c, 0x3c, 0x7e, 0xe7, 0xc3, + 0x42, 0xe7, 0x7e, 0x3c, 0x3c, 0x7e, 0xe7, 0x42, /* U+F011 "" */ - 0x6, 0x2, 0x64, 0x76, 0xe6, 0x66, 0xc6, 0x3c, - 0x63, 0xc6, 0x3c, 0x3, 0x60, 0x67, 0xe, 0x3f, - 0xc0, 0xf0, + 0xc, 0xb, 0x47, 0xfb, 0xb6, 0xcc, 0xf3, 0x3c, + 0xf, 0x87, 0x61, 0x8f, 0xc0, /* U+F013 "" */ - 0xe, 0x4, 0xf0, 0x7f, 0xef, 0xfe, 0x71, 0xe7, - 0xc, 0x71, 0xef, 0xfe, 0x7f, 0xe4, 0xf0, 0xe, - 0x0, + 0xc, 0x1f, 0xe7, 0xf9, 0xce, 0xe1, 0xf8, 0x77, + 0x39, 0xfe, 0x7f, 0x83, 0x0, + + /* U+F014 "" */ + 0x1c, 0x11, 0x3f, 0xe8, 0x14, 0xb, 0x55, 0xaa, + 0xd5, 0x6a, 0xa0, 0x5f, 0xc0, /* U+F015 "" */ - 0x3, 0x30, 0x1e, 0xc1, 0xcf, 0xc, 0xcc, 0x6f, - 0xdb, 0x7f, 0xb3, 0xff, 0xf, 0x3c, 0x3c, 0xf0, - 0xf3, 0xc0, + 0xd, 0x82, 0x70, 0xb6, 0x7f, 0xef, 0xfa, 0xff, + 0x1c, 0xe3, 0x9c, /* U+F019 "" */ - 0xe, 0x0, 0xe0, 0xe, 0x0, 0xe0, 0x3f, 0xc3, - 0xf8, 0x1f, 0x0, 0xe0, 0xf5, 0xff, 0xff, 0xff, - 0x5f, 0xff, + 0xe, 0x1, 0xc0, 0x38, 0x1f, 0xc1, 0xf0, 0x1c, + 0x1, 0x7, 0xdf, 0xff, 0xbf, 0xfc, /* U+F01C "" */ - 0x1f, 0xe0, 0xc0, 0xc6, 0x1, 0x90, 0x2, 0xf8, - 0xf, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x3f, 0x18, 0x64, 0xb, 0x3, 0x80, 0x7c, 0xff, + 0xff, 0xff, /* U+F021 "" */ - 0x0, 0x31, 0xf3, 0x71, 0xfc, 0x7, 0xc3, 0xf0, - 0x0, 0x0, 0x0, 0x0, 0xfc, 0x3e, 0x3, 0xf8, - 0xec, 0xf8, 0xc0, 0x0, + 0x3f, 0x5c, 0xf6, 0x1f, 0xf, 0x0, 0x0, 0xf, + 0xf, 0x86, 0xbe, 0x0, /* U+F026 "" */ - 0xc, 0x7f, 0xff, 0xff, 0xf1, 0xc3, + 0x8, 0xff, 0xff, 0xfc, 0x61, /* U+F027 "" */ - 0xc, 0xe, 0x3f, 0x7f, 0x9f, 0xdf, 0xe0, 0x70, - 0x18, + 0x8, 0x18, 0xfa, 0xf9, 0xf9, 0xfa, 0x18, 0x8, /* U+F028 "" */ - 0x0, 0x60, 0x1, 0x83, 0x34, 0x38, 0xdf, 0xda, - 0xfe, 0x57, 0xf6, 0xbf, 0x8d, 0x1c, 0xd0, 0x61, - 0x80, 0x18, + 0x0, 0x81, 0x28, 0x62, 0xfd, 0xdf, 0x9b, 0xf7, + 0x46, 0x68, 0x42, 0x0, 0x80, /* U+F03E "" */ - 0xff, 0xf9, 0xff, 0x9f, 0xf9, 0xef, 0xfc, 0x7d, - 0x83, 0xc0, 0x38, 0x3, 0xff, 0xf0, + 0xff, 0xfc, 0x0, 0x60, 0x3, 0x60, 0x1b, 0x8, + 0xc0, 0xe6, 0x7f, 0xb7, 0xfd, 0xbf, 0xec, 0x0, + 0x7f, 0xfe, + + /* U+F040 "" */ + 0x1, 0x80, 0x70, 0x6c, 0x3c, 0x1f, 0xf, 0x87, + 0xc2, 0xe0, 0xd0, 0x38, 0x0, /* U+F048 "" */ - 0xc3, 0xc7, 0xcf, 0xdf, 0xff, 0xff, 0xdf, 0xcf, - 0xc7, 0xc3, + 0xc3, 0x8f, 0x3e, 0xff, 0xff, 0xf7, 0xe7, 0xc7, + 0x84, /* U+F04B "" */ - 0x0, 0x1c, 0x3, 0xe0, 0x7f, 0xf, 0xf9, 0xff, - 0xbf, 0xff, 0xfe, 0xff, 0x9f, 0xc3, 0xe0, 0x70, - 0x0, 0x0, + 0x0, 0x60, 0x3c, 0x1f, 0xf, 0xe7, 0xff, 0xfd, + 0xf8, 0xf0, 0x70, 0x20, 0x0, /* U+F04C "" */ - 0xfb, 0xff, 0x7f, 0xef, 0xfd, 0xff, 0xbf, 0xf7, - 0xfe, 0xff, 0xdf, 0xfb, 0xff, 0x7c, + 0xf3, 0xfc, 0xff, 0x3f, 0xcf, 0xf3, 0xfc, 0xff, + 0x3f, 0xcf, 0xf3, 0xfc, 0xf0, /* U+F04D "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xff, 0xff, 0xf0, /* U+F051 "" */ - 0xc3, 0xe3, 0xf3, 0xfb, 0xff, 0xff, 0xfb, 0xf3, - 0xe3, 0xc3, + 0x87, 0x8f, 0x9f, 0xbf, 0xff, 0xfd, 0xf3, 0xc7, + 0xc, /* U+F052 "" */ - 0xc, 0x3, 0xc0, 0x7c, 0x1f, 0xc7, 0xfd, 0xff, - 0xbf, 0xf0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xc, 0x7, 0x83, 0xf1, 0xfe, 0xff, 0xc0, 0x0, + 0x3, 0xff, 0xff, 0xc0, /* U+F053 "" */ - 0xc, 0x73, 0x9c, 0xe3, 0x87, 0xe, 0x1c, 0x30, + 0x4, 0x1c, 0x71, 0xc7, 0x1c, 0x1c, 0x1c, 0x1c, + 0x1c, 0x10, /* U+F054 "" */ - 0x83, 0x87, 0xe, 0x1c, 0x73, 0x9c, 0xe2, 0x0, + 0xc1, 0xc3, 0xc3, 0xc3, 0xc3, 0xcf, 0x3c, 0xf1, + 0xc3, 0x0, /* U+F060 "" */ - 0xc, 0x3, 0x80, 0xe0, 0x38, 0xf, 0xff, 0xff, - 0xdc, 0x1, 0xc0, 0x1c, 0x1, 0x80, + 0xc, 0x7, 0x83, 0xc1, 0xe0, 0xff, 0xff, 0xf7, + 0x80, 0xf0, 0x1e, 0x3, 0x0, /* U+F067 "" */ - 0xe, 0x1, 0xc0, 0x38, 0x7, 0xf, 0xff, 0xff, - 0xc3, 0x80, 0x70, 0xe, 0x1, 0xc0, + 0x1c, 0xe, 0x7, 0x1f, 0xff, 0xff, 0xfc, 0x70, + 0x38, 0x1c, 0x0, /* U+F068 "" */ - 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xc0, /* U+F06E "" */ - 0xf, 0x81, 0xc7, 0x1c, 0x1d, 0xc6, 0x7e, 0xfb, - 0xf7, 0xdd, 0xdd, 0xc7, 0x1c, 0xf, 0x80, + 0xf, 0x3, 0xbc, 0x57, 0xa9, 0xf9, 0x9f, 0x94, + 0xf2, 0x30, 0xc0, 0xf0, /* U+F070 "" */ - 0x0, 0x1, 0xc0, 0x1, 0xdf, 0x0, 0xe3, 0x80, - 0xd3, 0x84, 0xfb, 0x9c, 0x77, 0x3c, 0x6e, 0x38, - 0x78, 0x38, 0x70, 0x1e, 0x30, 0x0, 0x30, 0x0, - 0x0, + 0x7, 0x83, 0xb0, 0x57, 0x29, 0x69, 0x9c, 0x94, + 0xd2, 0x28, 0x41, 0xb0, 0x0, 0x0, /* U+F071 "" */ - 0x3, 0x0, 0x1c, 0x0, 0xf8, 0x3, 0xf0, 0x1c, - 0xc0, 0x73, 0x83, 0xcf, 0x1f, 0xfc, 0x7c, 0xfb, - 0xf3, 0xef, 0xff, 0x80, + 0x6, 0x0, 0x60, 0xf, 0x1, 0x98, 0x19, 0x83, + 0x9c, 0x3f, 0xc7, 0x9e, 0xf9, 0xff, 0xff, /* U+F074 "" */ - 0x0, 0x0, 0x6, 0xe1, 0xff, 0x3f, 0x17, 0x60, - 0xe4, 0x1f, 0x6f, 0xbf, 0xf1, 0xf0, 0x6, 0x0, - 0x40, + 0x0, 0x0, 0x6, 0xf3, 0xf1, 0x66, 0x1c, 0x0, + 0xc0, 0x18, 0x1, 0x66, 0xe3, 0xf0, 0x6, /* U+F077 "" */ - 0x0, 0x3, 0x1, 0xe0, 0xcc, 0x61, 0xb0, 0x30, - 0x0, + 0x4, 0x1, 0xc0, 0x7c, 0x1d, 0xc7, 0x1d, 0xc1, + 0xd0, 0x10, /* U+F078 "" */ - 0x0, 0x30, 0x36, 0x18, 0xcc, 0x1e, 0x3, 0x0, - 0x0, + 0x40, 0x5c, 0x1f, 0xc7, 0x1d, 0xc1, 0xf0, 0x1c, + 0x1, 0x0, /* U+F079 "" */ - 0x30, 0x0, 0xf7, 0xf3, 0xf0, 0x65, 0xa0, 0xc3, - 0x1, 0x86, 0xb, 0x4c, 0x1f, 0x9f, 0xde, 0x0, - 0x18, + 0x37, 0xf1, 0xe0, 0xcf, 0xc3, 0xc, 0xc, 0x30, + 0xfc, 0xc1, 0xe3, 0xfb, 0x0, /* U+F07B "" */ - 0x78, 0xf, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x70, 0x1f, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, /* U+F093 "" */ - 0x6, 0x0, 0xf0, 0x1f, 0x83, 0xfc, 0x7, 0x0, - 0x70, 0x7, 0x0, 0x70, 0xf7, 0xff, 0xff, 0xff, - 0x5f, 0xff, + 0x4, 0x1, 0xc0, 0x7c, 0x1f, 0xc0, 0xe0, 0x1c, + 0x3, 0x87, 0x7, 0xff, 0xff, 0xf7, 0xff, 0x80, /* U+F095 "" */ - 0x0, 0x0, 0xf, 0x0, 0xf0, 0x1f, 0x0, 0xf0, - 0x6, 0x0, 0xe0, 0x1c, 0x73, 0xcf, 0xf8, 0xfe, - 0xf, 0xc0, 0x0, 0x0, + 0x40, 0x70, 0x38, 0x18, 0x4, 0x3, 0x0, 0xcc, + 0x3f, 0x7, 0x0, /* U+F0C4 "" */ - 0x70, 0x5b, 0x3f, 0x6f, 0x3f, 0xc1, 0xf0, 0x3e, - 0x1f, 0xe6, 0xde, 0xd9, 0xee, 0x8, + 0x60, 0x9, 0x3, 0x88, 0xdc, 0x92, 0x76, 0xc0, + 0xe8, 0x7f, 0x6c, 0x99, 0x98, 0x7f, 0x0, /* U+F0C5 "" */ - 0x1f, 0x43, 0xef, 0x7f, 0xef, 0xfd, 0xff, 0xbf, - 0xf7, 0xfe, 0xff, 0xdf, 0xf8, 0x3, 0xfc, 0x0, + 0x1f, 0x3, 0x10, 0x51, 0xff, 0x19, 0x86, 0x98, + 0xc9, 0x8f, 0x98, 0x81, 0xf8, 0x10, 0x81, 0x8, + 0x10, 0xff, /* U+F0C7 "" */ - 0xff, 0x98, 0x1b, 0x3, 0xe0, 0x7c, 0xf, 0xff, - 0xfe, 0x7f, 0x8f, 0xf9, 0xff, 0xfc, + 0xff, 0x2c, 0xeb, 0x2e, 0xc9, 0xbe, 0x60, 0x1b, + 0xf6, 0x85, 0xa1, 0x68, 0x5f, 0xfc, /* U+F0E7 "" */ - 0x78, 0x78, 0xf8, 0xf0, 0xff, 0xfe, 0xfc, 0x1c, - 0x18, 0x18, 0x10, 0x30, + 0x71, 0xc6, 0x1f, 0xfb, 0x61, 0x4, 0x20, 0x82, + 0x0, /* U+F0EA "" */ - 0x18, 0x3b, 0x8e, 0xe3, 0xf8, 0xe0, 0x3b, 0xae, - 0xe7, 0xbf, 0xef, 0xfb, 0xf0, 0xfc, 0x3f, + 0xff, 0x8c, 0x18, 0xff, 0x8f, 0x8c, 0xf8, 0xaf, + 0x8b, 0xf8, 0xff, 0x81, 0xf8, 0x1f, 0x81, 0x8, + 0x10, 0xff, /* U+F0F3 "" */ - 0x4, 0x0, 0x80, 0x7c, 0x1f, 0xc3, 0xf8, 0x7f, - 0x1f, 0xf3, 0xfe, 0x7f, 0xdf, 0xfc, 0x0, 0x7, + 0x4, 0x3, 0xe0, 0xfe, 0x1f, 0xc3, 0xf8, 0x7f, + 0xf, 0xe3, 0xfe, 0x7f, 0xdf, 0xfc, 0x78, 0x7, 0x0, /* U+F11C "" */ - 0xff, 0xff, 0x52, 0xbd, 0x4a, 0xff, 0xff, 0xeb, - 0x5f, 0xff, 0xfd, 0x2, 0xf4, 0xb, 0xff, 0xfc, + 0xff, 0xfc, 0x0, 0x75, 0xab, 0x0, 0x5a, 0xd6, + 0xc0, 0x6, 0x7e, 0xbf, 0xff, /* U+F124 "" */ - 0x0, 0x0, 0xf, 0x3, 0xf0, 0xfe, 0x3f, 0xef, - 0xfc, 0xff, 0xc0, 0x78, 0x7, 0x80, 0x78, 0x7, - 0x0, 0x70, 0x2, 0x0, + 0x0, 0x0, 0xc1, 0xe3, 0xe7, 0xf7, 0xf0, 0x38, + 0x18, 0xc, 0x4, 0x0, /* U+F15B "" */ - 0xfa, 0x7d, 0xbe, 0xff, 0xf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xfe, 0x3f, 0x4f, 0xdb, 0xf1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, /* U+F1EB "" */ - 0x7, 0xc0, 0x7f, 0xf1, 0xe0, 0xf7, 0x0, 0x70, - 0x7c, 0x3, 0xfe, 0x6, 0xc, 0x0, 0x0, 0x3, - 0x80, 0x7, 0x0, 0xe, 0x0, + 0x6, 0x1, 0xff, 0x1c, 0x1f, 0x9f, 0x23, 0x8e, + 0x18, 0x30, 0x3c, 0x1, 0xb0, 0x0, 0x0, 0x10, + 0x0, /* U+F240 "" */ - 0xff, 0xff, 0x80, 0x1f, 0x7f, 0xfe, 0xff, 0xbd, - 0xff, 0x78, 0x1, 0xff, 0xff, 0x80, + 0xff, 0xfe, 0x80, 0x2, 0xbf, 0xfa, 0xbf, 0xf9, + 0xbf, 0xf9, 0xbf, 0xf9, 0xbf, 0xfb, 0x80, 0x2, + 0xff, 0xfe, /* U+F241 "" */ - 0xff, 0xff, 0x80, 0x1f, 0x7f, 0x3e, 0xfe, 0x3d, - 0xfc, 0x78, 0x1, 0xff, 0xff, 0x80, + 0xff, 0xfe, 0x80, 0x2, 0xbf, 0xe2, 0xbf, 0xe1, + 0xbf, 0xe1, 0xbf, 0xe1, 0xbf, 0xe3, 0x80, 0x2, + 0xff, 0xfe, /* U+F242 "" */ - 0xff, 0xff, 0x80, 0x1f, 0x78, 0x3e, 0xf0, 0x3d, - 0xe0, 0x78, 0x1, 0xff, 0xff, 0x80, + 0xff, 0xfe, 0x80, 0x2, 0xbf, 0x2, 0xbf, 0x1, + 0xbf, 0x1, 0xbf, 0x1, 0xbf, 0x3, 0x80, 0x2, + 0xff, 0xfe, /* U+F243 "" */ - 0xff, 0xff, 0x80, 0x1f, 0x60, 0x3e, 0xc0, 0x3d, - 0x80, 0x78, 0x1, 0xff, 0xff, 0x80, + 0xff, 0xfe, 0x80, 0x2, 0xb8, 0x2, 0xb8, 0x1, + 0xb8, 0x1, 0xb8, 0x1, 0xb8, 0x3, 0x80, 0x2, + 0xff, 0xfe, /* U+F244 "" */ - 0xff, 0xff, 0x80, 0x1f, 0x0, 0x3e, 0x0, 0x3c, - 0x0, 0x78, 0x1, 0xff, 0xff, 0x80, + 0xff, 0xfe, 0x80, 0x2, 0x80, 0x2, 0x80, 0x1, + 0x80, 0x1, 0x80, 0x1, 0x80, 0x3, 0x80, 0x2, + 0xff, 0xfe, /* U+F287 "" */ 0x0, 0xc0, 0x7, 0x80, 0x10, 0x7, 0x20, 0x6f, @@ -533,16 +542,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { 0xf0, /* U+F293 "" */ - 0x3e, 0x3b, 0x9c, 0xdb, 0x7c, 0xbf, 0x1f, 0x9f, - 0x87, 0xd5, 0xf9, 0x9d, 0xc7, 0xc0, + 0x3e, 0x3b, 0xbc, 0xdb, 0x3c, 0x1f, 0x1f, 0x8f, + 0x83, 0xd9, 0xf9, 0x9d, 0xc7, 0xc0, /* U+F2ED "" */ - 0xe, 0x1f, 0xfc, 0x0, 0x0, 0x7, 0xfc, 0xd5, - 0x9a, 0xb3, 0x56, 0x6a, 0xcd, 0x59, 0xab, 0x3f, - 0xe0, + 0x0, /* U+F304 "" */ - 0x0, 0x0, 0xe, 0x0, 0xf0, 0x37, 0x7, 0xa0, + 0x0, 0x40, 0xe, 0x0, 0xf0, 0x37, 0x7, 0xa0, 0xfc, 0x1f, 0x83, 0xf0, 0x7e, 0xf, 0xc0, 0xf8, 0xf, 0x0, 0x80, 0x0, @@ -571,160 +578,162 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, - {.bitmap_index = 0, .adv_w = 48, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1, .adv_w = 49, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 3, .adv_w = 61, .box_w = 2, .box_h = 3, .ofs_x = 1, .ofs_y = 7}, - {.bitmap_index = 4, .adv_w = 118, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 11, .adv_w = 108, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 19, .adv_w = 141, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 28, .adv_w = 119, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 36, .adv_w = 33, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = 7}, - {.bitmap_index = 37, .adv_w = 66, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 42, .adv_w = 67, .box_w = 3, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 47, .adv_w = 83, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 4}, - {.bitmap_index = 51, .adv_w = 109, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 57, .adv_w = 38, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 58, .adv_w = 53, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 59, .adv_w = 51, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 60, .adv_w = 79, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 67, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 73, .adv_w = 108, .box_w = 3, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 77, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 83, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 89, .adv_w = 108, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 96, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 102, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 108, .adv_w = 108, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 115, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 121, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 127, .adv_w = 47, .box_w = 1, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 128, .adv_w = 41, .box_w = 1, .box_h = 8, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 129, .adv_w = 98, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 133, .adv_w = 105, .box_w = 5, .box_h = 4, .ofs_x = 1, .ofs_y = 3}, - {.bitmap_index = 136, .adv_w = 100, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 1}, - {.bitmap_index = 140, .adv_w = 91, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 146, .adv_w = 172, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 161, .adv_w = 125, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 170, .adv_w = 120, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 177, .adv_w = 125, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 184, .adv_w = 126, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 191, .adv_w = 109, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 197, .adv_w = 106, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 203, .adv_w = 131, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 211, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 219, .adv_w = 52, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 221, .adv_w = 106, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 227, .adv_w = 120, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 234, .adv_w = 103, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 240, .adv_w = 168, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 249, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 257, .adv_w = 132, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 265, .adv_w = 121, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 272, .adv_w = 132, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 281, .adv_w = 118, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 288, .adv_w = 114, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 295, .adv_w = 115, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 303, .adv_w = 125, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 310, .adv_w = 122, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 318, .adv_w = 170, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 330, .adv_w = 120, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 338, .adv_w = 115, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 346, .adv_w = 115, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 353, .adv_w = 51, .box_w = 2, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 357, .adv_w = 79, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 364, .adv_w = 51, .box_w = 2, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 368, .adv_w = 80, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 5}, - {.bitmap_index = 372, .adv_w = 87, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 373, .adv_w = 59, .box_w = 3, .box_h = 2, .ofs_x = 0, .ofs_y = 8}, - {.bitmap_index = 374, .adv_w = 104, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 379, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 386, .adv_w = 101, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 392, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 399, .adv_w = 102, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 404, .adv_w = 67, .box_w = 4, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 409, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 416, .adv_w = 106, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 423, .adv_w = 47, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 425, .adv_w = 46, .box_w = 2, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 428, .adv_w = 97, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 435, .adv_w = 47, .box_w = 1, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 437, .adv_w = 168, .box_w = 9, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 445, .adv_w = 106, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 450, .adv_w = 110, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 456, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 463, .adv_w = 109, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 470, .adv_w = 65, .box_w = 3, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 473, .adv_w = 99, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 478, .adv_w = 63, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 482, .adv_w = 106, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 487, .adv_w = 93, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 493, .adv_w = 144, .box_w = 9, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 501, .adv_w = 95, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 507, .adv_w = 91, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 515, .adv_w = 95, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, - {.bitmap_index = 520, .adv_w = 65, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, - {.bitmap_index = 525, .adv_w = 47, .box_w = 1, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 527, .adv_w = 65, .box_w = 3, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 532, .adv_w = 131, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 3}, - {.bitmap_index = 535, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 553, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 567, .adv_w = 192, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 585, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 599, .adv_w = 132, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 607, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 625, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 642, .adv_w = 216, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 660, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 678, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 694, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 714, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 720, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 729, .adv_w = 216, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 747, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 761, .adv_w = 168, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 771, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 789, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 803, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 817, .adv_w = 168, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 827, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 843, .adv_w = 120, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 851, .adv_w = 120, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, - {.bitmap_index = 859, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 873, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 887, .adv_w = 168, .box_w = 11, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 890, .adv_w = 216, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 905, .adv_w = 240, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 930, .adv_w = 216, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 950, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 967, .adv_w = 168, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 976, .adv_w = 168, .box_w = 10, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 985, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1002, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1016, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1034, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1054, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1068, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1084, .adv_w = 168, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1098, .adv_w = 120, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1110, .adv_w = 168, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1125, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1142, .adv_w = 216, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1158, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1178, .adv_w = 144, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1192, .adv_w = 240, .box_w = 15, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1213, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1227, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1241, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1255, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1269, .adv_w = 240, .box_w = 15, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1283, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1300, .adv_w = 168, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 1314, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1331, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 1351, .adv_w = 168, .box_w = 11, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, - {.bitmap_index = 1360, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 1377, .adv_w = 144, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 1391, .adv_w = 193, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 1} + {.bitmap_index = 0, .adv_w = 68, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 76, .box_w = 1, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3, .adv_w = 88, .box_w = 4, .box_h = 3, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 5, .adv_w = 157, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 14, .adv_w = 122, .box_w = 6, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 23, .adv_w = 207, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 36, .adv_w = 140, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 47, .adv_w = 52, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 48, .adv_w = 87, .box_w = 4, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 54, .adv_w = 87, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 60, .adv_w = 122, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 64, .adv_w = 157, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 71, .adv_w = 70, .box_w = 2, .box_h = 4, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 72, .adv_w = 87, .box_w = 4, .box_h = 1, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 73, .adv_w = 70, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 74, .adv_w = 87, .box_w = 5, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 82, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 88, .adv_w = 108, .box_w = 3, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 92, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 98, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 104, .adv_w = 108, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 111, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 117, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 123, .adv_w = 108, .box_w = 6, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 130, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 136, .adv_w = 108, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 142, .adv_w = 87, .box_w = 1, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 143, .adv_w = 87, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 146, .adv_w = 157, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 153, .adv_w = 157, .box_w = 7, .box_h = 4, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 157, .adv_w = 157, .box_w = 7, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 164, .adv_w = 105, .box_w = 5, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 170, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 183, .adv_w = 125, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 192, .adv_w = 120, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 199, .adv_w = 125, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 206, .adv_w = 126, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 213, .adv_w = 109, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 219, .adv_w = 106, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 225, .adv_w = 131, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 233, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 241, .adv_w = 52, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 243, .adv_w = 106, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 249, .adv_w = 120, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 256, .adv_w = 103, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 262, .adv_w = 168, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 271, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 279, .adv_w = 132, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 287, .adv_w = 121, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 294, .adv_w = 132, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 303, .adv_w = 118, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 310, .adv_w = 114, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 317, .adv_w = 115, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 325, .adv_w = 125, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 332, .adv_w = 122, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 340, .adv_w = 170, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 352, .adv_w = 120, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 360, .adv_w = 115, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 368, .adv_w = 115, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 375, .adv_w = 87, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 380, .adv_w = 87, .box_w = 6, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 389, .adv_w = 87, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 394, .adv_w = 157, .box_w = 8, .box_h = 5, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 399, .adv_w = 122, .box_w = 8, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 400, .adv_w = 122, .box_w = 2, .box_h = 3, .ofs_x = 2, .ofs_y = 8}, + {.bitmap_index = 401, .adv_w = 104, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 406, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 413, .adv_w = 101, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 418, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 425, .adv_w = 102, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 431, .adv_w = 67, .box_w = 4, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 436, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 443, .adv_w = 106, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 450, .adv_w = 47, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 452, .adv_w = 46, .box_w = 2, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 455, .adv_w = 97, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 462, .adv_w = 47, .box_w = 1, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 464, .adv_w = 168, .box_w = 9, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 472, .adv_w = 106, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 477, .adv_w = 110, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 483, .adv_w = 108, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 490, .adv_w = 109, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 497, .adv_w = 65, .box_w = 3, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 500, .adv_w = 99, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 505, .adv_w = 63, .box_w = 3, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 509, .adv_w = 106, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 514, .adv_w = 93, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 520, .adv_w = 144, .box_w = 9, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 528, .adv_w = 95, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 534, .adv_w = 91, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 542, .adv_w = 95, .box_w = 5, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 547, .adv_w = 122, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 555, .adv_w = 87, .box_w = 1, .box_h = 12, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 557, .adv_w = 122, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 565, .adv_w = 157, .box_w = 8, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 568, .adv_w = 165, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 582, .adv_w = 206, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 602, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 616, .adv_w = 192, .box_w = 10, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 626, .adv_w = 151, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 634, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 647, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 660, .adv_w = 151, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 673, .adv_w = 178, .box_w = 11, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 684, .adv_w = 178, .box_w = 11, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 698, .adv_w = 165, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 708, .adv_w = 165, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 720, .adv_w = 82, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 725, .adv_w = 123, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 733, .adv_w = 178, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 746, .adv_w = 206, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 764, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 777, .adv_w = 110, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 786, .adv_w = 151, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 799, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 812, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 825, .adv_w = 110, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 834, .adv_w = 165, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 846, .adv_w = 137, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 856, .adv_w = 137, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 866, .adv_w = 165, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 879, .adv_w = 151, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 890, .adv_w = 151, .box_w = 9, .box_h = 2, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 893, .adv_w = 192, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 905, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 919, .adv_w = 192, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 934, .adv_w = 192, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 949, .adv_w = 192, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 959, .adv_w = 192, .box_w = 11, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 969, .adv_w = 206, .box_w = 14, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 982, .adv_w = 178, .box_w = 11, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 995, .adv_w = 178, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1011, .adv_w = 151, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1022, .adv_w = 192, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1037, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1055, .adv_w = 165, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1069, .adv_w = 96, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1078, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1096, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1113, .adv_w = 206, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1126, .adv_w = 151, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1138, .adv_w = 165, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1152, .adv_w = 219, .box_w = 13, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1169, .adv_w = 247, .box_w = 16, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1187, .adv_w = 247, .box_w = 16, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1205, .adv_w = 247, .box_w = 16, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1223, .adv_w = 247, .box_w = 16, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1241, .adv_w = 247, .box_w = 16, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1259, .adv_w = 247, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1276, .adv_w = 165, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1290, .adv_w = 192, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1291, .adv_w = 192, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1311, .adv_w = 168, .box_w = 11, .box_h = 6, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1320, .adv_w = 240, .box_w = 15, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1337, .adv_w = 144, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1351, .adv_w = 193, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 1} }; /*--------------------- @@ -732,14 +741,14 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { *--------------------*/ static const uint16_t unicode_list_1[] = { - 0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x14, - 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d, 0x47, - 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52, 0x53, 0x5f, - 0x66, 0x67, 0x6d, 0x6f, 0x70, 0x73, 0x76, 0x77, - 0x78, 0x7a, 0x92, 0x94, 0xc3, 0xc4, 0xc6, 0xe6, - 0xe9, 0xf2, 0x11b, 0x123, 0x15a, 0x1ea, 0x23f, 0x240, - 0x241, 0x242, 0x243, 0x286, 0x292, 0x2ec, 0x303, 0x309, - 0x559, 0x7c1, 0x8a1 + 0x0, 0x7, 0xa, 0xb, 0xc, 0x10, 0x12, 0x13, + 0x14, 0x18, 0x1b, 0x20, 0x25, 0x26, 0x27, 0x3d, + 0x3f, 0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x51, 0x52, + 0x53, 0x5f, 0x66, 0x67, 0x6d, 0x6f, 0x70, 0x73, + 0x76, 0x77, 0x78, 0x7a, 0x92, 0x94, 0xc3, 0xc4, + 0xc6, 0xe6, 0xe9, 0xf2, 0x11b, 0x123, 0x15a, 0x1ea, + 0x23f, 0x240, 0x241, 0x242, 0x243, 0x286, 0x292, 0x2ec, + 0x303, 0x309, 0x559, 0x7c1, 0x8a1 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -751,7 +760,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 61441, .range_length = 2210, .glyph_id_start = 96, - .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 59, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 61, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -760,530 +769,196 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = *----------------*/ -/*Pair left and right glyphs for kerning*/ -static const uint8_t kern_pair_glyph_ids[] = +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = { - 1, 53, - 3, 3, - 3, 8, - 3, 34, - 3, 66, - 3, 68, - 3, 69, - 3, 70, - 3, 72, - 3, 78, - 3, 79, - 3, 80, - 3, 81, - 3, 82, - 3, 84, - 3, 88, - 8, 3, - 8, 8, - 8, 34, - 8, 66, - 8, 68, - 8, 69, - 8, 70, - 8, 72, - 8, 78, - 8, 79, - 8, 80, - 8, 81, - 8, 82, - 8, 84, - 8, 88, - 9, 55, - 9, 56, - 9, 58, - 13, 3, - 13, 8, - 15, 3, - 15, 8, - 16, 16, - 34, 3, - 34, 8, - 34, 32, - 34, 36, - 34, 40, - 34, 48, - 34, 50, - 34, 53, - 34, 54, - 34, 55, - 34, 56, - 34, 58, - 34, 80, - 34, 85, - 34, 86, - 34, 87, - 34, 88, - 34, 90, - 34, 91, - 35, 53, - 35, 55, - 35, 58, - 36, 10, - 36, 53, - 36, 62, - 36, 94, - 37, 13, - 37, 15, - 37, 34, - 37, 53, - 37, 55, - 37, 57, - 37, 58, - 37, 59, - 38, 53, - 38, 68, - 38, 69, - 38, 70, - 38, 71, - 38, 72, - 38, 80, - 38, 82, - 38, 86, - 38, 87, - 38, 88, - 38, 90, - 39, 13, - 39, 15, - 39, 34, - 39, 43, - 39, 53, - 39, 66, - 39, 68, - 39, 69, - 39, 70, - 39, 72, - 39, 80, - 39, 82, - 39, 83, - 39, 86, - 39, 87, - 39, 90, - 41, 34, - 41, 53, - 41, 57, - 41, 58, - 42, 34, - 42, 53, - 42, 57, - 42, 58, - 43, 34, - 44, 14, - 44, 36, - 44, 40, - 44, 48, - 44, 50, - 44, 68, - 44, 69, - 44, 70, - 44, 72, - 44, 78, - 44, 79, - 44, 80, - 44, 81, - 44, 82, - 44, 86, - 44, 87, - 44, 88, - 44, 90, - 45, 3, - 45, 8, - 45, 34, - 45, 36, - 45, 40, - 45, 48, - 45, 50, - 45, 53, - 45, 54, - 45, 55, - 45, 56, - 45, 58, - 45, 86, - 45, 87, - 45, 88, - 45, 90, - 46, 34, - 46, 53, - 46, 57, - 46, 58, - 47, 34, - 47, 53, - 47, 57, - 47, 58, - 48, 13, - 48, 15, - 48, 34, - 48, 53, - 48, 55, - 48, 57, - 48, 58, - 48, 59, - 49, 13, - 49, 15, - 49, 34, - 49, 43, - 49, 57, - 49, 59, - 49, 66, - 49, 68, - 49, 69, - 49, 70, - 49, 72, - 49, 80, - 49, 82, - 49, 85, - 49, 87, - 49, 90, - 50, 53, - 50, 55, - 50, 56, - 50, 58, - 51, 53, - 51, 55, - 51, 58, - 53, 1, - 53, 13, - 53, 14, - 53, 15, - 53, 34, - 53, 36, - 53, 40, - 53, 43, - 53, 48, - 53, 50, - 53, 52, - 53, 53, - 53, 55, - 53, 56, - 53, 58, - 53, 66, - 53, 68, - 53, 69, - 53, 70, - 53, 72, - 53, 78, - 53, 79, - 53, 80, - 53, 81, - 53, 82, - 53, 83, - 53, 84, - 53, 86, - 53, 87, - 53, 88, - 53, 89, - 53, 90, - 53, 91, - 54, 34, - 55, 10, - 55, 13, - 55, 14, - 55, 15, - 55, 34, - 55, 36, - 55, 40, - 55, 48, - 55, 50, - 55, 62, - 55, 66, - 55, 68, - 55, 69, - 55, 70, - 55, 72, - 55, 80, - 55, 82, - 55, 83, - 55, 86, - 55, 87, - 55, 90, - 55, 94, - 56, 10, - 56, 13, - 56, 14, - 56, 15, - 56, 34, - 56, 53, - 56, 62, - 56, 66, - 56, 68, - 56, 69, - 56, 70, - 56, 72, - 56, 80, - 56, 82, - 56, 83, - 56, 86, - 56, 94, - 57, 14, - 57, 36, - 57, 40, - 57, 48, - 57, 50, - 57, 55, - 57, 68, - 57, 69, - 57, 70, - 57, 72, - 57, 80, - 57, 82, - 57, 86, - 57, 87, - 57, 90, - 58, 7, - 58, 10, - 58, 11, - 58, 13, - 58, 14, - 58, 15, - 58, 34, - 58, 36, - 58, 40, - 58, 43, - 58, 48, - 58, 50, - 58, 52, - 58, 53, - 58, 54, - 58, 55, - 58, 56, - 58, 57, - 58, 58, - 58, 62, - 58, 66, - 58, 68, - 58, 69, - 58, 70, - 58, 71, - 58, 72, - 58, 78, - 58, 79, - 58, 80, - 58, 81, - 58, 82, - 58, 83, - 58, 84, - 58, 85, - 58, 86, - 58, 87, - 58, 89, - 58, 90, - 58, 91, - 58, 94, - 59, 34, - 59, 36, - 59, 40, - 59, 48, - 59, 50, - 59, 68, - 59, 69, - 59, 70, - 59, 72, - 59, 80, - 59, 82, - 59, 86, - 59, 87, - 59, 88, - 59, 90, - 60, 43, - 60, 54, - 66, 3, - 66, 8, - 66, 87, - 66, 90, - 67, 3, - 67, 8, - 67, 87, - 67, 89, - 67, 90, - 67, 91, - 68, 3, - 68, 8, - 70, 3, - 70, 8, - 70, 87, - 70, 90, - 71, 3, - 71, 8, - 71, 10, - 71, 62, - 71, 68, - 71, 69, - 71, 70, - 71, 72, - 71, 82, - 71, 94, - 73, 3, - 73, 8, - 76, 68, - 76, 69, - 76, 70, - 76, 72, - 76, 82, - 78, 3, - 78, 8, - 79, 3, - 79, 8, - 80, 3, - 80, 8, - 80, 87, - 80, 89, - 80, 90, - 80, 91, - 81, 3, - 81, 8, - 81, 87, - 81, 89, - 81, 90, - 81, 91, - 83, 3, - 83, 8, - 83, 13, - 83, 15, - 83, 66, - 83, 68, - 83, 69, - 83, 70, - 83, 71, - 83, 72, - 83, 80, - 83, 82, - 83, 85, - 83, 87, - 83, 88, - 83, 90, - 85, 80, - 87, 3, - 87, 8, - 87, 13, - 87, 15, - 87, 66, - 87, 68, - 87, 69, - 87, 70, - 87, 71, - 87, 72, - 87, 80, - 87, 82, - 88, 13, - 88, 15, - 89, 68, - 89, 69, - 89, 70, - 89, 72, - 89, 80, - 89, 82, - 90, 3, - 90, 8, - 90, 13, - 90, 15, - 90, 66, - 90, 68, - 90, 69, - 90, 70, - 90, 71, - 90, 72, - 90, 80, - 90, 82, - 91, 68, - 91, 69, - 91, 70, - 91, 72, - 91, 80, - 91, 82, - 92, 43, - 92, 54 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 4, 5, 6, 7, + 0, 8, 8, 9, 10, 11, 8, 8, + 5, 12, 13, 14, 0, 15, 9, 16, + 17, 18, 19, 20, 0, 0, 0, 0, + 0, 0, 21, 22, 0, 0, 23, 24, + 0, 0, 0, 0, 25, 0, 0, 0, + 26, 22, 0, 27, 0, 28, 0, 29, + 0, 30, 29, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; -/* Kerning between the respective left and right glyphs - * 4.4 format which needs to scaled with `kern_scale`*/ -static const int8_t kern_pair_values[] = +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = { - -4, -10, -10, -11, -5, -6, -6, -6, - -6, -2, -2, -6, -2, -6, -7, 1, - -10, -10, -11, -5, -6, -6, -6, -6, - -2, -2, -6, -2, -6, -7, 1, 2, - 2, 2, -16, -16, -16, -16, -21, -11, - -11, -6, -1, -1, -1, -1, -12, -2, - -8, -6, -9, -1, -2, -1, -5, -3, - -5, 1, -3, -2, -5, -2, -3, -1, - -2, -10, -10, -2, -3, -2, -2, -4, - -2, 2, -2, -2, -2, -2, -2, -2, - -2, -2, -2, -2, -2, -22, -22, -16, - -25, 2, -3, -2, -2, -2, -2, -2, - -2, -2, -2, -2, -2, 2, -3, 2, - -3, 2, -3, 2, -3, -2, -6, -3, - -3, -3, -3, -2, -2, -2, -2, -2, - -2, -3, -2, -2, -2, -4, -6, -4, - -31, -31, 2, -6, -6, -6, -6, -26, - -5, -16, -13, -22, -4, -12, -9, -12, - 2, -3, 2, -3, 2, -3, 2, -3, - -10, -10, -2, -3, -2, -2, -4, -2, - -30, -30, -13, -19, -3, -2, -1, -1, - -1, -1, -1, -1, -1, 1, 1, 1, - -4, -3, -2, -3, -7, -2, -4, -4, - -20, -22, -20, -7, -3, -3, -22, -3, - -3, -1, 2, 2, 1, 2, -11, -9, - -9, -9, -9, -10, -10, -9, -10, -9, - -7, -11, -9, -7, -5, -7, -7, -6, - -2, 2, -21, -3, -21, -7, -1, -1, - -1, -1, 2, -4, -4, -4, -4, -4, - -4, -4, -3, -3, -1, -1, 2, 1, - -12, -6, -12, -4, 1, 1, -3, -3, - -3, -3, -3, -3, -3, -2, -2, 1, - -4, -2, -2, -2, -2, 1, -2, -2, - -2, -2, -2, -2, -2, -3, -3, -3, - 2, -5, -20, -5, -20, -9, -3, -3, - -9, -3, -3, -1, 2, -9, 2, 2, - 1, 2, 2, -7, -6, -6, -6, -2, - -6, -4, -4, -6, -4, -6, -4, -5, - -2, -4, -2, -2, -2, -3, 2, 1, - -2, -2, -2, -2, -2, -2, -2, -2, - -2, -2, -2, -3, -3, -3, -2, -2, - -6, -6, -1, -1, -3, -3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - 2, 2, 2, 2, -2, -2, -2, -2, - -2, 2, -10, -10, -2, -2, -2, -2, - -2, -10, -10, -10, -10, -13, -13, -1, - -2, -1, -1, -3, -3, -1, -1, -1, - -1, 2, 2, -12, -12, -4, -2, -2, - -2, 1, -2, -2, -2, 5, 2, 2, - 2, -2, 1, 1, -10, -10, -1, -1, - -1, -1, 1, -1, -1, -1, -12, -12, - -2, -2, -2, -2, -2, -2, 1, 1, - -10, -10, -1, -1, -1, -1, 1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -2, -2 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 4, 0, 0, 0, + 4, 0, 0, 5, 0, 0, 0, 0, + 4, 0, 4, 0, 6, 7, 8, 9, + 10, 11, 12, 13, 0, 0, 0, 0, + 0, 0, 14, 0, 15, 15, 15, 16, + 15, 0, 0, 0, 0, 0, 17, 17, + 18, 17, 15, 19, 20, 21, 22, 23, + 24, 25, 23, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; -/*Collect the kern pair's data in one place*/ -static const lv_font_fmt_txt_kern_pair_t kern_pairs = +/*Kern values between classes*/ +static const int8_t kern_class_values[] = { - .glyph_ids = kern_pair_glyph_ids, - .values = kern_pair_values, - .pair_cnt = 434, - .glyph_ids_size = 0 + -12, -15, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + -12, -2, -8, -6, 0, -9, 0, 0, + 0, 0, 0, -1, 0, 0, -2, -1, + -5, -3, 0, 1, 0, 0, 0, 0, + 0, 0, -3, 0, -2, 0, 0, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, -3, 0, + -2, 0, -2, -4, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + -2, -2, 0, -2, 0, 0, 0, -2, + -2, -2, 0, 0, 0, 0, -16, 0, + -25, 0, 2, 0, 0, 0, 0, 0, + 0, -3, -2, 0, 0, -2, -2, 0, + 0, -2, -2, 0, 0, 0, 0, 0, + 2, 0, 0, 0, -3, 0, 0, 0, + 2, -3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, -2, -3, 0, 0, 0, -2, + -4, -6, 0, 0, 0, 0, 2, -6, + 0, 0, -26, -5, -16, -13, 0, -22, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, -12, -9, 0, 0, 0, 0, + -13, 0, -19, 0, 0, 0, 0, 0, + -3, 0, -2, -1, -1, 0, 0, -1, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -4, 0, + -3, -2, 0, -3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -7, 0, -2, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7, -3, + -22, -1, 2, 0, 2, 1, 0, 2, + 0, -11, -9, 0, -10, -9, -7, -11, + 0, -9, -7, -5, -7, -6, 0, 0, + -7, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, -4, 0, 0, -4, + -3, 0, 0, -3, -1, 0, 0, 0, + 0, 0, -4, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, -3, -3, 0, + 0, -3, -2, 0, 0, -2, 0, 0, + 0, 0, 0, 0, 0, -2, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + -2, 0, 0, -2, 0, 0, 0, -2, + -3, 0, 0, 0, 0, 0, -9, -3, + -9, -1, 2, -9, 2, 2, 1, 2, + 0, -7, -6, -2, -4, -6, -4, -5, + -2, -4, -2, 0, -2, -3, 0, 0, + 1, -2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + 0, 0, 0, -2, -3, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, -1, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, -2, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, -2, 1, 0, -2, 0, 0, + 5, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, -1, 1, + 0, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, 0, 0, -1, 0, 0, + 0, 0, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 31, + .right_class_cnt = 26, }; /*-------------------- * ALL CUSTOM DATA *--------------------*/ +#if LV_VERSION_CHECK(8, 0, 0) /*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else static lv_font_fmt_txt_dsc_t font_dsc = { - .glyph_bitmap = gylph_bitmap, +#endif + .glyph_bitmap = glyph_bitmap, .glyph_dsc = glyph_dsc, .cmaps = cmaps, - .kern_dsc = &kern_pairs, + .kern_dsc = &kern_classes, .kern_scale = 16, .cmap_num = 2, .bpp = 1, - .kern_classes = 0, - .bitmap_format = 0 + .kern_classes = 1, + .bitmap_format = 0, +#if LV_VERSION_CHECK(8, 0, 0) + .cache = &cache +#endif }; @@ -1292,16 +967,26 @@ static lv_font_fmt_txt_dsc_t font_dsc = { *----------------*/ /*Initialize a public general font descriptor*/ +#if LV_VERSION_CHECK(8, 0, 0) +const lv_font_t lv_font_roboto_12 = { +#else lv_font_t lv_font_roboto_12 = { +#endif .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ .line_height = 14, /*The maximum line height required by the font*/ .base_line = 3, /*Baseline measured from the bottom of the line*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, #endif .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ }; + + #endif /*#if LV_FONT_ROBOTO_12*/ From 9c8535d6030064201c46b704df1d632f7356ef87 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 19 Mar 2024 17:22:52 +0530 Subject: [PATCH 22/32] feat: Update font generation script --- .../scripts/built_in_font/FontAwesomeNew.woff | Bin 0 -> 353228 bytes common/lvgl/scripts/built_in_font/Verdana.ttf | Bin 0 -> 149752 bytes .../built_in_font/built_in_font_gen.py | 33 ++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 common/lvgl/scripts/built_in_font/FontAwesomeNew.woff create mode 100644 common/lvgl/scripts/built_in_font/Verdana.ttf diff --git a/common/lvgl/scripts/built_in_font/FontAwesomeNew.woff b/common/lvgl/scripts/built_in_font/FontAwesomeNew.woff new file mode 100644 index 0000000000000000000000000000000000000000..791b4101398bdd5b8ff606d2628c38a0876727eb GIT binary patch literal 353228 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

L%Z8dT46iUgR=7_y3~h3%I5A#)q58m7OEnA? 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

    !3{vLB6%Gl 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⋚cK6aX{4XyJOw{? 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 Qb60ag7_%75F2AWQsZn#z61m4UA~2Y5FWX!JKLN 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ⅈ1}j>c>|QNRciCbmIy&)rg5#iZ5&G~&f*((ZJg1g%%+Ul??kQ2 zusJO)_}S>?=tqi-4#m6UBk^7Fhm}LjPP>D#=(E8>(Iq~hT8^C674q#e{jjXrjh|#) z(G?m2KJ!=~SN&E8+&#+2m7ikFc%k}ZQDvUqq;%(L~iy6iLj&_`Ezqek#7R6R8< zdQueL>OA|DC!qZajC7AbR)0LS8Lp0~!#kVd=~`WepG^96RgS7R&;G8|suK^D)eQ^g zo3!fGPlZ0*qq@uVE~15^Z=T)v6HBK~+^IV32<%yO1ZlKZ2OX!rY@MriFFQlhaRzdZ z+0Nq=8UbG@yGJ8o1nPL7BfCc*;bcyB9@=j`MS|uwX|-+(hk7?7p7`s6*Tbu%&p#IF4NlQbIzc}ceLwDu$KuQ5lkt7= z#~e%H_q0ZP;!5~|!Zfng*>hIH4-^Yd(AWlqiz}5uJ{#N}{a4+GUNUBMO-yj9)uB;$ z7`^sUSACcIxi613!=JrYhfjh`8tiP*Y4j!a!`sUr+CS~=6xR(sn(NS*5j^>-AAs!ORUmBx)!w5}<26euB)GGP2Huxor; zhBK|uumhcEFqVuC#0$_Z!;Fny23tlifh_$EUIiGc9!bs>9;`o~QR5bGgb~+ zOS1do%hj)*b>Z3R`8v1LsVn4QG{}c{s87L{A5mBE<413?er{`4v`Sf!R#&&g&>Kbz zb!(^#r*toTLrgI7QCS^)Lsn?&p(2-~UzB}?^8Aj6&+9HSOkDPu^;)Y#?{V+tsMQfe zcDZHGu7!WDd#SU$6Z^Z;>KM=9Wq&u->I`09mr&GSYJ~KB#}_7RC893X1Ki?hPq=cC zweU;=5p>=jxhAF#pFLhdIGKE6G*&^|{C}mhN`S%3h3tPgi;mzT_;gj-5Ul!dE-KFQro{%p7QuMk( zvNQU$ba39`z`L{zr&hyTA2^2$^GVP5tEXoHpy6q@h#G%d6zRcgcw(kU(qd9?Bzs=1 z@Hn_OTQ65*cAnKB8|Y(JV)RS8i>MbK9iH55w;IkFyg7IXT<7l$K4$tF@9#Wy|l^6A25{ie5y!=BT_+HN5qO zchxY)sMYxMOgsU|p18|B5X_@>M7(Q1_hhBj&2_1l;96oY*HB57V z34WLhT;w6I+D5n=zX0PrL>Zw0p2p=}!TLrBG{UVE0)F=K&SSJ)bivd|JOwf0j^@4Xa@+&mrNtX`{{Rwd$ElW6L44np75J z^>usC;8W^Z^JUr;iw^ER2rtt^W8VnJ|JcH3jY3&Bsrq41jUDQR|#qs`Hk z(aGrE=%dk7(R1?Mv`CA0dHR%gP|r!1+>WTJ=b|G6urj(e?(XpK)nG^J zgPl8yV21nE2MJw!1CZ4qCwSwJzjx8)?v3h6eg-}aasawxYOwyXkcs|p_Em;RKkOQG zJJXx22F^pXbFIn7tn5)wIE$w)@UN`28fcKGEr8XgWX#9a6AvPu{Wj=7qz3OHUi}gE z8_k}9@qD$q{}QfM_PN!#?~;`&>%5_+JGw@9@svOOH z)oj%H%Pw8ZcAULeJ)J)j&s0Q>^Kkku5${=5y+>A)H`GMb*!vB%cYmji=&c0jc7GG> z=5YzVHsVdSB{))T2|noC2zy&W14K8Mz>oWZULIDeHMry;1$P+?a!^q%mMLQgv_Mt2?YHL`Q?jPQhlB!rdmp71OKk``|3Qp?5Bm(>$H1i3HC9{#S% zqlQn5GFUnDo)GJgEyJmR+y{ak(KmHhY8l99VC7V!#ound;uqD66<{a8iIiC(HUiYm z$cN|Iu;o7{XL^zyu*YySj%3DDf2!Q z-h9o|W8Q0?^%_whY}g6CBZ*$*&|<6N^G$K{LA4Cq+0K)wlM&@sJNpp zYbYo~F&T=eX`v1H*JuscW(IJZ!L{w7fY}7!U@3zY!(s-j+*!nt-&qR%479nk2wT;4 z34i`B732)LW!<8WHKLo;LxYxz_kW|P1ifjONt}Dtce6Cr7xlK~q41{guJG&O8`4xC zk6uug#oLu-@t*jB_+xqs=H>YH%7V%@%E!oYZ1hF#G|lr--iwvf3?F5@M4vJE^ZgUB zFl^C5kpRgWs_#*~=M<5fyERwt zOv;{#L{4uy`oHKdbYH%VApd_v8SR*FDi9y3^ZrlOf}~FPJ)(@Rmrzdl4|XTkv^@=D zWxS!D>$)zXy^4)ORL1)ahQyE;j27ZZ^&8M#&le0|! z#Jj7NY_svmcmpRq#p~<7SiRVnOU^cFrkr|2d629`ixNp1_o=1s?d^+hw6aHbB{{9U z%|GPlU9n7I2i{_ zf_Y9D@g!^#@-cQIzm(-fuFjRB&*#End|o+Xi=)-1Gu@%M(q|GL|6|SX&w|+- zN+Zht1X$g2=!l+GZ6-=&-mED;vyoo#Bk2HG7{9I2A=od z5&f<8;>~L4K5bTp-^tUO&`6mT#7k?dtq2?aR`%6agoTM*`8<_d)gPWjza@H08J>jS zvAT>3g3qcp`=%_)*|%<4ukanJCGN#jC0KrxiFu{(8-yc@_@fT&WwGU>74ZZfvT(Ov zMF=-Qknw?E7G8E|4iZ47xO3gvuy55BcPS1?vyk8cWZaM-nC3$w@I9QI6yynU%0a9dF*_U#o}vQ*{EIV9%3c;$6}3mk3UrpG63-$ ztPClU`G?oQpV8$FM_Yr-f@|Z))W%7T2Y%E_ZWl^2gmU=Aa_ks3xNlZ`9Uo?sgEW?AUXAbfGdIhX2AD>;v9RO`w7_&XAeR{p*EyA)AAsFhsCkTYtKs{UK`Kn@}a`>cf2L{7S7 zXwTDHo+=Z%fwF3}l&3n*odP9MlcyY~tsG?-4b`ZIQ7SpQpe9cTR+GmxdV;L%JdR87 zSjU{Lawc)0o$WL(jLfPHf`TZT%>g-G#>q5^}sg(Mpjt~YZ5GE zxH&qdURVaED}>)x$>KYjt=mc-?a=$ltS2^wpJv!)b&0dsM!7(zrk>f;n`d1r;}Pw# z5}XA0ZB^zf`+SqmT0O-VEm5iFjkHqM6PZe!UiBK%Uh$2riaS(7p4-;}tb_!#x9-RE zoD>}Jnq+nvud#W^hEXm|^_^B~(|GbyT8UZBmu5XZi-HW9{4U2;9uW1|I~S_cD%G9_ zu~O|RknmNT0r{q{>siTVn4Z2+G<2SJpJo?0@7-*5{@m^MkP_ZmbjQ9#rX5!u(S6Rk zfhr~9`kd1{6UsiMI<#8&uP35}Uj?2^BxelGx|Sym(Mqo4Nq>Z&3;aS&o#k ztItz-o)?m}<>=WczeejeGt^wCU*>^&>-1{#H&#zdi_T-E8L{`@09qrX$ zSN{R+1fK4*(oS(SJiXoQ1R@HX^)+|KO*{=jzm+)Wh;L6s-D<-^x=4T5)k^2pN?1pH z8+@tyWn@=)pUQZPU9X~quh{ge=&w{tbJqK;l;)~$kG`cgO0EM^qNnSJMqA+%s>7}{ z?~awgKs~zO9=^}+O5R0hC337xOH4TDf2&9BdH0A?{p|`q%Li1)U7LmB;gAxUaoxg3 ztB(x=}8d(?vr4m`tcRwBa#zi~m%M%WB^?1{CFSP6eVvADKqliJ7v z#dFnZC9*#`^~U3OsI3-*wNgF)>f8?f4C{Y;<~^o_735FGJ2anC9a*~P>))!768X88 z=$~g#wCCwJPur#yLCbaOwNcMRsj1{LI;>M(p1PpJ8s(V`fwt<@gj9i+>ePb_$DxLnMlO~9>H85S9R>Lk{oVqwRz}=qTw{p$lnQYo}^y4 zC=fqD>U&PLOuRREpYc}mjurejR|&JD^55JVd?9!#_=&!VyES~fbj=6CkA_c#FNLp# zKh<+KJ<(|7XX>)*FG%|Ejzmc>yXMW5$Ti@!Ec!>aA~|#>+cnrj8X;f0Wc`k-d_}|< z_!BM&E{K1{uFV^5*WgRC(E8wmcvJAEaI^ZXG5$Tru6JnmO?qC~<_vF9EBe}i{4QKW zmpetDzM|hy&4BTGYsB?VjgS51_x`?W@Wx2<4Y|e>lj^<8!UL*7&dTnzYvPbtq;_xo zt7@gKCs=6Lv~5+El(+6uEBr3aBj!4dA^5zrs!8AX%ysf!XmFf`Fy$N^p`-R-brw2V zsO6xedvow$tSkg*&+eHrJ5G10a&BLgvpb=GW*=H>dh)KU<)K4^9{JcLuZdeYMtOQ8 zh`#5m47lUL{lVkG*Ytepf^bj~kYnK;;r-!96nXuEJbLMVC$z44`hT0E1L<|Iq8;hA z>K*RYG4;f<5FYIsdj$MCR<2bmG8hjT*GT8o23}Tuvue=2r3>0Mau`j}@BJmU;zLlT zdCWB)1m1Gs7=4dwIA3Jpgj{1EVf*;KZ&eM?mf^|cnsbIHa=dj?H7m3(eX%0udV|(Q zY><ohCb)*9_sE83Z` zZP(~uVB1@Nq*k;Jo%Rve=p*O>j;{r(fld_Ri@AnQi0S#gTUBE#P_&I}TbXw6_bykB zKeMwa=Gr4ei@Y`bcdEhOm3PLjv4rv4_`Qtg@2yx9bM5a-Nal@qTC3AG*XRm0+OB*~ zHAE(*joCG^Nc1#cGcYWHo5>#_l|n~&H+UqlF}lh^fcDJ(tv$O-wP*Ke?b)3`SJ}0z zoLen22I!H=fw!Ib#9EyrK#@!i{3ygGcIn&*gXcMu0(+aTzBv9RJB5gNtyj<8@s~wI zWC;w}75M{`(Uq#>Exqk_#hZFZD<4;#`Q_}Y?ssdg9##wbTf1Fx+B^NU##q{p39cLu z$g*Y1z+m3`Z1p*OWbHUJ8t|x(z*~fgo(^apcF9-amTBGoj@rkx!C@`@kUcQC_=<#0k!bH+abH+shmmG z@WiK{qKW=V*JPLU+7)>v+oJnaXE9W}a$l#-AIEALk_=d5SCis?r`^`dAE*VZe8R36 z+n=v#4S_zVd%In6wkI$SuU8A@F}tEqhwrm`LM>>+tLzF*cng$P-@ldEv+q=Gncdl1 z>uay?%&3(;_{w!xecd)9YxNZ}TWx)`*1Y}BeSy3=X_w9%r!F2p7T@x2?t-f7X*l&J??KW(! zb)UA;M*Pd_2c1sX6?EGl3lfe^yUJiwnkY{Xx9Lph3XhtfyRGprCN1rDmBzr*b$wT@ z=0T3H))k(*e!Id;Hxbjy?pGv~F{?6JNBvc<$T#vcxV3s(Wxl>JYFB)t!F7h#_|0mu zsGeQ%+*Y!(@GELTTij+>c<+0`bshRfF*S%=TMf#-qB`UZt_IDd1y~t`>X5V%>hMvI z3{0HI^6)Sya93u(lxn-R6|zI$m)h#PQX3W~r-sLa$(A4<485+?>5;~Rd8(3luu*N; zDqTN$8;G*7@0Ta#>EK!At-c(*D(O_Q-L-^QNw-t3hW(P$!RlM8yH%^miTx5YvD)|w z)he=KziCXPB|b;BL|FJu->udXFH@;kQkLIsqGuZ+x>}`vJ%z~cgx2okGMo4><`=GG z_pFQc043^Kg|5>z*mXK1_31piu8mH8eN3LnCZdR4#%bkWTEY(FoC<^6wew|y=uT3zDc^=4g3U-iM# z=bORU{(L+6?C^Gz=8%sg_mm?8;iW z(j4anXfI*oh~cMo|7!btv99I?i^CcHcG=&J+?}*>MT^yGO>1Rs?Fs_*2qeMLmBK?) lvt(OWR1^H{XZ*GQ=n?$I58nI~zkk_%deDA9@!kLQ{{ct9y8ZwF literal 0 HcmV?d00001 diff --git a/common/lvgl/scripts/built_in_font/Verdana.ttf b/common/lvgl/scripts/built_in_font/Verdana.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aa4422f4c17ad2d6be02dce03b790d60711a793d GIT binary patch literal 149752 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

    gvEr z6hcZyG}o?_;OSDLlt`>c0QYb>d_Z|b)bw`A9o9U$Wb*HmivCi6zl5 z+7ex;yEYI?w4XgpQ zzzU#6)(G0jnuh+4?Kh$&RswBi&7du;1+%0L4ZnXoYnS{grjH zQJ|w(7ibr!quFR&ceC!Hzpx(G3);)+7&ZpieXI|(pY;#@nGLY9pkvuM&~coOXX9}_ zflV0t6W#+%1RZ3PKqs-|K#$|}cy|2I$80j240-~a0y>3F1)U1|M{Lba1D(#MgPzDv z1f9W70zHY%9Qp&B$>}UM3)d&JlR-~mvq5LGIYYl=b2vSfor>$ZY%b_LHV+hAQ$xSS zs-5Tpwg7Y?TL`*{EdpK4mJI!dwq8M(a=MHy!}W5u9Q1T{`p`#Mv9APO$>}P#3fFMn zK-aJ}L%+s4ek~|A^+4CLb)f6ndeAf3nM1$A%Kj|Sv$5myE3EH{p2N-oJ(rz3^dZ*z z=YgKjE&#oN(+k;!xW0&8H1tcX{WpSM%q{`Fglz)d#ObB%(xG3l%h+Y0m$S=3uV9-& zH*wCuVL4MUJLpGyN+E4x|MAOy`EhUdIP%=^hVJ4*-h*w z(3{!Kpxf9s(66vtKySew(jlw}iQdL;2fdxsJJ=n#zLR}*=x5k5A$k|P8}x2Y?_u}g z`d)V5(0kZ{*$%p$(;aLlu6J^}i|rcvDZ8KT2Hnl+9`*pPAK>&s_TbP@u=DbD(66(H zK(WsNx|h>^Y~RqkY(Lu%iWMyA0rm}0tZG3Y0sS#{Qyv9^bS_TM4x5Pf!X?|{C@ zUIhIv`yS}`*h@oi(asR)_c?u;y^QNu*sGw}B^r7YJ4HlaXRm|)fc*gU4fY1;580bT zI5>Tay^ZU)Iemw{gKO-8481}7AfWHEpMd^^)1R`R;`%-I-p~)QQ*sFO5U2064{-ef zr$1*uA9|hkQ$T;oJ_P-c{R;F~oc@~qdgwLmR(%Be8}?h!-*Wmp_B&kvp8bC4RqSj1 z0rZdTV^Hjtf&Pj88T8MfuVAn2FQ9*Ae+B&;`#UIho=X7WDE6^HKjU6(_-h~~AHLoFY-s2>~p!@~zsUUTJUr)JHHH5*jY9Y6c3s^?CRzpdvEPq3}$D_&e}^9I{4zswnx zE|o5mu9dEnwni_FUK_oxcZvb?euy;}=Jfz3PFzx`Czh_v#Y;>nLHRgf-ERi@g$EONst^VXtdo>0TGEKF4HT zE#Q&zP^pMtvonvXjwh)t>(Qe6de&n-ae8}OIu&&~L<>5Xm-nhu1Brpe{H0sufu-`6 zME|`0hCF&W&>xJ&W;Ntx-0qk63iITFy<^W>>f16v8TLBr_o`9@bS&T7bJaXtB>H2q z7@jzXp8zaZk9f3?p{}J68BTP}TPp9>pd2Sb+^M#Jo-LgRn&?LZj(PuxCXP*vowsGn z*n~WG%e*b~9~;_uT0*uZw(J`m+_Gk1p1hZxfT6+t$FBxuzA|aGY{JEzGd_Dnfq0O zs&C$yS^JWBHuIp&SP#FeI((P%$dqD(0wlX%W#Es32YVRX$n$FW4W3@`n85fwB@^xm zY{6qH<(`e_n>CBXqUxJIb7TwAN*XYH!X%<|X+PG!t~p;bNBvWHoowh=L+^jK;j@LG z%~Ib4Uy;Ge?txu;0oI`wo`l7ra271vGq58g!^N=BJ7HCRjCr^gZh_@}02Xm%*b0mN zRao2Iu$m9U;ys6ln_=&7VLR|PV>qma|8N~_`Q7XdAzZ!voXRCAE%*qZcz7MV_}9Yc z&BOPb4KL?H_#OM%i^3$_>%zSgaCa^In;UTVAnf4hLl-=`Is66uKIHfo&yYje>F~yu zV<-Axwa6LpjIPAHk6p0Mt8sk=+KW#LeJ)(Aim77ow0?<_-xF?Dy?`F=VwdS$@cfzf zb&{%P4wo&1=fXZ)2%nd!PgDI>b+77r_K<2hn`GcGrtr4uHRVvJg#=#t->UC`%ORV7y4Kp* zK~)KI`_|C2nkU(}aQ%e-MRt(xYu;tcc{$|68#*e#N?pfBtbJn9L~l02|Rm(_nZ2Tep8>TeOg29=WU{P9eq$6(Y}!f+H|+7H1t~>f5Wx*aNDST zBMxfU5eLReGlP%OUDfe=5My$Xt~GyW2QfBx(V>5h?a_KvVaV!a8aw?VW+mC<**!?V zjRRvUSWs?-HqM^H`DSP$^>M3qH#-CAE#UhV9OvNP>H6*H*Sl;E(r1wF;oc8$T#oVh z3C@2(*^)NHcH;Ot(tIpQR=m#Z*arQN*>do_74_e$esJjb(A{mS^w962uXk5@J;-H_ zaaa9fh;)!)%pb?`EIu&SuT|kd-${p2?(g97cS{~^rm>)LsGV`mb?;P$cTLbA=pnVC zc5po-UBf|o0r|9n@9%N;;c!A`F`OH4%*QbU2jnc2G#BFYR%4kD^;}LmL%K=&LAn8* zw`zWgaYNgAAKn2LpquCyWFsUrGw5Ki(t-XzP(7|jy`u;(q_fn{!@Qweq}QZlHT@>N zr@m7^Nxy1mj=cg~L2cj|gr3#Tggf-{0e(IedV{q30rVL-Bz>!$Nj9W&gh#?e^?XCE zJ%mrfNbSsJNP0rshocCe3N8ZA{X<$!<`+#WvA_>wP${srA1mqr+#6KjEw< zgW4JL;d1`m8FLlM0&|v(vlHWx2PXfF^IV)i!FeNODA4%ejL$&eIp!5UuVHS%cz=t_ zmoWTa6dB=#;B?XglocPwGPt9lWX~pJ|8X* z+(G`YLI1AACm#0I^bzMRIBpg8GSYnqwYqwS9b|J z1LLXX_el5gjP8-X=uR3MA|2M=jyWE9r?IE@(AXRP%p3-?UsnwcaUB5Wsjr7+0Gr6m z{)3r_m;Sp<*8HAL(FrJngUjO(bC5i!+!3-MyjNvG*a4pUbzYR&&#pC$W-l6MBR@VL zqMw6%YjNDc<{QT1yp!d*&G`*muX&aoR6mdY{)-t22fEW(i>AbSwNdB{4lbjAu(0+9 zr2R-!-|0-YbgY6;lCAD>wi@SAn9mPt-eK43RqUWXfHE@hdkXGdk7FL2rh5eE@3TIR zIl>RsJr8)t90~b8L^3A4=uco_9Atx?ybUx?R4?RAWuSL28RwxdbZ>^>$6WbG93SF% zxO)Bz&d(q1Tj}s2MCyZ11ZKv;H)AULY<7$>VLHxa|7d!9HVGoIbO})EkXfBR+|# z)#~+Ty;`Hu>(yE{Xf4nkz0PFN8w`4#!GL@^qrs>*;;sQ_yAkrU;OhH5rC;j^E}T?=~Dt|QJyl+~Mz#2008=usi=;kj}Lb(&B+{*6OLPt`gN zRijpEtf)bc+*&P|puQ2@b!yJXfaV}l9;(Mc6&euH7&;-+a~(RM(@@f=(`yhpr8F9; z)fts8QIpKbpw^lpF8uNGN(BlpPPKTVL=;o1F)Dn)RVjjc&=HhJuXP#{ETvUog+>}x zD26VR$ko(5y+KQY)Z-5cz0rt1XwhJuR!c2Mz!@SpLNX*j)It3g zFuDtQ8NrpBNWugMP$J-jK0;dHgZ}Wx7&jUus?lf$;eqA>k|>?&*@#f<<B<{2`zL01IUZe6V9CQM~P~{J%WSDWI`n-qlo~E;vlHsqz52K zTks5;V>ancS|~jlgjz`P^!UdriTcF#;n?`oX*vGT4X%$SQcU1a3x!5Y5l{hF2*Mw4 zBD79psNs*ALKV=|02~tjECf)UnNI=WK&%vvqNXabhCVIz71IC$;Y;CK%LH-JBNOHo ztr;TaX^0NOFcJO;GUyX$LHHwplK6=k@Q3EmBV5olLrq7IlqfBdW(VZXFM8z7<<@11Eh{=7;sSR9|6LEVI_6Oc+iM& z{AsHA(~?&6fdWgilr-V;z{mC|{Lwue_#_hwnGtD>c@e0*83;j|$`dCGRFv>XSv1f9 zWCZ@~)HALRRs8X~I8h9b(n_c-RGR96wv&wmh+v9PmgI#1^Z|d$4T2PbT**LF7{?!( z1Y{JUmKvP}Pk9D~6|qnxPb?1O4>gdHt5&0Mr4&UonBkEbXV_GV1SP$JKGp>z4>3dj z02Fs3P_%0Q=n2OktT3)Q{%}Tj@K?njA(sY7w2(`H063b#ka$3xd{B%Avjqq<5=0>q z6v0^u05hQq(;=Ef_yn@mYK@6cuy6oGnqDc4#9ys&^<3-a(dVPGaZwSQFL*c-b;GG6 zyMMUzz@Noo0sgdrm}mt43><$nL`vY!8lZ`>#z+{E0sf)M06+o^BG_Vh$y{M*VJ-}C zUDakv!bm9g5gJ42CBKpG^Nh%cpd>jZoxn(2EL4%jWKl3gb`S#(&CpVnD32TX1fan} z^DvYKz(9jgv0CTge9#y;ThLanuKX5QaK-2N19#FRst1Zm%0}h@?WX?m_Cc9p^GH2W z7vYbzPD^QOAT@@Rm{L|Ktwt|a@kdS~SaD9&TON_c8Hjzz1(h@l3=Q*TQR@i&ajw-&B08oqa{TEO{22iygAt7s33TYP&TO*q(ii|P z6#@@}*^G+yJU7I^5ek&xZv_4@W$N(RUdoS07-d`;Oc+DXg3hAV1cX8I1TY#is+0%~ z-7x-;R`6%xS>XUkN8yjYbKq$F)kJahne!h({$Ic!4VeehK;lkLq@Ge z=cXAQx~A2lEb1G<-Jqr!iMJBUOOplFV>V*S!BUcpIz1=HkJL^La|nOWgrrG_$PF8% zDH9Z%JYh^hMuW`){23(JNc>eO*)poN8_kpTX156v)`uvXUDBwogZ zRvIOUfOvof7pU1J;y(pUCMy{*Dq6LVC{Or9x8a{cXyln-=&;!&Vn8Ub)rK<etKjz3K7lpqLk{2A2}G>_wt+efH4o})z;f)oO2j*;V!S3oHY zkfIwBDzZq377JR8BG6k4G((3p62!@Ze~FRcv1u&uQnhFwifc7`FZGb)4`l&CQrBwW z_~V#CRpj9sB-CRe*kK}pVb)fqLrvlM1HR1E#l!fcG_SxSQe*WbLc3@%YYjFnDg`St z(7b1;f=4P+!=E0{!CB$T`2v5GLNrL2ukc*5T1skD`IzK6GiGjWCr{}Bn}4+0RnWuZo>S8!BAKb4ka5bAjT3UP#TB>OG?m-9!ima zik{PBn&EVqym(DECqb41**($;I#a4KUF1%woj9UqS)E5&zVOl>>4BUSJ0; zG{ZmDVkG(gq8UC7S8*$uB$4n#0VAs5kB>33BETo2!;XLXG+Uv9aJ_KHVkMht#muay ze=dbt11Hg8H`{5YX9ag!dLkn>ECWy~?px9#lJJMy)nLM_0&D=10-4Nw@}_#QB&r%J zv#ur`XbQ(4Ogtj?*AW%`fjQ+SUyZCLiO>ZbsxvwOKKy|LH#VedyfBwF-@xIUsOY;< z*Aj5+asf7W^Y6go%3KDOj&`2X;1zgcr>H`gs(+T5BQbF73Us&NBsQC8p(=(Jg|4F~aHU10?$ z?s=e#*z7_kNithaMzo3yJbAM=)QuYLuBu0K1paDLubxS?$BHDVkʩ-vW|Jdk* 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

    fSI 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] --bpp {1,2,3,4,8} [--lcd | --lcd-v] [--use-color-info] --format {dump,bin,lvgl} --font [-r RANGE] [--symbols SYMBOLS] + # [--autohint-off] [--autohint-strong] [--force-fast-kern-format] [--no-compress] [--no-prefilter] [--no-kerning] [--lv-include ] [--full-info] + +#command to generate font .c script: python built_in_font_gen.py --bpp 1 --size 12 --font Roboto-Regular.woff -o lv_font_roboto_12 \ No newline at end of file From b42dfad7c9ffaf9a28a295f612de73135f97847f Mon Sep 17 00:00:00 2001 From: ParnikaGupta9 <154982112+ParnikaGupta9@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:22:39 +0530 Subject: [PATCH 23/32] chore: Update lv_conf.h --- common/lv_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lv_conf.h b/common/lv_conf.h index 7f44e363..64be0efc 100644 --- a/common/lv_conf.h +++ b/common/lv_conf.h @@ -37,7 +37,7 @@ #define LV_COLOR_DEPTH 1 #endif -#define LV_SUBPX_BGR 1 +#define LV_SUBPX_BGR 0 /* Swap the 2 bytes of RGB565 color. * Useful if the display has a 8 bit interface (e.g. SPI)*/ From c44c2c88956720077a47d301acf1cabef01fb1db Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Thu, 21 Mar 2024 13:10:22 +0530 Subject: [PATCH 24/32] fix (evm): Updated typedata validation --- apps/evm_family/evm_typed_data_helper.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index b4d5462c..611ae3f6 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -179,11 +179,10 @@ bool evm_get_typed_struct_data_digest( uint16_t data_size = 0, offset = 0; data_size = sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; - if (0 < typed_data->domain.size) { - data_size += HASH_SIZE; - } - if (0 < typed_data->message.size) { + if (0 < typed_data->domain.children_count) { data_size += HASH_SIZE; + if (0 < typed_data->message.children_count) + data_size += HASH_SIZE; } data = malloc(data_size); @@ -194,16 +193,16 @@ bool evm_get_typed_struct_data_digest( sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1); offset += sizeof(ETH_SIGN_TYPED_DATA_IDENTIFIER) - 1; - if (0 < typed_data->domain.size) { + if (0 < typed_data->domain.children_count) { eip712_status = hash_struct(&(typed_data->domain), data + offset); - } else { - eip712_status = 0; - } - offset += HASH_SIZE; - if (0 < typed_data->message.size) { - eip712_status |= hash_struct(&(typed_data->message), data + offset); - } else { - eip712_status |= 0; + offset += HASH_SIZE; + if (0 < typed_data->message.children_count) { + eip712_status |= hash_struct(&(typed_data->message), data + offset); + } + } else if (!strncmp(UI_TEXT_EIP712_DOMAIN_TYPE, + typed_data->message.struct_name, + sizeof(UI_TEXT_EIP712_DOMAIN_TYPE))) { + eip712_status = EIP712_OK; } if (EIP712_OK == eip712_status) { From 1a37dfa015e8e08214929da476efc11d6a8195b7 Mon Sep 17 00:00:00 2001 From: ParnikaGupta Date: Tue, 26 Mar 2024 13:43:37 +0530 Subject: [PATCH 25/32] chore: Commented fix source --- apps/evm_family/evm_typed_data_helper.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/evm_family/evm_typed_data_helper.c b/apps/evm_family/evm_typed_data_helper.c index 611ae3f6..cf264a6d 100644 --- a/apps/evm_family/evm_typed_data_helper.c +++ b/apps/evm_family/evm_typed_data_helper.c @@ -199,9 +199,13 @@ bool evm_get_typed_struct_data_digest( if (0 < typed_data->message.children_count) { eip712_status |= hash_struct(&(typed_data->message), data + offset); } - } else if (!strncmp(UI_TEXT_EIP712_DOMAIN_TYPE, - typed_data->message.struct_name, - sizeof(UI_TEXT_EIP712_DOMAIN_TYPE))) { + } + // Setting the primary_type to "EIP712Domain" is technically in spec + // In this case, we ignore the "message" part and only use the "domain" part + // https://ethereum-magicians.org/t/eip-712-standards-clarification-primarytype-as-domaintype/3286 + else if (!strncmp(UI_TEXT_EIP712_DOMAIN_TYPE, + typed_data->message.struct_name, + sizeof(UI_TEXT_EIP712_DOMAIN_TYPE))) { eip712_status = EIP712_OK; } From 5ec894ef5e8a78c10ae5a4986c986f1aaf42a19d Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:08:05 +0530 Subject: [PATCH 26/32] chore: Version bump v0.6.256 (feature++) --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 80b1014f..342052ae 100755 --- a/version.txt +++ b/version.txt @@ -1,3 +1,3 @@ -firmware version=000:006:000:000 +firmware version=000:006:001:000 hardware version=000:001:000:000 magic number=45227A01 From dcd356134f5229845aaf9931548115dbfe3cf533 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Thu, 28 Mar 2024 20:15:52 +0530 Subject: [PATCH 27/32] fix(evm): Sign message escape non-printable characters This reverts commit 6a3fccc2bbd344335caa5ff6e96b47ef71e53b64. --- apps/evm_family/evm_sign_msg.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/evm_family/evm_sign_msg.c b/apps/evm_family/evm_sign_msg.c index c1786d7a..b553c215 100644 --- a/apps/evm_family/evm_sign_msg.c +++ b/apps/evm_family/evm_sign_msg.c @@ -366,9 +366,18 @@ static bool get_user_verification() { case EVM_SIGN_MSG_TYPE_PERSONAL_SIGN: { // TODO: Add a limit on size of data per confirmation based on LVGL buffer // and split message into multiple confirmations accordingly - result = core_scroll_page(UI_TEXT_VERIFY_MESSAGE, - (const char *)sign_msg_ctx.msg_data, - evm_send_error); + size_t len = 4 * sign_msg_ctx.init.total_msg_size; + char *escaped_str = malloc(len); + uint8_t status = string_to_escaped_string( + (const char *)sign_msg_ctx.msg_data, escaped_str, len); + if (1 == status || 5 == status) { + free(escaped_str); + result = false; + break; + } + result = + core_scroll_page(UI_TEXT_VERIFY_MESSAGE, escaped_str, evm_send_error); + free(escaped_str); } break; case EVM_SIGN_MSG_TYPE_SIGN_TYPED_DATA: { From 810fed538319b8204da77786fce0c25a7b7ac4df Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Fri, 5 Apr 2024 14:04:46 +0530 Subject: [PATCH 28/32] chore (tests): Update escaping of non-printable characters --- tests/common/util/utils_tests.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/common/util/utils_tests.c b/tests/common/util/utils_tests.c index 97812bd2..be314592 100644 --- a/tests/common/util/utils_tests.c +++ b/tests/common/util/utils_tests.c @@ -142,9 +142,14 @@ TEST(utils_tests, escape_string_symbol) { } TEST(utils_tests, escape_string_ascii) { - // message: "ASCII sample text" - char utf_8_string[] = "ASCII sample text"; - const char expected_string[] = "ASCII sample text"; + // message: + // "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789 + // !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~" + char utf_8_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz" + "\n0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; + const char expected_string[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789 " + "!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; char actual_string[300] = ""; uint8_t result = string_to_escaped_string( From a834c4f582cbe2d62315b1ed72abfd8a8c1fcc6c Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:01:05 +0530 Subject: [PATCH 29/32] fix (util): Handle `CRLF` when esacping string --- common/libraries/util/utils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/libraries/util/utils.c b/common/libraries/util/utils.c index 4b5ac82c..d6868099 100644 --- a/common/libraries/util/utils.c +++ b/common/libraries/util/utils.c @@ -623,8 +623,10 @@ uint8_t string_to_escaped_string(const char *input, bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0'); uint8_t bytes_read = in_idx - old_idx; - if (0 != letter && true == g_ret) { - // the glyph exists; keep the encoded character as it is + if (0 != letter && ('\n' == letter || '\r' == letter || true == g_ret)) { + // the glyph exists; keep the encoded character as it is. + // Additionally, CR/LF characters are handled as special case by LVGL + // hence glyphs for CR/LF are meaningless so we should keep it as it is if ((out_idx + bytes_read + 1) >= out_len) return 5; memcpy(&escaped_string[out_idx], &input[old_idx], bytes_read); From 8fac90030a75c9d8ef4629f1ec9549e7b3367638 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Fri, 5 Apr 2024 19:23:21 +0530 Subject: [PATCH 30/32] test: Add `CR` character in test --- common/libraries/util/utils.c | 1 + tests/common/util/utils_tests.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/common/libraries/util/utils.c b/common/libraries/util/utils.c index d6868099..1f215600 100644 --- a/common/libraries/util/utils.c +++ b/common/libraries/util/utils.c @@ -627,6 +627,7 @@ uint8_t string_to_escaped_string(const char *input, // the glyph exists; keep the encoded character as it is. // Additionally, CR/LF characters are handled as special case by LVGL // hence glyphs for CR/LF are meaningless so we should keep it as it is + // refer common/lvgl/src/lv_misc/lv_txt.c#174 if ((out_idx + bytes_read + 1) >= out_len) return 5; memcpy(&escaped_string[out_idx], &input[old_idx], bytes_read); diff --git a/tests/common/util/utils_tests.c b/tests/common/util/utils_tests.c index be314592..a5943e00 100644 --- a/tests/common/util/utils_tests.c +++ b/tests/common/util/utils_tests.c @@ -145,10 +145,10 @@ TEST(utils_tests, escape_string_ascii) { // message: // "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789 // !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~" - char utf_8_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz" - "\n0123456789 !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; + char utf_8_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\nabcdefghijklmnopqrstuvwx" + "yz\n0123456789\r !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; const char expected_string[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789 " + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\nabcdefghijklmnopqrstuvwxyz\n0123456789\r " "!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"; char actual_string[300] = ""; From 703b1f6893d89e3bd2386f7a147ab69a0e956122 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Sat, 6 Apr 2024 13:09:49 +0530 Subject: [PATCH 31/32] chore: Version bump v0.6.257 (patch++) --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 342052ae..c80da4e8 100755 --- a/version.txt +++ b/version.txt @@ -1,3 +1,3 @@ -firmware version=000:006:001:000 +firmware version=000:006:001:001 hardware version=000:001:000:000 magic number=45227A01 From fa54b4f1fbc4f8429d041fb081249ce9cd05e958 Mon Sep 17 00:00:00 2001 From: Ujjwal Kumar <31813384+Ujjwal0501@users.noreply.github.com> Date: Wed, 10 Apr 2024 13:55:51 +0530 Subject: [PATCH 32/32] fix (ci): Correct containerized build on branch --- .github/workflows/containerized-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/containerized-build.yml b/.github/workflows/containerized-build.yml index 86152c56..14d19dcc 100644 --- a/.github/workflows/containerized-build.yml +++ b/.github/workflows/containerized-build.yml @@ -19,9 +19,9 @@ jobs: - name: Build Firmware (${{ inputs.firmware }} - ${{ inputs.target }}) run: | if [[ "${{ github.ref_type }}" == "tag" ]]; then - export VERSION_TAG=$(echo "${{ github.ref }}" | awk -F/ '{print $3}') + export VERSION_TAG=$(echo "${{ github.ref }}" | cut -f 3- -d '/'') elif [[ "${{ github.ref_type }}" == "branch" ]]; then - export VERSION_TAG=$(echo "${{ github.ref }}" | awk -F/ '{print $3}') + export VERSION_TAG=$(echo "${{ github.ref }}" | cut -f 3- -d '/'') else # reftype is repository; use default branch export VERSION_TAG=main