Merge pull request #63 from augustozanellato/factory_reset

Add factory reset command
This commit is contained in:
Philippe Teuwen
2023-08-19 00:46:39 +02:00
committed by GitHub
10 changed files with 131 additions and 13 deletions
+1
View File
@@ -31,6 +31,7 @@ SRC_FILES += \
$(PROJ_DIR)/rfid/nfctag/hf/nfc_ntag.c \
$(PROJ_DIR)/rfid/nfctag/lf/lf_tag_em.c \
$(PROJ_DIR)/utils/dataframe.c \
$(PROJ_DIR)/utils/delayed_reset.c \
$(PROJ_DIR)/utils/fds_util.c \
$(PROJ_DIR)/utils/syssleep.c \
$(PROJ_DIR)/utils/timeslot.c \
+9
View File
@@ -13,6 +13,7 @@
#include "tag_persistence.h"
#include "nrf_pwr_mgmt.h"
#include "settings.h"
#include "delayed_reset.h"
#define NRF_LOG_MODULE_NAME app_cmd
@@ -357,6 +358,13 @@ data_frame_tx_t* cmd_processor_get_slot_info(uint16_t cmd, uint16_t status, uint
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 16, slot_info);
}
data_frame_tx_t* cmd_processor_wipe_fds(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
bool success = fds_wipe();
status = success ? STATUS_DEVICE_SUCCESS : STATUS_FLASH_WRITE_FAIL;
delayed_reset(50);
return data_frame_make(cmd, status, 0, NULL);
}
data_frame_tx_t* cmd_processor_set_em410x_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length == LF_EM410X_TAG_ID_SIZE) {
tag_data_buffer_t* buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
@@ -605,6 +613,7 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_SLOT_DATA_CONFIG_SAVE, NULL, cmd_processor_slot_data_config_save, NULL },
{ DATA_CMD_GET_ACTIVE_SLOT, NULL, cmd_processor_get_activated_slot, NULL },
{ DATA_CMD_GET_SLOT_INFO, NULL, cmd_processor_get_slot_info, NULL },
{ DATA_CMD_WIPE_FDS, NULL, cmd_processor_wipe_fds, NULL },
{ DATA_CMD_SET_EM410X_EMU_ID, NULL, cmd_processor_set_em410x_emu_id, NULL },
+1
View File
@@ -27,6 +27,7 @@
#define DATA_CMD_GET_GIT_VERSION (1017)
#define DATA_CMD_GET_ACTIVE_SLOT (1018)
#define DATA_CMD_GET_SLOT_INFO (1019)
#define DATA_CMD_WIPE_FDS (1020)
//
// ******************************************************************
@@ -0,0 +1,26 @@
#include "app_timer.h"
#include "delayed_reset.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
APP_TIMER_DEF(m_reset_timer);
static void delayed_reset_event_handler(void* ctx) {
while (NRF_LOG_PROCESS());
ret_code_t ret = sd_nvic_SystemReset();
APP_ERROR_CHECK(ret);
while (1) {
__NOP();
}
}
void delayed_reset(uint32_t delay) {
NRF_LOG_INFO("Resetting in %d ms...", delay);
ret_code_t ret;
ret = app_timer_create(&m_reset_timer, APP_TIMER_MODE_SINGLE_SHOT, delayed_reset_event_handler);
APP_ERROR_CHECK(ret);
ret = app_timer_start(m_reset_timer, APP_TIMER_TICKS(delay), NULL);
APP_ERROR_CHECK(ret);
}
@@ -0,0 +1,3 @@
#pragma once
void delayed_reset(uint32_t delay);
+56 -13
View File
@@ -10,10 +10,11 @@ NRF_LOG_MODULE_REGISTER();
// current write record info
static struct {
uint16_t id; // file id
uint16_t key; // file key
bool success; // task is success
bool waiting; // task waiting done.
uint32_t record_id; // record id, used for sync delete
uint16_t id; // file id
uint16_t key; // file key
bool success; // task is success
bool waiting; // task waiting done.
} fds_operation_info;
@@ -120,12 +121,7 @@ bool fds_write_sync(uint16_t id, uint16_t key, uint16_t data_length_words, void*
} else if (err_code == FDS_ERR_NO_SPACE_IN_FLASH) { // 确保还有空间可以操作,否则需要GC
// 当前报错是属于空间不足的报错,可能我们需要进行GC
NRF_LOG_INFO("FDS no space, gc auto start.");
err_code = fds_gc(); // 发起GC操作
APP_ERROR_CHECK(err_code); // 检查GC是否正常执行
// 等待GC完成
while(!fds_operation_info.success) {
__NOP();
};
fds_gc_sync();
// gc完成后,可以重新进行相应的操作了
NRF_LOG_INFO("FDS auto gc success, write record continue.");
@@ -162,6 +158,7 @@ int fds_delete_sync(uint16_t id, uint16_t key) {
ret_code_t err_code;
while(fds_find_record(id, key, &record_desc)) {
fds_operation_info.success = false;
fds_record_id_from_desc(&record_desc, &fds_operation_info.record_id);
err_code = fds_record_delete(&record_desc);
APP_ERROR_CHECK(err_code);
delete_count++;
@@ -199,9 +196,13 @@ static void fds_evt_handler(fds_evt_t const * p_evt) {
} break;
case FDS_EVT_DEL_RECORD: {
if (p_evt->result == NRF_SUCCESS) {
NRF_LOG_INFO("Record remove: FileID: 0x%04x, RecordKey: 0x%04x", p_evt->del.file_id, p_evt->del.record_key);
if (p_evt->write.file_id == fds_operation_info.id && p_evt->write.record_key == fds_operation_info.key) {
// 上面的逻辑已经确保是我们当前删除记录的任务完成了!
NRF_LOG_INFO(
"Record remove: FileID: 0x%04x, RecordKey: 0x%04x, RecordID: %08x",
p_evt->del.file_id, p_evt->del.record_key, p_evt->del.record_id
);
if (p_evt->del.record_id == fds_operation_info.record_id) {
// Only check record id because fileID and recordKey aren't available
// if deleting via fds_record_iterate. record id is guaranteed to be unique.
fds_operation_info.success = true;
}
} else {
@@ -234,3 +235,45 @@ void fds_util_init() {
err_code = fds_init();
APP_ERROR_CHECK(err_code);
}
void fds_gc_sync(void) {
fds_operation_info.success = false;
ret_code_t err_code = fds_gc();
APP_ERROR_CHECK(err_code);
while(!fds_operation_info.success) {
__NOP();
};
}
static bool fds_next_record_delete_sync() {
fds_find_token_t tok = {0};
fds_record_desc_t desc = {0};
if (fds_record_iterate(&desc, &tok) != NRF_SUCCESS) {
NRF_LOG_INFO("No more records to delete");
return false;
}
fds_record_id_from_desc(&desc, &fds_operation_info.record_id);
NRF_LOG_INFO("Deleting record with id=%08x", fds_operation_info.record_id);
fds_operation_info.success = false;
ret_code_t rc = fds_record_delete(&desc);
if (rc != NRF_SUCCESS) {
NRF_LOG_WARNING("Record id=%08x deletion failed with rc=%d!", fds_operation_info.record_id, rc);
return false;
}
while(!fds_operation_info.success) {
__NOP();
}
NRF_LOG_INFO("Record id=%08x deleted successfully", fds_operation_info.record_id);
return true;
}
bool fds_wipe(void) {
NRF_LOG_INFO("Full fds wipe requested");
while (fds_next_record_delete_sync()) {}
fds_gc_sync();
return true;
}
@@ -9,5 +9,7 @@ bool fds_write_sync(uint16_t id, uint16_t key, uint16_t data_length_words, void*
int fds_delete_sync(uint16_t id, uint16_t key);
bool fds_is_exists(uint16_t id, uint16_t key);
void fds_util_init(void);
void fds_gc_sync(void);
bool fds_wipe(void);
#endif
+1
View File
@@ -98,6 +98,7 @@ class ChameleonCLI:
'reset': new_uint(chameleon_cli_unit.HWSettingsReset, "Reset settings to default values"),
'help': "Chameleon settings management"
},
'factory_reset': new_uint(chameleon_cli_unit.HWFactoryReset, "Wipe all data and return to factory settings"),
'help': "hardware controller",
},
'hf': {
+24
View File
@@ -1067,3 +1067,27 @@ class HWSettingsReset(DeviceRequiredUnit):
print(" - Reset success @.@~")
else:
print(" - Reset failed")
class HWFactoryReset(DeviceRequiredUnit):
def args_parser(self) -> ArgumentParserNoExit:
parser = ArgumentParserNoExit()
parser.description = "Permanently wipes Chameleon to factory settings. " \
"This will delete all your slot data and custom settings. " \
"There's no going back."
parser.add_argument(
"--i-know-what-im-doing",
default=False,
action="store_true",
help="Just to be sure :)"
)
return parser
def on_exec(self, args: argparse.Namespace):
if not args.i_know_what_im_doing:
print("This time your data's safe. Read the command documentation next time.")
return
resp = self.cmd_positive.factory_reset()
if resp.status == chameleon_status.Device.STATUS_DEVICE_SUCCESS:
print(" - Reset successful! Please reconnect.")
print(" - A Serial Error below is normal, please ignore it")
else:
print(" - Reset failed!")
+8
View File
@@ -30,6 +30,8 @@ DATA_CMD_GET_GIT_VERSION = 1017
DATA_CMD_GET_ACTIVE_SLOT = 1018
DATA_CMD_GET_SLOT_INFO = 1019
DATA_CMD_WIPE_FDS = 1020
DATA_CMD_SCAN_14A_TAG = 2000
DATA_CMD_MF1_SUPPORT_DETECT = 2001
DATA_CMD_MF1_NT_LEVEL_DETECT = 2002
@@ -495,6 +497,12 @@ class BaseChameleonCMD:
Store settings to flash memory
"""
return self.device.send_cmd_sync(DATA_CMD_SAVE_SETTINGS, 0x00)
def factory_reset(self):
"""
Reset to factory settings
"""
return self.device.send_cmd_sync(DATA_CMD_WIPE_FDS, 0x00)
class NegativeResponseError(Exception):