mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-07 19:01:54 -07:00
better layer separation for ISO15693
This commit is contained in:
@@ -181,7 +181,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCV);
|
||||
|
||||
furi_hal_console_printf("Detect presence\r\n");
|
||||
ReturnCode ret = slix_l_get_random(nfcv_data);
|
||||
ReturnCode ret = slix_get_random(nfcv_data);
|
||||
|
||||
if(ret == ERR_NONE) {
|
||||
/* there is some chip, responding with a RAND */
|
||||
@@ -207,13 +207,13 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
|
||||
}
|
||||
|
||||
while(slix_l_get_random(NULL) == ERR_NONE) {
|
||||
while(slix_get_random(NULL) == ERR_NONE) {
|
||||
furi_delay_ms(100);
|
||||
}
|
||||
|
||||
furi_hal_console_printf(" => chip is already visible, wait for chip to disappear.\r\n");
|
||||
nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context);
|
||||
while(slix_l_get_random(NULL) == ERR_NONE) {
|
||||
while(slix_get_random(NULL) == ERR_NONE) {
|
||||
furi_delay_ms(100);
|
||||
}
|
||||
|
||||
@@ -233,14 +233,14 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
key |= key_data[2] << 8;
|
||||
key |= key_data[3] << 0;
|
||||
|
||||
ret = slix_l_unlock(nfcv_data, 4);
|
||||
ret = slix_unlock(nfcv_data, 4);
|
||||
} else {
|
||||
key = 0x7FFD6E5B;
|
||||
key_data[0] = key >> 24;
|
||||
key_data[1] = key >> 16;
|
||||
key_data[2] = key >> 8;
|
||||
key_data[3] = key >> 0;
|
||||
ret = slix_l_unlock(nfcv_data, 4);
|
||||
ret = slix_unlock(nfcv_data, 4);
|
||||
|
||||
if(ret != ERR_NONE) {
|
||||
/* main key failed, trying second one */
|
||||
@@ -251,7 +251,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
furi_delay_ms(20);
|
||||
furi_hal_nfc_ll_txrx_on();
|
||||
|
||||
if(slix_l_get_random(nfcv_data) != ERR_NONE) {
|
||||
if(slix_get_random(nfcv_data) != ERR_NONE) {
|
||||
furi_hal_console_printf(" reset failed\r\n");
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
key_data[1] = key >> 16;
|
||||
key_data[2] = key >> 8;
|
||||
key_data[3] = key >> 0;
|
||||
ret = slix_l_unlock(nfcv_data, 4);
|
||||
ret = slix_unlock(nfcv_data, 4);
|
||||
}
|
||||
}
|
||||
if(ret != ERR_NONE) {
|
||||
@@ -275,7 +275,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
|
||||
furi_hal_nfc_ll_txrx_on();
|
||||
|
||||
/* wait for disappearing */
|
||||
while(slix_l_get_random(NULL) == ERR_NONE) {
|
||||
while(slix_get_random(NULL) == ERR_NONE) {
|
||||
furi_delay_ms(100);
|
||||
}
|
||||
}
|
||||
|
||||
+27
-25
@@ -310,40 +310,40 @@ static int nfcv_uidcmp(uint8_t *dst, uint8_t *src) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint8_t* payload, uint32_t payload_length) {
|
||||
void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint8_t* payload, uint32_t payload_length) {
|
||||
|
||||
if(!payload_length) {
|
||||
return;
|
||||
}
|
||||
|
||||
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
|
||||
NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx;
|
||||
|
||||
ctx->payload = payload;
|
||||
ctx->flags = ctx->payload[0];
|
||||
ctx->command = ctx->payload[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->flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
|
||||
ctx->advanced = (ctx->command >= 0xA0);
|
||||
ctx->address_offset = 2 + (ctx->advanced ? 1 : 0);
|
||||
ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0);
|
||||
ctx->address = &ctx->payload[ctx->address_offset];
|
||||
ctx->response_flags = NfcVSendFlagsNormal;
|
||||
|
||||
bool handled = false;
|
||||
|
||||
/* first give control to the card specific protocol handler */
|
||||
if(nfcv_data->emu_protocol_handler != NULL) {
|
||||
handled = nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data);
|
||||
if(nfcv_data->emu_protocol_filter != NULL) {
|
||||
if(nfcv_data->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(handled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ctx->addressed && nfcv_uidcmp(ctx->address, nfc_data->uid)) {
|
||||
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
|
||||
FURI_LOG_D(TAG, " dest: %02X%02X%02X%02X%02X%02X%02X%02X", ctx->address[7], ctx->address[6], ctx->address[5], ctx->address[4], ctx->address[3], ctx->address[2], ctx->address[1], ctx->address[0]);
|
||||
FURI_LOG_D(TAG, " our UID: %02X%02X%02X%02X%02X%02X%02X%02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
|
||||
return;
|
||||
if(ctx->addressed) {
|
||||
uint8_t* address = &ctx->frame[ctx->address_offset];
|
||||
if(nfcv_uidcmp(address, nfc_data->uid)) {
|
||||
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
|
||||
FURI_LOG_D(TAG, " dest: %02X%02X%02X%02X%02X%02X%02X%02X", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
|
||||
FURI_LOG_D(TAG, " our UID: %02X%02X%02X%02X%02X%02X%02X%02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* unfortunately our response is quicker than the original NFC tag which causes frame misses */
|
||||
@@ -379,11 +379,11 @@ void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
|
||||
|
||||
case ISO15693_READ_MULTI_BLOCK:
|
||||
case ISO15693_READBLOCK: {
|
||||
uint8_t block = ctx->payload[ctx->payload_offset];
|
||||
uint8_t block = ctx->frame[ctx->payload_offset];
|
||||
uint8_t blocks = 1;
|
||||
|
||||
if(ctx->command == ISO15693_READ_MULTI_BLOCK) {
|
||||
blocks = ctx->payload[ctx->payload_offset + 1] + 1;
|
||||
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
|
||||
}
|
||||
|
||||
if(block + blocks > nfcv_data->block_num) {
|
||||
@@ -400,23 +400,23 @@ void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
|
||||
|
||||
case ISO15693_WRITE_MULTI_BLOCK:
|
||||
case ISO15693_WRITEBLOCK: {
|
||||
uint8_t block = ctx->payload[ctx->payload_offset];
|
||||
uint8_t block = ctx->frame[ctx->payload_offset];
|
||||
uint8_t blocks = 1;
|
||||
uint8_t data_pos = 1;
|
||||
|
||||
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
|
||||
blocks = ctx->payload[ctx->payload_offset + 1] + 1;
|
||||
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
|
||||
data_pos++;
|
||||
}
|
||||
|
||||
uint8_t *data = &ctx->payload[ctx->payload_offset + data_pos];
|
||||
uint8_t *data = &ctx->frame[ctx->payload_offset + data_pos];
|
||||
uint32_t data_len = nfcv_data->block_size * blocks;
|
||||
|
||||
if(block + blocks > nfcv_data->block_num || ctx->payload_offset + data_len + 2 > payload_length) {
|
||||
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
|
||||
} else {
|
||||
ctx->response_buffer[0] = ISO15693_NOERROR;
|
||||
memcpy(&nfcv_data->data[nfcv_data->block_size * block], &ctx->payload[ctx->payload_offset + data_pos], data_len);
|
||||
memcpy(&nfcv_data->data[nfcv_data->block_size * block], &ctx->frame[ctx->payload_offset + data_pos], data_len);
|
||||
}
|
||||
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
|
||||
|
||||
@@ -464,6 +464,8 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
|
||||
|
||||
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
|
||||
|
||||
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
|
||||
|
||||
FURI_LOG_D(TAG, "Starting NfcV emulation");
|
||||
FURI_LOG_D(TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X",
|
||||
nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3],
|
||||
@@ -650,7 +652,7 @@ bool nfcv_emu_loop(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, Nf
|
||||
if(tx_rx->sniff_rx) {
|
||||
tx_rx->sniff_rx(frame_payload, frame_pos * 8, false, tx_rx->sniff_context);
|
||||
}
|
||||
nfcv_emu_handle_packet(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos);
|
||||
nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos);
|
||||
pulse_reader_start(nfcv_data->emu_air.reader_signal);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
+15
-11
@@ -122,19 +122,22 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t* payload;
|
||||
uint8_t flags;
|
||||
uint8_t command;
|
||||
bool addressed;
|
||||
bool advanced;
|
||||
uint8_t address_offset;
|
||||
uint8_t payload_offset;
|
||||
uint8_t* address;
|
||||
uint8_t response_buffer[128];
|
||||
NfcVSendFlags response_flags;
|
||||
uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */
|
||||
uint8_t frame_length; /* ISO15693-2 length of incoming data */
|
||||
|
||||
uint8_t flags; /* ISO15693-3 flags of the header as specified */
|
||||
uint8_t command; /* ISO15693-3 command at offset 1 as specified */
|
||||
bool addressed; /* ISO15693-3 flags: addressed frame */
|
||||
bool advanced; /* ISO15693-3 command: advanced command */
|
||||
uint8_t address_offset; /* ISO15693-3 offset of the address in frame, if addressed is set */
|
||||
uint8_t payload_offset; /* ISO15693-3 offset of the payload in frame */
|
||||
|
||||
uint8_t response_buffer[128]; /* pre-allocated response buffer */
|
||||
NfcVSendFlags response_flags; /* flags to use when sending response */
|
||||
} NfcVEmuProtocolCtx;
|
||||
|
||||
typedef bool (*NfcVEmuProtocolHandler) (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data);
|
||||
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 {
|
||||
/* common ISO15693 fields */
|
||||
@@ -151,6 +154,7 @@ typedef struct {
|
||||
NfcVEmuAir emu_air;
|
||||
NfcVEmuProtocolCtx emu_protocol_ctx;
|
||||
NfcVEmuProtocolHandler emu_protocol_handler;
|
||||
NfcVEmuProtocolFilter emu_protocol_filter;
|
||||
|
||||
/* runtime data */
|
||||
char last_command[128];
|
||||
|
||||
+17
-17
@@ -63,7 +63,7 @@ bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data) {
|
||||
}
|
||||
|
||||
|
||||
ReturnCode slix_l_get_random(NfcVData* data) {
|
||||
ReturnCode slix_get_random(NfcVData* data) {
|
||||
uint16_t received = 0;
|
||||
uint8_t rxBuf[32];
|
||||
|
||||
@@ -91,7 +91,7 @@ ReturnCode slix_l_get_random(NfcVData* data) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id) {
|
||||
ReturnCode slix_unlock(NfcVData* data, uint32_t password_id) {
|
||||
furi_assert(rand);
|
||||
|
||||
uint16_t received = 0;
|
||||
@@ -148,7 +148,7 @@ ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id) {
|
||||
}
|
||||
|
||||
|
||||
bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint32_t password_supported) {
|
||||
bool slix_generic_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint32_t password_supported) {
|
||||
furi_assert(tx_rx);
|
||||
furi_assert(nfc_data);
|
||||
furi_assert(nfcv_data_in);
|
||||
@@ -186,13 +186,13 @@ bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevD
|
||||
}
|
||||
|
||||
case ISO15693_CMD_NXP_SET_PASSWORD: {
|
||||
uint8_t password_id = ctx->payload[ctx->payload_offset];
|
||||
uint8_t password_id = ctx->frame[ctx->payload_offset];
|
||||
|
||||
if(!(password_id & password_supported)) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *password_xored = &ctx->payload[ctx->payload_offset + 1];
|
||||
uint8_t *password_xored = &ctx->frame[ctx->payload_offset + 1];
|
||||
uint8_t *rand = slix->rand;
|
||||
uint8_t *password = NULL;
|
||||
uint8_t password_rcv[4];
|
||||
@@ -269,7 +269,7 @@ bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevD
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool slix_l_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
bool slix_l_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
furi_assert(tx_rx);
|
||||
furi_assert(nfc_data);
|
||||
furi_assert(nfcv_data_in);
|
||||
@@ -277,7 +277,7 @@ bool slix_l_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* n
|
||||
bool handled = false;
|
||||
|
||||
/* many SLIX share some of the functions, place that in a generic handler */
|
||||
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_PRIVACY | SLIX_PASS_DESTROY | SLIX_PASS_EASAFI)) {
|
||||
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_PRIVACY | SLIX_PASS_DESTROY | SLIX_PASS_EASAFI)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -290,10 +290,10 @@ 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, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||
|
||||
nfcv_data->emu_protocol_handler = &slix_l_protocol_handler;
|
||||
nfcv_data->emu_protocol_filter = &slix_l_protocol_filter;
|
||||
}
|
||||
|
||||
bool slix_s_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
bool slix_s_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
furi_assert(tx_rx);
|
||||
furi_assert(nfc_data);
|
||||
furi_assert(nfcv_data_in);
|
||||
@@ -301,7 +301,7 @@ bool slix_s_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* n
|
||||
bool handled = false;
|
||||
|
||||
/* many SLIX share some of the functions, place that in a generic handler */
|
||||
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
|
||||
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -314,10 +314,10 @@ 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, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||
|
||||
nfcv_data->emu_protocol_handler = &slix_s_protocol_handler;
|
||||
nfcv_data->emu_protocol_filter = &slix_s_protocol_filter;
|
||||
}
|
||||
|
||||
bool slix_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
bool slix_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
furi_assert(tx_rx);
|
||||
furi_assert(nfc_data);
|
||||
furi_assert(nfcv_data_in);
|
||||
@@ -325,7 +325,7 @@ bool slix_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
|
||||
bool handled = false;
|
||||
|
||||
/* many SLIX share some of the functions, place that in a generic handler */
|
||||
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_EASAFI)) {
|
||||
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_EASAFI)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -338,10 +338,10 @@ 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, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||
|
||||
nfcv_data->emu_protocol_handler = &slix_protocol_handler;
|
||||
nfcv_data->emu_protocol_filter = &slix_protocol_filter;
|
||||
}
|
||||
|
||||
bool slix2_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
bool slix2_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
|
||||
furi_assert(tx_rx);
|
||||
furi_assert(nfc_data);
|
||||
furi_assert(nfcv_data_in);
|
||||
@@ -349,7 +349,7 @@ bool slix2_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nf
|
||||
bool handled = false;
|
||||
|
||||
/* many SLIX share some of the functions, place that in a generic handler */
|
||||
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
|
||||
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -362,5 +362,5 @@ 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, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
|
||||
|
||||
nfcv_data->emu_protocol_handler = &slix2_protocol_handler;
|
||||
nfcv_data->emu_protocol_filter = &slix2_protocol_filter;
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ bool slix_check_card_type(FuriHalNfcDevData* nfc_data);
|
||||
bool slix2_check_card_type(FuriHalNfcDevData* nfc_data);
|
||||
bool slix_s_check_card_type(FuriHalNfcDevData* nfc_data);
|
||||
bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data);
|
||||
ReturnCode slix_l_get_random(NfcVData* data);
|
||||
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id);
|
||||
ReturnCode slix_get_random(NfcVData* data);
|
||||
ReturnCode slix_unlock(NfcVData* data, uint32_t password_id);
|
||||
|
||||
void slix_prepare(NfcVData* nfcv_data);
|
||||
void slix_s_prepare(NfcVData* nfcv_data);
|
||||
|
||||
Reference in New Issue
Block a user