flipperzero-firmware/lib/ST25RFAL002/include/rfal_nfc.h
gornekich eafeefb843
[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
2022-03-24 01:14:34 +03:00

426 lines
17 KiB
C

/******************************************************************************
* \attention
*
* <h2><center>&copy; COPYRIGHT 2020 STMicroelectronics</center></h2>
*
* Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* www.st.com/myliberty
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
* AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/*
* PROJECT: ST25R391x firmware
* Revision:
* LANGUAGE: ISO C99
*/
/*! \file rfal_nfc.h
*
* \brief RFAL NFC device
*
* This module provides the required features to behave as an NFC Poller
* or Listener device. It grants an easy to use interface for the following
* activities: Technology Detection, Collision Resolution, Activation,
* Data Exchange, and Deactivation
*
* This layer is influenced by (but not fully aligned with) the NFC Forum
* specifications, in particular: Activity 2.0 and NCI 2.0
*
*
*
* \addtogroup RFAL
* @{
*
* \addtogroup RFAL-HL
* \brief RFAL Higher Layer
* @{
*
* \addtogroup NFC
* \brief RFAL NFC Device
* @{
*
*/
#ifndef RFAL_NFC_H
#define RFAL_NFC_H
/*
******************************************************************************
* INCLUDES
******************************************************************************
*/
#include "platform.h"
#include "st_errno.h"
#include "rfal_rf.h"
#include "rfal_nfca.h"
#include "rfal_nfcb.h"
#include "rfal_nfcf.h"
#include "rfal_nfcv.h"
#include "rfal_st25tb.h"
#include "rfal_nfcDep.h"
#include "rfal_isoDep.h"
/*
******************************************************************************
* GLOBAL DEFINES
******************************************************************************
*/
#define RFAL_NFC_TECH_NONE 0x0000U /*!< No technology */
#define RFAL_NFC_POLL_TECH_A 0x0001U /*!< NFC-A technology Flag */
#define RFAL_NFC_POLL_TECH_B 0x0002U /*!< NFC-B technology Flag */
#define RFAL_NFC_POLL_TECH_F 0x0004U /*!< NFC-F technology Flag */
#define RFAL_NFC_POLL_TECH_V 0x0008U /*!< NFC-V technology Flag */
#define RFAL_NFC_POLL_TECH_AP2P 0x0010U /*!< AP2P technology Flag */
#define RFAL_NFC_POLL_TECH_ST25TB 0x0020U /*!< ST25TB technology Flag */
#define RFAL_NFC_LISTEN_TECH_A 0x1000U /*!< NFC-V technology Flag */
#define RFAL_NFC_LISTEN_TECH_B 0x2000U /*!< NFC-V technology Flag */
#define RFAL_NFC_LISTEN_TECH_F 0x4000U /*!< NFC-V technology Flag */
#define RFAL_NFC_LISTEN_TECH_AP2P 0x8000U /*!< NFC-V technology Flag */
/*
******************************************************************************
* GLOBAL MACROS
******************************************************************************
*/
/*! Checks if a device is currently activated */
#define rfalNfcIsDevActivated(st) \
(((st) >= RFAL_NFC_STATE_ACTIVATED) && ((st) < RFAL_NFC_STATE_DEACTIVATION))
/*! Checks if a device is in discovery */
#define rfalNfcIsInDiscovery(st) \
(((st) >= RFAL_NFC_STATE_START_DISCOVERY) && ((st) < RFAL_NFC_STATE_ACTIVATED))
/*! Checks if remote device is in Poll mode */
#define rfalNfcIsRemDevPoller(tp) \
(((tp) >= RFAL_NFC_POLL_TYPE_NFCA) && ((tp) <= RFAL_NFC_POLL_TYPE_AP2P))
/*! Checks if remote device is in Listen mode */
#define rfalNfcIsRemDevListener(tp) \
(((int16_t)(tp) >= (int16_t)RFAL_NFC_LISTEN_TYPE_NFCA) && ((tp) <= RFAL_NFC_LISTEN_TYPE_AP2P))
/*
******************************************************************************
* GLOBAL ENUMS
******************************************************************************
*/
/*
******************************************************************************
* GLOBAL TYPES
******************************************************************************
*/
/*! Main state */
typedef enum {
RFAL_NFC_STATE_NOTINIT = 0, /*!< Not Initialized state */
RFAL_NFC_STATE_IDLE = 1, /*!< Initialize state */
RFAL_NFC_STATE_START_DISCOVERY = 2, /*!< Start Discovery loop state */
RFAL_NFC_STATE_WAKEUP_MODE = 3, /*!< Wake-Up state */
RFAL_NFC_STATE_POLL_TECHDETECT = 10, /*!< Technology Detection state */
RFAL_NFC_STATE_POLL_COLAVOIDANCE = 11, /*!< Collision Avoidance state */
RFAL_NFC_STATE_POLL_SELECT = 12, /*!< Wait for Selection state */
RFAL_NFC_STATE_POLL_ACTIVATION = 13, /*!< Activation state */
RFAL_NFC_STATE_LISTEN_TECHDETECT = 20, /*!< Listen Tech Detect */
RFAL_NFC_STATE_LISTEN_COLAVOIDANCE = 21, /*!< Listen Collision Avoidance */
RFAL_NFC_STATE_LISTEN_ACTIVATION = 22, /*!< Listen Activation state */
RFAL_NFC_STATE_LISTEN_SLEEP = 23, /*!< Listen Sleep state */
RFAL_NFC_STATE_ACTIVATED = 30, /*!< Activated state */
RFAL_NFC_STATE_DATAEXCHANGE = 31, /*!< Data Exchange Start state */
RFAL_NFC_STATE_DATAEXCHANGE_DONE = 33, /*!< Data Exchange terminated */
RFAL_NFC_STATE_DEACTIVATION = 34 /*!< Deactivation state */
} rfalNfcState;
/*! Device type */
typedef enum {
RFAL_NFC_LISTEN_TYPE_NFCA = 0, /*!< NFC-A Listener device type */
RFAL_NFC_LISTEN_TYPE_NFCB = 1, /*!< NFC-B Listener device type */
RFAL_NFC_LISTEN_TYPE_NFCF = 2, /*!< NFC-F Listener device type */
RFAL_NFC_LISTEN_TYPE_NFCV = 3, /*!< NFC-V Listener device type */
RFAL_NFC_LISTEN_TYPE_ST25TB = 4, /*!< ST25TB Listener device type */
RFAL_NFC_LISTEN_TYPE_AP2P = 5, /*!< AP2P Listener device type */
RFAL_NFC_POLL_TYPE_NFCA = 10, /*!< NFC-A Poller device type */
RFAL_NFC_POLL_TYPE_NFCB = 11, /*!< NFC-B Poller device type */
RFAL_NFC_POLL_TYPE_NFCF = 12, /*!< NFC-F Poller device type */
RFAL_NFC_POLL_TYPE_NFCV = 13, /*!< NFC-V Poller device type */
RFAL_NFC_POLL_TYPE_AP2P = 15 /*!< AP2P Poller device type */
} rfalNfcDevType;
/*! Device interface */
typedef enum {
RFAL_NFC_INTERFACE_RF = 0, /*!< RF Frame interface */
RFAL_NFC_INTERFACE_ISODEP = 1, /*!< ISO-DEP interface */
RFAL_NFC_INTERFACE_NFCDEP = 2 /*!< NFC-DEP interface */
} rfalNfcRfInterface;
/*! Device struct containing all its details */
typedef struct {
rfalNfcDevType type; /*!< Device's type */
union { /* PRQA S 0750 # MISRA 19.2 - Members of the union will not be used concurrently, only one technology at a time */
rfalNfcaListenDevice nfca; /*!< NFC-A Listen Device instance */
rfalNfcbListenDevice nfcb; /*!< NFC-B Listen Device instance */
rfalNfcfListenDevice nfcf; /*!< NFC-F Listen Device instance */
rfalNfcvListenDevice nfcv; /*!< NFC-V Listen Device instance */
rfalSt25tbListenDevice st25tb; /*!< ST25TB Listen Device instance*/
} dev; /*!< Device's instance */
uint8_t* nfcid; /*!< Device's NFCID */
uint8_t nfcidLen; /*!< Device's NFCID length */
rfalNfcRfInterface rfInterface; /*!< Device's interface */
union { /* PRQA S 0750 # MISRA 19.2 - Members of the union will not be used concurrently, only one protocol at a time */
rfalIsoDepDevice isoDep; /*!< ISO-DEP instance */
rfalNfcDepDevice nfcDep; /*!< NFC-DEP instance */
} proto; /*!< Device's protocol */
} rfalNfcDevice;
/*! Discovery parameters */
typedef struct {
rfalComplianceMode compMode; /*!< Compliancy mode to be used */
uint16_t techs2Find; /*!< Technologies to search for */
uint16_t totalDuration; /*!< Duration of a whole Poll + Listen cycle */
uint8_t devLimit; /*!< Max number of devices */
rfalBitRate maxBR; /*!< Max Bit rate to be used for communications */
rfalBitRate nfcfBR; /*!< Bit rate to poll for NFC-F */
uint8_t
nfcid3[RFAL_NFCDEP_NFCID3_LEN]; /*!< NFCID3 to be used on the ATR_REQ/ATR_RES */
uint8_t GB[RFAL_NFCDEP_GB_MAX_LEN]; /*!< General bytes to be used on the ATR-REQ */
uint8_t GBLen; /*!< Length of the General Bytes */
rfalBitRate ap2pBR; /*!< Bit rate to poll for AP2P */
rfalLmConfPA lmConfigPA; /*!< Configuration for Passive Listen mode NFC-A */
rfalLmConfPF lmConfigPF; /*!< Configuration for Passive Listen mode NFC-A */
void (*notifyCb)(rfalNfcState st); /*!< Callback to Notify upper layer */
bool wakeupEnabled; /*!< Enable Wake-Up mode before polling */
bool wakeupConfigDefault; /*!< Wake-Up mode default configuration */
rfalWakeUpConfig wakeupConfig; /*!< Wake-Up mode configuration */
bool activate_after_sak; // Set device to Active mode after SAK responce
} rfalNfcDiscoverParam;
/*! Buffer union, only one interface is used at a time */
typedef union { /* PRQA S 0750 # MISRA 19.2 - Members of the union will not be used concurrently, only one interface at a time */
uint8_t rfBuf[RFAL_FEATURE_NFC_RF_BUF_LEN]; /*!< RF buffer */
rfalIsoDepApduBufFormat isoDepBuf; /*!< ISO-DEP buffer format (with header/prologue) */
rfalNfcDepPduBufFormat nfcDepBuf; /*!< NFC-DEP buffer format (with header/prologue) */
} rfalNfcBuffer;
/*******************************************************************************/
/*
******************************************************************************
* GLOBAL FUNCTION PROTOTYPES
******************************************************************************
*/
/*!
*****************************************************************************
* \brief RFAL NFC Worker
*
* It runs the internal state machine and runs the RFAL RF worker.
*****************************************************************************
*/
void rfalNfcWorker(void);
/*!
*****************************************************************************
* \brief RFAL NFC Initialize
*
* It initializes this module and its dependencies
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* \return ERR_IO : Generic internal error
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcInitialize(void);
/*!
*****************************************************************************
* \brief RFAL NFC Discovery
*
* It set the device in Discovery state.
* In discovery it will Poll and/or Listen for the technologies configured,
* and perform Wake-up mode if configured to do so.
*
* The device list passed on disParams must not be empty.
* The number of devices on the list is indicated by the devLimit and shall
* be at >= 1.
*
* \param[in] disParams : discovery configuration parameters
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* \return ERR_PARAM : Invalid parameters
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcDiscover(const rfalNfcDiscoverParam* disParams);
/*!
*****************************************************************************
* \brief RFAL NFC Get State
*
* It returns the current state
*
* \return rfalNfcState : the current state
*****************************************************************************
*/
rfalNfcState rfalNfcGetState(void);
/*!
*****************************************************************************
* \brief RFAL NFC Get Devices Found
*
* It returns the location of the device list and the number of
* devices found.
*
* \param[out] devList : device list location
* \param[out] devCnt : number of devices found
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* Discovery still ongoing
* \return ERR_PARAM : Invalid parameters
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcGetDevicesFound(rfalNfcDevice** devList, uint8_t* devCnt);
/*!
*****************************************************************************
* \brief RFAL NFC Get Active Device
*
* It returns the location of the device current Active device
*
* \param[out] dev : device info location
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* No device activated
* \return ERR_PARAM : Invalid parameters
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcGetActiveDevice(rfalNfcDevice** dev);
/*!
*****************************************************************************
* \brief RFAL NFC Select Device
*
* It selects the device to be activated.
* It shall be called when more than one device has been identified to
* indiacte which device shall be actived
*
* \param[in] devIdx : device index to be activated
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* Not in select state
* \return ERR_PARAM : Invalid parameters
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcSelect(uint8_t devIdx);
/*!
*****************************************************************************
* \brief RFAL NFC Start Data Exchange
*
* After a device has been activated, it starts a data exchange.
* It handles automatically which interface/protocol to be used and acts accordingly.
*
* In Listen mode the first frame/data shall be sent by the Reader/Initiator
* therefore this method must be called first with txDataLen set to zero
* to retrieve the rxData and rcvLen locations.
*
*
* \param[in] txData : data to be transmitted
* \param[in] txDataLen : size of the data to be transmitted
* \param[out] rxData : location of the received data after operation is completed
* \param[out] rvdLen : location of thelength of the received data
* \param[in] fwt : FWT to be used in case of RF interface.
* If ISO-DEP or NFC-DEP interface is used, this will be ignored
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* \return ERR_PARAM : Invalid parameters
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcDataExchangeStart(
uint8_t* txData,
uint16_t txDataLen,
uint8_t** rxData,
uint16_t** rvdLen,
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
*
* Gets current Data Exchange status
*
* \return ERR_NONE : Transceive done with no error
* \return ERR_BUSY : Transceive ongoing
* \return ERR_AGAIN : received one chaining block, copy received data
* and continue to call this method to retrieve the
* remaining blocks
* \return ERR_XXXX : Error occurred
* \return ERR_TIMEOUT : No response
* \return ERR_FRAMING : Framing error detected
* \return ERR_PAR : Parity error detected
* \return ERR_CRC : CRC error detected
* \return ERR_LINK_LOSS : Link Loss - External Field is Off
* \return ERR_RF_COLLISION : Collision detected
* \return ERR_IO : Internal error
*****************************************************************************
*/
ReturnCode rfalNfcDataExchangeGetStatus(void);
/*!
*****************************************************************************
* \brief RFAL NFC Deactivate
*
* It triggers the deactivation procedure to terminate communications with
* remote device. At the end the field will be turned off.
*
* \param[in] discovery : TRUE if after deactivation go back into discovery
* : FALSE if after deactivation remain in idle
*
* \return ERR_WRONG_STATE : Incorrect state for this operation
* \return ERR_NONE : No error
*****************************************************************************
*/
ReturnCode rfalNfcDeactivate(bool discovery);
#endif /* RFAL_NFC_H */
/**
* @}
*
* @}
*
* @}
*/