mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Implement DATA_CMD_GET_MF1_ANTI_COLL_DATA and DATA_CMD_GET_SETTINGS
This commit is contained in:
@@ -117,6 +117,19 @@ data_frame_tx_t *cmd_processor_reset_settings(uint16_t cmd, uint16_t status, uin
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
data_frame_tx_t *cmd_processor_get_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
uint8_t settings[6 + BLE_CONNECT_KEY_LEN_MAX] = {};
|
||||
settings[0] = SETTINGS_CURRENT_VERSION; // current version
|
||||
settings[1] = settings_get_animation_config(); // animation mode
|
||||
settings[2] = settings_get_button_press_config('A'); // short A button press mode
|
||||
settings[3] = settings_get_button_press_config('B'); // short B button press mode
|
||||
settings[4] = settings_get_long_button_press_config('A'); // long A button press mode
|
||||
settings[5] = settings_get_long_button_press_config('B'); // long B button press mode
|
||||
memcpy(settings + 6, settings_get_ble_connect_key(), BLE_CONNECT_KEY_LEN_MAX);
|
||||
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 6 + BLE_CONNECT_KEY_LEN_MAX, settings);
|
||||
}
|
||||
|
||||
|
||||
data_frame_tx_t *cmd_processor_set_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length == 1) {
|
||||
status = STATUS_DEVICE_SUCCESS;
|
||||
@@ -446,11 +459,30 @@ data_frame_tx_t *cmd_processor_set_em410x_emu_id(uint16_t cmd, uint16_t status,
|
||||
}
|
||||
|
||||
data_frame_tx_t *cmd_processor_get_em410x_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
tag_specific_type_t tag_type[2];
|
||||
tag_emulation_get_specific_type_by_slot(tag_emulation_get_slot(), tag_type);
|
||||
if (tag_type[1] == TAG_TYPE_UNKNOWN) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
|
||||
uint8_t responseData[LF_EM410X_TAG_ID_SIZE];
|
||||
memcpy(responseData, buffer->buffer, LF_EM410X_TAG_ID_SIZE);
|
||||
status = STATUS_DEVICE_SUCCESS;
|
||||
return data_frame_make(cmd, status, LF_EM410X_TAG_ID_SIZE, responseData);
|
||||
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, LF_EM410X_TAG_ID_SIZE, responseData);
|
||||
}
|
||||
|
||||
data_frame_tx_t *cmd_processor_get_mf1_anti_coll_data(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
tag_specific_type_t tag_type[2];
|
||||
tag_emulation_get_specific_type_by_slot(tag_emulation_get_slot(), tag_type);
|
||||
if (tag_type[0] == TAG_TYPE_UNKNOWN) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
|
||||
}
|
||||
uint8_t responseData[sizeof(picc_14a_tag_t)] = {};
|
||||
nfc_tag_14a_coll_res_reference_t *info = get_saved_mifare_coll_res();
|
||||
memcpy(responseData, info->uid, *info->size);
|
||||
responseData[10] = *info->size; // size is 2 byte len, but...
|
||||
responseData[12] = info->sak[0];
|
||||
memcpy(&responseData[13], info->atqa, 2);
|
||||
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, sizeof(picc_14a_tag_t), responseData);
|
||||
}
|
||||
|
||||
data_frame_tx_t *cmd_processor_set_mf1_detection_enable(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
@@ -855,7 +887,7 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG, NULL, cmd_processor_set_ble_connect_key, NULL },
|
||||
{ DATA_CMD_DELETE_ALL_BLE_BONDS, NULL, cmd_processor_del_ble_all_bonds, NULL },
|
||||
{ DATA_CMD_GET_DEVICE, NULL, cmd_processor_get_device, NULL },
|
||||
// { DATA_CMD_GET_SETTINGS, NULL, NULL, NULL },
|
||||
{ DATA_CMD_GET_SETTINGS, NULL, cmd_processor_get_settings, NULL },
|
||||
{ DATA_CMD_GET_DEVICE_CAPABILITIES, NULL, NULL, NULL },
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
@@ -910,6 +942,7 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_SET_MF1_USE_FIRST_BLOCK_COLL, NULL, cmd_processor_set_mf1_use_coll_res, NULL },
|
||||
{ DATA_CMD_GET_MF1_WRITE_MODE, NULL, cmd_processor_get_mf1_write_mode, NULL },
|
||||
{ DATA_CMD_SET_MF1_WRITE_MODE, NULL, cmd_processor_set_mf1_write_mode, NULL },
|
||||
{ DATA_CMD_GET_MF1_ANTI_COLL_DATA, NULL, cmd_processor_get_mf1_anti_coll_data, NULL },
|
||||
|
||||
{ DATA_CMD_SET_SLOT_TAG_NICK, NULL, cmd_processor_set_slot_tag_nick_name, NULL },
|
||||
{ DATA_CMD_GET_SLOT_TAG_NICK, NULL, cmd_processor_get_slot_tag_nick_name, NULL },
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#define DATA_CMD_SET_MF1_USE_FIRST_BLOCK_COLL (4015)
|
||||
#define DATA_CMD_GET_MF1_WRITE_MODE (4016)
|
||||
#define DATA_CMD_SET_MF1_WRITE_MODE (4017)
|
||||
#define DATA_CMD_GET_MF1_ANTI_COLL_DATA (4018)
|
||||
//
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
@@ -1070,6 +1070,17 @@ nfc_tag_14a_coll_res_reference_t *get_mifare_coll_res() {
|
||||
return &m_shadow_coll_res;
|
||||
}
|
||||
|
||||
|
||||
nfc_tag_14a_coll_res_reference_t *get_saved_mifare_coll_res() {
|
||||
// Always give saved data, not from block 0
|
||||
m_shadow_coll_res.sak = m_tag_information->res_coll.sak;
|
||||
m_shadow_coll_res.atqa = m_tag_information->res_coll.atqa;
|
||||
m_shadow_coll_res.uid = m_tag_information->res_coll.uid;
|
||||
m_shadow_coll_res.size = &(m_tag_information->res_coll.size);
|
||||
m_shadow_coll_res.ats = &(m_tag_information->res_coll.ats);
|
||||
return &m_shadow_coll_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reconcile when the parameter label needs to be reset
|
||||
*/
|
||||
|
||||
@@ -145,6 +145,7 @@ bool nfc_tag_mf1_is_detection_enable(void);
|
||||
void nfc_tag_mf1_detection_log_clear(void);
|
||||
uint32_t nfc_tag_mf1_detection_log_count(void);
|
||||
nfc_tag_14a_coll_res_reference_t *get_mifare_coll_res(void);
|
||||
nfc_tag_14a_coll_res_reference_t *get_saved_mifare_coll_res(void);
|
||||
void nfc_tag_mf1_set_gen1a_magic_mode(bool enable);
|
||||
bool nfc_tag_mf1_is_gen1a_magic_mode(void);
|
||||
void nfc_tag_mf1_set_gen2_magic_mode(bool enable);
|
||||
|
||||
@@ -841,6 +841,28 @@ class HFMFSim(DeviceRequiredUnit):
|
||||
print(" - Set anti-collision resources success")
|
||||
|
||||
|
||||
@hf_mf.command('info', 'Get information about current slot (UID/SAK/ATQA)')
|
||||
class HFMFInfo(DeviceRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit or None:
|
||||
pass
|
||||
|
||||
def scan(self):
|
||||
resp: chameleon_com.Response = self.cmd.get_mf1_anti_coll_data()
|
||||
if resp.status == chameleon_status.Device.STATUS_DEVICE_SUCCESS:
|
||||
info = chameleon_cstruct.parse_14a_scan_tag_result(resp.data)
|
||||
print(f"- UID Size: {info['uid_size']}")
|
||||
print(f"- UID Hex : {info['uid_hex'].upper()}")
|
||||
print(f"- SAK Hex : {info['sak_hex'].upper()}")
|
||||
print(f"- ATQA Hex : {info['atqa_hex'].upper()}")
|
||||
return True
|
||||
else:
|
||||
print("No data loaded in slot")
|
||||
return False
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
return self.scan()
|
||||
|
||||
|
||||
@lf_em.command('read', 'Scan em410x tag and print id')
|
||||
class LFEMRead(ReaderRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit or None:
|
||||
@@ -1354,15 +1376,13 @@ class HWSettingsBLEKeySet(DeviceRequiredUnit):
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
if len(args.key) != 6:
|
||||
print(
|
||||
f" - {colorama.Fore.RED}The ble connect key length must be 6{colorama.Style.RESET_ALL}")
|
||||
print(f" - {colorama.Fore.RED}The ble connect key length must be 6{colorama.Style.RESET_ALL}")
|
||||
return
|
||||
if re.match(r'[0-9]{6}', args.key):
|
||||
self.cmd.set_ble_connect_key(args.key)
|
||||
print(" - Successfully set ble connect key to settings")
|
||||
else:
|
||||
print(
|
||||
f" - {colorama.Fore.RED}Only 6 ASCII characters from 0 to 9 are supported.{colorama.Style.RESET_ALL}")
|
||||
print(f" - {colorama.Fore.RED}Only 6 ASCII characters from 0 to 9 are supported.{colorama.Style.RESET_ALL}")
|
||||
|
||||
|
||||
@hw_settings_ble_key.command('get', 'Get the ble connect key')
|
||||
|
||||
@@ -5,6 +5,8 @@ import chameleon_com
|
||||
import chameleon_status
|
||||
from chameleon_utils import expect_response
|
||||
|
||||
CURRENT_VERSION_SETTINGS = 4
|
||||
|
||||
DATA_CMD_GET_APP_VERSION = 1000
|
||||
DATA_CMD_CHANGE_MODE = 1001
|
||||
DATA_CMD_GET_DEVICE_MODE = 1002
|
||||
@@ -86,6 +88,7 @@ DATA_CMD_GET_MF1_USE_FIRST_BLOCK_COLL = 4014
|
||||
DATA_CMD_SET_MF1_USE_FIRST_BLOCK_COLL = 4015
|
||||
DATA_CMD_GET_MF1_WRITE_MODE = 4016
|
||||
DATA_CMD_SET_MF1_WRITE_MODE = 4017
|
||||
DATA_CMD_GET_MF1_ANTI_COLL_DATA = 4018
|
||||
|
||||
DATA_CMD_SET_EM410X_EMU_ID = 5000
|
||||
DATA_CMD_GET_EM410X_EMU_ID = 5001
|
||||
@@ -272,8 +275,8 @@ class ButtonPressFunction(enum.IntEnum):
|
||||
elif self == ButtonPressFunction.SettingsButtonCycleSlotDec:
|
||||
return "Card slot number sequence decreases after pressing"
|
||||
elif self == ButtonPressFunction.SettingsButtonCloneIcUid:
|
||||
return "Read the UID card number immediately after pressing, continue searching," + \
|
||||
"and simulate immediately after reading the card"
|
||||
return ("Read the UID card number immediately after pressing, continue searching," +
|
||||
"and simulate immediately after reading the card")
|
||||
return "Unknown"
|
||||
|
||||
|
||||
@@ -407,10 +410,7 @@ class ChameleonCMD:
|
||||
data.append(sync_max)
|
||||
return self.device.send_cmd_sync(DATA_CMD_MF1_DARKSIDE_ACQUIRE, 0x00, data, timeout=sync_max + 5)
|
||||
|
||||
@expect_response([
|
||||
chameleon_status.Device.HF_TAG_OK,
|
||||
chameleon_status.Device.MF_ERR_AUTH,
|
||||
])
|
||||
@expect_response([chameleon_status.Device.HF_TAG_OK, chameleon_status.Device.MF_ERR_AUTH])
|
||||
def auth_mf1_key(self, block, type_value, key):
|
||||
"""
|
||||
Verify the mf1 key, only verify the specified type of key for a single sector
|
||||
@@ -533,10 +533,8 @@ class ChameleonCMD:
|
||||
:param sense_type: Sense type to disable
|
||||
:return:
|
||||
"""
|
||||
return self.device.send_cmd_sync(DATA_CMD_DELETE_SLOT_SENSE_TYPE, 0x00, bytearray([
|
||||
SlotNumber.to_fw(slot_index),
|
||||
sense_type,
|
||||
]))
|
||||
return self.device.send_cmd_sync(DATA_CMD_DELETE_SLOT_SENSE_TYPE, 0x00,
|
||||
bytearray([SlotNumber.to_fw(slot_index), sense_type]))
|
||||
|
||||
@expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS)
|
||||
def set_slot_data_default(self, slot_index: SlotNumber, tag_type: TagSpecificType):
|
||||
@@ -784,11 +782,7 @@ class ChameleonCMD:
|
||||
"""
|
||||
Set config of button press function
|
||||
"""
|
||||
return self.device.send_cmd_sync(
|
||||
DATA_CMD_SET_BUTTON_PRESS_CONFIG,
|
||||
0x00,
|
||||
bytearray([button, function])
|
||||
)
|
||||
return self.device.send_cmd_sync(DATA_CMD_SET_BUTTON_PRESS_CONFIG, 0x00, bytearray([button, function]))
|
||||
|
||||
@expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS)
|
||||
def get_long_button_press_fun(self, button: ButtonType):
|
||||
@@ -802,11 +796,7 @@ class ChameleonCMD:
|
||||
"""
|
||||
Set config of button press function
|
||||
"""
|
||||
return self.device.send_cmd_sync(
|
||||
DATA_CMD_SET_LONG_BUTTON_PRESS_CONFIG,
|
||||
0x00,
|
||||
bytearray([button, function])
|
||||
)
|
||||
return self.device.send_cmd_sync(DATA_CMD_SET_LONG_BUTTON_PRESS_CONFIG, 0x00, bytearray([button, function]))
|
||||
|
||||
@expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS)
|
||||
def set_ble_connect_key(self, key: str):
|
||||
@@ -819,11 +809,7 @@ class ChameleonCMD:
|
||||
if len(data_bytes) != 6:
|
||||
raise ValueError("The ble connect key length must be 6")
|
||||
|
||||
return self.device.send_cmd_sync(
|
||||
DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG,
|
||||
0x00,
|
||||
data_bytes
|
||||
)
|
||||
return self.device.send_cmd_sync(DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG, 0x00, data_bytes)
|
||||
|
||||
def get_ble_connect_key(self):
|
||||
"""
|
||||
@@ -852,6 +838,41 @@ class ChameleonCMD:
|
||||
|
||||
return commands
|
||||
|
||||
def get_device_type(self):
|
||||
"""
|
||||
Get device type
|
||||
0 - Chameleon Ultra
|
||||
1 - Chameleon Lite
|
||||
"""
|
||||
|
||||
return self.device.send_cmd_sync(DATA_CMD_GET_DEVICE, 0x00).data[0]
|
||||
|
||||
def get_device_settings(self):
|
||||
"""
|
||||
Get all possible settings
|
||||
For version 4:
|
||||
settings[0] = SETTINGS_CURRENT_VERSION; // current version
|
||||
settings[1] = settings_get_animation_config(); // animation mode
|
||||
settings[2] = settings_get_button_press_config('A'); // short A button press mode
|
||||
settings[3] = settings_get_button_press_config('B'); // short B button press mode
|
||||
settings[4] = settings_get_long_button_press_config('A'); // long A button press mode
|
||||
settings[5] = settings_get_long_button_press_config('B'); // long B button press mode
|
||||
settings[6:12] = settings_get_ble_connect_key(); // BLE connection key
|
||||
"""
|
||||
data = self.device.send_cmd_sync(DATA_CMD_GET_SETTINGS, 0x00).data
|
||||
if data[0] != CURRENT_VERSION_SETTINGS:
|
||||
raise ValueError("Settings version in app doesn't match Chameleon response. Upgrade client or Chameleon "
|
||||
"firmware")
|
||||
return data
|
||||
|
||||
def get_mf1_anti_coll_data(self):
|
||||
"""
|
||||
Get data from current slot (UID/SAK/ATQA)
|
||||
:return:
|
||||
"""
|
||||
return self.device.send_cmd_sync(DATA_CMD_GET_MF1_ANTI_COLL_DATA, 0x00)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# connect to chameleon
|
||||
dev = chameleon_com.ChameleonCom()
|
||||
|
||||
Reference in New Issue
Block a user