diff --git a/Makefile b/Makefile index e6eef26..9a1f818 100755 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ APPVERSION_M=1 APPVERSION_N=2 APPVERSION_P=0 APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) -APP_LOAD_FLAGS= --appFlags 0x40 --dep Ethereum:$(APPVERSION) +APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION) ifeq ($(CHAIN),) CHAIN=ethereum @@ -41,7 +41,7 @@ APP_LOAD_PARAMS += --path "44'/60'" DEFINES += CHAINID_UPCASE=\"ETHEREUM\" CHAINID_COINNAME=\"ETH\" CHAIN_KIND=CHAIN_KIND_ETHEREUM CHAIN_ID=0 APPNAME = "Ethereum" DEFINES_LIB= -APP_LOAD_FLAGS=--appFlags 0x840 +APP_LOAD_FLAGS=--appFlags 0xa40 else ifeq ($(CHAIN),ellaism) APP_LOAD_PARAMS += --path "44'/163'" DEFINES += CHAINID_UPCASE=\"ELLA\" CHAINID_COINNAME=\"ELLA\" CHAIN_KIND=CHAIN_KIND_ELLAISM CHAIN_ID=64 @@ -144,8 +144,12 @@ DEFINES += $(DEFINES_LIB) ifeq ($(TARGET_NAME),TARGET_BLUE) ICONNAME=blue_app_$(CHAIN).gif else +ifeq ($(TARGET_NAME), TARGET_NANOX) +ICONNAME=balenos_app_$(CHAIN).gif +else ICONNAME=nanos_app_$(CHAIN).gif endif +endif ################ # Default rule # @@ -177,6 +181,22 @@ DEFINES += APPVERSION=\"$(APPVERSION)\" DEFINES += CX_COMPLIANCE_141 +ifeq ($(TARGET_NAME),TARGET_NANOX) +DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 +DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE + +DEFINES += HAVE_GLO096 HAVE_UX_LEGACY +DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64 +DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature +DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX +DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX +DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX +endif + +ifneq ($(NOCONSENT),) +DEFINES += NO_CONSENT +endif + DEFINES += HAVE_TOKENS_LIST # Do not activate external ERC-20 support yet ############## @@ -213,6 +233,10 @@ include $(BOLOS_SDK)/Makefile.glyphs ### variables processed by the common makefile.rules of the SDK to grab source files and include dirs APP_SOURCE_PATH += src_common src SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f +ifeq ($(TARGET_NAME),TARGET_NANOX) +SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl +SDK_SOURCE_PATH += lib_ux +endif load: all python -m ledgerblue.loadApp $(APP_LOAD_PARAMS) diff --git a/balenos_app_akroma.gif b/balenos_app_akroma.gif new file mode 100644 index 0000000..491f505 Binary files /dev/null and b/balenos_app_akroma.gif differ diff --git a/balenos_app_atheios.gif b/balenos_app_atheios.gif new file mode 100644 index 0000000..d520d30 Binary files /dev/null and b/balenos_app_atheios.gif differ diff --git a/balenos_app_callisto.gif b/balenos_app_callisto.gif new file mode 100644 index 0000000..60e4f69 Binary files /dev/null and b/balenos_app_callisto.gif differ diff --git a/balenos_app_ellaism.gif b/balenos_app_ellaism.gif new file mode 100644 index 0000000..a53e796 Binary files /dev/null and b/balenos_app_ellaism.gif differ diff --git a/balenos_app_ether1.gif b/balenos_app_ether1.gif new file mode 100644 index 0000000..2f42c19 Binary files /dev/null and b/balenos_app_ether1.gif differ diff --git a/balenos_app_ethereum.gif b/balenos_app_ethereum.gif new file mode 100644 index 0000000..d70e8a7 Binary files /dev/null and b/balenos_app_ethereum.gif differ diff --git a/balenos_app_ethereum_classic.gif b/balenos_app_ethereum_classic.gif new file mode 100644 index 0000000..cfd24ca Binary files /dev/null and b/balenos_app_ethereum_classic.gif differ diff --git a/balenos_app_ethergem.gif b/balenos_app_ethergem.gif new file mode 100644 index 0000000..9950036 Binary files /dev/null and b/balenos_app_ethergem.gif differ diff --git a/balenos_app_ethersocial.gif b/balenos_app_ethersocial.gif new file mode 100644 index 0000000..60563d8 Binary files /dev/null and b/balenos_app_ethersocial.gif differ diff --git a/balenos_app_expanse.gif b/balenos_app_expanse.gif new file mode 100644 index 0000000..c19720d Binary files /dev/null and b/balenos_app_expanse.gif differ diff --git a/balenos_app_gochain.gif b/balenos_app_gochain.gif new file mode 100644 index 0000000..ff10036 Binary files /dev/null and b/balenos_app_gochain.gif differ diff --git a/balenos_app_hpb.gif b/balenos_app_hpb.gif new file mode 100644 index 0000000..cc57e1d Binary files /dev/null and b/balenos_app_hpb.gif differ diff --git a/balenos_app_kusd.gif b/balenos_app_kusd.gif new file mode 100644 index 0000000..6c8d03b Binary files /dev/null and b/balenos_app_kusd.gif differ diff --git a/balenos_app_mix.gif b/balenos_app_mix.gif new file mode 100644 index 0000000..73a2e61 Binary files /dev/null and b/balenos_app_mix.gif differ diff --git a/balenos_app_musicoin.gif b/balenos_app_musicoin.gif new file mode 100644 index 0000000..63650a1 Binary files /dev/null and b/balenos_app_musicoin.gif differ diff --git a/balenos_app_pirl.gif b/balenos_app_pirl.gif new file mode 100644 index 0000000..78b9d0d Binary files /dev/null and b/balenos_app_pirl.gif differ diff --git a/balenos_app_poa.gif b/balenos_app_poa.gif new file mode 100644 index 0000000..951bb49 Binary files /dev/null and b/balenos_app_poa.gif differ diff --git a/balenos_app_reosc.gif b/balenos_app_reosc.gif new file mode 100644 index 0000000..cdd6cee Binary files /dev/null and b/balenos_app_reosc.gif differ diff --git a/balenos_app_rsk.gif b/balenos_app_rsk.gif new file mode 100644 index 0000000..96803cf Binary files /dev/null and b/balenos_app_rsk.gif differ diff --git a/balenos_app_rsk_testnet.gif b/balenos_app_rsk_testnet.gif new file mode 100644 index 0000000..acffd9c Binary files /dev/null and b/balenos_app_rsk_testnet.gif differ diff --git a/balenos_app_ubiq.gif b/balenos_app_ubiq.gif new file mode 100644 index 0000000..d6f9825 Binary files /dev/null and b/balenos_app_ubiq.gif differ diff --git a/balenos_app_wanchain.gif b/balenos_app_wanchain.gif new file mode 100644 index 0000000..c6f2a30 Binary files /dev/null and b/balenos_app_wanchain.gif differ diff --git a/glyphs/icon_certificate.gif b/glyphs/icon_certificate.gif new file mode 100644 index 0000000..89b529f Binary files /dev/null and b/glyphs/icon_certificate.gif differ diff --git a/glyphs/icon_crossmark.gif b/glyphs/icon_crossmark.gif new file mode 100644 index 0000000..2dcf9d9 Binary files /dev/null and b/glyphs/icon_crossmark.gif differ diff --git a/glyphs/icon_down.gif b/glyphs/icon_down.gif new file mode 100644 index 0000000..4f4e39e Binary files /dev/null and b/glyphs/icon_down.gif differ diff --git a/glyphs/icon_eye.gif b/glyphs/icon_eye.gif new file mode 100644 index 0000000..df4bb82 Binary files /dev/null and b/glyphs/icon_eye.gif differ diff --git a/glyphs/icon_left.gif b/glyphs/icon_left.gif new file mode 100644 index 0000000..524226b Binary files /dev/null and b/glyphs/icon_left.gif differ diff --git a/glyphs/icon_right.gif b/glyphs/icon_right.gif new file mode 100644 index 0000000..15ff3cf Binary files /dev/null and b/glyphs/icon_right.gif differ diff --git a/glyphs/icon_up.gif b/glyphs/icon_up.gif new file mode 100644 index 0000000..4e13c06 Binary files /dev/null and b/glyphs/icon_up.gif differ diff --git a/glyphs/icon_validate_14.gif b/glyphs/icon_validate_14.gif new file mode 100644 index 0000000..ccb5cab Binary files /dev/null and b/glyphs/icon_validate_14.gif differ diff --git a/src/main.c b/src/main.c index 0ed1892..efc1faf 100644 --- a/src/main.c +++ b/src/main.c @@ -153,10 +153,18 @@ volatile bool currentTokenSet; bagl_element_t tmp_element; +#ifdef TARGET_NANOX +#include "ux.h" +ux_state_t G_ux; +bolos_ux_params_t G_ux_params; +#else // TARGET_NANOX ux_state_t ux; + // display stepped screens unsigned int ux_step; unsigned int ux_step_count; +#endif // TARGET_NANOX + typedef struct internalStorage_t { unsigned char dataAllowed; @@ -180,8 +188,8 @@ union { strDataTmp_t tmp; } strings; -internalStorage_t N_storage_real; -#define N_storage (*(internalStorage_t*) PIC(&N_storage_real)) +const internalStorage_t N_storage_real; +#define N_storage (*(volatile internalStorage_t*) PIC(&N_storage_real)) static const char const CONTRACT_ADDRESS[] = "New contract"; @@ -1048,12 +1056,367 @@ unsigned int ui_data_parameter_nanos_button(unsigned int button_mask, unsigned int button_mask_counter); #endif // #if defined(TARGET_NANOS) +#if defined(TARGET_NANOX) + +void display_settings(void); +void switch_settings_contract_data(void); +void switch_settings_display_data(void); + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB( + ux_idle_flow_1_step, + bnn, //pnn, + { + "", //&C_icon_dashboard, + "Application", + "is ready", + }); +UX_FLOW_DEF_NOCB( + ux_idle_flow_2_step, + bn, + { + "Version", + APPVERSION, + }); +UX_FLOW_DEF_VALID( + ux_idle_flow_3_step, + pb, + display_settings(), + { + &C_icon_eye, + "Settings", + }); +UX_FLOW_DEF_VALID( + ux_idle_flow_4_step, + pb, + os_sched_exit(-1), + { + &C_icon_dashboard, + "Quit", + }); +const ux_flow_step_t * const ux_idle_flow [] = { + &ux_idle_flow_1_step, + &ux_idle_flow_2_step, + &ux_idle_flow_3_step, + &ux_idle_flow_4_step, + FLOW_END_STEP, +}; + +UX_FLOW_DEF_VALID( + ux_settings_flow_1_step, + bnnn, + switch_settings_contract_data(), + { + "Contract data", + "Allow contract data", + "in transactions", + strings.common.fullAddress, + }); + +UX_FLOW_DEF_VALID( + ux_settings_flow_2_step, + bnnn, + switch_settings_display_data(), + { + "Display data", + "Display contract data", + "details", + strings.common.fullAddress + 20 + }); + +UX_FLOW_DEF_VALID( + ux_settings_flow_3_step, + pb, + ui_idle(), + { + &C_icon_back, + "Back", + }); + +const ux_flow_step_t * const ux_settings_flow [] = { + &ux_settings_flow_1_step, + &ux_settings_flow_2_step, + &ux_settings_flow_3_step, + FLOW_END_STEP, +}; + +void display_settings() { + strcpy(strings.common.fullAddress, (N_storage.dataAllowed ? "Allowed" : "NOT Allowed")); + strcpy(strings.common.fullAddress + 20, (N_storage.contractDetails ? "Displayed" : "NOT Displayed")); + ux_flow_init(0, ux_settings_flow, NULL); +} + +void switch_settings_contract_data() { + uint8_t value = (N_storage.dataAllowed ? 0 : 1); + nvm_write(&N_storage.dataAllowed, (void*)&value, sizeof(uint8_t)); + display_settings(); +} + +void switch_settings_display_data() { + uint8_t value = (N_storage.contractDetails ? 0 : 1); + nvm_write(&N_storage.contractDetails, (void*)&value, sizeof(uint8_t)); + display_settings(); +} + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB( + ux_display_public_flow_1_step, + pnn, + { + &C_icon_eye, + "Verify", + "address", + }); +UX_FLOW_DEF_NOCB( + ux_display_public_flow_2_step, + bnnn_paging, + { + .title = "Address", + .text = strings.common.fullAddress, + }); +UX_FLOW_DEF_VALID( + ux_display_public_flow_3_step, + pb, + io_seproxyhal_touch_address_ok(NULL), + { + &C_icon_validate_14, + "Approve", + }); +UX_FLOW_DEF_VALID( + ux_display_public_flow_4_step, + pb, + io_seproxyhal_touch_address_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +const ux_flow_step_t * const ux_display_public_flow [] = { + &ux_display_public_flow_1_step, + &ux_display_public_flow_2_step, + &ux_display_public_flow_3_step, + &ux_display_public_flow_4_step, + FLOW_END_STEP, +}; + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB( + ux_confirm_selector_flow_1_step, + pnn, + { + &C_icon_eye, + "Verify", + "selector", + }); + +UX_FLOW_DEF_NOCB( + ux_confirm_selector_flow_2_step, + bn, + { + "Selector", + strings.tmp.tmp + }); +UX_FLOW_DEF_VALID( + ux_confirm_selector_flow_3_step, + pb, + io_seproxyhal_touch_data_ok(NULL), + { + &C_icon_validate_14, + "Approve", + }); +UX_FLOW_DEF_VALID( + ux_confirm_selector_flow_4_step, + pb, + io_seproxyhal_touch_data_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +const ux_flow_step_t * const ux_confirm_selector_flow [] = { + &ux_confirm_selector_flow_1_step, + &ux_confirm_selector_flow_2_step, + &ux_confirm_selector_flow_3_step, + &ux_confirm_selector_flow_4_step, + FLOW_END_STEP, +}; + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB( + ux_confirm_parameter_flow_1_step, + pnn, + { + &C_icon_eye, + "Verify", + strings.tmp.tmp2 + }); +UX_FLOW_DEF_NOCB( + ux_confirm_parameter_flow_2_step, + bnnn_paging, + { + .title = "Parameter", + .text = strings.tmp.tmp, + }); +UX_FLOW_DEF_VALID( + ux_confirm_parameter_flow_3_step, + pb, + io_seproxyhal_touch_data_ok(NULL), + { + &C_icon_validate_14, + "Approve", + }); +UX_FLOW_DEF_VALID( + ux_confirm_parameter_flow_4_step, + pb, + io_seproxyhal_touch_data_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +const ux_flow_step_t * const ux_confirm_parameter_flow [] = { + &ux_confirm_parameter_flow_1_step, + &ux_confirm_parameter_flow_2_step, + &ux_confirm_parameter_flow_3_step, + &ux_confirm_parameter_flow_4_step, + FLOW_END_STEP, +}; + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB(ux_approval_tx_1_step, + pnn, + { + &C_icon_eye, + "Review", + "transaction", + }); +UX_FLOW_DEF_NOCB( + ux_approval_tx_2_step, + bnnn_paging, + { + .title = "Amount", + .text = strings.common.fullAmount + }); +UX_FLOW_DEF_NOCB( + ux_approval_tx_3_step, + bnnn_paging, + { + .title = "Address", + .text = strings.common.fullAddress, + }); +UX_FLOW_DEF_NOCB( + ux_approval_tx_4_step, + bnnn_paging, + { + .title = "Max Fees", + .text = strings.common.maxFee, + }); +UX_FLOW_DEF_VALID( + ux_approval_tx_5_step, + pbb, + io_seproxyhal_touch_tx_ok(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_FLOW_DEF_VALID( + ux_approval_tx_6_step, + pb, + io_seproxyhal_touch_tx_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW_DEF_NOCB(ux_approval_tx_data_warning_step, + pbb, + { + &C_icon_warning, + "Data", + "Present", + }); + + +const ux_flow_step_t * const ux_approval_tx_flow [] = { + &ux_approval_tx_1_step, + &ux_approval_tx_2_step, + &ux_approval_tx_3_step, + &ux_approval_tx_4_step, + &ux_approval_tx_5_step, + &ux_approval_tx_6_step, + FLOW_END_STEP, +}; + +const ux_flow_step_t * const ux_approval_tx_data_warning_flow [] = { + &ux_approval_tx_1_step, + &ux_approval_tx_data_warning_step, + &ux_approval_tx_2_step, + &ux_approval_tx_3_step, + &ux_approval_tx_4_step, + &ux_approval_tx_5_step, + &ux_approval_tx_6_step, + FLOW_END_STEP, +}; + +////////////////////////////////////////////////////////////////////// +UX_FLOW_DEF_NOCB( + ux_sign_flow_1_step, + pnn, + { + &C_icon_certificate, + "Sign", + "message", + }); +UX_FLOW_DEF_NOCB( + ux_sign_flow_2_step, + bnnn_paging, + { + .title = "Message hash", + .text = strings.common.fullAddress, + }); +UX_FLOW_DEF_VALID( + ux_sign_flow_3_step, + pbb, + io_seproxyhal_touch_signMessage_ok(NULL), + { + &C_icon_validate_14, + "Sign", + "message", + }); +UX_FLOW_DEF_VALID( + ux_sign_flow_4_step, + pbb, + io_seproxyhal_touch_signMessage_cancel(NULL), + { + &C_icon_crossmark, + "Cancel", + "signature", + }); + +const ux_flow_step_t * const ux_sign_flow [] = { + &ux_sign_flow_1_step, + &ux_sign_flow_2_step, + &ux_sign_flow_3_step, + &ux_sign_flow_4_step, + FLOW_END_STEP, +}; + + +#endif // #if defined(TARGET_NANOX) + void ui_idle(void) { #if defined(TARGET_BLUE) UX_DISPLAY(ui_idle_blue, ui_idle_blue_prepro); #elif defined(TARGET_NANOS) UX_MENU_DISPLAY(0, menu_main, NULL); +#elif defined(TARGET_NANOX) + // reserve a display stack slot if none yet + if(G_ux.stack_count == 0) { + ux_stack_push(); + } + ux_flow_init(0, ux_idle_flow, NULL); #endif // #if TARGET_ID } @@ -1663,6 +2026,8 @@ customStatus_e customProcessor(txContext_t *context) { ux_step = 0; ux_step_count = 2; UX_DISPLAY(ui_data_selector_nanos, ui_data_selector_prepro); +#elif defined(TARGET_NANOX) + ux_flow_init(0, ux_confirm_selector_flow, NULL); #endif // #if TARGET_ID } else { @@ -1681,6 +2046,8 @@ customStatus_e customProcessor(txContext_t *context) { ux_step = 0; ux_step_count = 2; UX_DISPLAY(ui_data_parameter_nanos, ui_data_parameter_prepro); +#elif defined(TARGET_NANOX) + ux_flow_init(0, ux_confirm_parameter_flow, NULL); #endif // #if TARGET_ID } } @@ -1725,10 +2092,14 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da os_memset(&privateKey, 0, sizeof(privateKey)); os_memset(privateKeyData, 0, sizeof(privateKeyData)); getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, tmpCtx.publicKeyContext.address, &sha3); - if (p1 == P1_NON_CONFIRM) { +#ifndef NO_CONSENT + if (p1 == P1_NON_CONFIRM) +#endif // NO_CONSENT + { *tx = set_result_get_publicKey(); THROW(0x9000); } +#ifndef NO_CONSENT else { /* @@ -1749,10 +2120,14 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da ux_step = 0; ux_step_count = 2; UX_DISPLAY(ui_address_nanos, ui_address_prepro); +#elif defined(TARGET_NANOX) + snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "0x%.*s", 40, tmpCtx.publicKeyContext.address); + ux_flow_init(0, ux_display_public_flow, NULL); #endif // #if TARGET_ID *flags |= IO_ASYNCH_REPLY; } +#endif // NO_CONSENT } void finalizeParsing(bool direct) { @@ -1871,13 +2246,21 @@ void finalizeParsing(bool direct) { } strings.common.maxFee[tickerOffset + i] = '\0'; +#ifdef NO_CONSENT + io_seproxyhal_touch_tx_ok(NULL); +#else // NO_CONSENT #if defined(TARGET_BLUE) ui_approval_transaction_blue_init(); #elif defined(TARGET_NANOS) ux_step = 0; ux_step_count = 5; UX_DISPLAY(ui_approval_nanos, ui_approval_prepro); +#elif defined(TARGET_NANOX) + ux_flow_init(0, + ((dataPresent && !N_storage.contractDetails) ? ux_approval_tx_data_warning_flow : ux_approval_tx_flow), + NULL); #endif // #if TARGET_ID +#endif // NO_CONSENT } void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint16_t dataLength, volatile unsigned int *flags, volatile unsigned int *tx) { @@ -2060,6 +2443,9 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint strings.common.fullAddress[HASH_LENGTH / 2 * 2 + 2] = '.'; array_hexstr(strings.common.fullAddress + HASH_LENGTH / 2 * 2 + 3, hashMessage + 32 - HASH_LENGTH / 2, HASH_LENGTH / 2); +#ifdef NO_CONSENT + io_seproxyhal_touch_signMessage_ok(NULL); +#else NO_CONSENT #if defined(TARGET_BLUE) ui_approval_message_sign_blue_init(); #elif defined(TARGET_NANOS) @@ -2067,7 +2453,10 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint ux_step_count = 2; UX_DISPLAY(ui_approval_signMessage_nanos, ui_approval_signMessage_prepro); +#elif defined(TARGET_NANOX) + ux_flow_init(0, ux_sign_flow, NULL); #endif // #if TARGET_ID +#endif // NO_CONSENT *flags |= IO_ASYNCH_REPLY; @@ -2251,6 +2640,7 @@ unsigned char io_event(unsigned char channel) { case SEPROXYHAL_TAG_TICKER_EVENT: UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, { + #ifndef TARGET_NANOX if (UX_ALLOWED) { if (ux_step_count) { // prepare next screen @@ -2259,6 +2649,7 @@ unsigned char io_event(unsigned char channel) { UX_REDISPLAY(); } } + #endif // TARGET_NANOX }); break; } @@ -2350,6 +2741,11 @@ __attribute__((section(".boot"))) int main(int arg0) { TRY { io_seproxyhal_init(); +#ifdef TARGET_NANOX + // grab the current plane mode setting + G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); +#endif // TARGET_NANOX + if (N_storage.initialized != 0x01) { internalStorage_t storage; storage.dataAllowed = 0x00; @@ -2360,10 +2756,15 @@ __attribute__((section(".boot"))) int main(int arg0) { dataAllowed = N_storage.dataAllowed; contractDetails = N_storage.contractDetails; + ui_idle(); + USB_power(0); USB_power(1); - ui_idle(); +#ifdef HAVE_BLE + BLE_power(0, NULL); + BLE_power(1, "Nano X"); +#endif // HAVE_BLE #if defined(TARGET_BLUE) // setup the status bar colors (remembered after wards, even more if another app does not resetup after app switch)