mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Merge pull request #63 from augustozanellato/factory_reset
Add factory reset command
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
|
||||
@@ -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': {
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user