1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 23:48:12 +00:00

rework layoutProgress functions

This commit is contained in:
Pavol Rusnak 2014-12-21 18:58:56 +01:00
parent 03a053c944
commit 2a2eba7de5
10 changed files with 73 additions and 39 deletions

View File

@ -320,7 +320,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
buttonUpdate(); buttonUpdate();
} while (!button.YesUp && !button.NoUp); } while (!button.YesUp && !button.NoUp);
if (button.YesUp) { if (button.YesUp) {
layoutProgress("INSTALLING ... Please wait", 0, 0); layoutProgress("INSTALLING ... Please wait", 0);
// backup metadata // backup metadata
memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN); memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN);
flash_unlock(); flash_unlock();
@ -392,7 +392,9 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
return; return;
} }
p = buf + 1; p = buf + 1;
layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len, flash_anim / 8); if (flash_anim % 8 == 4) {
layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len);
}
flash_anim++; flash_anim++;
flash_unlock(); flash_unlock();
while (p < buf + 64 && flash_pos < flash_len) { while (p < buf + 64 && flash_pos < flash_len) {
@ -440,7 +442,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
bool hash_check_ok = button.YesUp; bool hash_check_ok = button.YesUp;
layoutProgress("INSTALLING ... Please wait", 1000, 0); layoutProgress("INSTALLING ... Please wait", 1000);
uint8_t flags = *((uint8_t *)FLASH_META_FLAGS); uint8_t flags = *((uint8_t *)FLASH_META_FLAGS);
// check if to restore old storage area but only if signatures are ok // check if to restore old storage area but only if signatures are ok
if ((flags & 0x01) && signatures_ok()) { if ((flags & 0x01) && signatures_ok()) {

View File

@ -25,7 +25,7 @@
#include "aes.h" #include "aes.h"
#include "hmac.h" #include "hmac.h"
#include "bip32.h" #include "bip32.h"
#include "layout2.h" #include "layout.h"
uint32_t ser_length(uint32_t len, uint8_t *out) uint32_t ser_length(uint32_t len, uint8_t *out)
{ {
@ -261,11 +261,13 @@ uint8_t *cryptoHDNodePathToPubkey(const HDNodePathType *hdnodepath)
if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, &node) == 0) { if (hdnode_from_xpub(hdnodepath->node.depth, hdnodepath->node.fingerprint, hdnodepath->node.child_num, hdnodepath->node.chain_code.bytes, hdnodepath->node.public_key.bytes, &node) == 0) {
return 0; return 0;
} }
layoutProgressUpdate(true);
uint32_t i; uint32_t i;
for (i = 0; i < hdnodepath->address_n_count; i++) { for (i = 0; i < hdnodepath->address_n_count; i++) {
if (hdnode_public_ckd(&node, hdnodepath->address_n[i]) == 0) { if (hdnode_public_ckd(&node, hdnodepath->address_n[i]) == 0) {
return 0; return 0;
} }
layoutProgressUpdate(true);
} }
return node.public_key; return node.public_key;
} }
@ -317,5 +319,6 @@ int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig, uint8_t
sha256_Update(&ctx, ptr[i]->node.public_key.bytes, 33); sha256_Update(&ctx, ptr[i]->node.public_key.bytes, 33);
} }
sha256_Final(hash, &ctx); sha256_Final(hash, &ctx);
layoutProgressUpdate(true);
return 1; return 1;
} }

View File

@ -93,7 +93,7 @@ int fsm_deriveKey(HDNode *node, uint32_t *address_n, size_t address_n_count)
{ {
size_t i; size_t i;
if (address_n_count > 3) { if (address_n_count > 3) {
layoutProgressSwipe("Preparing keys", 0, 0); layoutProgressSwipe("Preparing keys", 0);
} }
for (i = 0; i < address_n_count; i++) { for (i = 0; i < address_n_count; i++) {
if (hdnode_private_ckd(node, address_n[i]) == 0) { if (hdnode_private_ckd(node, address_n[i]) == 0) {
@ -102,7 +102,7 @@ int fsm_deriveKey(HDNode *node, uint32_t *address_n, size_t address_n_count)
return 0; return 0;
} }
if (address_n_count > 3) { if (address_n_count > 3) {
layoutProgress("Preparing keys", 1000 * i / address_n_count, i); layoutProgress("Preparing keys", 1000 * i / address_n_count);
} }
} }
return 1; return 1;
@ -572,7 +572,7 @@ void fsm_msgSignMessage(SignMessage *msg)
} }
if (fsm_deriveKey(node, msg->address_n, msg->address_n_count) == 0) return; if (fsm_deriveKey(node, msg->address_n, msg->address_n_count) == 0) return;
layoutProgressSwipe("Signing", 0, 0); layoutProgressSwipe("Signing", 0);
if (cryptoMessageSign(msg->message.bytes, msg->message.size, node->private_key, resp->signature.bytes) == 0) { if (cryptoMessageSign(msg->message.bytes, msg->message.size, node->private_key, resp->signature.bytes) == 0) {
resp->has_address = true; resp->has_address = true;
uint8_t addr_raw[21]; uint8_t addr_raw[21];
@ -597,7 +597,7 @@ void fsm_msgVerifyMessage(VerifyMessage *msg)
fsm_sendFailure(FailureType_Failure_Other, "No message provided"); fsm_sendFailure(FailureType_Failure_Other, "No message provided");
return; return;
} }
layoutProgressSwipe("Verifying", 0, 0); layoutProgressSwipe("Verifying", 0);
uint8_t addr_raw[21]; uint8_t addr_raw[21];
if (!ecdsa_address_decode(msg->address, addr_raw)) { if (!ecdsa_address_decode(msg->address, addr_raw)) {
fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address"); fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address");
@ -656,7 +656,7 @@ void fsm_msgEncryptMessage(EncryptMessage *msg)
layoutHome(); layoutHome();
return; return;
} }
layoutProgressSwipe("Encrypting", 0, 0); layoutProgressSwipe("Encrypting", 0);
if (cryptoMessageEncrypt(&pubkey, msg->message.bytes, msg->message.size, display_only, resp->nonce.bytes, &(resp->nonce.size), resp->message.bytes, &(resp->message.size), resp->hmac.bytes, &(resp->hmac.size), signing ? node->private_key : 0, signing ? address_raw : 0) != 0) { if (cryptoMessageEncrypt(&pubkey, msg->message.bytes, msg->message.size, display_only, resp->nonce.bytes, &(resp->nonce.size), resp->message.bytes, &(resp->message.size), resp->hmac.bytes, &(resp->hmac.size), signing ? node->private_key : 0, signing ? address_raw : 0) != 0) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Error encrypting message"); fsm_sendFailure(FailureType_Failure_ActionCancelled, "Error encrypting message");
layoutHome(); layoutHome();
@ -696,7 +696,7 @@ void fsm_msgDecryptMessage(DecryptMessage *msg)
if (!node) return; if (!node) return;
if (fsm_deriveKey(node, msg->address_n, msg->address_n_count) == 0) return; if (fsm_deriveKey(node, msg->address_n, msg->address_n_count) == 0) return;
layoutProgressSwipe("Decrypting", 0, 0); layoutProgressSwipe("Decrypting", 0);
RESP_INIT(DecryptedMessage); RESP_INIT(DecryptedMessage);
bool display_only = false; bool display_only = false;
bool signing = false; bool signing = false;

View File

@ -37,7 +37,7 @@ void layoutDialogSwipe(LayoutDialogIcon icon, const char *btnNo, const char *btn
layoutDialog(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, line6); layoutDialog(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, line6);
} }
void layoutProgressSwipe(const char *desc, int permil, int gearstep) void layoutProgressSwipe(const char *desc, int permil)
{ {
if (layoutLast == layoutProgressSwipe) { if (layoutLast == layoutProgressSwipe) {
oledClear(); oledClear();
@ -45,7 +45,7 @@ void layoutProgressSwipe(const char *desc, int permil, int gearstep)
layoutLast = layoutProgressSwipe; layoutLast = layoutProgressSwipe;
oledSwipeLeft(); oledSwipeLeft();
} }
layoutProgress(desc, permil, gearstep); layoutProgress(desc, permil);
} }
void layoutHome(void) void layoutHome(void)

View File

@ -24,7 +24,7 @@
#include "types.pb.h" #include "types.pb.h"
void layoutDialogSwipe(LayoutDialogIcon icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); void layoutDialogSwipe(LayoutDialogIcon icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6);
void layoutProgressSwipe(const char *desc, int permil, int gearstep); void layoutProgressSwipe(const char *desc, int permil);
void layoutHome(void); void layoutHome(void);
void layoutConfirmOutput(const CoinType *coin, const TxOutputType *out); void layoutConfirmOutput(const CoinType *coin, const TxOutputType *out);

View File

@ -51,6 +51,8 @@ static uint64_t to_spend, spending, change_spend;
const uint32_t version = 1; const uint32_t version = 1;
const uint32_t lock_time = 0; const uint32_t lock_time = 0;
static uint32_t progress, progress_total; static uint32_t progress, progress_total;
static bool multisig_fp_set, multisig_fp_mismatch;
static uint8_t multisig_fp[32];
/* /*
Workflow of streamed signing Workflow of streamed signing
@ -96,6 +98,7 @@ foreach I:
void send_req_1_input(void) void send_req_1_input(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
idx2i = idx2o = idx3i = idx3o = 0; idx2i = idx2o = idx3i = idx3o = 0;
signing_stage = STAGE_REQUEST_1_INPUT; signing_stage = STAGE_REQUEST_1_INPUT;
resp.has_request_type = true; resp.has_request_type = true;
@ -108,6 +111,7 @@ void send_req_1_input(void)
void send_req_2_prev_meta(void) void send_req_2_prev_meta(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_2_PREV_META; signing_stage = STAGE_REQUEST_2_PREV_META;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXMETA; resp.request_type = RequestType_TXMETA;
@ -120,6 +124,7 @@ void send_req_2_prev_meta(void)
void send_req_2_prev_input(void) void send_req_2_prev_input(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_2_PREV_INPUT; signing_stage = STAGE_REQUEST_2_PREV_INPUT;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXINPUT; resp.request_type = RequestType_TXINPUT;
@ -134,6 +139,7 @@ void send_req_2_prev_input(void)
void send_req_2_prev_output(void) void send_req_2_prev_output(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_2_PREV_OUTPUT; signing_stage = STAGE_REQUEST_2_PREV_OUTPUT;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXOUTPUT; resp.request_type = RequestType_TXOUTPUT;
@ -148,6 +154,7 @@ void send_req_2_prev_output(void)
void send_req_3_input(void) void send_req_3_input(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_3_INPUT; signing_stage = STAGE_REQUEST_3_INPUT;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXINPUT; resp.request_type = RequestType_TXINPUT;
@ -159,6 +166,7 @@ void send_req_3_input(void)
void send_req_3_output(void) void send_req_3_output(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_3_OUTPUT; signing_stage = STAGE_REQUEST_3_OUTPUT;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXOUTPUT; resp.request_type = RequestType_TXOUTPUT;
@ -170,6 +178,7 @@ void send_req_3_output(void)
void send_req_4_output(void) void send_req_4_output(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
signing_stage = STAGE_REQUEST_4_OUTPUT; signing_stage = STAGE_REQUEST_4_OUTPUT;
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXOUTPUT; resp.request_type = RequestType_TXOUTPUT;
@ -181,6 +190,7 @@ void send_req_4_output(void)
void send_req_finished(void) void send_req_finished(void)
{ {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
resp.has_request_type = true; resp.has_request_type = true;
resp.request_type = RequestType_TXFINISHED; resp.request_type = RequestType_TXFINISHED;
msg_write(MessageType_MessageType_TxRequest, &resp); msg_write(MessageType_MessageType_TxRequest, &resp);
@ -202,10 +212,15 @@ void signing_init(uint32_t _inputs_count, uint32_t _outputs_count, const CoinTyp
signing = true; signing = true;
progress = 1; progress = 1;
progress_total = inputs_count * (1 + inputs_count + outputs_count) + outputs_count; progress_total = inputs_count * (1 + inputs_count + outputs_count) + outputs_count + 1;
multisig_fp_set = false;
multisig_fp_mismatch = false;
tx_init(&to, inputs_count, outputs_count, version, lock_time, false); tx_init(&to, inputs_count, outputs_count, version, lock_time, false);
layoutProgressSwipe("Signing transaction", 0);
send_req_1_input(); send_req_1_input();
} }
@ -217,18 +232,15 @@ void signing_txack(TransactionType *tx)
return; return;
} }
int co; layoutProgress("Signing transaction", 1000 * progress / progress_total);
static bool multisig_fp_set, multisig_fp_mismatch;
static uint8_t multisig_fp[32];
int co;
memset(&resp, 0, sizeof(TxRequest)); memset(&resp, 0, sizeof(TxRequest));
switch (signing_stage) { switch (signing_stage) {
case STAGE_REQUEST_1_INPUT: case STAGE_REQUEST_1_INPUT:
layoutProgress("Preparing", 1000 * progress / progress_total, progress); progress++; progress++;
memcpy(&input, tx->inputs, sizeof(TxInputType)); memcpy(&input, tx->inputs, sizeof(TxInputType));
multisig_fp_set = false;
multisig_fp_mismatch = false;
send_req_2_prev_meta(); send_req_2_prev_meta();
return; return;
case STAGE_REQUEST_2_PREV_META: case STAGE_REQUEST_2_PREV_META:
@ -275,7 +287,7 @@ void signing_txack(TransactionType *tx)
} }
return; return;
case STAGE_REQUEST_3_INPUT: case STAGE_REQUEST_3_INPUT:
layoutProgress("Preparing", 1000 * progress / progress_total, progress); progress++; progress++;
if (!tx_hash_input(&tc, tx->inputs)) { if (!tx_hash_input(&tc, tx->inputs)) {
fsm_sendFailure(FailureType_Failure_Other, "Failed to serialize input"); fsm_sendFailure(FailureType_Failure_Other, "Failed to serialize input");
signing_abort(); signing_abort();
@ -348,9 +360,9 @@ void signing_txack(TransactionType *tx)
} }
return; return;
case STAGE_REQUEST_3_OUTPUT: case STAGE_REQUEST_3_OUTPUT:
layoutProgress("Signing", 1000 * progress / progress_total, progress); progress++; progress++;
bool is_change = false;
if (idx1i == 0) { if (idx1i == 0) {
bool is_change = false;
if (tx->outputs[0].script_type == OutputScriptType_PAYTOMULTISIG && if (tx->outputs[0].script_type == OutputScriptType_PAYTOMULTISIG &&
tx->outputs[0].has_multisig && tx->outputs[0].has_multisig &&
multisig_fp_set && !multisig_fp_mismatch) { multisig_fp_set && !multisig_fp_mismatch) {
@ -378,9 +390,13 @@ void signing_txack(TransactionType *tx)
} }
} }
spending += tx->outputs[0].amount; spending += tx->outputs[0].amount;
co = compile_output(coin, root, tx->outputs, &bin_output, !is_change);
if (!is_change) {
layoutProgress("Signing transaction", 1000 * progress / progress_total);
}
} else {
co = compile_output(coin, root, tx->outputs, &bin_output, false);
} }
co = compile_output(coin, root, tx->outputs, &bin_output, idx1i == 0 && !is_change);
layoutProgress("Signing", 1000 * progress / progress_total, progress); progress++;
if (co < 0) { if (co < 0) {
fsm_sendFailure(FailureType_Failure_Other, "Signing cancelled by user"); fsm_sendFailure(FailureType_Failure_Other, "Signing cancelled by user");
signing_abort(); signing_abort();
@ -473,13 +489,12 @@ void signing_txack(TransactionType *tx)
signing_abort(); signing_abort();
return; return;
} }
layoutProgress("Signing", 1000 * progress / progress_total, progress); progress++;
send_req_4_output(); send_req_4_output();
} }
} }
return; return;
case STAGE_REQUEST_4_OUTPUT: case STAGE_REQUEST_4_OUTPUT:
layoutProgress("Signing", 1000 * progress / progress_total, progress); progress++; progress++;
if (compile_output(coin, root, tx->outputs, &bin_output, false) <= 0) { if (compile_output(coin, root, tx->outputs, &bin_output, false) <= 0) {
fsm_sendFailure(FailureType_Failure_Other, "Failed to compile output"); fsm_sendFailure(FailureType_Failure_Other, "Failed to compile output");
signing_abort(); signing_abort();

View File

@ -216,8 +216,7 @@ void storage_setPassphraseProtection(bool passphrase_protection)
void get_root_node_callback(uint32_t iter, uint32_t total) void get_root_node_callback(uint32_t iter, uint32_t total)
{ {
static uint8_t i; layoutProgress("Waking up", 1000 * iter / total);
layoutProgress("Waking up", 1000 * iter / total, i++);
} }
bool storage_getRootNode(HDNode *node) bool storage_getRootNode(HDNode *node)
@ -239,7 +238,7 @@ bool storage_getRootNode(HDNode *node)
if (storage.has_passphrase_protection && storage.passphrase_protection && strlen(sessionPassphrase)) { if (storage.has_passphrase_protection && storage.passphrase_protection && strlen(sessionPassphrase)) {
// decrypt hd node // decrypt hd node
uint8_t secret[64]; uint8_t secret[64];
layoutProgressSwipe("Waking up", 0, 0); layoutProgressSwipe("Waking up", 0);
pbkdf2_hmac_sha512((const uint8_t *)sessionPassphrase, strlen(sessionPassphrase), (uint8_t *)"TREZORHD", 8, BIP39_PBKDF2_ROUNDS, secret, 64, get_root_node_callback); pbkdf2_hmac_sha512((const uint8_t *)sessionPassphrase, strlen(sessionPassphrase), (uint8_t *)"TREZORHD", 8, BIP39_PBKDF2_ROUNDS, secret, 64, get_root_node_callback);
aes_decrypt_ctx ctx; aes_decrypt_ctx ctx;
aes_decrypt_key256(secret, &ctx); aes_decrypt_key256(secret, &ctx);
@ -257,7 +256,7 @@ bool storage_getRootNode(HDNode *node)
return false; return false;
} }
uint8_t seed[64]; uint8_t seed[64];
layoutProgressSwipe("Waking up", 0, 0); layoutProgressSwipe("Waking up", 0);
mnemonic_to_seed(storage.mnemonic, sessionPassphrase, seed, get_root_node_callback); // BIP-0039 mnemonic_to_seed(storage.mnemonic, sessionPassphrase, seed, get_root_node_callback); // BIP-0039
if (hdnode_from_seed(seed, sizeof(seed), &sessionRootNode) == 0) { if (hdnode_from_seed(seed, sizeof(seed), &sessionRootNode) == 0) {
return false; return false;

View File

@ -67,10 +67,12 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
HDNode node; HDNode node;
uint32_t k; uint32_t k;
memcpy(&node, root, sizeof(HDNode)); memcpy(&node, root, sizeof(HDNode));
layoutProgressUpdate(true);
for (k = 0; k < in->address_n_count; k++) { for (k = 0; k < in->address_n_count; k++) {
if (hdnode_private_ckd(&node, in->address_n[k]) == 0) { if (hdnode_private_ckd(&node, in->address_n[k]) == 0) {
return 0; return 0;
} }
layoutProgressUpdate(true);
} }
ecdsa_get_address_raw(node.public_key, coin->address_type, addr_raw); ecdsa_get_address_raw(node.public_key, coin->address_type, addr_raw);
} else } else
@ -201,17 +203,18 @@ uint32_t compile_script_multisig_hash(const MultisigRedeemScriptType *multisig,
SHA256_CTX ctx; SHA256_CTX ctx;
sha256_Init(&ctx); sha256_Init(&ctx);
uint8_t d; uint8_t d[2];
d = 0x50 + m; sha256_Update(&ctx, &d, 1); d[0] = 0x50 + m; sha256_Update(&ctx, d, 1);
uint32_t i; uint32_t i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
d = 33; sha256_Update(&ctx, &d, 1); // OP_PUSH 33 d[0] = 33; sha256_Update(&ctx, d, 1); // OP_PUSH 33
const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i])); const uint8_t *pubkey = cryptoHDNodePathToPubkey(&(multisig->pubkeys[i]));
if (!pubkey) return 0; if (!pubkey) return 0;
sha256_Update(&ctx, pubkey, 33); sha256_Update(&ctx, pubkey, 33);
} }
d = 0x50 + n; sha256_Update(&ctx, &d, 1); d[0] = 0x50 + n;
d = 0xAE; sha256_Update(&ctx, &d, 1); d[1] = 0xAE;
sha256_Update(&ctx, d, 2);
sha256_Final(hash, &ctx); sha256_Final(hash, &ctx);

View File

@ -79,11 +79,21 @@ void layoutDialog(LayoutDialogIcon icon, const char *btnNo, const char *btnYes,
oledRefresh(); oledRefresh();
} }
void layoutProgress(const char *desc, int permil, int gearstep) void layoutProgressUpdate(bool refresh)
{ {
static uint8_t step = 0;
const BITMAP *bmp_gears[4] = { &bmp_gears0, &bmp_gears1, &bmp_gears2, &bmp_gears3 }; const BITMAP *bmp_gears[4] = { &bmp_gears0, &bmp_gears1, &bmp_gears2, &bmp_gears3 };
oledDrawBitmap(40, 0, bmp_gears[step]);
step = (step + 1) % 4;
if (refresh) {
oledRefresh();
}
}
void layoutProgress(const char *desc, int permil)
{
oledClear(); oledClear();
oledDrawBitmap(40, 0, bmp_gears[gearstep % 4]); layoutProgressUpdate(false);
// progressbar // progressbar
oledFrame(0, OLED_HEIGHT - 8, OLED_WIDTH - 1, OLED_HEIGHT - 1); oledFrame(0, OLED_HEIGHT - 8, OLED_WIDTH - 1, OLED_HEIGHT - 1);
oledBox(1, OLED_HEIGHT - 7, OLED_WIDTH - 2, OLED_HEIGHT - 2, 0); oledBox(1, OLED_HEIGHT - 7, OLED_WIDTH - 2, OLED_HEIGHT - 2, 0);

View File

@ -21,6 +21,7 @@
#define __LAYOUT_H__ #define __LAYOUT_H__
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
typedef enum { typedef enum {
DIALOG_NOICON = 0, DIALOG_NOICON = 0,
@ -32,6 +33,7 @@ typedef enum {
} LayoutDialogIcon; } LayoutDialogIcon;
void layoutDialog(LayoutDialogIcon icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6); void layoutDialog(LayoutDialogIcon icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6);
void layoutProgress(const char *desc, int permil, int gearstep); void layoutProgressUpdate(bool refresh);
void layoutProgress(const char *desc, int permil);
#endif #endif