[FL-1396] Mifare Classic read (#1034)

* rfal: add new data exchange function
* core: add FURI_BIT to common defines
* furi_hal_nfc: add data exchange with custom patiry bits
* lib: extend nfc common API
* assets: add mf classic dictionary
* lib: introduce mifare classic library
* nfc: add dictionary reader helper
* nfc worker: add worker events, add mifare classic read
* nfc: rework scenes with worker events
* nfc: add read mifare classic GUI
* nfc device: add mifare classic save
* nfc: add dictionary open fail scene
* nfc: mention resources
* stream: fix stream read line
* subghz: rework file read with fixed stream_read_line
* furi_hal_nfc: decrease communication timeout
* nfc: rework keys load from dictionary with file_stream
* nfc: add read mifare classic suggestion
* nfc: fix mifare classic read view
* nfc: fix index size
* nfc: add switch to no dictionary found scene
* nfc: add mifare classic load
* nfc: improve read mifare classic design
* mifare_classic: add proxmark3 mention
* nfc: format sources
* nfc: fix typos, add documentation
This commit is contained in:
gornekich
2022-03-24 01:14:34 +03:00
committed by GitHub
parent 46a894bc5c
commit eafeefb843
46 changed files with 3113 additions and 111 deletions

View File

@@ -367,6 +367,14 @@ ReturnCode rfalNfcDataExchangeStart(
uint32_t fwt,
uint32_t tx_flag);
ReturnCode rfalNfcDataExchangeCustomStart(
uint8_t* txData,
uint16_t txDataLen,
uint8_t** rxData,
uint16_t** rvdLen,
uint32_t fwt,
uint32_t flags);
/*!
*****************************************************************************
* \brief RFAL NFC Get Data Exchange Status

View File

@@ -115,9 +115,9 @@
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO | \
(uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO)
#define RFAL_TXRX_FLAGS_RAW \
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_REMV | \
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
(uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON | \
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE | \
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE | \
(uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO)
#define RFAL_LM_MASK_NFCA \

134
lib/ST25RFAL002/source/rfal_nfc.c Normal file → Executable file
View File

@@ -686,6 +686,140 @@ ReturnCode rfalNfcDataExchangeStart(
return ERR_WRONG_STATE;
}
ReturnCode rfalNfcDataExchangeCustomStart(
uint8_t* txData,
uint16_t txDataLen,
uint8_t** rxData,
uint16_t** rvdLen,
uint32_t fwt,
uint32_t flags) {
ReturnCode err;
rfalTransceiveContext ctx;
/*******************************************************************************/
/* The Data Exchange is divided in two different moments, the trigger/Start of *
* the transfer followed by the check until its completion */
if((gNfcDev.state >= RFAL_NFC_STATE_ACTIVATED) && (gNfcDev.activeDev != NULL)) {
/*******************************************************************************/
/* In Listen mode is the Poller that initiates the communicatation */
/* Assign output parameters and rfalNfcDataExchangeGetStatus will return */
/* incoming data from Poller/Initiator */
if((gNfcDev.state == RFAL_NFC_STATE_ACTIVATED) &&
rfalNfcIsRemDevPoller(gNfcDev.activeDev->type)) {
if(txDataLen > 0U) {
return ERR_WRONG_STATE;
}
*rvdLen = (uint16_t*)&gNfcDev.rxLen;
*rxData = (uint8_t*)( (gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) ? gNfcDev.rxBuf.isoDepBuf.apdu :
((gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_NFCDEP) ? gNfcDev.rxBuf.nfcDepBuf.pdu : gNfcDev.rxBuf.rfBuf));
if(gNfcDev.disc.activate_after_sak) {
gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE_DONE;
}
return ERR_NONE;
}
/*******************************************************************************/
switch(gNfcDev.activeDev
->rfInterface) /* Check which RF interface shall be used/has been activated */
{
/*******************************************************************************/
case RFAL_NFC_INTERFACE_RF:
ctx.rxBuf = gNfcDev.rxBuf.rfBuf, ctx.rxBufLen = sizeof(gNfcDev.rxBuf.rfBuf),
ctx.rxRcvdLen = &gNfcDev.rxLen, ctx.txBuf = txData, ctx.txBufLen = txDataLen,
ctx.flags = flags, ctx.fwt = fwt, *rxData = (uint8_t*)gNfcDev.rxBuf.rfBuf;
*rvdLen = (uint16_t*)&gNfcDev.rxLen;
err = rfalStartTransceive(&ctx);
break;
#if RFAL_FEATURE_ISO_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_ISODEP: {
rfalIsoDepApduTxRxParam isoDepTxRx;
if(txDataLen > sizeof(gNfcDev.txBuf.isoDepBuf.apdu)) {
return ERR_NOMEM;
}
if(txDataLen > 0U) {
ST_MEMCPY((uint8_t*)gNfcDev.txBuf.isoDepBuf.apdu, txData, txDataLen);
}
isoDepTxRx.DID = RFAL_ISODEP_NO_DID;
isoDepTxRx.ourFSx = RFAL_ISODEP_FSX_KEEP;
isoDepTxRx.FSx = gNfcDev.activeDev->proto.isoDep.info.FSx;
isoDepTxRx.dFWT = gNfcDev.activeDev->proto.isoDep.info.dFWT;
isoDepTxRx.FWT = gNfcDev.activeDev->proto.isoDep.info.FWT;
isoDepTxRx.txBuf = &gNfcDev.txBuf.isoDepBuf;
isoDepTxRx.txBufLen = txDataLen;
isoDepTxRx.rxBuf = &gNfcDev.rxBuf.isoDepBuf;
isoDepTxRx.rxLen = &gNfcDev.rxLen;
isoDepTxRx.tmpBuf = &gNfcDev.tmpBuf.isoDepBuf;
*rxData = (uint8_t*)gNfcDev.rxBuf.isoDepBuf.apdu;
*rvdLen = (uint16_t*)&gNfcDev.rxLen;
/*******************************************************************************/
/* Trigger a RFAL ISO-DEP Transceive */
err = rfalIsoDepStartApduTransceive(isoDepTxRx);
break;
}
#endif /* RFAL_FEATURE_ISO_DEP */
#if RFAL_FEATURE_NFC_DEP
/*******************************************************************************/
case RFAL_NFC_INTERFACE_NFCDEP: {
rfalNfcDepPduTxRxParam nfcDepTxRx;
if(txDataLen > sizeof(gNfcDev.txBuf.nfcDepBuf.pdu)) {
return ERR_NOMEM;
}
if(txDataLen > 0U) {
ST_MEMCPY((uint8_t*)gNfcDev.txBuf.nfcDepBuf.pdu, txData, txDataLen);
}
nfcDepTxRx.DID = RFAL_NFCDEP_DID_KEEP;
nfcDepTxRx.FSx =
rfalNfcIsRemDevListener(gNfcDev.activeDev->type) ?
rfalNfcDepLR2FS((uint8_t)rfalNfcDepPP2LR(
gNfcDev.activeDev->proto.nfcDep.activation.Target.ATR_RES.PPt)) :
rfalNfcDepLR2FS((uint8_t)rfalNfcDepPP2LR(
gNfcDev.activeDev->proto.nfcDep.activation.Initiator.ATR_REQ.PPi));
nfcDepTxRx.dFWT = gNfcDev.activeDev->proto.nfcDep.info.dFWT;
nfcDepTxRx.FWT = gNfcDev.activeDev->proto.nfcDep.info.FWT;
nfcDepTxRx.txBuf = &gNfcDev.txBuf.nfcDepBuf;
nfcDepTxRx.txBufLen = txDataLen;
nfcDepTxRx.rxBuf = &gNfcDev.rxBuf.nfcDepBuf;
nfcDepTxRx.rxLen = &gNfcDev.rxLen;
nfcDepTxRx.tmpBuf = &gNfcDev.tmpBuf.nfcDepBuf;
*rxData = (uint8_t*)gNfcDev.rxBuf.nfcDepBuf.pdu;
*rvdLen = (uint16_t*)&gNfcDev.rxLen;
/*******************************************************************************/
/* Trigger a RFAL NFC-DEP Transceive */
err = rfalNfcDepStartPduTransceive(nfcDepTxRx);
break;
}
#endif /* RFAL_FEATURE_NFC_DEP */
/*******************************************************************************/
default:
err = ERR_PARAM;
break;
}
/* If a transceive has succesfully started flag Data Exchange as ongoing */
if(err == ERR_NONE) {
gNfcDev.dataExErr = ERR_BUSY;
gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE;
}
return err;
}
return ERR_WRONG_STATE;
}
/*******************************************************************************/
ReturnCode rfalNfcDataExchangeGetStatus(void) {
/*******************************************************************************/