mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Merge branch 'main' into fix-hidprox-cli-args
This commit is contained in:
@@ -3,7 +3,17 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Fix for FAST_READ command for nfc - mf0 tags
|
||||
- Rewrite of the dynamic and static locks logic for NTAG213, NTAG215 and NTAG216; we shouldn't take into account the block lock bits
|
||||
- Fixed an issue where we wouldn't be able to change CFG0 and CFG1 for NTAG213, NTAG215 and NTG216 once a password was added even if the cfg bit was reset.
|
||||
- Fix for static nested key recovery (@jekkos)
|
||||
- Fix LEDs being stuck on after battery check (@suut)
|
||||
- Add TCP support for the CLI (@suut)
|
||||
- Fix build on Android in Termux (@suut)
|
||||
- Fix the issue where some reader cause CU to enter a strange state (@xianglin1998)
|
||||
- The transmission performance of USB has been improved (@xianglin1998)
|
||||
- Added cmd for set mf1 config 'field_off_do_reset' (@xianglin1998)
|
||||
|
||||
|
||||
## [v2.1.0][2025-09-02]
|
||||
- Added UV, formatter and linter. Contribution guidelines. (@GameTec-live)
|
||||
|
||||
@@ -996,7 +996,7 @@ static data_frame_tx_t *cmd_processor_mf1_write_emu_block_data(uint16_t cmd, uin
|
||||
uint8_t block_index = data[0];
|
||||
uint8_t block_count = (length - 1) / NFC_TAG_MF1_DATA_SIZE;
|
||||
if (block_index + block_count > NFC_TAG_MF1_BLOCK_MAX) {
|
||||
status = STATUS_PAR_ERR;
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_MIFARE_4096);
|
||||
nfc_tag_mf1_information_t *info = (nfc_tag_mf1_information_t *)buffer->buffer;
|
||||
@@ -1374,6 +1374,19 @@ static data_frame_tx_t *cmd_processor_mf1_set_write_mode(uint16_t cmd, uint16_t
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_mf1_get_field_off_do_reset(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
uint8_t enable = nfc_tag_mf1_is_field_off_do_reset();
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 1, &enable);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_mf1_set_field_off_do_reset(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length != 1 || data[0] >= 2) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
nfc_tag_mf1_set_field_off_do_reset(data[0]);
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_get_enabled_slots(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
struct {
|
||||
uint8_t enabled_hf;
|
||||
@@ -1630,6 +1643,8 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_MF1_SET_BLOCK_ANTI_COLL_MODE, NULL, cmd_processor_mf1_set_block_anti_coll_mode, NULL },
|
||||
{ DATA_CMD_MF1_GET_WRITE_MODE, NULL, cmd_processor_mf1_get_write_mode, NULL },
|
||||
{ DATA_CMD_MF1_SET_WRITE_MODE, NULL, cmd_processor_mf1_set_write_mode, NULL },
|
||||
{ DATA_CMD_MF1_GET_FIELD_OFF_DO_RESET, NULL, cmd_processor_mf1_get_field_off_do_reset, NULL },
|
||||
{ DATA_CMD_MF1_SET_FIELD_OFF_DO_RESET, NULL, cmd_processor_mf1_set_field_off_do_reset, NULL },
|
||||
|
||||
{ DATA_CMD_MF0_NTAG_GET_UID_MAGIC_MODE, NULL, cmd_processor_mf0_ntag_get_uid_mode, NULL },
|
||||
{ DATA_CMD_MF0_NTAG_SET_UID_MAGIC_MODE, NULL, cmd_processor_mf0_ntag_set_uid_mode, NULL },
|
||||
|
||||
@@ -559,6 +559,12 @@ static void cycle_slot(bool dec) {
|
||||
}
|
||||
// Update status only if the new card slot switch is valid
|
||||
tag_emulation_change_slot(slot_new, true); // Tell the analog card module that we need to switch card slots
|
||||
// Turn off the LEDs in case we were showing the battery status
|
||||
rgb_marquee_stop();
|
||||
uint32_t *led_pins = hw_get_led_array();
|
||||
for (int i = 0; i < RGB_LIST_NUM; i++) {
|
||||
nrf_gpio_pin_clear(led_pins[i]);
|
||||
}
|
||||
// Go back to the color corresponding to the field enablement type
|
||||
apply_slot_change(slot_now, slot_new);
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@
|
||||
#define DATA_CMD_MF0_NTAG_GET_DETECTION_LOG (4035)
|
||||
#define DATA_CMD_MF0_NTAG_GET_DETECTION_ENABLE (4036)
|
||||
#define DATA_CMD_MF0_NTAG_GET_EMULATOR_CONFIG (4037)
|
||||
#define DATA_CMD_MF1_SET_FIELD_OFF_DO_RESET (4038)
|
||||
#define DATA_CMD_MF1_GET_FIELD_OFF_DO_RESET (4039)
|
||||
//
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
@@ -61,7 +61,10 @@ static volatile bool m_is_responded = false;
|
||||
static uint8_t m_nfc_rx_buffer[MAX_NFC_RX_BUFFER_SIZE] = { 0x00 };
|
||||
static uint8_t m_nfc_tx_buffer[MAX_NFC_TX_BUFFER_SIZE] = { 0x00 };
|
||||
// The N -secondary connection needs to use SAK, when the "third 'bit' in SAK is 1 is 1, the logo UID is incomplete
|
||||
static uint8_t m_uid_incomplete_sak[] = { 0x04, 0xda, 0x17 };
|
||||
static uint8_t m_uid_incomplete_sak[] = { 0x04, 0xda, 0x17 };
|
||||
// Reset nfc peripheral after field lost?
|
||||
static bool reset_if_field_lost = false; // default is 'false', Unless there is a genuine need for a reset.
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate BCC
|
||||
@@ -349,7 +352,7 @@ void nfc_tag_14a_data_process(uint8_t *p_data) {
|
||||
m_tag_state_14a = NFC_TAG_STATE_14A_READY;
|
||||
// After receiving the WUPA or REQA instruction, we need to reply to ATQA
|
||||
nfc_tag_14a_tx_bytes(auto_coll_res->atqa, 2, false);
|
||||
// NRF_LOG_INFO("ATQA reply.");
|
||||
// NRF_LOG_INFO("ATQA reply: %02x%02x", auto_coll_res->atqa[0], auto_coll_res->atqa[1]);
|
||||
} else {
|
||||
m_tag_state_14a = NFC_TAG_STATE_14A_IDLE;
|
||||
NRF_LOG_INFO("Auto anti-collision resource no exists.");
|
||||
@@ -397,6 +400,15 @@ void nfc_tag_14a_data_process(uint8_t *p_data) {
|
||||
m_tag_state_14a = NFC_TAG_STATE_14A_IDLE;
|
||||
}
|
||||
return;
|
||||
case NFC_TAG_14A_CMD_REQA:
|
||||
case NFC_TAG_14A_CMD_WUPA:
|
||||
// Reader is re-sending REQA/WUPA while in READY state
|
||||
// This can happen if reader retries or if frame was received incorrectly
|
||||
// Respond with ATQA again and stay in READY state
|
||||
if (auto_coll_res != NULL) {
|
||||
nfc_tag_14a_tx_bytes(auto_coll_res->atqa, 2, false);
|
||||
}
|
||||
return;
|
||||
default: {
|
||||
// After receiving the wrong level instruction, directly reset the status machine
|
||||
NRF_LOG_INFO("[MFEMUL_SELECT] Incorrect cascade level received: %02x", p_data[0]);
|
||||
@@ -523,6 +535,43 @@ void nfc_tag_14a_data_process(uint8_t *p_data) {
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from nrf_nfct.c and modified for nrf52840 adapted(no verify on nrf52832)
|
||||
static inline void nrf_nfct_reset(void) {
|
||||
uint32_t fdm;
|
||||
uint32_t int_enabled;
|
||||
|
||||
// Save parameter settings before the reset of the NFCT peripheral.
|
||||
fdm = nrf_nfct_frame_delay_max_get();
|
||||
int_enabled = nrf_nfct_int_enable_get();
|
||||
|
||||
// Reset the NFCT peripheral.
|
||||
*(volatile uint32_t *)0x40005FFC = 0;
|
||||
*(volatile uint32_t *)0x40005FFC;
|
||||
*(volatile uint32_t *)0x40005FFC = 1;
|
||||
|
||||
// Restore parameter settings after the reset of the NFCT peripheral.
|
||||
nrf_nfct_frame_delay_max_set(fdm);
|
||||
|
||||
// Use Window Grid frame delay mode.
|
||||
nrf_nfct_frame_delay_mode_set(NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID);
|
||||
|
||||
/* Begin: Workaround for anomaly 25 */
|
||||
/* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
|
||||
because it is required to operate with Windows Phone */
|
||||
nrf_nfct_sensres_bit_frame_sdd_set(NRF_NFCT_SENSRES_BIT_FRAME_SDD_00100);
|
||||
/* End: Workaround for anomaly 25 */
|
||||
|
||||
// Restore interrupts.
|
||||
nrf_nfct_int_enable(int_enabled);
|
||||
|
||||
// Disable interrupts associated with data exchange.
|
||||
nrf_nfct_int_disable(NRF_NFCT_INT_RXFRAMESTART_MASK |
|
||||
NRF_NFCT_INT_RXFRAMEEND_MASK |
|
||||
NRF_NFCT_INT_RXERROR_MASK |
|
||||
NRF_NFCT_INT_TXFRAMESTART_MASK |
|
||||
NRF_NFCT_INT_TXFRAMEEND_MASK);
|
||||
}
|
||||
|
||||
static inline void nfc_fdt_reset(void) {
|
||||
// STOP TX
|
||||
*(volatile uint32_t *)0x40005010 = 0x01;
|
||||
@@ -571,6 +620,13 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) {
|
||||
TAG_FIELD_LED_OFF()
|
||||
m_tag_state_14a = NFC_TAG_STATE_14A_IDLE;
|
||||
|
||||
if (reset_if_field_lost) {
|
||||
// Fix a bug where certain special conditions prevent triggering TX start events and actually transmit incorrect data to the card reader.
|
||||
// After more more more testing, I found that simply going into sleep mode and restarting can restore work.
|
||||
// Therefore, I suspect that there may be some issues with the NFC peripheral that require a reset to resolve.
|
||||
nrf_nfct_reset();
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("HF FIELD LOST");
|
||||
break;
|
||||
}
|
||||
@@ -688,3 +744,11 @@ bool is_valid_uid_size(uint8_t uid_length) {
|
||||
uid_length == NFC_TAG_14A_UID_DOUBLE_SIZE ||
|
||||
uid_length == NFC_TAG_14A_UID_TRIPLE_SIZE;
|
||||
}
|
||||
|
||||
void nfc_tag_14a_set_reset_enable(bool enable) {
|
||||
reset_if_field_lost = enable;
|
||||
}
|
||||
|
||||
bool nfc_tag_14a_is_reset_enable() {
|
||||
return reset_if_field_lost;
|
||||
}
|
||||
|
||||
@@ -115,4 +115,8 @@ void nfc_tag_14a_tx_nbit(uint8_t data, uint32_t bits);
|
||||
// Determine whether it is an effective UID length
|
||||
bool is_valid_uid_size(uint8_t uid_length);
|
||||
|
||||
// Reset nfc peripheral after field lost
|
||||
void nfc_tag_14a_set_reset_enable(bool enable);
|
||||
bool nfc_tag_14a_is_reset_enable();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -675,29 +675,49 @@ static void handle_fast_read_command(uint8_t block_num, uint8_t end_block_num) {
|
||||
|
||||
int block_max = get_block_max_by_tag_type(m_tag_type, true);
|
||||
|
||||
if (block_num >= end_block_num || end_block_num >= block_max) {
|
||||
if (block_num > end_block_num || end_block_num >= block_max) {
|
||||
nfc_tag_14a_tx_nbit(NAK_INVALID_OPERATION_TBV, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("HANDLING FAST READ %02x %02x", block_num, end_block_num);
|
||||
|
||||
handle_any_read(block_num, end_block_num - block_num, block_max);
|
||||
// FAST_READ is inclusive: read from block_num to end_block_num (both included)
|
||||
handle_any_read(block_num, end_block_num - block_num + 1, block_max);
|
||||
}
|
||||
|
||||
static bool check_ro_lock_on_page(int block_num) {
|
||||
if (block_num < 3) return true;
|
||||
else if (block_num == 3) return (m_tag_information->memory[2][2] & 9) != 0; // bits 0 and 3
|
||||
else if (block_num <= MF0ICU1_PAGES) {
|
||||
else if (block_num == 3) {
|
||||
switch (m_tag_type) {
|
||||
case TAG_TYPE_NTAG_213:
|
||||
case TAG_TYPE_NTAG_215:
|
||||
case TAG_TYPE_NTAG_216:
|
||||
//page 3 can be locked or not independant of BL CC bit
|
||||
//the BL bit only freezes the lock bytes !
|
||||
return (m_tag_information->memory[2][2] & 8) != 0;
|
||||
default:
|
||||
return (m_tag_information->memory[2][2] & 9) != 0;
|
||||
}
|
||||
// bits 0 and 3
|
||||
} else if (block_num <= MF0ICU1_PAGES) {
|
||||
bool locked = false;
|
||||
switch (m_tag_type) {
|
||||
case TAG_TYPE_NTAG_213:
|
||||
case TAG_TYPE_NTAG_215:
|
||||
case TAG_TYPE_NTAG_216:
|
||||
// pages can be locked or not independant of BL bits
|
||||
//the BL bits only freezes the lock bytes !
|
||||
uint16_t lock_bits = *(uint16_t *)&m_tag_information->memory[2][2];
|
||||
return ((lock_bits >> block_num) & 0x01) == 1;
|
||||
default:
|
||||
// check block locking bits
|
||||
if (block_num <= 9) locked |= (m_tag_information->memory[2][2] & 2) == 2;
|
||||
else locked |= (m_tag_information->memory[2][2] & 4) == 4;
|
||||
|
||||
// check block locking bits
|
||||
if (block_num <= 9) locked |= (m_tag_information->memory[2][2] & 2) == 2;
|
||||
else locked |= (m_tag_information->memory[2][2] & 4) == 4;
|
||||
locked |= (((*(uint16_t *)&m_tag_information->memory[2][2]) >> block_num) & 1) == 1;
|
||||
|
||||
locked |= (((*(uint16_t *)&m_tag_information->memory[2][2]) >> block_num) & 1) == 1;
|
||||
|
||||
return locked;
|
||||
return locked;
|
||||
}
|
||||
} else {
|
||||
uint8_t *p_lock_bytes = NULL;
|
||||
int user_memory_end = 0;
|
||||
@@ -776,9 +796,43 @@ static bool check_ro_lock_on_page(int block_num) {
|
||||
|
||||
bool locked_small_range = ((lock_word >> (index / dyn_lock_bit_page_cnt)) & 1) != 0;
|
||||
bool locked_large_range = ((p_lock_bytes[2] >> (index / dyn_lock_bit_page_cnt / 2)) & 1) != 0;
|
||||
|
||||
return locked_small_range | locked_large_range;
|
||||
switch (m_tag_type) {
|
||||
case TAG_TYPE_NTAG_213:
|
||||
case TAG_TYPE_NTAG_215:
|
||||
case TAG_TYPE_NTAG_216:
|
||||
// For NTAG213/215/216: byte 2 contains block-locking bits (BL) which only freeze
|
||||
// the lock configuration. We only check the actual lock bits (L0-L15) in bytes 0-1.
|
||||
return locked_small_range;
|
||||
default:
|
||||
return locked_small_range | locked_large_range;
|
||||
}
|
||||
} else {
|
||||
//Check the block locking bits to see if we can touch the dynamic locks bytes for NTAG tags
|
||||
if(block_num == user_memory_end)
|
||||
{
|
||||
switch (m_tag_type) {
|
||||
case TAG_TYPE_NTAG_213:
|
||||
case TAG_TYPE_NTAG_215:
|
||||
case TAG_TYPE_NTAG_216:
|
||||
{
|
||||
uint8_t block_bytes = m_tag_information->memory[user_memory_end][2];
|
||||
uint16_t block_world = 0;
|
||||
|
||||
// Each bit in block_bytes maps to 2 bits in block_world
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (block_bytes & (0x01 << i)) {
|
||||
block_world |= (0x0003 << (i * 2));
|
||||
}
|
||||
}
|
||||
|
||||
p_lock_bytes = m_tag_information->memory[user_memory_end];
|
||||
uint16_t lock_word = (((uint16_t)p_lock_bytes[1]) << 8) | (uint16_t)p_lock_bytes[0];
|
||||
return (lock_word & block_world) != 0;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check CFGLCK bit
|
||||
int first_cfg_page = get_first_cfg_page_by_tag_type(m_tag_type);
|
||||
uint8_t access = m_tag_information->memory[first_cfg_page + CONF_ACCESS_PAGE_OFFSET][CONF_ACCESS_BYTE];
|
||||
@@ -793,7 +847,25 @@ static bool check_ro_lock_on_page(int block_num) {
|
||||
static int handle_write_command(uint8_t block_num, uint8_t *p_data) {
|
||||
int block_max = get_block_max_by_tag_type(m_tag_type, false);
|
||||
|
||||
if (block_num >= block_max) {
|
||||
bool out_of_bounds = false;
|
||||
switch (m_tag_type) {
|
||||
case TAG_TYPE_NTAG_213:
|
||||
case TAG_TYPE_NTAG_215:
|
||||
case TAG_TYPE_NTAG_216:
|
||||
int first_cfg_page = get_first_cfg_page_by_tag_type(m_tag_type);
|
||||
uint8_t cfglck = m_tag_information->memory[first_cfg_page][0] & 0x40;
|
||||
// For NTAG cards we need to check CFGLCK bit for config pages
|
||||
bool is_config_page = (block_num >= first_cfg_page) && (block_num <= first_cfg_page + 1);
|
||||
bool config_locked = (cfglck != 0) && (!m_tag_information->config.mode_uid_magic);
|
||||
bool is_beyond_user_memory = (block_num >= block_max);
|
||||
out_of_bounds = (is_beyond_user_memory && !is_config_page) || (config_locked && is_config_page);
|
||||
break;
|
||||
default:
|
||||
out_of_bounds = block_num >= block_max;
|
||||
break;
|
||||
}
|
||||
// Reject out-of-bounds writes (except config pages)
|
||||
if (out_of_bounds) {
|
||||
NRF_LOG_ERROR("Write failed: block_num %08x >= block_max %08x", block_num, block_max);
|
||||
return NAK_INVALID_OPERATION_TBV;
|
||||
}
|
||||
|
||||
@@ -1111,6 +1111,8 @@ int nfc_tag_mf1_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer)
|
||||
.cb_reset = nfc_tag_mf1_reset_handler,
|
||||
};
|
||||
nfc_tag_14a_set_handler(&handler_for_14a);
|
||||
NRF_LOG_INFO("HF mf1 config 'field_off_do_reset' = %d", m_tag_information->config.field_off_do_reset);
|
||||
nfc_tag_14a_set_reset_enable(m_tag_information->config.field_off_do_reset);
|
||||
NRF_LOG_INFO("HF mf1 data load finish.");
|
||||
} else {
|
||||
NRF_LOG_ERROR("nfc_tag_mf1_information_t too big.");
|
||||
@@ -1157,6 +1159,12 @@ bool nfc_tag_mf1_data_factory(uint8_t slot, tag_specific_type_t tag_type) {
|
||||
p_mf1_information->config.use_mf1_coll_res = false;
|
||||
p_mf1_information->config.mode_block_write = NFC_TAG_MF1_WRITE_NORMAL;
|
||||
p_mf1_information->config.detection_enable = false;
|
||||
p_mf1_information->config.field_off_do_reset = false;
|
||||
|
||||
// zero for reserved byte
|
||||
p_mf1_information->config.reserved1 = 0x00;
|
||||
p_mf1_information->config.reserved2 = 0x00;
|
||||
p_mf1_information->config.reserved3 = 0x00;
|
||||
|
||||
// save data to flash
|
||||
tag_sense_type_t sense_type = get_sense_type_from_tag_type(tag_type);
|
||||
@@ -1236,3 +1244,10 @@ nfc_tag_mf1_write_mode_t nfc_tag_mf1_get_write_mode(void) {
|
||||
return m_tag_information->config.mode_block_write;
|
||||
}
|
||||
|
||||
void nfc_tag_mf1_set_field_off_do_reset(bool enable) {
|
||||
m_tag_information->config.field_off_do_reset = enable;
|
||||
}
|
||||
|
||||
bool nfc_tag_mf1_is_field_off_do_reset(void) {
|
||||
return m_tag_information->config.field_off_do_reset;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,15 @@ typedef struct {
|
||||
uint8_t detection_enable: 1;
|
||||
// Allow to write block 0 (CUID/gen2 mode)
|
||||
uint8_t mode_gen2_magic: 1;
|
||||
// reserve
|
||||
uint8_t reserved1: 4;
|
||||
/**
|
||||
* Should the NFC peripheral be reset after losing the RF field?
|
||||
* This configuration can fix the issue where some card readers cause the CU to enter a strange state of no response/incorrect response.
|
||||
* Once in this state, the device must be restarted to resolve the issue.
|
||||
* Alternatively, enabling this configuration for resetting the NFC after leaving the rf field can also solve the aforementioned problem.
|
||||
*/
|
||||
uint8_t field_off_do_reset: 1;
|
||||
// reserved
|
||||
uint8_t reserved1: 3;
|
||||
uint8_t reserved2;
|
||||
uint8_t reserved3;
|
||||
} nfc_tag_mf1_configure_t;
|
||||
@@ -157,6 +164,7 @@ void nfc_tag_mf1_set_use_mf1_coll_res(bool enable);
|
||||
bool nfc_tag_mf1_is_use_mf1_coll_res(void);
|
||||
void nfc_tag_mf1_set_write_mode(nfc_tag_mf1_write_mode_t write_mode);
|
||||
nfc_tag_mf1_write_mode_t nfc_tag_mf1_get_write_mode(void);
|
||||
|
||||
void nfc_tag_mf1_set_field_off_do_reset(bool enable);
|
||||
bool nfc_tag_mf1_is_field_off_do_reset(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define PREAMBLE_34BIT (0x009)
|
||||
#define PREAMBLE_35BIT (0x005)
|
||||
#define PREAMBLE_36BIT (0x003)
|
||||
#define PREAMBLE_ACTP (0x095)
|
||||
|
||||
/**@brief Set a bit in the uint64 word.
|
||||
*
|
||||
@@ -548,6 +549,37 @@ static wiegand_card_t *unpack_c15001(uint64_t hi, uint64_t lo) {
|
||||
return d;
|
||||
}
|
||||
|
||||
static uint64_t pack_actprox(wiegand_card_t *card) {
|
||||
if (card->oem == 0) {
|
||||
card->oem = 900;
|
||||
}
|
||||
uint64_t bits = PREAMBLE_ACTP;
|
||||
bits <<= 1;
|
||||
bits = (bits << 10) | (card->oem & 0x3ff);
|
||||
bits = (bits << 8) | (card->facility_code & 0xff);
|
||||
bits = (bits << 16) | (card->card_number & 0xffff);
|
||||
bits <<= 1;
|
||||
if (evenparity32((bits >> 18) & 0x1ffff)) {
|
||||
SET_BIT64(bits, 35);
|
||||
}
|
||||
if (oddparity32((bits >> 1) & 0x1ffff)) {
|
||||
SET_BIT64(bits, 0);
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
static wiegand_card_t *unpack_actprox(uint64_t hi, uint64_t lo) {
|
||||
if (!(IS_SET(lo, 35) == evenparity32((lo >> 18) & 0x1ffff) &&
|
||||
IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) {
|
||||
return NULL;
|
||||
}
|
||||
wiegand_card_t *d = wiegand_card_alloc();
|
||||
d->oem = (lo >> 25) & 0x3ff;
|
||||
d->facility_code = (lo >> 17) & 0xff;
|
||||
d->card_number = (lo >> 1) & 0xffff;
|
||||
return d;
|
||||
}
|
||||
|
||||
static uint64_t pack_s12906(wiegand_card_t *card) {
|
||||
uint64_t bits = PREAMBLE_36BIT;
|
||||
bits <<= 1;
|
||||
@@ -819,6 +851,7 @@ static const card_format_table_t formats[] = {
|
||||
{P10004, pack_p10004, unpack_p10004, 37, {0, 0x1FFF, 0x3FFFF, 0, 0}}, // HID P10004 37-bit PCSC
|
||||
{HGEN37, pack_hgeneric37, unpack_hgeneric37, 37, {1, 0, 0xFFFFFFFF, 0, 0}}, // HID Generic 37-bit
|
||||
{MDI37, pack_mdi37, unpack_mdi37, 37, {1, 0xF, 0x1FFFFFFF, 0, 0}}, // PointGuard MDI 37-bit
|
||||
{ACTPHID, pack_actprox, unpack_actprox, 36, {1, 0xFF, 0xFFFF, 0x3FF, 0}}, // HID ACTProx 36-bit
|
||||
};
|
||||
|
||||
uint64_t pack(wiegand_card_t *card) {
|
||||
|
||||
@@ -72,6 +72,7 @@ typedef enum {
|
||||
C1K48S,
|
||||
AVIG56,
|
||||
IR56,
|
||||
ACTPHID,
|
||||
} card_format_t;
|
||||
|
||||
// Structure for defined Wiegand card formats available for packing/unpacking
|
||||
|
||||
@@ -40,19 +40,19 @@ APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
|
||||
volatile bool g_usb_connected = false;
|
||||
volatile bool g_usb_port_opened = false;
|
||||
volatile bool g_usb_led_marquee_enable = true;
|
||||
static uint8_t cdc_data_buffer[NRF_DRV_USBD_EPSIZE];
|
||||
|
||||
/** @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t */
|
||||
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst, app_usbd_cdc_acm_user_event_t event) {
|
||||
static uint8_t cdc_data_buffer[1];
|
||||
|
||||
// app_usbd_cdc_acm_t const *p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
|
||||
|
||||
switch (event) {
|
||||
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: {
|
||||
/*
|
||||
*theProbabilityOfTheEntireUsbReceivingDataIsTheAppUsbdCdcAcmRead *AppUsbdCdcAcmReadFunctionIsNotASeriousReception,ItIsGivenAPointer,AndThenWaitForTheUsbBuffer *SoYouNeedToInitializeTheHeadPointerFirstWhenTheAppUsbdCdcAcmUserEvtPortOpenIsInitialized *IfTheAppUsbdCdcAcmUserEvtRxDoneUsesASubscribed0ToAccessTheBuffer,ItWillCauseTheFirstByteToLoseTheFirstSendEssence
|
||||
*/
|
||||
ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, cdc_data_buffer, 1);
|
||||
// Setup first transfer
|
||||
ret_code_t ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm, cdc_data_buffer, sizeof(cdc_data_buffer));
|
||||
UNUSED_VARIABLE(ret);
|
||||
|
||||
NRF_LOG_INFO("CDC ACM port opened");
|
||||
g_usb_port_opened = true;
|
||||
break;
|
||||
@@ -68,16 +68,13 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst, app_usb
|
||||
break;
|
||||
|
||||
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: {
|
||||
ret_code_t ret;
|
||||
//Take out the first byte first
|
||||
data_frame_receive(cdc_data_buffer, 1);
|
||||
do {
|
||||
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, cdc_data_buffer, 1);
|
||||
if (ret == NRF_SUCCESS) {
|
||||
// The byte after success
|
||||
data_frame_receive(cdc_data_buffer, 1);
|
||||
}
|
||||
} while (ret == NRF_SUCCESS);
|
||||
// Get amount of data transfered to process data
|
||||
size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm);
|
||||
data_frame_receive(cdc_data_buffer, size);
|
||||
|
||||
// Setup next transfer
|
||||
ret_code_t ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm, cdc_data_buffer, sizeof(cdc_data_buffer));
|
||||
UNUSED_VARIABLE(ret);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -28,6 +28,11 @@ static uint8_t compute_lrc(uint8_t *buf, uint16_t bufsize) {
|
||||
return 0x100 - lrc;
|
||||
}
|
||||
|
||||
//
|
||||
// !!!!!!!!!!!!!!!!! NRF_LOG_HEXDUMP_INFO() printing long data can cause freezing and needs to be fixed. !!!!!!!!!!!!!!!!!
|
||||
// FIXME.
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief: create a packet, put the created data packet into the buffer, and wait for the post to set up a non busy state
|
||||
* @param cmd: instructionResponse
|
||||
@@ -44,10 +49,11 @@ data_frame_tx_t *data_frame_make(uint16_t cmd, uint16_t status, uint16_t data_le
|
||||
NRF_LOG_ERROR("data_frame_make error, too much data.");
|
||||
return NULL;
|
||||
}
|
||||
NRF_LOG_INFO("TX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", cmd, cmd, status, data_length, data_length > 0 ? ", data =" : "");
|
||||
if (data_length > 0) {
|
||||
NRF_LOG_HEXDUMP_INFO(data, data_length);
|
||||
}
|
||||
|
||||
// NRF_LOG_INFO("TX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", cmd, cmd, status, data_length, data_length > 0 ? ", data =" : "");
|
||||
// if (data_length > 0) {
|
||||
// NRF_LOG_HEXDUMP_INFO(data, data_length);
|
||||
// }
|
||||
|
||||
netdata_frame_postamble_t *tx_post = (netdata_frame_postamble_t *)((uint8_t *)&m_netdata_frame_tx_buf + sizeof(netdata_frame_preamble_t) + data_length);
|
||||
// sof
|
||||
@@ -92,7 +98,7 @@ void data_frame_receive(uint8_t *data, uint16_t length) {
|
||||
return;
|
||||
}
|
||||
// buffer overflow
|
||||
if (m_data_rx_position + length >= sizeof(m_netdata_frame_rx_buf)) {
|
||||
if (m_data_rx_position + length > sizeof(m_netdata_frame_rx_buf)) {
|
||||
NRF_LOG_ERROR("Data frame wait overflow.");
|
||||
data_frame_reset();
|
||||
return;
|
||||
@@ -142,10 +148,10 @@ void data_frame_receive(uint8_t *data, uint16_t length) {
|
||||
// and we are receive completed
|
||||
m_data_buffer = m_data_len > 0 ? (uint8_t *)&m_netdata_frame_rx_buf.data : NULL;
|
||||
m_data_completed = true;
|
||||
NRF_LOG_INFO("RX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", m_data_cmd, m_data_cmd, m_data_status, m_data_len, m_data_len > 0 ? ", data =" : "");
|
||||
if (m_data_len > 0) {
|
||||
NRF_LOG_HEXDUMP_INFO(m_data_buffer, m_data_len);
|
||||
}
|
||||
// NRF_LOG_INFO("RX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", m_data_cmd, m_data_cmd, m_data_status, m_data_len, m_data_len > 0 ? ", data =" : "");
|
||||
// if (m_data_len > 0) {
|
||||
// NRF_LOG_HEXDUMP_INFO(m_data_buffer, m_data_len);
|
||||
// }
|
||||
} else {
|
||||
// data frame lrc error
|
||||
NRF_LOG_ERROR("Data frame finally lrc error.");
|
||||
|
||||
@@ -259,7 +259,8 @@ include $(TEMPLATE_PATH)/Makefile.common
|
||||
|
||||
# tolerate warnings in newer gcc versions
|
||||
# need to be called after $(TEMPLATE_PATH)/Makefile.common
|
||||
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//')
|
||||
# The return value of the Windows+msys2 build platform has carriage returns and line breaks, which need to be removed.
|
||||
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null | tr -d '\r' | cut -d. -f1)
|
||||
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
|
||||
ifeq ($(shell expr $(CC_VERSION) \>= 12), 1)
|
||||
# avoid a couple of false warnings in nRF SDK
|
||||
|
||||
@@ -818,29 +818,9 @@ void nrfx_nfct_irq_handler(void)
|
||||
|
||||
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
|
||||
|
||||
/* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */
|
||||
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMESTART);
|
||||
|
||||
NRFX_LOG_DEBUG("Rx fend");
|
||||
}
|
||||
|
||||
if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
|
||||
{
|
||||
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
|
||||
|
||||
nrfx_nfct_evt_t nfct_evt =
|
||||
{
|
||||
.evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
|
||||
};
|
||||
|
||||
/* Disable TX END event to ignore frame transmission other than READ response */
|
||||
nrf_nfct_int_disable(NRFX_NFCT_TX_INT_MASK);
|
||||
|
||||
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
|
||||
|
||||
NRFX_LOG_DEBUG("Tx fend");
|
||||
}
|
||||
|
||||
if (NRFX_NFCT_EVT_ACTIVE(SELECTED))
|
||||
{
|
||||
nrf_nfct_event_clear(NRF_NFCT_EVENT_SELECTED);
|
||||
@@ -913,6 +893,23 @@ void nrfx_nfct_irq_handler(void)
|
||||
m_nfct_cb.config.cb(&nfct_evt);
|
||||
}
|
||||
}
|
||||
|
||||
if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
|
||||
{
|
||||
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
|
||||
|
||||
nrfx_nfct_evt_t nfct_evt =
|
||||
{
|
||||
.evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
|
||||
};
|
||||
|
||||
/* Disable TX END event to ignore frame transmission other than READ response */
|
||||
nrf_nfct_int_disable(NRFX_NFCT_TX_INT_MASK);
|
||||
|
||||
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
|
||||
|
||||
NRFX_LOG_DEBUG("Tx fend");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NRFX_CHECK(NRFX_NFCT_ENABLED)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1304,6 +1304,18 @@ class ChameleonCMD:
|
||||
def set_ble_pairing_enable(self, enabled: bool):
|
||||
data = struct.pack('!B', enabled)
|
||||
return self.device.send_cmd_sync(Command.SET_BLE_PAIRING_ENABLE, data)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def mf1_get_field_off_do_reset(self):
|
||||
resp = self.device.send_cmd_sync(Command.MF1_GET_FIELD_OFF_DO_RESET)
|
||||
if resp.status == Status.SUCCESS:
|
||||
resp.parsed = struct.unpack('!B', resp.data)[0] == 1
|
||||
return resp
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def mf1_set_field_off_do_reset(self, enabled: bool):
|
||||
data = struct.pack('!B', enabled)
|
||||
return self.device.send_cmd_sync(Command.MF1_SET_FIELD_OFF_DO_RESET, data)
|
||||
|
||||
|
||||
def test_fn():
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import sys
|
||||
import queue
|
||||
import struct
|
||||
import threading
|
||||
import time
|
||||
import serial
|
||||
import platform
|
||||
from typing import Union
|
||||
from enum import Enum, auto
|
||||
import serial
|
||||
import socket
|
||||
|
||||
from chameleon_utils import CR, CG, CC, CY, color_string
|
||||
from chameleon_enum import Command, Status
|
||||
|
||||
ANDROID = 'android' in platform.release()
|
||||
|
||||
# each thread is waiting for its data for 100 ms before looping again
|
||||
THREAD_BLOCKING_TIMEOUT = 0.1
|
||||
|
||||
# TODO: client settings
|
||||
DEBUG = False
|
||||
|
||||
class TransportType(Enum):
|
||||
NONE = auto()
|
||||
SERIAL = auto()
|
||||
SOCKET = auto()
|
||||
|
||||
class NotOpenException(Exception):
|
||||
"""
|
||||
@@ -57,7 +68,8 @@ class ChameleonCom:
|
||||
"""
|
||||
Create a chameleon device instance
|
||||
"""
|
||||
self.serial_instance: Union[serial.Serial, None] = None
|
||||
self.transport: Union[serial.Serial, socket.socket, None] = None
|
||||
self.transport_type = TransportType.NONE
|
||||
self.send_data_queue = queue.Queue()
|
||||
self.wait_response_map = {}
|
||||
self.event_closing = threading.Event()
|
||||
@@ -68,7 +80,7 @@ class ChameleonCom:
|
||||
|
||||
:return:
|
||||
"""
|
||||
return self.serial_instance is not None and self.serial_instance.is_open
|
||||
return self.transport is not None and (self.transport_type is TransportType.SOCKET or self.transport.is_open)
|
||||
|
||||
def open(self, port) -> "ChameleonCom":
|
||||
"""
|
||||
@@ -82,19 +94,35 @@ class ChameleonCom:
|
||||
error = None
|
||||
try:
|
||||
# open serial port
|
||||
self.serial_instance = serial.Serial(port=port, baudrate=115200)
|
||||
if port.startswith('tcp:'):
|
||||
host, _, port = port[4:].partition(':')
|
||||
if not host or not port:
|
||||
sys.exit(color_string(CR, 'Usage: tcp:127.0.0.1:4321'))
|
||||
self.transport = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
print('Connecting to', host, int(port))
|
||||
self.transport.connect((host, int(port)))
|
||||
self.transport_type = TransportType.SOCKET
|
||||
else:
|
||||
if ANDROID:
|
||||
sys.exit(color_string(CR, 'COM port is not supported on Android, make a USB-serial to TCP communication bridge'))
|
||||
self.transport = serial.Serial(port=port, baudrate=115200)
|
||||
self.transport_type = TransportType.SERIAL
|
||||
except Exception as e:
|
||||
error = e
|
||||
finally:
|
||||
if error is not None:
|
||||
raise OpenFailException(error)
|
||||
assert self.serial_instance is not None
|
||||
try:
|
||||
self.serial_instance.dtr = True # must make dtr enable
|
||||
except Exception:
|
||||
# not all serial support dtr, e.g. virtual serial over BLE
|
||||
pass
|
||||
self.serial_instance.timeout = THREAD_BLOCKING_TIMEOUT
|
||||
assert self.transport is not None
|
||||
assert self.transport_type is not TransportType.NONE
|
||||
if self.transport_type is TransportType.SERIAL:
|
||||
try:
|
||||
self.transport.dtr = True # must make dtr enable
|
||||
except Exception:
|
||||
# not all serial support dtr, e.g. virtual serial over BLE
|
||||
pass
|
||||
self.transport.timeout = THREAD_BLOCKING_TIMEOUT
|
||||
else: # SOCKET
|
||||
self.transport.settimeout(THREAD_BLOCKING_TIMEOUT)
|
||||
# clear variable
|
||||
self.send_data_queue.queue.clear()
|
||||
self.wait_response_map.clear()
|
||||
@@ -136,12 +164,14 @@ class ChameleonCom:
|
||||
"""
|
||||
self.event_closing.set()
|
||||
try:
|
||||
assert self.serial_instance is not None
|
||||
self.serial_instance.close()
|
||||
assert self.transport is not None
|
||||
if self.transport_type is TransportType.SOCKET:
|
||||
self.transport.shutdown()
|
||||
self.transport.close()
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
self.serial_instance = None
|
||||
self.transport = None
|
||||
self.wait_response_map.clear()
|
||||
self.send_data_queue.queue.clear()
|
||||
|
||||
@@ -159,16 +189,29 @@ class ChameleonCom:
|
||||
|
||||
while self.isOpen():
|
||||
# receive
|
||||
try:
|
||||
assert self.serial_instance is not None
|
||||
data_bytes = self.serial_instance.read()
|
||||
except Exception as e:
|
||||
if not self.event_closing.is_set():
|
||||
print(f"Serial Error {e}, thread for receiver exit.")
|
||||
self.close()
|
||||
break
|
||||
if len(data_bytes) > 0:
|
||||
assert self.transport_type is not TransportType.NONE
|
||||
if self.transport_type is TransportType.SERIAL:
|
||||
try:
|
||||
assert self.transport is not None
|
||||
data_bytes = bytearray(self.transport.read())
|
||||
except Exception as e:
|
||||
if not self.event_closing.is_set():
|
||||
print(f"Serial Error {e}, thread for receiver exit.")
|
||||
self.close()
|
||||
break
|
||||
else: # SOCKET
|
||||
try:
|
||||
data_bytes = bytearray(self.transport.recv(1024))
|
||||
except socket.timeout:
|
||||
continue
|
||||
except OSError:
|
||||
print(color_string(CR, 'socket closed'))
|
||||
self.transport = None
|
||||
break
|
||||
|
||||
while len(data_bytes) > 0:
|
||||
data_byte = data_bytes[0]
|
||||
data_bytes = data_bytes[1:]
|
||||
data_buffer.append(data_byte)
|
||||
if data_position < struct.calcsize('!BB'): # start of frame + lrc1
|
||||
if data_position == 0:
|
||||
@@ -267,14 +310,25 @@ class ChameleonCom:
|
||||
self.wait_response_map[task_cmd]['start_time'] = start_time
|
||||
self.wait_response_map[task_cmd]['end_time'] = start_time + task_timeout
|
||||
self.wait_response_map[task_cmd]['is_timeout'] = False
|
||||
try:
|
||||
assert self.serial_instance is not None
|
||||
# send to device
|
||||
self.serial_instance.write(task['frame'])
|
||||
except Exception as e:
|
||||
print(f"Serial Error {e}, thread for transfer exit.")
|
||||
self.close()
|
||||
break
|
||||
assert self.transport_type is not TransportType.NONE
|
||||
if self.transport_type == TransportType.SERIAL:
|
||||
try:
|
||||
assert self.transport is not None
|
||||
# send to device
|
||||
self.transport.write(task['frame'])
|
||||
except Exception as e:
|
||||
print(f"Serial Error {e}, thread for transfer exit.")
|
||||
self.close()
|
||||
break
|
||||
else: # SOCKET
|
||||
try:
|
||||
assert self.transport is not None
|
||||
self.transport.sendall(task['frame'])
|
||||
except OSError as e:
|
||||
self.transport = None
|
||||
print(f'Socket error {e}, thread for transfer exit.')
|
||||
self.close()
|
||||
break
|
||||
# update queue status
|
||||
self.send_data_queue.task_done()
|
||||
# disconnect if DFU command has been sent
|
||||
|
||||
@@ -124,6 +124,9 @@ class Command(enum.IntEnum):
|
||||
# FIXME: not implemented
|
||||
MF0_NTAG_GET_EMULATOR_CONFIG = 4037
|
||||
|
||||
MF1_SET_FIELD_OFF_DO_RESET = 4038
|
||||
MF1_GET_FIELD_OFF_DO_RESET = 4039
|
||||
|
||||
EM410X_SET_EMU_ID = 5000
|
||||
EM410X_GET_EMU_ID = 5001
|
||||
HIDPROX_SET_EMU_ID = 5002
|
||||
@@ -581,6 +584,7 @@ class HIDFormat(enum.IntEnum):
|
||||
C1K35S = 21
|
||||
C15001 = 22
|
||||
S12906 = 23
|
||||
ACTPHID = 42
|
||||
SIE36 = 24
|
||||
H10320 = 25
|
||||
H10302 = 26
|
||||
@@ -614,6 +618,7 @@ class HIDFormat(enum.IntEnum):
|
||||
HIDFormat.C1K35S: "HID Corporate 1000 35-bit Std",
|
||||
HIDFormat.C15001: "HID KeyScan 36-bit",
|
||||
HIDFormat.S12906: "HID Simplex 36-bit",
|
||||
HIDFormat.ACTPHID: "HID ACTProx 36-bit",
|
||||
HIDFormat.SIE36: "HID 36-bit Siemens",
|
||||
HIDFormat.H10320: "HID H10320 37-bit BCD",
|
||||
HIDFormat.H10302: "HID H10302 37-bit huge ID",
|
||||
|
||||
+25
-11
@@ -77,7 +77,7 @@ endif()
|
||||
|
||||
|
||||
# --- Platform specific settings ---
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
MESSAGE(STATUS "Run on linux.")
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
@@ -126,7 +126,7 @@ endif()
|
||||
add_executable(nested ${COMMON_FILES} ${NESTED_UTIL} nested.c)
|
||||
target_include_directories(nested PRIVATE ${SRC_DIR})
|
||||
target_link_libraries(nested PRIVATE ${LIBTHREAD}) # Link common thread lib
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(nested PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -138,7 +138,7 @@ endif()
|
||||
add_executable(staticnested ${COMMON_FILES} ${NESTED_UTIL} staticnested.c)
|
||||
target_include_directories(staticnested PRIVATE ${SRC_DIR})
|
||||
target_link_libraries(staticnested PRIVATE ${LIBTHREAD}) # Link common thread lib
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(staticnested PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -150,7 +150,7 @@ endif()
|
||||
add_executable(darkside ${COMMON_FILES} ${MFKEY_UTIL} darkside.c)
|
||||
target_include_directories(darkside PRIVATE ${SRC_DIR})
|
||||
# darkside doesn't seem to need pthreads based on original file
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(darkside PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -161,7 +161,7 @@ endif()
|
||||
add_executable(mfkey32 ${COMMON_FILES} mfkey32.c)
|
||||
target_include_directories(mfkey32 PRIVATE ${SRC_DIR})
|
||||
# mfkey32 doesn't seem to need pthreads based on original file
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(mfkey32 PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -172,7 +172,7 @@ endif()
|
||||
add_executable(mfkey32v2 ${COMMON_FILES} mfkey32v2.c)
|
||||
target_include_directories(mfkey32v2 PRIVATE ${SRC_DIR})
|
||||
# mfkey32v2 doesn't seem to need pthreads based on original file
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(mfkey32v2 PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -183,7 +183,7 @@ endif()
|
||||
add_executable(mfkey64 ${COMMON_FILES} mfkey64.c)
|
||||
target_include_directories(mfkey64 PRIVATE ${SRC_DIR})
|
||||
# mfkey64 doesn't seem to need pthreads based on original file
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(mfkey64 PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -192,7 +192,7 @@ endif()
|
||||
|
||||
add_executable(staticnested_1nt ${COMMON_FILES} staticnested_1nt.c)
|
||||
target_include_directories(staticnested_1nt PRIVATE ${SRC_DIR})
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(staticnested_1nt PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -201,7 +201,7 @@ endif()
|
||||
|
||||
add_executable(staticnested_2x1nt_rf08s ${COMMON_FILES} staticnested_2x1nt_rf08s.c)
|
||||
target_include_directories(staticnested_2x1nt_rf08s PRIVATE ${SRC_DIR})
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(staticnested_2x1nt_rf08s PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
@@ -210,13 +210,27 @@ endif()
|
||||
|
||||
add_executable(staticnested_2x1nt_rf08s_1key ${COMMON_FILES} staticnested_2x1nt_rf08s_1key.c)
|
||||
target_include_directories(staticnested_2x1nt_rf08s_1key PRIVATE ${SRC_DIR})
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(staticnested_2x1nt_rf08s_1key PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_compile_definitions(staticnested_2x1nt_rf08s_1key PRIVATE HAVE_STRUCT_TIMESPEC)
|
||||
endif()
|
||||
|
||||
# --- mfulc_des_brute Executable ---
|
||||
add_executable(mfulc_des_brute mfulc_des_brute.c)
|
||||
target_include_directories(mfulc_des_brute PRIVATE ${SRC_DIR})
|
||||
target_link_libraries(mfulc_des_brute PRIVATE ${LIBTHREAD} OpenSSL::Crypto)
|
||||
target_compile_options(mfulc_des_brute PRIVATE -Wno-deprecated-declarations)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(mfulc_des_brute PRIVATE _GNU_SOURCE)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_compile_definitions(mfulc_des_brute PRIVATE HAVE_STRUCT_TIMESPEC)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
# --- hardnested Executable ---
|
||||
add_executable(hardnested ${COMMON_FILES} ${HARDNESTED_SOURCES})
|
||||
@@ -230,7 +244,7 @@ target_include_directories(hardnested PRIVATE
|
||||
)
|
||||
target_compile_options(hardnested PRIVATE -Wall)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(hardnested PRIVATE _GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user