23const char *
TAG =
"ui";
308 reinterpret_cast<intptr_t
>(lv_event_get_user_data(e)));
361 CW_Utils::secure_wipe(
reinterpret_cast<uint8_t *
>(
s_pin),
sizeof(
s_pin));
388 CW_Utils::secure_wipe(
reinterpret_cast<uint8_t *
>(
s_admin_first),
436 CW_Utils::secure_wipe(
reinterpret_cast<uint8_t *
>(
s_wifi_pass),
528 tft.invertDisplay(
true);
533 tft.writecommand(0x26);
536 tft.writecommand(0x26);
541 tft.fillScreen(TFT_WHITE);
545 touch.setRotation(0);
573 const esp_timer_create_args_t targs = {
576 .dispatch_method = ESP_TIMER_TASK,
578 .skip_unhandled_events =
true,
580 esp_timer_handle_t th;
581 if (esp_timer_create(&targs, &th) == ESP_OK) {
585 ESP_LOGI(
TAG,
"UI initialized (LVGL %d.%d + TFT_eSPI/XPT2046)",
586 lv_version_major(), lv_version_minor());
591 if (esp_task_wdt_add(NULL) != ESP_OK) {
592 ESP_LOGE(
TAG,
"UI loop not on the task watchdog");
598 vTaskDelay(pdMS_TO_TICKS(5));
633 snprintf(c,
sizeof(c),
"Reverting in %d s",
634 (
int)((left + 999) / 1000));
653 snprintf(f,
sizeof(f),
"%u",
656 snprintf(f,
sizeof(f),
"%u",
697 s_ui_mx = xSemaphoreCreateRecursiveMutex();
703 xTaskCreate(
ui_task,
"ui", 16384, NULL, 4, NULL);
723 (fee != NULL) ? fee :
"");
724 if (dest_addr != NULL) {
735 if ((out == NULL) || (n == 0U)) {
return 0U; }
737 if (len > (n - 1U)) { len = n - 1U; }
738 (void)CW_Utils::safe_memcpy(
reinterpret_cast<uint8_t *
>(out), n,
739 reinterpret_cast<const uint8_t *
>(
s_pin), len);
742 CW_Utils::secure_wipe(
reinterpret_cast<uint8_t *
>(
s_pin),
sizeof(
s_pin));
798 if (detail != NULL) {
810 ((sub != NULL) && (sub[0] !=
'\0')) ? sub
811 :
"Let's configure your terminal.",
822 CW_Utils::secure_wipe(
reinterpret_cast<uint8_t *
>(
s_admin_first),
828 char *pass,
size_t pass_n) {
830 if ((ssid == NULL) || (pass == NULL) || (ssid_n == 0U) || (pass_n == 0U)) {
834 ssid[ssid_n - 1U] =
'\0';
836 pass[pass_n - 1U] =
'\0';
static const pos_asset_t * pos_asset_of(pos_chain_t chain)
The row describing chain.
static bool pos_chain_is_native_evm(pos_chain_t c)
true for ETH and POL: no contract, the amount goes in value, 21000 gas, 18 decimals....
static const pos_net_info_t * pos_net_info(pos_net_t net)
Names for net, or Ethereum's for a value out of range.
static const char *const TAG
static uint64_t amount_cents_cap(bool native)
Ceiling on what the keypad will accept, in cents.
bool ota_receiving(void)
Whether an upload is in flight, so a second can be refused.
bool ota_staged(char *version, size_t version_n, bool *older)
Fetch the version of an image that has been received and verified but not yet installed.
bool ota_commit(bool install)
Resolve a staged image.
void ui_refresh_addresses(void)
Implemented by main: repoint those two rows at the selected chain.
static net_wifi_ap_t s_aps[PROV_MAX_APS]
void prov_auth_resolve(bool grant)
Answer a pending authorisation request from the panel.
static uint16_t s_ap_count
bool prov_pending_commit(bool accept)
Resolve a pending proposal from the panel.
static ui_event_cb_t s_cb
prov_mode_t prov_mode(void)
Which mode is running, or PROV_MODE_OFF.
unsigned prov_window_left_min(void)
Minutes left before the portal closes itself, 0 once it has.
const char * settings_net_str(const char *testnet, const char *mainnet)
Pick the string belonging to the network the terminal is on.
pos_chain_t settings_get_chain(void)
Selected chain, or POS_CHAIN_ETH_USDC if never set.
uint32_t settings_get_priority_fee_gwei(void)
EIP-1559 max priority fee (tip) per gas, in Gwei.
uint8_t settings_get_brightness(void)
Backlight level in percent, or 80 if never set.
void settings_set_chain(pos_chain_t chain)
Persist the selected chain.
void settings_factory_reset(void)
Erase all stored settings (brightness, auto, Wi-Fi creds, fees).
uint8_t settings_admin_fail_count(void)
Consecutive failed unlock attempts, persisted.
bool settings_has_admin_code(void)
true once an admin code exists.
void settings_set_touch_cal(uint16_t x_min, uint16_t x_max, uint16_t y_min, uint16_t y_max)
Persist a calibration. Rejected (and ignored) if an axis is inverted or collapsed — a bad store here ...
uint32_t settings_get_max_fee_gwei(void)
EIP-1559 max fee per gas, in Gwei.
pos_chain_t
Which chain (and therefore which asset) the terminal charges in.
UiLock & operator=(const UiLock &)=delete
UiLock(const UiLock &)=delete
A scanned access point (subset of fields the UI needs).
Names for one network, in both deployments.
static bool s_welcome_sent
void ui_set_prov_note(const char *msg)
Put a failure line on the setup screen, in red under the step title.
static volatile bool s_screen_dirty
const char * asset_caption(pos_chain_t c)
static void open_admin_entry(void)
Open the admin panel's front door — the code screen, not the panel.
void ui_show_prov(int step)
Show the setup screen: QR code, AP name and passphrase.
void set_wifi_progress(const char *caption, const char *name)
void ui_show_confirm(uint64_t amount_units, const char *dest_addr, const char *fee)
Switch to the confirm screen.
void ui_show_prov_auth(void)
Demand the admin code so a browser can be authorised.
static uint32_t s_prov_stop_at
void ui_show_welcome(const char *sub)
Greet the operator at the start of first-run setup, or after an update.
void ui_set_boot_status(const char *step)
Set the one-line progress note on the splash screen.
uint32_t s_admin_lock_start
void ui_show_wifi_list(const net_wifi_ap_t *aps, uint16_t n, const char *note)
Show the scanned Wi-Fi networks for the user to pick from.
char s_admin_first[ADMIN_CODE_MAX+1]
void btn_event_cb(lv_event_t *e)
static volatile bool s_ota_modal_dirty
static volatile bool s_tx_info_dirty
void ui_show_card_pin(void)
Ask for the card PIN before reading an address off a Cryptnox card.
void request_screen(ui_screen_t s)
void ui_show_ota_confirm(void)
Raise the modal that asks the operator to accept a firmware image the update page has uploaded,...
volatile bool s_sheet_pending
uint64_t amount_cents_max(void)
lv_obj_t * s_cal_countdown
void ui_init(ui_event_cb_t cb)
Initialise display + touch and start the UI task.
size_t ui_take_wifi_creds(char *ssid, size_t ssid_n, char *pass, size_t pass_n)
Fetch the selected SSID + entered password and wipe the UI's copy.
lv_obj_t * s_amount_cents_label
void ui_set_addresses(const char *token_contract, const char *dest_addr)
Provide the token contract and destination addresses for the confirm screen and the settings "Tx" tab...
static volatile bool s_addr_modal_dirty
lv_obj_t * s_fee_prio_lbl
static void request_prov_stop(void)
void ui_fees_changed(void)
Note that the stored gas caps have changed, so the Tx tab can catch up.
void ui_show_tx_status(ui_tx_state_t state, const char *info)
Switch to the transaction-status screen.
void ui_stage_wifi_creds(const char *ssid, const char *pass)
Load credentials into the same handoff buffers the picker fills.
void ui_show_amount_entry(void)
Switch to the amount-entry screen (forces a value redraw).
void ui_show_prov_confirm(void)
Raise the modal that asks the operator to accept a value a browser proposed, reading the pending prop...
static SemaphoreHandle_t s_ui_mx
void ui_show_admin_set(void)
Run the first-run admin-code creation (enter, then confirm).
lv_obj_t * s_amount_label
static volatile bool s_fees_dirty
lv_obj_t * s_wifi_eye_lbl
static volatile bool s_boot_step_dirty
void ui_set_tx_info(const char *info)
Replace the transaction screen's info line without rebuilding it.
void ui_show_splash(void)
Switch to the splash screen.
lv_obj_t * s_boot_step_lbl
const char * asset_network(pos_chain_t c)
volatile ui_screen_t s_req_screen
uint64_t s_confirm_amount
const char * asset_name(pos_chain_t c)
static void ui_task(void *arg)
lv_obj_t * s_admin_eye_lbl
void ui_show_wifi_connecting(const char *ssid)
Show a "Connecting to <ssid>…" screen while main associates.
void ui_show_card_wait(const char *note)
"Hold your card to the reader" while the address is read.
const pos_asset_t * asset(pos_chain_t c)
static uint16_t s_cal_prev[4]
lv_obj_t * s_admin_note_lbl
void ui_show_boot_error(ui_boot_err_t kind, const char *detail)
Show a startup fault, naming the cause and what to do about it.
static ui_screen_t s_settings_return
size_t ui_take_pin(char *out, size_t n)
Copy the most recently entered PIN out and wipe the UI's copy.
void ui_clock_changed(void)
Note that the stored UTC offset has changed, so the clock can catch up.
lv_obj_t * s_wifi_pass_ta
ui_screen_t
Top-level screens of the payment flow.
@ UI_SCREEN_WIFI_CONNECTING
ui_tx_state_t
States shown on the transaction-status screen.
@ UI_EVENT_CONFIRM_CANCEL
@ UI_EVENT_AMOUNT_CONFIRMED
ui_boot_err_t
Startup faults shown on UI_SCREEN_BOOT_ERROR.
void(* ui_event_cb_t)(ui_event_t event, uint64_t payload)
Callback invoked from the UI task on user interaction.
void open_network_picker(void)
uint32_t admin_penalty_ms(uint8_t fails)
void settings_persist(void)
void touch_cal_poll(void)
void open_coin_picker(pos_net_t net)
void build_ota_confirm(void)
void open_reset_confirm(void)
void open_portal_window(void)
volatile bool s_swipe_admin
lv_indev_drv_t s_indev_drv
void touch_cal_load(void)
lv_disp_draw_buf_t s_draw_buf
void indev_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
lv_color_t s_buf[SCR_W *40]
void disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *px)
void backlight_init(uint8_t pct)
Private to the ui*.cpp files: the state and helpers they share.
#define LV_TICK_PERIOD_MS
XPT2046_Touchscreen touch
void code_field_reveal(lv_obj_t *ta, lv_obj_t *eye_lbl)
void render_requested_screen(void)
void build_prov_confirm(void)
void charge_set_busy(void)
#define ACT_CHAIN_OF(chain)
void theme_init(void)
Install the theme. After lv_disp_drv_register(), before any object.
static void wdt_feed(void)
Feed the task watchdog if, and only if, the calling task is subscribed.