diff --git a/.gitignore b/.gitignore
index f547702b5..c6a86b1cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,7 +61,7 @@ PVS-Studio.log
.gdbinit
-PATREONbuildRelease.sh
RM*-*.tgz
RM*-*.zip
-RM*-*-*/
\ No newline at end of file
+RM*-*-*/
+PATREONbuildRelease.sh
diff --git a/applications/plugins/nrf24scan/README.md b/applications/plugins/nrf24scan/README.md
index bc4838174..a93ec913e 100644
--- a/applications/plugins/nrf24scan/README.md
+++ b/applications/plugins/nrf24scan/README.md
@@ -16,7 +16,13 @@ ___________________________________________________________________________
В настройках задается минимальный размер нагрузки (payload)
После принятия, пакет сдвигается побитно и валидируется. Побитный сдвиг сильно увеличивает вероятность отлова пакета, но так же увеличивается количество мусорных пакетов.
Количество уникальных адресов запоминается (просмотр - стрелка вниз в режиме просмотра адресов)
-После поиска можно переключиться в режим сканирования по найденным адресам или сканировать адрес конкретного пакета - нажать ОК в режиме просмотра адресов
+После поиска можно переключиться в режим сканирования по найденным адресам или сканировать адрес конкретного пакета или группы адресов с различным LSB в адресе
+
+
+
+Адреса, которые попались дважды и более раз отображаются списком:
+
+
Изменение режима sniff/scan - стрелками на пункте Scan.
Режим сканирования (scan) - просто чтение пакетов по заданным в настройках мак адресам и виду пакета - ESB/DPL.
На начальном экране в режиме чтения можно загрузить файл настроек (по умолчанию загружается settings.txt из папки nrf24_scanner на SD карте).
diff --git a/applications/plugins/nrf24scan/Screenshot-6.png b/applications/plugins/nrf24scan/Screenshot-6.png
new file mode 100644
index 000000000..7c9ecfc34
Binary files /dev/null and b/applications/plugins/nrf24scan/Screenshot-6.png differ
diff --git a/applications/plugins/nrf24scan/Screenshot-7.png b/applications/plugins/nrf24scan/Screenshot-7.png
new file mode 100644
index 000000000..579a88e06
Binary files /dev/null and b/applications/plugins/nrf24scan/Screenshot-7.png differ
diff --git a/applications/plugins/nrf24scan/nrf24scan.c b/applications/plugins/nrf24scan/nrf24scan.c
index 9f9a17398..a206c1e9c 100644
--- a/applications/plugins/nrf24scan/nrf24scan.c
+++ b/applications/plugins/nrf24scan/nrf24scan.c
@@ -14,11 +14,11 @@
#include
#define TAG "nrf24scan"
-#define VERSION "2.0"
+#define VERSION "2.1"
#define MAX_CHANNEL 125
#define MAX_ADDR 6
-#define SCAN_APP_PATH_FOLDER "/ext/apps_data/nrf24scan"
+#define SCAN_APP_PATH_FOLDER "/ext/nrf24scan"
#define SETTINGS_FILENAME "addresses.txt" // Settings file format (1 parameter per line):
// SNIFF - if present then sniff mode
// Rate: 0/1/2 - rate in Mbps (=0.25/1/2)
@@ -41,7 +41,7 @@
#define LOG_FILENAME "log"
#define LOG_FILEEXT ".txt"
#define MAX_LOG_RECORDS 200
-#define MAX_FOUND_RECORDS 100
+#define MAX_FOUND_RECORDS 70
#define LOG_REC_SIZE 34 // max packet size
#define VIEW_LOG_MAX_X 22
#define VIEW_LOG_WIDTH_B 10 // bytes
@@ -87,7 +87,7 @@ struct ADDRS addrs;
struct ADDRS addrs_sniff;
bool sniff_loaded = 0;
int16_t found_total;
-int16_t view_found = -1;
+int16_t view_found;
int8_t log_to_file = 0; // 0 - no, 1 - yes(new), 2 - append, -1 - only clear
uint16_t log_arr_idx;
@@ -165,7 +165,7 @@ void clear_log() {
view_log_arr_idx = 0;
last_packet_send = -1;
found_total = 0;
- view_found = 0;
+ view_found = -1;
}
void write_to_log_file(Storage* storage, bool f_settings) {
@@ -455,6 +455,28 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
furi_message_queue_put(event_queue, &event, FuriWaitForever);
}
+void check_add_addr(uint8_t* pkt) {
+ if(addrs.addr_count > 0 && memcmp(addrs.addr_P0, pkt, addrs.addr_len) == 0) return;
+ if(addrs.addr_count > 1 && memcmp(addrs.addr_P1, pkt, addrs.addr_len - 1) == 0) {
+ if(addrs.addr_P1[addrs.addr_len - 1] == pkt[addrs.addr_len - 1]) return;
+ if(addrs.addr_count > 2 && addrs.addr_P2 == pkt[addrs.addr_len - 1]) return;
+ if(addrs.addr_count > 3 && addrs.addr_P3 == pkt[addrs.addr_len - 1]) return;
+ if(addrs.addr_count > 4 && addrs.addr_P4 == pkt[addrs.addr_len - 1]) return;
+ if(addrs.addr_count > 5 && addrs.addr_P5 == pkt[addrs.addr_len - 1]) return;
+ }
+ if(addrs.addr_count == 1)
+ memcpy(addrs.addr_P1, pkt, addrs.addr_len);
+ else if(addrs.addr_count == 2)
+ addrs.addr_P2 = pkt[addrs.addr_len - 1];
+ else if(addrs.addr_count == 3)
+ addrs.addr_P3 = pkt[addrs.addr_len - 1];
+ else if(addrs.addr_count == 4)
+ addrs.addr_P4 = pkt[addrs.addr_len - 1];
+ else if(addrs.addr_count == 5)
+ addrs.addr_P5 = pkt[addrs.addr_len - 1];
+ addrs.addr_count++;
+}
+
static void prepare_nrf24(bool fsend_packet) {
nrf24_write_reg(nrf24_HANDLE, REG_STATUS, 0x70); // clear interrupts
nrf24_write_reg(nrf24_HANDLE, REG_RF_SETUP, NRF_rate);
@@ -462,11 +484,32 @@ static void prepare_nrf24(bool fsend_packet) {
struct ADDRS* adr = what_to_do == 1 ? &addrs_sniff : &addrs;
if(!fsend_packet) {
uint8_t payload = NRF_Payload;
+ uint8_t* rec = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
+ uint8_t addr_size = (*(rec + 1) & 0b11) + 2;
+ bool setup_from_log = false;
+ if(what_to_do >= 2) {
+ if(log_arr_idx && (*rec & 0x80)) {
+ setup_from_log = true;
+ memcpy(addrs.addr_P0, rec + 2, addr_size);
+ addrs.addr_count = 1;
+ addrs.addr_len = addr_size;
+ payload = *(rec + 1) >> 3;
+ if(what_to_do == 2) {
+ uint8_t* p = APP->log_arr + 2;
+ int16_t i = 0;
+ for(i = 0; i < log_arr_idx; i++, p += LOG_REC_SIZE) {
+ if((*(p - 2) & 0x80) && (*(p - 1) & 0b11) + 2 == addr_size &&
+ rec + 2 != p) {
+ if(memcmp(p, addrs.addr_P0, addr_size - 1) == 0) {
+ check_add_addr(rec + 2);
+ if(addrs.addr_count >= 6) break;
+ }
+ }
+ }
+ }
+ }
+ }
if(what_to_do == 1) { // SNIFF
- if(adr->addr_count == 0) return;
- //payload += 5 + NRF_CRC; // + addr_max + CRC
- //if(NRF_ESB) payload += 2;
- //if(payload > 32) payload = 32;
payload = 32;
nrf24_write_reg(nrf24_HANDLE, REG_CONFIG, 0x70); // Mask all interrupts
nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
@@ -475,8 +518,28 @@ static void prepare_nrf24(bool fsend_packet) {
nrf24_HANDLE,
REG_FEATURE,
0); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
- } else if(what_to_do == 2) {
- if(adr->addr_count == 0) return;
+ } else if(setup_from_log) { // Scan
+ nrf24_write_reg(
+ nrf24_HANDLE,
+ REG_CONFIG,
+ 0x70 | ((NRF_CRC == 1 ? 0b1000 :
+ NRF_CRC == 2 ? 0b1100 :
+ 0))); // Mask all interrupts
+ nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *rec & 0x7F);
+ nrf24_write_reg(
+ nrf24_HANDLE,
+ REG_FEATURE,
+ *(rec + 2 + addr_size) >> 2 != 0x33 ?
+ 4 + 1 :
+ 1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
+ if(*(rec + 1) & 0b100) { // ESB
+ nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission
+ nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement
+ } else {
+ nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
+ nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement
+ }
+ } else {
nrf24_write_reg(
nrf24_HANDLE,
REG_CONFIG,
@@ -495,85 +558,55 @@ static void prepare_nrf24(bool fsend_packet) {
NRF_DPL ?
4 + 1 :
1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
- }
- if(what_to_do == 3) {
- uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
- uint8_t addr_size = (*(p + 1) & 0b11) + 2;
- nrf24_set_maclen(nrf24_HANDLE, addr_size);
- nrf24_set_mac(REG_RX_ADDR_P0, p + 2, addr_size);
- memcpy(addrs.addr_P0, p + 2, addr_size);
- addrs.addr_count = 1;
- addrs.addr_len = addr_size;
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, *(p + 1) >> 3);
- nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
- nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, *p & 0x7F);
- nrf24_write_reg(
- nrf24_HANDLE,
- REG_CONFIG,
- 0x70 | ((NRF_CRC == 1 ? 0b1000 :
- NRF_CRC == 2 ? 0b1100 :
- 0))); // Mask all interrupts
- if(*(p + 1) & 0b100) { // ESB
- nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0x01); // Automatic Retransmission
- nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0x3F); // Auto acknowledgement
- nrf24_write_reg(
- nrf24_HANDLE,
- REG_FEATURE,
- *(p + 2 + addr_size) >> 2 != 0x33 ?
- 4 + 1 :
- 1); // Enables the W_TX_PAYLOAD_NOACK command, Disable Payload with ACK, set Dynamic Payload
- } else {
- nrf24_write_reg(nrf24_HANDLE, REG_SETUP_RETR, 0); // Automatic Retransmission
- nrf24_write_reg(nrf24_HANDLE, REG_EN_AA, 0); // Auto acknowledgement
- }
- } else {
- nrf24_set_maclen(nrf24_HANDLE, adr->addr_len);
- nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len);
- uint8_t tmp[5] = {0};
- nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len);
- for(uint8_t i = 0; i < adr->addr_len / 2; i++) {
- uint8_t tb = tmp[i];
- tmp[i] = tmp[adr->addr_len - i - 1];
- tmp[adr->addr_len - i - 1] = tb;
- }
- NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0;
- FURI_LOG_D(TAG, "Payload: %d", payload);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
- if(adr->addr_count > 1) {
- nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload);
- erx_addr |= (1 << 1); // Enable RX_P1
- } else
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0);
- if(adr->addr_count > 2) {
- nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload);
- erx_addr |= (1 << 2); // Enable RX_P2
- } else
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0);
- if(adr->addr_count > 3) {
- nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload);
- erx_addr |= (1 << 3); // Enable RX_P3
- } else
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0);
- if(adr->addr_count > 4) {
- nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload);
- erx_addr |= (1 << 4); // Enable RX_P4
- } else
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0);
- if(adr->addr_count > 5) {
- nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1);
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload);
- erx_addr |= (1 << 5); // Enable RX_P5
- } else
- nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0);
nrf24_write_reg(
nrf24_HANDLE, REG_DYNPD, NRF_DPL ? 0x3F : 0); // Enable dynamic payload reg
- nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
nrf24_write_reg(nrf24_HANDLE, REG_RF_CH, NRF_channel);
}
+ if(adr->addr_count == 0) return;
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
+ nrf24_set_maclen(nrf24_HANDLE, adr->addr_len);
+ nrf24_set_mac(REG_RX_ADDR_P0, adr->addr_P0, adr->addr_len);
+ uint8_t tmp[5] = {0};
+ nrf24_read_reg(nrf24_HANDLE, REG_RX_ADDR_P0, tmp, adr->addr_len);
+ for(uint8_t i = 0; i < adr->addr_len / 2; i++) {
+ uint8_t tb = tmp[i];
+ tmp[i] = tmp[adr->addr_len - i - 1];
+ tmp[adr->addr_len - i - 1] = tb;
+ }
+ NRF_ERROR = memcmp(adr->addr_P0, tmp, adr->addr_len) != 0;
+ FURI_LOG_D(TAG, "Payload: %d", payload);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P0, payload);
+ if(adr->addr_count > 1) {
+ nrf24_set_mac(REG_RX_ADDR_P1, adr->addr_P1, adr->addr_len);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, payload);
+ erx_addr |= (1 << 1); // Enable RX_P1
+ } else
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P1, 0);
+ if(adr->addr_count > 2) {
+ nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P2, &adr->addr_P2, 1);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, payload);
+ erx_addr |= (1 << 2); // Enable RX_P2
+ } else
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P2, 0);
+ if(adr->addr_count > 3) {
+ nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P3, &adr->addr_P3, 1);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, payload);
+ erx_addr |= (1 << 3); // Enable RX_P3
+ } else
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P3, 0);
+ if(adr->addr_count > 4) {
+ nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P4, &adr->addr_P4, 1);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, payload);
+ erx_addr |= (1 << 4); // Enable RX_P4
+ } else
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P4, 0);
+ if(adr->addr_count > 5) {
+ nrf24_write_buf_reg(nrf24_HANDLE, REG_RX_ADDR_P5, &adr->addr_P5, 1);
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, payload);
+ erx_addr |= (1 << 5); // Enable RX_P5
+ } else
+ nrf24_write_reg(nrf24_HANDLE, RX_PW_P5, 0);
+ nrf24_write_reg(nrf24_HANDLE, REG_EN_RXADDR, erx_addr);
}
nrf24_flush_rx(nrf24_HANDLE);
nrf24_flush_tx(nrf24_HANDLE);
@@ -602,26 +635,6 @@ static void start_scanning() {
start_time = furi_get_tick();
}
-/*
-bool check_addr_found(uint8_t *pkt)
-{
- uint8_t idx = 255;
- if(addrs_found.addr_count > 0 && memcmp(addrs_found.addr_P0, pkt, addrs_found.addr_len) == 0) { idx = 0; goto x_end; }
- if(addrs_found.addr_count > 1 && memcmp(addrs_found.addr_P1, pkt, addrs_found.addr_len - 1) == 0) {
- if(addrs_found.addr_P1[addrs_found.addr_len - 1] == pkt[addrs_found.addr_len - 1]) { idx = 1; goto x_end; }
- if(addrs_found.addr_count > 2 && addrs_found.addr_P2 == pkt[addrs_found.addr_len - 1]) { idx = 2; goto x_end; }
- if(addrs_found.addr_count > 3 && addrs_found.addr_P3 == pkt[addrs_found.addr_len - 1]) { idx = 3; goto x_end; }
- if(addrs_found.addr_count > 4 && addrs_found.addr_P4 == pkt[addrs_found.addr_len - 1]) { idx = 4; goto x_end; }
- if(addrs_found.addr_count > 5 && addrs_found.addr_P5 == pkt[addrs_found.addr_len - 1]) { idx = 5; goto x_end; }
- }
-x_end:
- if(idx < sizeof(found_total) / sizeof(found_total[0])) {
- found_total[idx]++;
- return true;
- } else return false;
-}
-*/
-
// start bitnum = 7
uint32_t calc_crc(uint32_t crc, uint8_t* ptr, uint8_t bitnum, uint16_t bits) {
//uint8_t bitnum = 7;
@@ -775,55 +788,6 @@ bool check_packet(uint8_t* pkt, uint16_t size) {
found_total++;
}
}
- /*
- if(addrs_found.addr_count == 0) {
- memcpy(addrs_found.addr_P0, pkt, addr_size);
- addrs_found.addr_len = addr_size;
- found_total[0]++;
- addrs_found.addr_count++;
- } else if(addr_size == addrs_found.addr_len) {
- if(!check_addr_found(pkt)) {
- if(addrs_found.addr_count == 1) {
- memcpy(addrs_found.addr_P1, pkt, addr_size);
- found_total[1]++;
- addrs_found.addr_count++;
- } else if(addrs_found.addr_count == 2) {
- if(memcmp(addrs_found.addr_P1, pkt, addr_size - 1) == 0) {
- addrs_found.addr_P2 = pkt[addr_size - 1];
- found_total[2]++;
- addrs_found.addr_count++;
- } else if(memcmp(addrs_found.addr_P0, pkt, addr_size - 1) == 0) {
- uint8_t tmp[5];
- memcpy(tmp, addrs_found.addr_P1, addr_size); // swap P0-P1
- memcpy(addrs_found.addr_P1, addrs_found.addr_P0, addr_size);
- memcpy(addrs_found.addr_P0, tmp, addr_size);
- uint32_t n = found_total[0];
- found_total[0] = found_total[1];
- found_total[1] = n;
- addrs_found.addr_P2 = pkt[addr_size - 1];
- found_total[2]++;
- addrs_found.addr_count++;
- }
- } else if(addrs_found.addr_count >= 3) {
- if(memcmp(addrs_found.addr_P1, pkt, addr_size - 1) == 0) {
- if(addrs_found.addr_count == 3) {
- addrs_found.addr_P3 = pkt[addr_size - 1];
- found_total[3]++;
- addrs_found.addr_count++;
- } else if(addrs_found.addr_count == 4) {
- addrs_found.addr_P4 = pkt[addr_size - 1];
- found_total[4]++;
- addrs_found.addr_count++;
- } else if(addrs_found.addr_count == 5) {
- addrs_found.addr_P5 = pkt[addr_size - 1];
- found_total[5]++;
- addrs_found.addr_count++;
- }
- }
- }
- }
- }
-*/
}
return found;
@@ -1008,7 +972,7 @@ static void render_callback(Canvas* const canvas, void* ctx) {
canvas_draw_str(canvas, 10, 30, screen_buf);
if(what_to_do == 1)
snprintf(screen_buf, sizeof(screen_buf), "Min Payl: %d", NRF_Payload_sniff_min);
- else if(what_to_do == 3) {
+ else if(what_to_do >= 2) {
uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
snprintf(
screen_buf,
@@ -1045,11 +1009,11 @@ static void render_callback(Canvas* const canvas, void* ctx) {
if(what_to_do == 1)
snprintf(screen_buf, sizeof(screen_buf), "Start sniff");
else {
- uint8_t* p;
- if(what_to_do == 3 && log_arr_idx &&
- *(p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) & 0x80) { // +RAW
+ uint8_t* p = APP->log_arr + view_log_arr_idx * LOG_REC_SIZE;
+ if(log_arr_idx && (*p & 0x80)) { // +RAW
snprintf(screen_buf, sizeof(screen_buf), "Start read: ");
add_to_str_hex_bytes(screen_buf, (char*)p + 2, (*(p + 1) & 0b11) + 2);
+ if(what_to_do == 3) strcpy(screen_buf + strlen(screen_buf) - 2, "* ");
} else
snprintf(
screen_buf,
@@ -1585,7 +1549,7 @@ int32_t nrf24scan_app(void* p) {
case Menu_ok:
if(what_to_do) {
if((addrs.addr_count ||
- (what_to_do == 3 && log_arr_idx &&
+ (what_to_do >= 2 && log_arr_idx &&
*(APP->log_arr + view_log_arr_idx * LOG_REC_SIZE) &
0x80)) ||
what_to_do == 1) {
@@ -1667,4 +1631,4 @@ int32_t nrf24scan_app(void* p) {
if(APP->found) free(APP->found);
free(APP);
return 0;
-}
\ No newline at end of file
+}
diff --git a/applications/plugins/totp/cli/cli_helpers.h b/applications/plugins/totp/cli/cli_helpers.h
index 075822cd6..ae6fe6e0c 100644
--- a/applications/plugins/totp/cli/cli_helpers.h
+++ b/applications/plugins/totp/cli/cli_helpers.h
@@ -38,6 +38,9 @@
TOTP_CLI_PRINTF( \
"Invalid command arguments. use \"help\" command to get list of available commands")
+#define TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE() \
+ TOTP_CLI_PRINTF("An error has occurred during updating config file\r\n")
+
/**
* @brief Checks whether user is authenticated and entered correct PIN.
* If user is not authenticated it prompts user to enter correct PIN to authenticate.
diff --git a/applications/plugins/totp/cli/commands/add/add.c b/applications/plugins/totp/cli/commands/add/add.c
index 90cc0f420..e037546e2 100644
--- a/applications/plugins/totp/cli/commands/add/add.c
+++ b/applications/plugins/totp/cli/commands/add/add.c
@@ -206,11 +206,13 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
plugin_state->tokens_count++;
- totp_config_file_save_new_token(token_info);
+ if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
+ TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ }
if(load_generate_token_scene) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
-
- TOTP_CLI_PRINTF("Token \"%s\" has been successfully added\r\n", token_info->name);
}
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/commands/delete/delete.c b/applications/plugins/totp/cli/commands/delete/delete.c
index 7eddb96bd..046341693 100644
--- a/applications/plugins/totp/cli/commands/delete/delete.c
+++ b/applications/plugins/totp/cli/commands/delete/delete.c
@@ -93,14 +93,17 @@ void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args,
plugin_state->tokens_list = list_remove(plugin_state->tokens_list, list_node);
plugin_state->tokens_count--;
- totp_full_save_config_file(plugin_state);
+ if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
+ TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ }
+
+ token_info_free(token_info);
if(activate_generate_token_scene) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
-
- TOTP_CLI_PRINTF("Token \"%s\" has been successfully deleted\r\n", token_info->name);
- token_info_free(token_info);
} else {
TOTP_CLI_PRINTF("User not confirmed\r\n");
}
diff --git a/applications/plugins/totp/cli/commands/move/move.c b/applications/plugins/totp/cli/commands/move/move.c
index 95cb8dcac..9d47134e5 100644
--- a/applications/plugins/totp/cli/commands/move/move.c
+++ b/applications/plugins/totp/cli/commands/move/move.c
@@ -147,18 +147,18 @@ void totp_cli_command_move_handle(PluginState* plugin_state, FuriString* args, C
}
if(token_updated) {
- totp_full_save_config_file(plugin_state);
+ if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
+ TOTP_CLI_PRINTF("Token \"%s\" has been successfully updated\r\n", token_info->name);
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ }
+ } else {
+ TOTP_CLI_PRINT_INVALID_ARGUMENTS();
}
if(activate_generate_token_scene) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
- if(token_updated) {
- TOTP_CLI_PRINTF("Token \"%s\" has been successfully updated\r\n", token_info->name);
- } else {
- TOTP_CLI_PRINT_INVALID_ARGUMENTS();
- }
-
furi_string_free(temp_str);
}
\ No newline at end of file
diff --git a/applications/plugins/totp/cli/commands/notification/notification.c b/applications/plugins/totp/cli/commands/notification/notification.c
index 91dd44d4f..5b98a857b 100644
--- a/applications/plugins/totp/cli/commands/notification/notification.c
+++ b/applications/plugins/totp/cli/commands/notification/notification.c
@@ -86,15 +86,18 @@ void totp_cli_command_notification_handle(PluginState* plugin_state, FuriString*
}
plugin_state->notification_method = new_method;
- totp_config_file_update_notification_method(new_method);
+ if(totp_config_file_update_notification_method(new_method) ==
+ TotpConfigFileUpdateSuccess) {
+ TOTP_CLI_PRINTF("Notification method is set to ");
+ totp_cli_command_notification_print_method(new_method);
+ cli_nl();
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ }
if(previous_scene != TotpSceneNone) {
totp_scene_director_activate_scene(plugin_state, previous_scene, NULL);
}
-
- TOTP_CLI_PRINTF("Notification method is set to ");
- totp_cli_command_notification_print_method(new_method);
- cli_nl();
} else {
TOTP_CLI_PRINTF("Current notification method is ");
totp_cli_command_notification_print_method(plugin_state->notification_method);
diff --git a/applications/plugins/totp/cli/commands/pin/pin.c b/applications/plugins/totp/cli/commands/pin/pin.c
index 045976eef..198324e27 100644
--- a/applications/plugins/totp/cli/commands/pin/pin.c
+++ b/applications/plugins/totp/cli/commands/pin/pin.c
@@ -134,8 +134,14 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl
plugin_state->crypto_verify_data = NULL;
}
- totp_crypto_seed_iv(
- plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length);
+ if(!totp_crypto_seed_iv(
+ plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length)) {
+ memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ break;
+ }
+
+ memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
TokenInfo* token_info = node->data;
@@ -152,15 +158,18 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl
free(plain_token);
});
- totp_full_save_config_file(plugin_state);
-
TOTP_CLI_DELETE_LAST_LINE();
- if(do_change) {
- TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
- } else if(do_remove) {
- TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
+ if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
+ if(do_change) {
+ TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
+ } else if(do_remove) {
+ TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
+ }
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
}
+
} while(false);
if(load_generate_token_scene) {
diff --git a/applications/plugins/totp/cli/commands/timezone/timezone.c b/applications/plugins/totp/cli/commands/timezone/timezone.c
index 7a17c1ae2..537cf8a4a 100644
--- a/applications/plugins/totp/cli/commands/timezone/timezone.c
+++ b/applications/plugins/totp/cli/commands/timezone/timezone.c
@@ -33,8 +33,11 @@ void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* arg
float tz = strtof(furi_string_get_cstr(temp_str), NULL);
if(tz >= -12.75f && tz <= 12.75f) {
plugin_state->timezone_offset = tz;
- totp_config_file_update_timezone_offset(tz);
- TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
+ if(totp_config_file_update_timezone_offset(tz) == TotpConfigFileUpdateSuccess) {
+ TOTP_CLI_PRINTF("Timezone is set to %f\r\n", tz);
+ } else {
+ TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
+ }
if(plugin_state->current_scene == TotpSceneGenerateToken) {
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c
index b18edc5de..799db79b8 100644
--- a/applications/plugins/totp/services/config/config.c
+++ b/applications/plugins/totp/services/config/config.c
@@ -9,6 +9,8 @@
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/authenticator")
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
#define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup"
+#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
+#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
@@ -36,15 +38,38 @@ static void token_info_set_algo_from_str(TokenInfo* token_info, const FuriString
}
}
-Storage* totp_open_storage() {
+/**
+ * @brief Opens storage record
+ * @return Storage record
+ */
+static Storage* totp_open_storage() {
return furi_record_open(RECORD_STORAGE);
}
-void totp_close_storage() {
+/**
+ * @brief Closes storage record
+ */
+static void totp_close_storage() {
furi_record_close(RECORD_STORAGE);
}
-FlipperFormat* totp_open_config_file(Storage* storage) {
+/**
+ * @brief Closes config file
+ * @param file config file reference
+ */
+static void totp_close_config_file(FlipperFormat* file) {
+ if(file == NULL) return;
+ flipper_format_file_close(file);
+ flipper_format_free(file);
+}
+
+/**
+ * @brief Opens or creates TOTP application standard config file
+ * @param storage storage record to use
+ * @param[out] file opened config file
+ * @return Config file open result
+ */
+static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperFormat** file) {
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) {
@@ -52,7 +77,7 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
if(!flipper_format_file_open_existing(fff_data_file, CONFIG_FILE_PATH)) {
FURI_LOG_E(LOGGING_TAG, "Error opening existing file %s", CONFIG_FILE_PATH);
totp_close_config_file(fff_data_file);
- return NULL;
+ return TotpConfigFileOpenError;
}
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
@@ -63,15 +88,17 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
CONFIG_FILE_DIRECTORY_PATH);
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
- return NULL;
+ totp_close_config_file(fff_data_file);
+ return TotpConfigFileOpenError;
}
}
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
- return NULL;
+ totp_close_config_file(fff_data_file);
+ return TotpConfigFileOpenError;
}
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
- return totp_open_config_file(storage);
+ return totp_open_config_file(storage, file);
} else {
FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH);
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
@@ -81,14 +108,14 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
CONFIG_FILE_DIRECTORY_PATH);
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
- return NULL;
+ return TotpConfigFileOpenError;
}
}
if(!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) {
totp_close_config_file(fff_data_file);
FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH);
- return NULL;
+ return TotpConfigFileOpenError;
}
flipper_format_write_header_cstr(
@@ -153,228 +180,415 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
if(!flipper_format_rewind(fff_data_file)) {
totp_close_config_file(fff_data_file);
FURI_LOG_E(LOGGING_TAG, "Rewind error");
- return NULL;
+ return TotpConfigFileOpenError;
}
}
- return fff_data_file;
+ *file = fff_data_file;
+ return TotpConfigFileOpenSuccess;
}
-void totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
- flipper_format_seek_to_end(file);
- flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name);
- bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
- if(!token_is_valid) {
- flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!");
+TotpConfigFileUpdateResult
+ totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
+ TotpConfigFileUpdateResult update_result;
+ do {
+ if(!flipper_format_seek_to_end(file)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
+ if(!token_is_valid &&
+ !flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!")) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_hex(
+ file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!token_is_valid && !flipper_format_write_comment_cstr(file, "!!! WARNING END !!!")) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_string_cstr(
+ file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info))) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ uint32_t tmp_uint32 = token_info->digits;
+ if(!flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ return update_result;
+}
+
+TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info) {
+ Storage* cfg_storage = totp_open_storage();
+ FlipperFormat* file;
+ TotpConfigFileUpdateResult update_result;
+
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
+ do {
+ if(totp_config_file_save_new_token_i(file, token_info) !=
+ TotpConfigFileUpdateSuccess) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ totp_close_config_file(file);
+ } else {
+ update_result = TotpConfigFileUpdateError;
}
- flipper_format_write_hex(
- file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length);
- if(!token_is_valid) {
- flipper_format_write_comment_cstr(file, "!!! WARNING END !!!");
+
+ totp_close_storage();
+ return update_result;
+}
+
+TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_timezone_offset) {
+ Storage* cfg_storage = totp_open_storage();
+ FlipperFormat* file;
+ TotpConfigFileUpdateResult update_result;
+
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
+ do {
+ if(!flipper_format_insert_or_update_float(
+ file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ totp_close_config_file(file);
+ } else {
+ update_result = TotpConfigFileUpdateError;
}
- flipper_format_write_string_cstr(
- file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info));
- uint32_t tmp_uint32 = token_info->digits;
- flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1);
-}
-void totp_config_file_save_new_token(const TokenInfo* token_info) {
- Storage* cfg_storage = totp_open_storage();
- FlipperFormat* file = totp_open_config_file(cfg_storage);
-
- totp_config_file_save_new_token_i(file, token_info);
-
- totp_close_config_file(file);
totp_close_storage();
+ return update_result;
}
-void totp_config_file_update_timezone_offset(float new_timezone_offset) {
+TotpConfigFileUpdateResult
+ totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
Storage* cfg_storage = totp_open_storage();
- FlipperFormat* file = totp_open_config_file(cfg_storage);
+ FlipperFormat* file;
+ TotpConfigFileUpdateResult update_result;
- flipper_format_insert_or_update_float(file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1);
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
+ do {
+ uint32_t tmp_uint32 = new_notification_method;
+ if(!flipper_format_insert_or_update_uint32(
+ file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ totp_close_config_file(file);
+ } else {
+ update_result = TotpConfigFileUpdateError;
+ }
- totp_close_config_file(file);
totp_close_storage();
+ return update_result;
}
-void totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
+TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state) {
Storage* cfg_storage = totp_open_storage();
- FlipperFormat* file = totp_open_config_file(cfg_storage);
+ FlipperFormat* file;
+ TotpConfigFileUpdateResult update_result;
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
+ do {
+ if(!flipper_format_insert_or_update_float(
+ file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+ uint32_t tmp_uint32 = plugin_state->notification_method;
+ if(!flipper_format_insert_or_update_uint32(
+ file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
- uint32_t tmp_uint32 = new_notification_method;
- flipper_format_insert_or_update_uint32(
- file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ totp_close_config_file(file);
+ } else {
+ update_result = TotpConfigFileUpdateError;
+ }
- totp_close_config_file(file);
totp_close_storage();
+ return update_result;
}
-void totp_config_file_update_user_settings(const PluginState* plugin_state) {
- Storage* cfg_storage = totp_open_storage();
- FlipperFormat* file = totp_open_config_file(cfg_storage);
-
- flipper_format_insert_or_update_float(
- file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
- uint32_t tmp_uint32 = plugin_state->notification_method;
- flipper_format_insert_or_update_uint32(
- file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
-
- totp_close_config_file(file);
- totp_close_storage();
-}
-
-void totp_full_save_config_file(const PluginState* const plugin_state) {
+TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const plugin_state) {
Storage* storage = totp_open_storage();
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
+ TotpConfigFileUpdateResult result = TotpConfigFileUpdateSuccess;
- flipper_format_file_open_always(fff_data_file, CONFIG_FILE_PATH);
- flipper_format_write_header_cstr(
- fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION);
- flipper_format_write_hex(
- fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE);
- flipper_format_write_hex(
- fff_data_file,
- TOTP_CONFIG_KEY_CRYPTO_VERIFY,
- plugin_state->crypto_verify_data,
- plugin_state->crypto_verify_data_length);
- flipper_format_write_float(
- fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
- flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
- uint32_t tmp_uint32 = plugin_state->notification_method;
- flipper_format_write_uint32(
- fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
+ do {
+ if(!flipper_format_file_open_always(fff_data_file, CONFIG_FILE_TEMP_PATH)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
- TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
- const TokenInfo* token_info = node->data;
- totp_config_file_save_new_token_i(fff_data_file, token_info);
- });
+ if(!flipper_format_write_header_cstr(
+ fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_hex(
+ fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_hex(
+ fff_data_file,
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
+ plugin_state->crypto_verify_data,
+ plugin_state->crypto_verify_data_length)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_float(
+ fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_write_bool(
+ fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+ uint32_t tmp_uint32 = plugin_state->notification_method;
+ if(!flipper_format_write_uint32(
+ fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ bool tokens_written = true;
+ TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
+ const TokenInfo* token_info = node->data;
+ tokens_written = tokens_written &&
+ totp_config_file_save_new_token_i(fff_data_file, token_info) ==
+ TotpConfigFileUpdateSuccess;
+ });
+
+ if(!tokens_written) {
+ result = TotpConfigFileUpdateError;
+ break;
+ }
+ } while(false);
totp_close_config_file(fff_data_file);
+
+ if(result == TotpConfigFileUpdateSuccess) {
+ if(storage_file_exists(storage, CONFIG_FILE_ORIG_PATH)) {
+ storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH);
+ }
+
+ if(storage_common_rename(storage, CONFIG_FILE_PATH, CONFIG_FILE_ORIG_PATH) != FSE_OK) {
+ result = TotpConfigFileUpdateError;
+ } else if(storage_common_rename(storage, CONFIG_FILE_TEMP_PATH, CONFIG_FILE_PATH) != FSE_OK) {
+ result = TotpConfigFileUpdateError;
+ } else if(!storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH)) {
+ result = TotpConfigFileUpdateError;
+ }
+ }
+
totp_close_storage();
+ return result;
}
-void totp_config_file_load_base(PluginState* const plugin_state) {
+TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_state) {
Storage* storage = totp_open_storage();
- FlipperFormat* fff_data_file = totp_open_config_file(storage);
+ FlipperFormat* fff_data_file;
+
+ TotpConfigFileOpenResult result;
+ if((result = totp_open_config_file(storage, &fff_data_file)) != TotpConfigFileOpenSuccess) {
+ totp_close_storage();
+ return result;
+ }
plugin_state->timezone_offset = 0;
FuriString* temp_str = furi_string_alloc();
- uint32_t file_version;
- if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
- FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
- furi_string_free(temp_str);
- return;
- }
-
- if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
- FURI_LOG_I(
- LOGGING_TAG,
- "Obsolete config file version detected. Current version: %" PRIu32
- "; Actual version: %" PRId16,
- file_version,
- CONFIG_FILE_ACTUAL_VERSION);
- totp_close_config_file(fff_data_file);
-
- if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
- storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
+ do {
+ uint32_t file_version;
+ if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
+ FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
+ result = TotpConfigFileOpenError;
+ break;
}
- if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
- FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
- fff_data_file = totp_open_config_file(storage);
- FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
- flipper_format_file_open_existing(fff_backup_data_file, CONFIG_FILE_BACKUP_PATH);
+ if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
+ FURI_LOG_I(
+ LOGGING_TAG,
+ "Obsolete config file version detected. Current version: %" PRIu32
+ "; Actual version: %" PRId16,
+ file_version,
+ CONFIG_FILE_ACTUAL_VERSION);
+ totp_close_config_file(fff_data_file);
- if(file_version == 1) {
- if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
- FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
- } else {
- FURI_LOG_W(LOGGING_TAG, "An error occurred during migration from v1 to v2");
- }
+ if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
+ storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
}
- flipper_format_file_close(fff_backup_data_file);
- flipper_format_free(fff_backup_data_file);
- flipper_format_rewind(fff_data_file);
- } else {
- FURI_LOG_E(
- LOGGING_TAG,
- "An error occurred during taking backup of %s into %s before migration",
- CONFIG_FILE_PATH,
- CONFIG_FILE_BACKUP_PATH);
+ if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
+ FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
+ if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
+ result = TotpConfigFileOpenError;
+ break;
+ }
+
+ FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
+ if(!flipper_format_file_open_existing(
+ fff_backup_data_file, CONFIG_FILE_BACKUP_PATH)) {
+ flipper_format_file_close(fff_backup_data_file);
+ flipper_format_free(fff_backup_data_file);
+ result = TotpConfigFileOpenError;
+ break;
+ }
+
+ if(file_version == 1) {
+ if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
+ FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
+ } else {
+ FURI_LOG_W(
+ LOGGING_TAG, "An error occurred during migration from v1 to v2");
+ result = TotpConfigFileOpenError;
+ break;
+ }
+ }
+
+ flipper_format_file_close(fff_backup_data_file);
+ flipper_format_free(fff_backup_data_file);
+ flipper_format_rewind(fff_data_file);
+ } else {
+ FURI_LOG_E(
+ LOGGING_TAG,
+ "An error occurred during taking backup of %s into %s before migration",
+ CONFIG_FILE_PATH,
+ CONFIG_FILE_BACKUP_PATH);
+ result = TotpConfigFileOpenError;
+ break;
+ }
}
- }
- if(!flipper_format_read_hex(
- fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
- FURI_LOG_D(LOGGING_TAG, "Missing base IV");
- }
-
- flipper_format_rewind(fff_data_file);
-
- uint32_t crypto_size;
- if(flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
- crypto_size > 0) {
- plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
- furi_check(plugin_state->crypto_verify_data != NULL);
- plugin_state->crypto_verify_data_length = crypto_size;
if(!flipper_format_read_hex(
- fff_data_file,
- TOTP_CONFIG_KEY_CRYPTO_VERIFY,
- plugin_state->crypto_verify_data,
- crypto_size)) {
- FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
- free(plugin_state->crypto_verify_data);
+ fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
+ FURI_LOG_D(LOGGING_TAG, "Missing base IV");
+ }
+
+ if(!flipper_format_rewind(fff_data_file)) {
+ result = TotpConfigFileOpenError;
+ break;
+ }
+
+ uint32_t crypto_size;
+ if(flipper_format_get_value_count(
+ fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
+ crypto_size > 0) {
+ plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
+ furi_check(plugin_state->crypto_verify_data != NULL);
+ plugin_state->crypto_verify_data_length = crypto_size;
+ if(!flipper_format_read_hex(
+ fff_data_file,
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
+ plugin_state->crypto_verify_data,
+ crypto_size)) {
+ FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
+ free(plugin_state->crypto_verify_data);
+ plugin_state->crypto_verify_data = NULL;
+ plugin_state->crypto_verify_data_length = 0;
+ }
+ } else {
plugin_state->crypto_verify_data = NULL;
plugin_state->crypto_verify_data_length = 0;
}
- } else {
- plugin_state->crypto_verify_data = NULL;
- plugin_state->crypto_verify_data_length = 0;
- }
- flipper_format_rewind(fff_data_file);
+ if(!flipper_format_rewind(fff_data_file)) {
+ result = TotpConfigFileOpenError;
+ break;
+ }
- if(!flipper_format_read_float(
- fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
- plugin_state->timezone_offset = 0;
- FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
- }
+ if(!flipper_format_read_float(
+ fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
+ plugin_state->timezone_offset = 0;
+ FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
+ }
- flipper_format_rewind(fff_data_file);
+ if(!flipper_format_rewind(fff_data_file)) {
+ result = TotpConfigFileOpenError;
+ break;
+ }
- if(!flipper_format_read_bool(
- fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
- plugin_state->pin_set = true;
- }
+ if(!flipper_format_read_bool(
+ fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
+ plugin_state->pin_set = true;
+ }
- flipper_format_rewind(fff_data_file);
+ flipper_format_rewind(fff_data_file);
- uint32_t tmp_uint32;
- if(!flipper_format_read_uint32(
- fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
- tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
- }
+ uint32_t tmp_uint32;
+ if(!flipper_format_read_uint32(
+ fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
+ tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
+ }
- plugin_state->notification_method = tmp_uint32;
+ plugin_state->notification_method = tmp_uint32;
+ } while(false);
furi_string_free(temp_str);
totp_close_config_file(fff_data_file);
totp_close_storage();
+ return result;
}
TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) {
Storage* storage = totp_open_storage();
- FlipperFormat* fff_data_file = totp_open_config_file(storage);
+ FlipperFormat* fff_data_file;
+ if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
+ totp_close_storage();
+ return TokenLoadingResultError;
+ }
FuriString* temp_str = furi_string_alloc();
uint32_t temp_data32;
if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
+ totp_close_storage();
furi_string_free(temp_str);
return TokenLoadingResultError;
}
@@ -478,8 +692,42 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
return result;
}
-void totp_close_config_file(FlipperFormat* file) {
- if(file == NULL) return;
- flipper_format_file_close(file);
- flipper_format_free(file);
-}
+TotpConfigFileUpdateResult
+ totp_config_file_update_crypto_signatures(const PluginState* plugin_state) {
+ Storage* storage = totp_open_storage();
+ FlipperFormat* config_file;
+ TotpConfigFileUpdateResult update_result;
+ if(totp_open_config_file(storage, &config_file) == TotpConfigFileOpenSuccess) {
+ do {
+ if(!flipper_format_insert_or_update_hex(
+ config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_insert_or_update_hex(
+ config_file,
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
+ plugin_state->crypto_verify_data,
+ plugin_state->crypto_verify_data_length)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ if(!flipper_format_insert_or_update_bool(
+ config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
+ update_result = TotpConfigFileUpdateError;
+ break;
+ }
+
+ update_result = TotpConfigFileUpdateSuccess;
+ } while(false);
+
+ totp_close_config_file(config_file);
+ } else {
+ update_result = TotpConfigFileUpdateError;
+ }
+
+ totp_close_storage();
+ return update_result;
+}
\ No newline at end of file
diff --git a/applications/plugins/totp/services/config/config.h b/applications/plugins/totp/services/config/config.h
index 1eabe3365..bb48105f7 100644
--- a/applications/plugins/totp/services/config/config.h
+++ b/applications/plugins/totp/services/config/config.h
@@ -7,6 +7,8 @@
#include "constants.h"
typedef uint8_t TokenLoadingResult;
+typedef uint8_t TotpConfigFileOpenResult;
+typedef uint8_t TotpConfigFileUpdateResult;
/**
* @brief Token loading results
@@ -29,40 +31,48 @@ enum TokenLoadingResults {
};
/**
- * @brief Opens storage record
- * @return Storage record
+ * @brief Config file opening result
*/
-Storage* totp_open_storage();
+enum TotpConfigFileOpenResults {
+ /**
+ * @brief Config file opened successfully
+ */
+ TotpConfigFileOpenSuccess = 0,
+
+ /**
+ * @brief An error has occurred during opening config file
+ */
+ TotpConfigFileOpenError = 1
+};
/**
- * @brief Closes storage record
+ * @brief Config file updating result
*/
-void totp_close_storage();
+enum TotpConfigFileUpdateResults {
+ /**
+ * @brief Config file updated successfully
+ */
+ TotpConfigFileUpdateSuccess,
-/**
- * @brief Opens or creates TOTP application standard config file
- * @param storage storage record to use
- * @return Config file reference
- */
-FlipperFormat* totp_open_config_file(Storage* storage);
-
-/**
- * @brief Closes config file
- * @param file config file reference
- */
-void totp_close_config_file(FlipperFormat* file);
+ /**
+ * @brief An error has occurred during updating config file
+ */
+ TotpConfigFileUpdateError
+};
/**
* @brief Saves all the settings and tokens to an application config file
* @param plugin_state application state
+ * @return Config file update result
*/
-void totp_full_save_config_file(const PluginState* const plugin_state);
+TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const plugin_state);
/**
* @brief Loads basic information from an application config file into application state without loading all the tokens
* @param plugin_state application state
+ * @return Config file open result
*/
-void totp_config_file_load_base(PluginState* const plugin_state);
+TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_state);
/**
* @brief Loads tokens from an application config file into application state
@@ -74,23 +84,36 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
/**
* @brief Add new token to the end of the application config file
* @param token_info token information to be saved
+ * @return Config file update result
*/
-void totp_config_file_save_new_token(const TokenInfo* token_info);
+TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info);
/**
* @brief Updates timezone offset in an application config file
* @param new_timezone_offset new timezone offset to be set
+ * @return Config file update result
*/
-void totp_config_file_update_timezone_offset(float new_timezone_offset);
+TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_timezone_offset);
/**
* @brief Updates notification method in an application config file
* @param new_notification_method new notification method to be set
+ * @return Config file update result
*/
-void totp_config_file_update_notification_method(NotificationMethod new_notification_method);
+TotpConfigFileUpdateResult
+ totp_config_file_update_notification_method(NotificationMethod new_notification_method);
/**
* @brief Updates application user settings
* @param plugin_state application state
+ * @return Config file update result
*/
-void totp_config_file_update_user_settings(const PluginState* plugin_state);
\ No newline at end of file
+TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state);
+
+/**
+ * @brief Updates crypto signatures information
+ * @param plugin_state application state
+ * @return Config file update result
+ */
+TotpConfigFileUpdateResult
+ totp_config_file_update_crypto_signatures(const PluginState* plugin_state);
\ No newline at end of file
diff --git a/applications/plugins/totp/services/crypto/crypto.c b/applications/plugins/totp/services/crypto/crypto.c
index 794d0b0be..ed4775dfb 100644
--- a/applications/plugins/totp/services/crypto/crypto.c
+++ b/applications/plugins/totp/services/crypto/crypto.c
@@ -61,7 +61,7 @@ uint8_t* totp_crypto_decrypt(
return decrypted_data;
}
-void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length) {
+bool totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length) {
if(plugin_state->crypto_verify_data == NULL) {
FURI_LOG_D(LOGGING_TAG, "Generating new IV");
furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE);
@@ -94,13 +94,12 @@ void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t
}
}
+ bool result = true;
if(plugin_state->crypto_verify_data == NULL) {
FURI_LOG_D(LOGGING_TAG, "Generating crypto verify data");
plugin_state->crypto_verify_data = malloc(CRYPTO_VERIFY_KEY_LENGTH);
furi_check(plugin_state->crypto_verify_data != NULL);
plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH;
- Storage* storage = totp_open_storage();
- FlipperFormat* config_file = totp_open_config_file(storage);
plugin_state->crypto_verify_data = totp_crypto_encrypt(
(uint8_t*)CRYPTO_VERIFY_KEY,
@@ -108,19 +107,13 @@ void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t
&plugin_state->iv[0],
&plugin_state->crypto_verify_data_length);
- flipper_format_insert_or_update_hex(
- config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE);
- flipper_format_insert_or_update_hex(
- config_file,
- TOTP_CONFIG_KEY_CRYPTO_VERIFY,
- plugin_state->crypto_verify_data,
- CRYPTO_VERIFY_KEY_LENGTH);
plugin_state->pin_set = pin != NULL && pin_length > 0;
- flipper_format_insert_or_update_bool(
- config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
- totp_close_config_file(config_file);
- totp_close_storage();
+
+ result = totp_config_file_update_crypto_signatures(plugin_state) ==
+ TotpConfigFileUpdateSuccess;
}
+
+ return result;
}
bool totp_crypto_verify_key(const PluginState* plugin_state) {
diff --git a/applications/plugins/totp/services/crypto/crypto.h b/applications/plugins/totp/services/crypto/crypto.h
index d39fe013b..3442b9a6e 100644
--- a/applications/plugins/totp/services/crypto/crypto.h
+++ b/applications/plugins/totp/services/crypto/crypto.h
@@ -35,8 +35,9 @@ uint8_t* totp_crypto_decrypt(
* @param plugin_state application state
* @param pin user's PIN
* @param pin_length user's PIN length
+ * @return \c true on success; \c false otherwise
*/
-void totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length);
+bool totp_crypto_seed_iv(PluginState* plugin_state, const uint8_t* pin, uint8_t pin_length);
/**
* @brief Verifies whether cryptographic information (certificate + IV) is valid and can be used for encryption and decryption
diff --git a/applications/plugins/totp/services/hmac/memxor.c b/applications/plugins/totp/services/hmac/memxor.c
index 6824ea33b..ab6026aa3 100644
--- a/applications/plugins/totp/services/hmac/memxor.c
+++ b/applications/plugins/totp/services/hmac/memxor.c
@@ -18,8 +18,6 @@
/* Written by Simon Josefsson. The interface was inspired by memxor
in Niels Möller's Nettle. */
-/* #include */
-
#include "memxor.h"
void* memxor(void* /*restrict*/ dest, const void* /*restrict*/ src, size_t n) {
diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c
index 5a551c4f1..93acf8e4d 100644
--- a/applications/plugins/totp/totp_app.c
+++ b/applications/plugins/totp/totp_app.c
@@ -15,6 +15,7 @@
#include "types/common.h"
#include "ui/scene_director.h"
#include "ui/constants.h"
+#include "ui/common_dialogs.h"
#include "services/crypto/crypto.h"
#include "cli/cli.h"
@@ -36,17 +37,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu
furi_message_queue_put(event_queue, &event, FuriWaitForever);
}
-static bool totp_plugin_state_init(PluginState* const plugin_state) {
- plugin_state->gui = furi_record_open(RECORD_GUI);
- plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
- plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
-
- totp_config_file_load_base(plugin_state);
-
- totp_cli_register_command_handler(plugin_state);
-
- totp_scene_director_init_scenes(plugin_state);
-
+static bool totp_activate_initial_scene(PluginState* const plugin_state) {
if(plugin_state->crypto_verify_data == NULL) {
DialogMessage* message = dialog_message_alloc();
dialog_message_set_buttons(message, "No", NULL, "Yes");
@@ -63,13 +54,19 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
if(dialog_result == DialogMessageButtonRight) {
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
} else {
- totp_crypto_seed_iv(plugin_state, NULL, 0);
+ if(!totp_crypto_seed_iv(plugin_state, NULL, 0)) {
+ totp_dialogs_config_loading_error(plugin_state);
+ return false;
+ }
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
} else if(plugin_state->pin_set) {
totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication, NULL);
} else {
- totp_crypto_seed_iv(plugin_state, NULL, 0);
+ if(!totp_crypto_seed_iv(plugin_state, NULL, 0)) {
+ totp_dialogs_config_loading_error(plugin_state);
+ return false;
+ }
if(totp_crypto_verify_key(plugin_state)) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
} else {
@@ -94,13 +91,20 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
return true;
}
+static bool totp_plugin_state_init(PluginState* const plugin_state) {
+ plugin_state->gui = furi_record_open(RECORD_GUI);
+ plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
+ plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
+
+ if(totp_config_file_load_base(plugin_state) != TotpConfigFileOpenSuccess) {
+ totp_dialogs_config_loading_error(plugin_state);
+ return false;
+ }
+
+ return true;
+}
+
static void totp_plugin_state_free(PluginState* plugin_state) {
- totp_cli_unregister_command_handler();
-
- totp_scene_director_deactivate_active_scene(plugin_state);
-
- totp_scene_director_dispose(plugin_state);
-
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
furi_record_close(RECORD_DIALOGS);
@@ -139,6 +143,14 @@ int32_t totp_app() {
return 255;
}
+ totp_cli_register_command_handler(plugin_state);
+ totp_scene_director_init_scenes(plugin_state);
+ if(!totp_activate_initial_scene(plugin_state)) {
+ FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n");
+ totp_plugin_state_free(plugin_state);
+ return 253;
+ }
+
// Set system callbacks
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, render_callback, &state_mutex);
@@ -171,6 +183,10 @@ int32_t totp_app() {
release_mutex(&state_mutex, plugin_state_m);
}
+ totp_cli_unregister_command_handler();
+ totp_scene_director_deactivate_active_scene(plugin_state);
+ totp_scene_director_dispose(plugin_state);
+
view_port_enabled_set(view_port, false);
gui_remove_view_port(plugin_state->gui, view_port);
view_port_free(view_port);
diff --git a/applications/plugins/totp/ui/common_dialogs.c b/applications/plugins/totp/ui/common_dialogs.c
new file mode 100644
index 000000000..0a10389e1
--- /dev/null
+++ b/applications/plugins/totp/ui/common_dialogs.c
@@ -0,0 +1,20 @@
+#include "common_dialogs.h"
+#include "constants.h"
+
+static DialogMessageButton totp_dialogs_common(PluginState* plugin_state, const char* text) {
+ DialogMessage* message = dialog_message_alloc();
+ dialog_message_set_buttons(message, "Exit", NULL, NULL);
+ dialog_message_set_text(
+ message, text, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter);
+ DialogMessageButton result = dialog_message_show(plugin_state->dialogs_app, message);
+ dialog_message_free(message);
+ return result;
+}
+
+DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state) {
+ return totp_dialogs_common(plugin_state, "An error has occurred\nduring loading config file");
+}
+
+DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state) {
+ return totp_dialogs_common(plugin_state, "An error has occurred\nduring updating config file");
+}
\ No newline at end of file
diff --git a/applications/plugins/totp/ui/common_dialogs.h b/applications/plugins/totp/ui/common_dialogs.h
new file mode 100644
index 000000000..187d0e95c
--- /dev/null
+++ b/applications/plugins/totp/ui/common_dialogs.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include
+#include "../types/plugin_state.h"
+
+DialogMessageButton totp_dialogs_config_loading_error(PluginState* plugin_state);
+DialogMessageButton totp_dialogs_config_updating_error(PluginState* plugin_state);
\ No newline at end of file
diff --git a/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c
index e6351010e..592a12d0f 100644
--- a/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c
+++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c
@@ -7,6 +7,7 @@
#include "../../../lib/list/list.h"
#include "../../../services/config/config.h"
#include "../../ui_controls.h"
+#include "../../common_dialogs.h"
#include "../../../lib/roll_value/roll_value.h"
#include "../../../types/nullable.h"
#include "../generate_token/totp_scene_generate_token.h"
@@ -248,7 +249,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
plugin_state->tokens_count++;
- totp_config_file_save_new_token(tokenInfo);
+ if(totp_config_file_save_new_token(tokenInfo) != TotpConfigFileUpdateSuccess) {
+ token_info_free(tokenInfo);
+ totp_dialogs_config_updating_error(plugin_state);
+ return false;
+ }
GenerateTokenSceneContext generate_scene_context = {
.current_token_index = plugin_state->tokens_count - 1};
diff --git a/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
index e97c4fb29..5ff6b4cd7 100644
--- a/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
+++ b/applications/plugins/totp/ui/scenes/app_settings/totp_app_settings.c
@@ -2,6 +2,7 @@
#include
#include
#include "../../ui_controls.h"
+#include "../../common_dialogs.h"
#include "../../scene_director.h"
#include "../token_menu/totp_scene_token_menu.h"
#include "../../constants.h"
@@ -202,7 +203,12 @@ bool totp_scene_app_settings_handle_event(
NotificationMethodNone) |
(scene_state->notification_vibro ? NotificationMethodVibro :
NotificationMethodNone);
- totp_config_file_update_user_settings(plugin_state);
+
+ if(totp_config_file_update_user_settings(plugin_state) !=
+ TotpConfigFileUpdateSuccess) {
+ totp_dialogs_config_updating_error(plugin_state);
+ return false;
+ }
if(!scene_state->current_token_index.is_null) {
TokenMenuSceneContext generate_scene_context = {
diff --git a/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c
index 79930dff9..00349ddc4 100644
--- a/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c
+++ b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c
@@ -128,7 +128,7 @@ static void int_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount
str[len] = '\0';
}
-TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
+static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
switch(algo) {
case SHA1:
return TOTP_ALGO_SHA1;
@@ -143,7 +143,7 @@ TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
return NULL;
}
-void update_totp_params(PluginState* const plugin_state) {
+static void update_totp_params(PluginState* const plugin_state) {
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
if(scene_state->current_token_index < plugin_state->tokens_count) {
diff --git a/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c
index dc713f0a8..167762602 100644
--- a/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c
+++ b/applications/plugins/totp/ui/scenes/token_menu/totp_scene_token_menu.c
@@ -2,6 +2,7 @@
#include
#include
#include "../../ui_controls.h"
+#include "../../common_dialogs.h"
#include "../../constants.h"
#include "../../scene_director.h"
#include "../../../services/config/config.h"
@@ -156,7 +157,10 @@ bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginSt
furi_check(tokenInfo != NULL);
token_info_free(tokenInfo);
- totp_full_save_config_file(plugin_state);
+ if(totp_full_save_config_file(plugin_state) != TotpConfigFileUpdateSuccess) {
+ totp_dialogs_config_updating_error(plugin_state);
+ return false;
+ }
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
break;
diff --git a/assets/resources/apps_data/nrf24scan/sniff2.txt b/assets/resources/apps_data/nrf24scan/sniff2.txt
new file mode 100644
index 000000000..fa8c5ba9f
--- /dev/null
+++ b/assets/resources/apps_data/nrf24scan/sniff2.txt
@@ -0,0 +1,5 @@
+SNIFF
+ESB: 1
+CRC: 2
+P0: 00AA
+P1: 0055
diff --git a/assets/resources/apps_data/nrf24scan/sniff3.txt b/assets/resources/apps_data/nrf24scan/sniff3.txt
new file mode 100644
index 000000000..675852f2d
--- /dev/null
+++ b/assets/resources/apps_data/nrf24scan/sniff3.txt
@@ -0,0 +1,6 @@
+SNIFF
+ESB: 1
+CRC: 2
+P0: FFAA
+P1: 0055
+P2: AA