mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-21 05:04:46 -07:00
fix emulation by using latest sources
fixed file saving
This commit is contained in:
@@ -55,7 +55,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) {
|
|||||||
} else if(protocol == NfcDeviceProtocolMifareDesfire) {
|
} else if(protocol == NfcDeviceProtocolMifareDesfire) {
|
||||||
furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n");
|
furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n");
|
||||||
} else if(protocol == NfcDeviceProtocolNfcV) {
|
} else if(protocol == NfcDeviceProtocolNfcV) {
|
||||||
switch(dev_data->nfcv_data.type) {
|
switch(dev_data->nfcv_data.sub_type) {
|
||||||
case NfcVTypePlain:
|
case NfcVTypePlain:
|
||||||
furi_string_cat_printf(temp_str, "\e#ISO15693\n");
|
furi_string_cat_printf(temp_str, "\e#ISO15693\n");
|
||||||
break;
|
break;
|
||||||
@@ -113,7 +113,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) {
|
|||||||
}
|
}
|
||||||
furi_string_cat_printf(temp_str, "\n");
|
furi_string_cat_printf(temp_str, "\n");
|
||||||
|
|
||||||
switch(dev_data->nfcv_data.type) {
|
switch(dev_data->nfcv_data.sub_type) {
|
||||||
case NfcVTypePlain:
|
case NfcVTypePlain:
|
||||||
furi_string_cat_printf(temp_str, "Type: Plain\n");
|
furi_string_cat_printf(temp_str, "Type: Plain\n");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) {
|
|||||||
Popup* popup = nfc->popup;
|
Popup* popup = nfc->popup;
|
||||||
if(state == NfcSceneNfcVUnlockStateDetecting) {
|
if(state == NfcSceneNfcVUnlockStateDetecting) {
|
||||||
popup_reset(popup);
|
popup_reset(popup);
|
||||||
popup_set_text(popup, "Put Tonie On\nFlipper's Back", 97, 24, AlignCenter, AlignTop);
|
popup_set_text(
|
||||||
|
popup, "Put figurine on\nFlipper's back", 97, 24, AlignCenter, AlignTop);
|
||||||
popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50);
|
popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50);
|
||||||
} else if(state == NfcSceneNfcVUnlockStateUnlocked) {
|
} else if(state == NfcSceneNfcVUnlockStateUnlocked) {
|
||||||
popup_reset(popup);
|
popup_reset(popup);
|
||||||
@@ -43,7 +44,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) {
|
|||||||
if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) {
|
if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) {
|
||||||
nfc_text_store_set(
|
nfc_text_store_set(
|
||||||
nfc,
|
nfc,
|
||||||
"SLIX_%02X%02X%02X%02X%02X%02X%02X%02X",
|
"%s/SLIX_%02X%02X%02X%02X%02X%02X%02X%02X%s",
|
||||||
|
NFC_APP_FOLDER,
|
||||||
nfc_data->uid[0],
|
nfc_data->uid[0],
|
||||||
nfc_data->uid[1],
|
nfc_data->uid[1],
|
||||||
nfc_data->uid[2],
|
nfc_data->uid[2],
|
||||||
@@ -51,7 +53,8 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) {
|
|||||||
nfc_data->uid[4],
|
nfc_data->uid[4],
|
||||||
nfc_data->uid[5],
|
nfc_data->uid[5],
|
||||||
nfc_data->uid[6],
|
nfc_data->uid[6],
|
||||||
nfc_data->uid[7]);
|
nfc_data->uid[7],
|
||||||
|
NFC_APP_EXTENSION);
|
||||||
|
|
||||||
nfc->dev->format = NfcDeviceSaveFormatNfcV;
|
nfc->dev->format = NfcDeviceSaveFormatNfcV;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,10.1,,
|
Version,+,10.2,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@@ -732,6 +732,7 @@ Function,-,digital_sequence_alloc,DigitalSequence*,"uint32_t, const GpioPin*"
|
|||||||
Function,-,digital_sequence_clear,void,DigitalSequence*
|
Function,-,digital_sequence_clear,void,DigitalSequence*
|
||||||
Function,-,digital_sequence_free,void,DigitalSequence*
|
Function,-,digital_sequence_free,void,DigitalSequence*
|
||||||
Function,-,digital_sequence_send,_Bool,DigitalSequence*
|
Function,-,digital_sequence_send,_Bool,DigitalSequence*
|
||||||
|
Function,-,digital_sequence_set_sendtime,void,"DigitalSequence*, uint32_t"
|
||||||
Function,-,digital_sequence_set_signal,void,"DigitalSequence*, uint8_t, DigitalSignal*"
|
Function,-,digital_sequence_set_signal,void,"DigitalSequence*, uint8_t, DigitalSignal*"
|
||||||
Function,-,digital_signal_add,void,"DigitalSignal*, uint32_t"
|
Function,-,digital_signal_add,void,"DigitalSignal*, uint32_t"
|
||||||
Function,-,digital_signal_add_pulse,void,"DigitalSignal*, uint32_t, _Bool"
|
Function,-,digital_signal_add_pulse,void,"DigitalSignal*, uint32_t, _Bool"
|
||||||
@@ -2031,7 +2032,7 @@ Function,-,nfca_signal_free,void,NfcaSignal*
|
|||||||
Function,-,nfcv_emu_deinit,void,NfcVData*
|
Function,-,nfcv_emu_deinit,void,NfcVData*
|
||||||
Function,-,nfcv_emu_init,void,"FuriHalNfcDevData*, NfcVData*"
|
Function,-,nfcv_emu_init,void,"FuriHalNfcDevData*, NfcVData*"
|
||||||
Function,-,nfcv_emu_loop,_Bool,"FuriHalNfcTxRxContext*, FuriHalNfcDevData*, NfcVData*, uint32_t"
|
Function,-,nfcv_emu_loop,_Bool,"FuriHalNfcTxRxContext*, FuriHalNfcDevData*, NfcVData*, uint32_t"
|
||||||
Function,-,nfcv_emu_send,void,"FuriHalNfcTxRxContext*, NfcVData*, uint8_t*, uint8_t, NfcVSendFlags"
|
Function,-,nfcv_emu_send,void,"FuriHalNfcTxRxContext*, NfcVData*, uint8_t*, uint8_t, NfcVSendFlags, uint32_t"
|
||||||
Function,-,nfcv_inventory,ReturnCode,uint8_t*
|
Function,-,nfcv_inventory,ReturnCode,uint8_t*
|
||||||
Function,-,nfcv_read_blocks,ReturnCode,"NfcVReader*, NfcVData*"
|
Function,-,nfcv_read_blocks,ReturnCode,"NfcVReader*, NfcVData*"
|
||||||
Function,-,nfcv_read_card,_Bool,"NfcVReader*, FuriHalNfcDevData*, NfcVData*"
|
Function,-,nfcv_read_card,_Bool,"NfcVReader*, FuriHalNfcDevData*, NfcVData*"
|
||||||
|
|||||||
|
@@ -250,6 +250,7 @@ void digital_sequence_alloc_sequence(DigitalSequence* sequence, uint32_t size) {
|
|||||||
sequence->sequence_used = 0;
|
sequence->sequence_used = 0;
|
||||||
sequence->sequence_size = size;
|
sequence->sequence_size = size;
|
||||||
sequence->sequence = malloc(sequence->sequence_size);
|
sequence->sequence = malloc(sequence->sequence_size);
|
||||||
|
sequence->send_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio) {
|
DigitalSequence* digital_sequence_alloc(uint32_t size, const GpioPin* gpio) {
|
||||||
@@ -287,6 +288,10 @@ void digital_sequence_set_signal(
|
|||||||
digital_signal_prepare(signal);
|
digital_signal_prepare(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void digital_sequence_set_sendtime(DigitalSequence* sequence, uint32_t send_time) {
|
||||||
|
sequence->send_time = send_time;
|
||||||
|
}
|
||||||
|
|
||||||
void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) {
|
void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) {
|
||||||
furi_assert(sequence);
|
furi_assert(sequence);
|
||||||
furi_assert(signal_index < sequence->signals_size);
|
furi_assert(signal_index < sequence->signals_size);
|
||||||
@@ -347,7 +352,8 @@ void digital_signal_update_dma(DigitalSignal* signal) {
|
|||||||
LL_DMA_ClearFlag_TC2(DMA1);
|
LL_DMA_ClearFlag_TC2(DMA1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool digital_sequence_send_signal(DigitalSignal* signal) {
|
static bool digital_sequence_send_signal(DigitalSequence* sequence, DigitalSignal* signal) {
|
||||||
|
furi_assert(sequence);
|
||||||
furi_assert(signal);
|
furi_assert(signal);
|
||||||
|
|
||||||
/* the first iteration has to set up the whole machinery */
|
/* the first iteration has to set up the whole machinery */
|
||||||
@@ -357,6 +363,17 @@ static bool digital_sequence_send_signal(DigitalSignal* signal) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
digital_signal_setup_timer();
|
digital_signal_setup_timer();
|
||||||
|
|
||||||
|
/* if the send time is specified, wait till the core timer passed beyond that time */
|
||||||
|
if(sequence->send_time != 0) {
|
||||||
|
while(true) {
|
||||||
|
uint32_t delta = sequence->send_time - DWT->CYCCNT;
|
||||||
|
/* yeah, it's making use of underflows... */
|
||||||
|
if(delta > 0x80000000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
digital_signal_start_timer();
|
digital_signal_start_timer();
|
||||||
} else {
|
} else {
|
||||||
/* configure next polarities and timings */
|
/* configure next polarities and timings */
|
||||||
@@ -438,7 +455,7 @@ bool digital_sequence_send(DigitalSequence* sequence) {
|
|||||||
sequence->signals_prolonged[signal_index] = needs_prolongation;
|
sequence->signals_prolonged[signal_index] = needs_prolongation;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = digital_sequence_send_signal(sig);
|
bool success = digital_sequence_send_signal(sequence, sig);
|
||||||
|
|
||||||
if(!success) {
|
if(!success) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ typedef struct {
|
|||||||
bool* signals_prolonged;
|
bool* signals_prolonged;
|
||||||
uint8_t* sequence;
|
uint8_t* sequence;
|
||||||
const GpioPin* gpio;
|
const GpioPin* gpio;
|
||||||
|
uint32_t send_time;
|
||||||
} DigitalSequence;
|
} DigitalSequence;
|
||||||
|
|
||||||
DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt);
|
DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt);
|
||||||
@@ -69,6 +70,7 @@ void digital_sequence_set_signal(
|
|||||||
DigitalSequence* sequence,
|
DigitalSequence* sequence,
|
||||||
uint8_t signal_index,
|
uint8_t signal_index,
|
||||||
DigitalSignal* signal);
|
DigitalSignal* signal);
|
||||||
|
void digital_sequence_set_sendtime(DigitalSequence* sequence, uint32_t send_time);
|
||||||
void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index);
|
void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index);
|
||||||
bool digital_sequence_send(DigitalSequence* sequence);
|
bool digital_sequence_send(DigitalSequence* sequence);
|
||||||
void digital_sequence_clear(DigitalSequence* sequence);
|
void digital_sequence_clear(DigitalSequence* sequence);
|
||||||
|
|||||||
@@ -860,10 +860,10 @@ static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
|
|||||||
file,
|
file,
|
||||||
"Subtype of this card (0 = ISO15693, 1 = SLIX, 2 = SLIX-S, 3 = SLIX-L, 4 = SLIX2)"))
|
"Subtype of this card (0 = ISO15693, 1 = SLIX, 2 = SLIX-S, 3 = SLIX-L, 4 = SLIX2)"))
|
||||||
break;
|
break;
|
||||||
temp_uint8 = (uint8_t)data->type;
|
temp_uint8 = (uint8_t)data->sub_type;
|
||||||
if(!flipper_format_write_hex(file, "Subtype", &temp_uint8, 1)) break;
|
if(!flipper_format_write_hex(file, "Subtype", &temp_uint8, 1)) break;
|
||||||
|
|
||||||
switch(data->type) {
|
switch(data->sub_type) {
|
||||||
case NfcVTypePlain:
|
case NfcVTypePlain:
|
||||||
if(!flipper_format_write_comment_cstr(file, "End of ISO15693 parameters")) break;
|
if(!flipper_format_write_comment_cstr(file, "End of ISO15693 parameters")) break;
|
||||||
saved = true;
|
saved = true;
|
||||||
@@ -906,9 +906,9 @@ bool nfc_device_load_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
|
|||||||
file, "Data Content", data->data, data->block_num * data->block_size))
|
file, "Data Content", data->data, data->block_num * data->block_size))
|
||||||
break;
|
break;
|
||||||
if(!flipper_format_read_hex(file, "Subtype", &temp_value, 1)) break;
|
if(!flipper_format_read_hex(file, "Subtype", &temp_value, 1)) break;
|
||||||
data->type = temp_value;
|
data->sub_type = temp_value;
|
||||||
|
|
||||||
switch(data->type) {
|
switch(data->sub_type) {
|
||||||
case NfcVTypePlain:
|
case NfcVTypePlain:
|
||||||
parsed = true;
|
parsed = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ ReturnCode nfcv_inventory(uint8_t* uid) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* data) {
|
ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* nfcv_data) {
|
||||||
UNUSED(reader);
|
UNUSED(reader);
|
||||||
|
|
||||||
uint16_t received = 0;
|
uint16_t received = 0;
|
||||||
for(size_t block = 0; block < data->block_num; block++) {
|
for(size_t block = 0; block < nfcv_data->block_num; block++) {
|
||||||
uint8_t rxBuf[32];
|
uint8_t rxBuf[32];
|
||||||
FURI_LOG_D(TAG, "Reading block %d/%d", block, (data->block_num - 1));
|
FURI_LOG_D(TAG, "Reading block %d/%d", block, (nfcv_data->block_num - 1));
|
||||||
|
|
||||||
ReturnCode ret = ERR_NONE;
|
ReturnCode ret = ERR_NONE;
|
||||||
for(int tries = 0; tries < 5; tries++) {
|
for(int tries = 0; tries < 5; tries++) {
|
||||||
@@ -59,20 +59,21 @@ ReturnCode nfcv_read_blocks(NfcVReader* reader, NfcVData* data) {
|
|||||||
FURI_LOG_D(TAG, "failed to read: %d", ret);
|
FURI_LOG_D(TAG, "failed to read: %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
memcpy(&(data->data[block * data->block_size]), &rxBuf[1], data->block_size);
|
memcpy(
|
||||||
|
&(nfcv_data->data[block * nfcv_data->block_size]), &rxBuf[1], nfcv_data->block_size);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
TAG,
|
TAG,
|
||||||
" %02X %02X %02X %02X",
|
" %02X %02X %02X %02X",
|
||||||
data->data[block * data->block_size + 0],
|
nfcv_data->data[block * nfcv_data->block_size + 0],
|
||||||
data->data[block * data->block_size + 1],
|
nfcv_data->data[block * nfcv_data->block_size + 1],
|
||||||
data->data[block * data->block_size + 2],
|
nfcv_data->data[block * nfcv_data->block_size + 2],
|
||||||
data->data[block * data->block_size + 3]);
|
nfcv_data->data[block * nfcv_data->block_size + 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) {
|
ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
||||||
uint8_t rxBuf[32];
|
uint8_t rxBuf[32];
|
||||||
uint16_t received = 0;
|
uint16_t received = 0;
|
||||||
ReturnCode ret = ERR_NONE;
|
ReturnCode ret = ERR_NONE;
|
||||||
@@ -96,11 +97,11 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) {
|
|||||||
for(int pos = 0; pos < nfc_data->uid_len; pos++) {
|
for(int pos = 0; pos < nfc_data->uid_len; pos++) {
|
||||||
nfc_data->uid[pos] = rxBuf[2 + (7 - pos)];
|
nfc_data->uid[pos] = rxBuf[2 + (7 - pos)];
|
||||||
}
|
}
|
||||||
data->dsfid = rxBuf[10];
|
nfcv_data->dsfid = rxBuf[10];
|
||||||
data->afi = rxBuf[11];
|
nfcv_data->afi = rxBuf[11];
|
||||||
data->block_num = rxBuf[12] + 1;
|
nfcv_data->block_num = rxBuf[12] + 1;
|
||||||
data->block_size = rxBuf[13] + 1;
|
nfcv_data->block_size = rxBuf[13] + 1;
|
||||||
data->ic_ref = rxBuf[14];
|
nfcv_data->ic_ref = rxBuf[14];
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
TAG,
|
TAG,
|
||||||
" UID: %02X %02X %02X %02X %02X %02X %02X %02X",
|
" UID: %02X %02X %02X %02X %02X %02X %02X %02X",
|
||||||
@@ -115,11 +116,11 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) {
|
|||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
TAG,
|
TAG,
|
||||||
" DSFID %d, AFI %d, Blocks %d, Size %d, IC Ref %d",
|
" DSFID %d, AFI %d, Blocks %d, Size %d, IC Ref %d",
|
||||||
data->dsfid,
|
nfcv_data->dsfid,
|
||||||
data->afi,
|
nfcv_data->afi,
|
||||||
data->block_num,
|
nfcv_data->block_num,
|
||||||
data->block_size,
|
nfcv_data->block_size,
|
||||||
data->ic_ref);
|
nfcv_data->ic_ref);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
FURI_LOG_D(TAG, "Failed: %d", ret);
|
FURI_LOG_D(TAG, "Failed: %d", ret);
|
||||||
@@ -142,18 +143,18 @@ bool nfcv_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* n
|
|||||||
|
|
||||||
if(slix_check_card_type(nfc_data)) {
|
if(slix_check_card_type(nfc_data)) {
|
||||||
FURI_LOG_I(TAG, "NXP SLIX detected");
|
FURI_LOG_I(TAG, "NXP SLIX detected");
|
||||||
nfcv_data->type = NfcVTypeSlix;
|
nfcv_data->sub_type = NfcVTypeSlix;
|
||||||
} else if(slix2_check_card_type(nfc_data)) {
|
} else if(slix2_check_card_type(nfc_data)) {
|
||||||
FURI_LOG_I(TAG, "NXP SLIX2 detected");
|
FURI_LOG_I(TAG, "NXP SLIX2 detected");
|
||||||
nfcv_data->type = NfcVTypeSlix2;
|
nfcv_data->sub_type = NfcVTypeSlix2;
|
||||||
} else if(slix_s_check_card_type(nfc_data)) {
|
} else if(slix_s_check_card_type(nfc_data)) {
|
||||||
FURI_LOG_I(TAG, "NXP SLIX-S detected");
|
FURI_LOG_I(TAG, "NXP SLIX-S detected");
|
||||||
nfcv_data->type = NfcVTypeSlixS;
|
nfcv_data->sub_type = NfcVTypeSlixS;
|
||||||
} else if(slix_l_check_card_type(nfc_data)) {
|
} else if(slix_l_check_card_type(nfc_data)) {
|
||||||
FURI_LOG_I(TAG, "NXP SLIX-L detected");
|
FURI_LOG_I(TAG, "NXP SLIX-L detected");
|
||||||
nfcv_data->type = NfcVTypeSlixL;
|
nfcv_data->sub_type = NfcVTypeSlixL;
|
||||||
} else {
|
} else {
|
||||||
nfcv_data->type = NfcVTypePlain;
|
nfcv_data->sub_type = NfcVTypePlain;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -179,97 +180,128 @@ void nfcv_crc(uint8_t* data, uint32_t length) {
|
|||||||
data[length + 1] = crc >> 8;
|
data[length + 1] = crc >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfcv_emu_free(NfcVData* data) {
|
void nfcv_emu_free(NfcVData* nfcv_data) {
|
||||||
digital_sequence_free(data->emu_air.nfcv_signal);
|
if(nfcv_data->emu_air.nfcv_signal) {
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_unmod_256);
|
digital_sequence_free(nfcv_data->emu_air.nfcv_signal);
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_pulse_32);
|
}
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_one);
|
if(nfcv_data->emu_air.nfcv_resp_unmod_256) {
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_zero);
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_sof);
|
}
|
||||||
digital_signal_free(data->emu_air.nfcv_resp_eof);
|
if(nfcv_data->emu_air.nfcv_resp_pulse_32) {
|
||||||
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_pulse_32);
|
||||||
|
}
|
||||||
|
if(nfcv_data->emu_air.nfcv_resp_one) {
|
||||||
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_one);
|
||||||
|
}
|
||||||
|
if(nfcv_data->emu_air.nfcv_resp_zero) {
|
||||||
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_zero);
|
||||||
|
}
|
||||||
|
if(nfcv_data->emu_air.nfcv_resp_sof) {
|
||||||
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_sof);
|
||||||
|
}
|
||||||
|
if(nfcv_data->emu_air.nfcv_resp_eof) {
|
||||||
|
digital_signal_free(nfcv_data->emu_air.nfcv_resp_eof);
|
||||||
|
}
|
||||||
|
if(nfcv_data->emu_air.reader_signal) {
|
||||||
|
pulse_reader_free(nfcv_data->emu_air.reader_signal);
|
||||||
|
}
|
||||||
|
|
||||||
data->emu_air.nfcv_signal = NULL;
|
nfcv_data->emu_air.nfcv_signal = NULL;
|
||||||
data->emu_air.nfcv_resp_unmod_256 = NULL;
|
nfcv_data->emu_air.nfcv_resp_unmod_256 = NULL;
|
||||||
data->emu_air.nfcv_resp_pulse_32 = NULL;
|
nfcv_data->emu_air.nfcv_resp_pulse_32 = NULL;
|
||||||
data->emu_air.nfcv_resp_one = NULL;
|
nfcv_data->emu_air.nfcv_resp_one = NULL;
|
||||||
data->emu_air.nfcv_resp_zero = NULL;
|
nfcv_data->emu_air.nfcv_resp_zero = NULL;
|
||||||
data->emu_air.nfcv_resp_sof = NULL;
|
nfcv_data->emu_air.nfcv_resp_sof = NULL;
|
||||||
data->emu_air.nfcv_resp_eof = NULL;
|
nfcv_data->emu_air.nfcv_resp_eof = NULL;
|
||||||
|
nfcv_data->emu_air.reader_signal = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfcv_emu_alloc(NfcVData* data) {
|
void nfcv_emu_alloc(NfcVData* nfcv_data) {
|
||||||
if(!data->emu_air.nfcv_signal) {
|
if(!nfcv_data->emu_air.nfcv_signal) {
|
||||||
/* assuming max frame length is 255 bytes */
|
/* assuming max frame length is 255 bytes */
|
||||||
data->emu_air.nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi);
|
nfcv_data->emu_air.nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!data->emu_air.nfcv_resp_unmod_256) {
|
if(!nfcv_data->emu_air.nfcv_resp_unmod_256) {
|
||||||
/* unmodulated 256/fc signal as building block */
|
/* unmodulated 256/fc signal as building block */
|
||||||
data->emu_air.nfcv_resp_unmod_256 = digital_signal_alloc(4);
|
nfcv_data->emu_air.nfcv_resp_unmod_256 = digital_signal_alloc(4);
|
||||||
data->emu_air.nfcv_resp_unmod_256->start_level = false;
|
nfcv_data->emu_air.nfcv_resp_unmod_256->start_level = false;
|
||||||
data->emu_air.nfcv_resp_unmod_256->edge_timings[0] =
|
nfcv_data->emu_air.nfcv_resp_unmod_256->edge_timings[0] =
|
||||||
(uint32_t)(NFCV_RESP_SUBC1_UNMOD_256 * DIGITAL_SIGNAL_UNIT_S);
|
(uint32_t)(NFCV_RESP_SUBC1_UNMOD_256 * DIGITAL_SIGNAL_UNIT_S);
|
||||||
data->emu_air.nfcv_resp_unmod_256->edge_cnt = 1;
|
nfcv_data->emu_air.nfcv_resp_unmod_256->edge_cnt = 1;
|
||||||
}
|
}
|
||||||
if(!data->emu_air.nfcv_resp_pulse_32) {
|
if(!nfcv_data->emu_air.nfcv_resp_pulse_32) {
|
||||||
/* modulated fc/32 pulse as building block */
|
/* modulated fc/32 pulse as building block */
|
||||||
data->emu_air.nfcv_resp_pulse_32 = digital_signal_alloc(4);
|
nfcv_data->emu_air.nfcv_resp_pulse_32 = digital_signal_alloc(4);
|
||||||
data->emu_air.nfcv_resp_pulse_32->start_level = true;
|
nfcv_data->emu_air.nfcv_resp_pulse_32->start_level = true;
|
||||||
data->emu_air.nfcv_resp_pulse_32->edge_timings[0] =
|
nfcv_data->emu_air.nfcv_resp_pulse_32->edge_timings[0] =
|
||||||
(uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S);
|
(uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S);
|
||||||
data->emu_air.nfcv_resp_pulse_32->edge_timings[1] =
|
nfcv_data->emu_air.nfcv_resp_pulse_32->edge_timings[1] =
|
||||||
(uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S);
|
(uint32_t)(NFCV_RESP_SUBC1_PULSE_32 * DIGITAL_SIGNAL_UNIT_S);
|
||||||
data->emu_air.nfcv_resp_pulse_32->edge_cnt = 2;
|
nfcv_data->emu_air.nfcv_resp_pulse_32->edge_cnt = 2;
|
||||||
}
|
}
|
||||||
if(!data->emu_air.nfcv_resp_one) {
|
if(!nfcv_data->emu_air.nfcv_resp_one) {
|
||||||
/* logical one: 256/fc unmodulated then 8 pulses fc/32 */
|
/* logical one: 256/fc unmodulated then 8 pulses fc/32 */
|
||||||
data->emu_air.nfcv_resp_one = digital_signal_alloc(24);
|
nfcv_data->emu_air.nfcv_resp_one = digital_signal_alloc(24);
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_one, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_one, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
for(size_t i = 0; i < 8; i++) {
|
for(size_t i = 0; i < 8; i++) {
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_one, data->emu_air.nfcv_resp_pulse_32);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_one, nfcv_data->emu_air.nfcv_resp_pulse_32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!data->emu_air.nfcv_resp_zero) {
|
if(!nfcv_data->emu_air.nfcv_resp_zero) {
|
||||||
/* logical zero: 8 pulses fc/32 then 256/fc unmodulated */
|
/* logical zero: 8 pulses fc/32 then 256/fc unmodulated */
|
||||||
data->emu_air.nfcv_resp_zero = digital_signal_alloc(24);
|
nfcv_data->emu_air.nfcv_resp_zero = digital_signal_alloc(24);
|
||||||
for(size_t i = 0; i < 8; i++) {
|
for(size_t i = 0; i < 8; i++) {
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_zero, data->emu_air.nfcv_resp_pulse_32);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_zero, nfcv_data->emu_air.nfcv_resp_pulse_32);
|
||||||
}
|
}
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_zero, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_zero, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
}
|
}
|
||||||
if(!data->emu_air.nfcv_resp_sof) {
|
if(!nfcv_data->emu_air.nfcv_resp_sof) {
|
||||||
/* SOF: unmodulated 768/fc, 24 pulses fc/32, logic 1 */
|
/* SOF: unmodulated 768/fc, 24 pulses fc/32, logic 1 */
|
||||||
data->emu_air.nfcv_resp_sof = digital_signal_alloc(128);
|
nfcv_data->emu_air.nfcv_resp_sof = digital_signal_alloc(128);
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256);
|
nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
for(size_t i = 0; i < 24; i++) {
|
for(size_t i = 0; i < 24; i++) {
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_pulse_32);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_pulse_32);
|
||||||
}
|
}
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_sof, data->emu_air.nfcv_resp_one);
|
digital_signal_append(nfcv_data->emu_air.nfcv_resp_sof, nfcv_data->emu_air.nfcv_resp_one);
|
||||||
}
|
}
|
||||||
if(!data->emu_air.nfcv_resp_eof) {
|
if(!nfcv_data->emu_air.nfcv_resp_eof) {
|
||||||
/* EOF: logic 0, 24 pulses fc/32, unmodulated 768/fc */
|
/* EOF: logic 0, 24 pulses fc/32, unmodulated 768/fc */
|
||||||
data->emu_air.nfcv_resp_eof = digital_signal_alloc(128);
|
nfcv_data->emu_air.nfcv_resp_eof = digital_signal_alloc(128);
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_zero);
|
digital_signal_append(nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_zero);
|
||||||
for(size_t i = 0; i < 24; i++) {
|
for(size_t i = 0; i < 24; i++) {
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_pulse_32);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_pulse_32);
|
||||||
}
|
}
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256);
|
nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
/* add extra silence */
|
/* add extra silence */
|
||||||
digital_signal_append(data->emu_air.nfcv_resp_eof, data->emu_air.nfcv_resp_unmod_256);
|
digital_signal_append(
|
||||||
|
nfcv_data->emu_air.nfcv_resp_eof, nfcv_data->emu_air.nfcv_resp_unmod_256);
|
||||||
}
|
}
|
||||||
|
|
||||||
digital_sequence_set_signal(
|
digital_sequence_set_signal(
|
||||||
data->emu_air.nfcv_signal, NFCV_SIG_SOF, data->emu_air.nfcv_resp_sof);
|
nfcv_data->emu_air.nfcv_signal, NFCV_SIG_SOF, nfcv_data->emu_air.nfcv_resp_sof);
|
||||||
digital_sequence_set_signal(
|
digital_sequence_set_signal(
|
||||||
data->emu_air.nfcv_signal, NFCV_SIG_BIT0, data->emu_air.nfcv_resp_zero);
|
nfcv_data->emu_air.nfcv_signal, NFCV_SIG_BIT0, nfcv_data->emu_air.nfcv_resp_zero);
|
||||||
digital_sequence_set_signal(
|
digital_sequence_set_signal(
|
||||||
data->emu_air.nfcv_signal, NFCV_SIG_BIT1, data->emu_air.nfcv_resp_one);
|
nfcv_data->emu_air.nfcv_signal, NFCV_SIG_BIT1, nfcv_data->emu_air.nfcv_resp_one);
|
||||||
digital_sequence_set_signal(
|
digital_sequence_set_signal(
|
||||||
data->emu_air.nfcv_signal, NFCV_SIG_EOF, data->emu_air.nfcv_resp_eof);
|
nfcv_data->emu_air.nfcv_signal, NFCV_SIG_EOF, nfcv_data->emu_air.nfcv_resp_eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfcv_emu_send(
|
void nfcv_emu_send(
|
||||||
@@ -277,7 +309,8 @@ void nfcv_emu_send(
|
|||||||
NfcVData* nfcv,
|
NfcVData* nfcv,
|
||||||
uint8_t* data,
|
uint8_t* data,
|
||||||
uint8_t length,
|
uint8_t length,
|
||||||
NfcVSendFlags flags) {
|
NfcVSendFlags flags,
|
||||||
|
uint32_t send_time) {
|
||||||
/* picked default value (0) to match the most common format */
|
/* picked default value (0) to match the most common format */
|
||||||
if(!flags) {
|
if(!flags) {
|
||||||
flags = NfcVSendFlagsSof | NfcVSendFlagsCrc | NfcVSendFlagsEof |
|
flags = NfcVSendFlagsSof | NfcVSendFlagsCrc | NfcVSendFlagsEof |
|
||||||
@@ -309,6 +342,7 @@ void nfcv_emu_send(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
|
digital_sequence_set_sendtime(nfcv->emu_air.nfcv_signal, send_time);
|
||||||
digital_sequence_send(nfcv->emu_air.nfcv_signal);
|
digital_sequence_send(nfcv->emu_air.nfcv_signal);
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
|
||||||
@@ -318,13 +352,13 @@ void nfcv_emu_send(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfcv_uidcpy(uint8_t* dst, uint8_t* src) {
|
static void nfcv_revuidcpy(uint8_t* dst, uint8_t* src) {
|
||||||
for(int pos = 0; pos < 8; pos++) {
|
for(int pos = 0; pos < 8; pos++) {
|
||||||
dst[pos] = src[7 - pos];
|
dst[pos] = src[7 - pos];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfcv_uidcmp(uint8_t* dst, uint8_t* src) {
|
static int nfcv_revuidcmp(uint8_t* dst, uint8_t* src) {
|
||||||
for(int pos = 0; pos < 8; pos++) {
|
for(int pos = 0; pos < 8; pos++) {
|
||||||
if(dst[pos] != src[7 - pos]) {
|
if(dst[pos] != src[7 - pos]) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -336,37 +370,29 @@ static int nfcv_uidcmp(uint8_t* dst, uint8_t* src) {
|
|||||||
void nfcv_emu_handle_packet(
|
void nfcv_emu_handle_packet(
|
||||||
FuriHalNfcTxRxContext* tx_rx,
|
FuriHalNfcTxRxContext* tx_rx,
|
||||||
FuriHalNfcDevData* nfc_data,
|
FuriHalNfcDevData* nfc_data,
|
||||||
void* nfcv_data_in,
|
void* nfcv_data_in) {
|
||||||
uint8_t* payload,
|
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
|
||||||
uint32_t payload_length) {
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
if(!payload_length) {
|
|
||||||
|
if(nfcv_data->frame_length < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
|
/* parse the frame data for the upcoming part 3 handling */
|
||||||
NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx;
|
ctx->flags = nfcv_data->frame[0];
|
||||||
|
ctx->command = nfcv_data->frame[1];
|
||||||
ctx->frame = payload;
|
|
||||||
ctx->frame_length = payload_length;
|
|
||||||
ctx->flags = ctx->frame[0];
|
|
||||||
ctx->command = ctx->frame[1];
|
|
||||||
ctx->addressed = !(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) &&
|
ctx->addressed = !(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) &&
|
||||||
(ctx->flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
|
(ctx->flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
|
||||||
ctx->advanced = (ctx->command >= 0xA0);
|
ctx->advanced = (ctx->command >= 0xA0);
|
||||||
ctx->address_offset = 2 + (ctx->advanced ? 1 : 0);
|
ctx->address_offset = 2 + (ctx->advanced ? 1 : 0);
|
||||||
ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0);
|
ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0);
|
||||||
ctx->response_flags = NfcVSendFlagsNormal;
|
ctx->response_flags = NfcVSendFlagsNormal;
|
||||||
|
ctx->send_time = nfcv_data->eof_timestamp + NFCV_FDT_FC(4130);
|
||||||
|
|
||||||
/* first give control to the card specific protocol handler */
|
/* standard behavior is implemented */
|
||||||
if(nfcv_data->emu_protocol_filter != NULL) {
|
|
||||||
if(nfcv_data->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ctx->addressed) {
|
if(ctx->addressed) {
|
||||||
uint8_t* address = &ctx->frame[ctx->address_offset];
|
uint8_t* address = &nfcv_data->frame[ctx->address_offset];
|
||||||
if(nfcv_uidcmp(address, nfc_data->uid)) {
|
if(nfcv_revuidcmp(address, nfc_data->uid)) {
|
||||||
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
|
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
TAG,
|
TAG,
|
||||||
@@ -394,16 +420,25 @@ void nfcv_emu_handle_packet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unfortunately our response is quicker than the original NFC tag which causes frame misses */
|
/* then give control to the card subtype specific protocol filter */
|
||||||
furi_delay_us(270);
|
if(ctx->emu_protocol_filter != NULL) {
|
||||||
|
if(ctx->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) {
|
||||||
|
if(strlen(nfcv_data->last_command) > 0) {
|
||||||
|
FURI_LOG_D(
|
||||||
|
TAG, "Received command %s (handled by filter)", nfcv_data->last_command);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(ctx->command) {
|
switch(ctx->command) {
|
||||||
case ISO15693_INVENTORY: {
|
case ISO15693_INVENTORY: {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
ctx->response_buffer[1] = nfcv_data->dsfid;
|
ctx->response_buffer[1] = nfcv_data->dsfid;
|
||||||
nfcv_uidcpy(&ctx->response_buffer[2], nfc_data->uid);
|
nfcv_revuidcpy(&ctx->response_buffer[2], nfc_data->uid);
|
||||||
|
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 10, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 10, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY");
|
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -420,23 +455,25 @@ void nfcv_emu_handle_packet(
|
|||||||
|
|
||||||
case ISO15693_SELECT: {
|
case ISO15693_SELECT: {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SELECT");
|
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SELECT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ISO15693_READ_MULTI_BLOCK:
|
case ISO15693_READ_MULTI_BLOCK:
|
||||||
case ISO15693_READBLOCK: {
|
case ISO15693_READBLOCK: {
|
||||||
uint8_t block = ctx->frame[ctx->payload_offset];
|
uint8_t block = nfcv_data->frame[ctx->payload_offset];
|
||||||
uint8_t blocks = 1;
|
uint8_t blocks = 1;
|
||||||
|
|
||||||
if(ctx->command == ISO15693_READ_MULTI_BLOCK) {
|
if(ctx->command == ISO15693_READ_MULTI_BLOCK) {
|
||||||
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
|
blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block + blocks > nfcv_data->block_num) {
|
if(block + blocks > nfcv_data->block_num) {
|
||||||
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
|
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time);
|
||||||
} else {
|
} else {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
memcpy(
|
memcpy(
|
||||||
@@ -448,7 +485,8 @@ void nfcv_emu_handle_packet(
|
|||||||
nfcv_data,
|
nfcv_data,
|
||||||
ctx->response_buffer,
|
ctx->response_buffer,
|
||||||
1 + nfcv_data->block_size * blocks,
|
1 + nfcv_data->block_size * blocks,
|
||||||
ctx->response_flags);
|
ctx->response_flags,
|
||||||
|
ctx->send_time);
|
||||||
}
|
}
|
||||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "READ BLOCK %d", block);
|
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "READ BLOCK %d", block);
|
||||||
break;
|
break;
|
||||||
@@ -456,29 +494,30 @@ void nfcv_emu_handle_packet(
|
|||||||
|
|
||||||
case ISO15693_WRITE_MULTI_BLOCK:
|
case ISO15693_WRITE_MULTI_BLOCK:
|
||||||
case ISO15693_WRITEBLOCK: {
|
case ISO15693_WRITEBLOCK: {
|
||||||
uint8_t block = ctx->frame[ctx->payload_offset];
|
uint8_t block = nfcv_data->frame[ctx->payload_offset];
|
||||||
uint8_t blocks = 1;
|
uint8_t blocks = 1;
|
||||||
uint8_t data_pos = 1;
|
uint8_t data_pos = 1;
|
||||||
|
|
||||||
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
|
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
|
||||||
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
|
blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1;
|
||||||
data_pos++;
|
data_pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* data = &ctx->frame[ctx->payload_offset + data_pos];
|
uint8_t* data = &nfcv_data->frame[ctx->payload_offset + data_pos];
|
||||||
uint32_t data_len = nfcv_data->block_size * blocks;
|
uint32_t data_len = nfcv_data->block_size * blocks;
|
||||||
|
|
||||||
if(block + blocks > nfcv_data->block_num ||
|
if(block + blocks > nfcv_data->block_num ||
|
||||||
ctx->payload_offset + data_len + 2 > payload_length) {
|
ctx->payload_offset + data_len + 2 > nfcv_data->frame_length) {
|
||||||
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
|
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
|
||||||
} else {
|
} else {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
memcpy(
|
memcpy(
|
||||||
&nfcv_data->data[nfcv_data->block_size * block],
|
&nfcv_data->data[nfcv_data->block_size * block],
|
||||||
&ctx->frame[ctx->payload_offset + data_pos],
|
&nfcv_data->frame[ctx->payload_offset + data_pos],
|
||||||
data_len);
|
data_len);
|
||||||
}
|
}
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time);
|
||||||
|
|
||||||
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
|
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
|
||||||
snprintf(
|
snprintf(
|
||||||
@@ -504,14 +543,15 @@ void nfcv_emu_handle_packet(
|
|||||||
case ISO15693_GET_SYSTEM_INFO: {
|
case ISO15693_GET_SYSTEM_INFO: {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
ctx->response_buffer[1] = 0x0F;
|
ctx->response_buffer[1] = 0x0F;
|
||||||
nfcv_uidcpy(&ctx->response_buffer[2], nfc_data->uid);
|
nfcv_revuidcpy(&ctx->response_buffer[2], nfc_data->uid);
|
||||||
ctx->response_buffer[10] = nfcv_data->dsfid; /* DSFID */
|
ctx->response_buffer[10] = nfcv_data->dsfid; /* DSFID */
|
||||||
ctx->response_buffer[11] = nfcv_data->afi; /* AFI */
|
ctx->response_buffer[11] = nfcv_data->afi; /* AFI */
|
||||||
ctx->response_buffer[12] = nfcv_data->block_num - 1; /* number of blocks */
|
ctx->response_buffer[12] = nfcv_data->block_num - 1; /* number of blocks */
|
||||||
ctx->response_buffer[13] = nfcv_data->block_size - 1; /* block size */
|
ctx->response_buffer[13] = nfcv_data->block_size - 1; /* block size */
|
||||||
ctx->response_buffer[14] = nfcv_data->ic_ref; /* IC reference */
|
ctx->response_buffer[14] = nfcv_data->ic_ref; /* IC reference */
|
||||||
|
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 15, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 15, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO");
|
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -533,15 +573,22 @@ void nfcv_emu_handle_packet(
|
|||||||
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
||||||
nfcv_emu_alloc(nfcv_data);
|
nfcv_emu_alloc(nfcv_data);
|
||||||
rfal_platform_spi_acquire();
|
rfal_platform_spi_acquire();
|
||||||
|
/* configure for transparent and passive mode */
|
||||||
st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
|
st25r3916ExecuteCommand(ST25R3916_CMD_STOP);
|
||||||
|
/* set enable, rx_enable and field detector enable */
|
||||||
st25r3916WriteRegister(ST25R3916_REG_OP_CONTROL, 0xC3);
|
st25r3916WriteRegister(ST25R3916_REG_OP_CONTROL, 0xC3);
|
||||||
|
/* target mode: ISO14443 passive mode */
|
||||||
st25r3916WriteRegister(ST25R3916_REG_MODE, 0x88);
|
st25r3916WriteRegister(ST25R3916_REG_MODE, 0x88);
|
||||||
|
/* let us modulate the field using MOSI, read modulation using MISO */
|
||||||
st25r3916ExecuteCommand(ST25R3916_CMD_TRANSPARENT_MODE);
|
st25r3916ExecuteCommand(ST25R3916_CMD_TRANSPARENT_MODE);
|
||||||
|
|
||||||
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
|
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
|
||||||
|
|
||||||
|
/* if not set already, initialize the default protocol handler */
|
||||||
|
if(!nfcv_data->emu_protocol_ctx) {
|
||||||
|
nfcv_data->emu_protocol_ctx = malloc(sizeof(NfcVEmuProtocolCtx));
|
||||||
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
|
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
|
||||||
|
}
|
||||||
|
|
||||||
FURI_LOG_D(TAG, "Starting NfcV emulation");
|
FURI_LOG_D(TAG, "Starting NfcV emulation");
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
@@ -556,7 +603,7 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
|||||||
nfc_data->uid[6],
|
nfc_data->uid[6],
|
||||||
nfc_data->uid[7]);
|
nfc_data->uid[7]);
|
||||||
|
|
||||||
switch(nfcv_data->type) {
|
switch(nfcv_data->sub_type) {
|
||||||
case NfcVTypeSlixL:
|
case NfcVTypeSlixL:
|
||||||
FURI_LOG_D(TAG, " Card type: SLIX-L");
|
FURI_LOG_D(TAG, " Card type: SLIX-L");
|
||||||
slix_l_prepare(nfcv_data);
|
slix_l_prepare(nfcv_data);
|
||||||
@@ -592,7 +639,10 @@ void nfcv_emu_deinit(NfcVData* nfcv_data) {
|
|||||||
rfal_platform_spi_release();
|
rfal_platform_spi_release();
|
||||||
nfcv_emu_free(nfcv_data);
|
nfcv_emu_free(nfcv_data);
|
||||||
|
|
||||||
pulse_reader_free(nfcv_data->emu_air.reader_signal);
|
if(nfcv_data->emu_protocol_ctx) {
|
||||||
|
free(nfcv_data->emu_protocol_ctx);
|
||||||
|
nfcv_data->emu_protocol_ctx = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nfcv_emu_loop(
|
bool nfcv_emu_loop(
|
||||||
@@ -613,6 +663,7 @@ bool nfcv_emu_loop(
|
|||||||
while(true) {
|
while(true) {
|
||||||
uint32_t periods =
|
uint32_t periods =
|
||||||
pulse_reader_receive(nfcv_data->emu_air.reader_signal, timeout_ms * 1000);
|
pulse_reader_receive(nfcv_data->emu_air.reader_signal, timeout_ms * 1000);
|
||||||
|
uint32_t timestamp = DWT->CYCCNT;
|
||||||
|
|
||||||
if(periods == PULSE_READER_NO_EDGE) {
|
if(periods == PULSE_READER_NO_EDGE) {
|
||||||
break;
|
break;
|
||||||
@@ -754,6 +805,9 @@ bool nfcv_emu_loop(
|
|||||||
|
|
||||||
FURI_LOG_D(TAG, "Resetting state machine, reason: '%s'", reset_reason);
|
FURI_LOG_D(TAG, "Resetting state machine, reason: '%s'", reset_reason);
|
||||||
} else if(frame_state == NFCV_FRAME_STATE_EOF) {
|
} else if(frame_state == NFCV_FRAME_STATE_EOF) {
|
||||||
|
nfcv_data->frame = frame_payload;
|
||||||
|
nfcv_data->frame_length = frame_pos;
|
||||||
|
nfcv_data->eof_timestamp = timestamp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -764,7 +818,7 @@ bool nfcv_emu_loop(
|
|||||||
if(tx_rx->sniff_rx) {
|
if(tx_rx->sniff_rx) {
|
||||||
tx_rx->sniff_rx(frame_payload, frame_pos * 8, false, tx_rx->sniff_context);
|
tx_rx->sniff_rx(frame_payload, frame_pos * 8, false, tx_rx->sniff_context);
|
||||||
}
|
}
|
||||||
nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos);
|
nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data);
|
||||||
pulse_reader_start(nfcv_data->emu_air.reader_signal);
|
pulse_reader_start(nfcv_data->emu_air.reader_signal);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "nfc_util.h"
|
#include "nfc_util.h"
|
||||||
#include <furi_hal_nfc.h>
|
#include <furi_hal_nfc.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NFCV_FC (13560000.0f) /* MHz */
|
#define NFCV_FC (13560000.0f) /* MHz */
|
||||||
#define NFCV_RESP_SUBC1_PULSE_32 (1.0f / (NFCV_FC / 32) / 2.0f) /* 1.1799 µs */
|
#define NFCV_RESP_SUBC1_PULSE_32 (1.0f / (NFCV_FC / 32) / 2.0f) /* 1.1799 µs */
|
||||||
#define NFCV_RESP_SUBC1_UNMOD_256 (256.0f / NFCV_FC) /* 18.8791 µs */
|
#define NFCV_RESP_SUBC1_UNMOD_256 (256.0f / NFCV_FC) /* 18.8791 µs */
|
||||||
@@ -21,6 +25,10 @@
|
|||||||
#define NFCV_BLOCK_SIZE 4
|
#define NFCV_BLOCK_SIZE 4
|
||||||
#define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE * NFCV_TOTAL_BLOCKS_MAX)
|
#define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE * NFCV_TOTAL_BLOCKS_MAX)
|
||||||
|
|
||||||
|
/* helpers to calculate the send time based on DWT->CYCCNT */
|
||||||
|
#define NFCV_FDT_USEC(usec) (usec * 64)
|
||||||
|
#define NFCV_FDT_FC(ticks) (ticks * 6400 / 1356)
|
||||||
|
|
||||||
#define NFCV_FRAME_STATE_SOF1 0
|
#define NFCV_FRAME_STATE_SOF1 0
|
||||||
#define NFCV_FRAME_STATE_SOF2 1
|
#define NFCV_FRAME_STATE_SOF2 1
|
||||||
#define NFCV_FRAME_STATE_CODING_4 2
|
#define NFCV_FRAME_STATE_CODING_4 2
|
||||||
@@ -73,7 +81,7 @@ typedef enum {
|
|||||||
NfcVTypeSlixS = 2,
|
NfcVTypeSlixS = 2,
|
||||||
NfcVTypeSlixL = 3,
|
NfcVTypeSlixL = 3,
|
||||||
NfcVTypeSlix2 = 4,
|
NfcVTypeSlix2 = 4,
|
||||||
} NfcVType;
|
} NfcVSubtype;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NfcVSendFlagsNormal = 0,
|
NfcVSendFlagsNormal = 0,
|
||||||
@@ -113,10 +121,16 @@ typedef struct {
|
|||||||
DigitalSequence* nfcv_signal;
|
DigitalSequence* nfcv_signal;
|
||||||
} NfcVEmuAir;
|
} NfcVEmuAir;
|
||||||
|
|
||||||
typedef struct {
|
typedef void (*NfcVEmuProtocolHandler)(
|
||||||
uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */
|
FuriHalNfcTxRxContext* tx_rx,
|
||||||
uint8_t frame_length; /* ISO15693-2 length of incoming data */
|
FuriHalNfcDevData* nfc_data,
|
||||||
|
void* nfcv_data);
|
||||||
|
typedef bool (*NfcVEmuProtocolFilter)(
|
||||||
|
FuriHalNfcTxRxContext* tx_rx,
|
||||||
|
FuriHalNfcDevData* nfc_data,
|
||||||
|
void* nfcv_data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
uint8_t flags; /* ISO15693-3 flags of the header as specified */
|
uint8_t flags; /* ISO15693-3 flags of the header as specified */
|
||||||
uint8_t command; /* ISO15693-3 command at offset 1 as specified */
|
uint8_t command; /* ISO15693-3 command at offset 1 as specified */
|
||||||
bool addressed; /* ISO15693-3 flags: addressed frame */
|
bool addressed; /* ISO15693-3 flags: addressed frame */
|
||||||
@@ -126,21 +140,13 @@ typedef struct {
|
|||||||
|
|
||||||
uint8_t response_buffer[128]; /* pre-allocated response buffer */
|
uint8_t response_buffer[128]; /* pre-allocated response buffer */
|
||||||
NfcVSendFlags response_flags; /* flags to use when sending response */
|
NfcVSendFlags response_flags; /* flags to use when sending response */
|
||||||
|
uint32_t send_time; /* timestamp when to send the response */
|
||||||
|
|
||||||
|
NfcVEmuProtocolFilter emu_protocol_filter;
|
||||||
} NfcVEmuProtocolCtx;
|
} NfcVEmuProtocolCtx;
|
||||||
|
|
||||||
typedef void (*NfcVEmuProtocolHandler)(
|
|
||||||
FuriHalNfcTxRxContext* tx_rx,
|
|
||||||
FuriHalNfcDevData* nfc_data,
|
|
||||||
void* nfcv_data,
|
|
||||||
uint8_t* payload,
|
|
||||||
uint32_t payload_length);
|
|
||||||
typedef bool (*NfcVEmuProtocolFilter)(
|
|
||||||
FuriHalNfcTxRxContext* tx_rx,
|
|
||||||
FuriHalNfcDevData* nfc_data,
|
|
||||||
void* nfcv_data);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* common ISO15693 fields */
|
/* common ISO15693 fields, being specified in ISO15693-3 */
|
||||||
uint8_t dsfid;
|
uint8_t dsfid;
|
||||||
uint8_t afi;
|
uint8_t afi;
|
||||||
uint8_t ic_ref;
|
uint8_t ic_ref;
|
||||||
@@ -149,18 +155,24 @@ typedef struct {
|
|||||||
uint8_t data[NFCV_MAX_DUMP_SIZE];
|
uint8_t data[NFCV_MAX_DUMP_SIZE];
|
||||||
|
|
||||||
/* specfic variant infos */
|
/* specfic variant infos */
|
||||||
NfcVType type;
|
NfcVSubtype sub_type;
|
||||||
NfcVSubtypeData sub_data;
|
NfcVSubtypeData sub_data;
|
||||||
|
NfcVAuthMethod auth_method;
|
||||||
|
|
||||||
|
/* precalced air level data */
|
||||||
NfcVEmuAir emu_air;
|
NfcVEmuAir emu_air;
|
||||||
NfcVEmuProtocolCtx emu_protocol_ctx;
|
|
||||||
|
uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */
|
||||||
|
uint8_t frame_length; /* ISO15693-2 length of incoming data */
|
||||||
|
uint32_t eof_timestamp; /* ISO15693-2 EOF timestamp, read from DWT->CYCCNT */
|
||||||
|
|
||||||
|
/* handler for the protocol layer as specified in ISO15693-3 */
|
||||||
NfcVEmuProtocolHandler emu_protocol_handler;
|
NfcVEmuProtocolHandler emu_protocol_handler;
|
||||||
NfcVEmuProtocolFilter emu_protocol_filter;
|
void* emu_protocol_ctx;
|
||||||
|
|
||||||
/* runtime data */
|
/* runtime data */
|
||||||
char last_command[128];
|
char last_command[128];
|
||||||
char error[32];
|
char error[32];
|
||||||
NfcVAuthMethod auth_method;
|
|
||||||
bool auth_success;
|
|
||||||
} NfcVData;
|
} NfcVData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -175,7 +187,6 @@ bool nfcv_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* d
|
|||||||
|
|
||||||
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data);
|
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data);
|
||||||
void nfcv_emu_deinit(NfcVData* nfcv_data);
|
void nfcv_emu_deinit(NfcVData* nfcv_data);
|
||||||
|
|
||||||
bool nfcv_emu_loop(
|
bool nfcv_emu_loop(
|
||||||
FuriHalNfcTxRxContext* tx_rx,
|
FuriHalNfcTxRxContext* tx_rx,
|
||||||
FuriHalNfcDevData* nfc_data,
|
FuriHalNfcDevData* nfc_data,
|
||||||
@@ -186,4 +197,9 @@ void nfcv_emu_send(
|
|||||||
NfcVData* nfcv,
|
NfcVData* nfcv,
|
||||||
uint8_t* data,
|
uint8_t* data,
|
||||||
uint8_t length,
|
uint8_t length,
|
||||||
NfcVSendFlags flags);
|
NfcVSendFlags flags,
|
||||||
|
uint32_t send_time);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ bool slix_generic_protocol_filter(
|
|||||||
furi_assert(nfcv_data_in);
|
furi_assert(nfcv_data_in);
|
||||||
|
|
||||||
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
|
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
|
||||||
NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx;
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
NfcVSlixData* slix = &nfcv_data->sub_data.slix;
|
NfcVSlixData* slix = &nfcv_data->sub_data.slix;
|
||||||
|
|
||||||
if(slix->privacy && ctx->command != ISO15693_CMD_NXP_GET_RANDOM_NUMBER &&
|
if(slix->privacy && ctx->command != ISO15693_CMD_NXP_GET_RANDOM_NUMBER &&
|
||||||
@@ -172,7 +172,8 @@ bool slix_generic_protocol_filter(
|
|||||||
ctx->response_buffer[1] = slix->rand[1];
|
ctx->response_buffer[1] = slix->rand[1];
|
||||||
ctx->response_buffer[2] = slix->rand[0];
|
ctx->response_buffer[2] = slix->rand[0];
|
||||||
|
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 3, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 3, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(
|
snprintf(
|
||||||
nfcv_data->last_command,
|
nfcv_data->last_command,
|
||||||
sizeof(nfcv_data->last_command),
|
sizeof(nfcv_data->last_command),
|
||||||
@@ -185,13 +186,13 @@ bool slix_generic_protocol_filter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ISO15693_CMD_NXP_SET_PASSWORD: {
|
case ISO15693_CMD_NXP_SET_PASSWORD: {
|
||||||
uint8_t password_id = ctx->frame[ctx->payload_offset];
|
uint8_t password_id = nfcv_data->frame[ctx->payload_offset];
|
||||||
|
|
||||||
if(!(password_id & password_supported)) {
|
if(!(password_id & password_supported)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* password_xored = &ctx->frame[ctx->payload_offset + 1];
|
uint8_t* password_xored = &nfcv_data->frame[ctx->payload_offset + 1];
|
||||||
uint8_t* rand = slix->rand;
|
uint8_t* rand = slix->rand;
|
||||||
uint8_t* password = NULL;
|
uint8_t* password = NULL;
|
||||||
uint8_t password_rcv[4];
|
uint8_t password_rcv[4];
|
||||||
@@ -241,7 +242,8 @@ bool slix_generic_protocol_filter(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(
|
snprintf(
|
||||||
nfcv_data->last_command,
|
nfcv_data->last_command,
|
||||||
sizeof(nfcv_data->last_command),
|
sizeof(nfcv_data->last_command),
|
||||||
@@ -264,7 +266,8 @@ bool slix_generic_protocol_filter(
|
|||||||
case ISO15693_CMD_NXP_ENABLE_PRIVACY: {
|
case ISO15693_CMD_NXP_ENABLE_PRIVACY: {
|
||||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||||
|
|
||||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
nfcv_emu_send(
|
||||||
|
tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags, ctx->send_time);
|
||||||
snprintf(
|
snprintf(
|
||||||
nfcv_data->last_command,
|
nfcv_data->last_command,
|
||||||
sizeof(nfcv_data->last_command),
|
sizeof(nfcv_data->last_command),
|
||||||
@@ -309,7 +312,8 @@ void slix_l_prepare(NfcVData* nfcv_data) {
|
|||||||
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
||||||
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||||
|
|
||||||
nfcv_data->emu_protocol_filter = &slix_l_protocol_filter;
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
|
ctx->emu_protocol_filter = &slix_l_protocol_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool slix_s_protocol_filter(
|
bool slix_s_protocol_filter(
|
||||||
@@ -338,7 +342,8 @@ void slix_s_prepare(NfcVData* nfcv_data) {
|
|||||||
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
||||||
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||||
|
|
||||||
nfcv_data->emu_protocol_filter = &slix_s_protocol_filter;
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
|
ctx->emu_protocol_filter = &slix_s_protocol_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool slix_protocol_filter(
|
bool slix_protocol_filter(
|
||||||
@@ -367,7 +372,8 @@ void slix_prepare(NfcVData* nfcv_data) {
|
|||||||
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
||||||
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||||
|
|
||||||
nfcv_data->emu_protocol_filter = &slix_protocol_filter;
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
|
ctx->emu_protocol_filter = &slix_protocol_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool slix2_protocol_filter(
|
bool slix2_protocol_filter(
|
||||||
@@ -396,5 +402,6 @@ void slix2_prepare(NfcVData* nfcv_data) {
|
|||||||
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
|
||||||
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||||
|
|
||||||
nfcv_data->emu_protocol_filter = &slix2_protocol_filter;
|
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
|
||||||
|
ctx->emu_protocol_filter = &slix2_protocol_filter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,8 +198,5 @@ uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) {
|
|||||||
if(elapsed > timeout_ticks) {
|
if(elapsed > timeout_ticks) {
|
||||||
return PULSE_READER_NO_EDGE;
|
return PULSE_READER_NO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//furi_delay_ms(0);
|
|
||||||
|
|
||||||
} while(true);
|
} while(true);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user