Functions

nfc.c File Reference

NFC library implementation. More...

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <nfc/nfc.h>
#include "chips.h"
#include "drivers.h"
#include <nfc/nfc-messages.h>

Go to the source code of this file.

Functions

nfc_device_desc_tnfc_pick_device (void)
 Probe for the first discoverable supported devices (ie. only available for some drivers).
void nfc_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound)
 Probe for discoverable supported devices (ie. only available for some drivers).
nfc_device_tnfc_connect (nfc_device_desc_t *pndd)
 Connect to a NFC device.
void nfc_disconnect (nfc_device_t *pnd)
 Disconnect from a NFC device.
bool nfc_configure (nfc_device_t *pnd, const nfc_device_option_t ndo, const bool bEnable)
 Configure advanced NFC device settings.
bool nfc_initiator_init (nfc_device_t *pnd)
 Initialize NFC device as initiator (reader).
bool nfc_initiator_select_dep_target (nfc_device_t *pnd, const nfc_modulation_t nmInitModulation, const byte_t *pbtPidData, const size_t szPidDataLen, const byte_t *pbtNFCID3i, const size_t szNFCID3iDataLen, const byte_t *pbtGbData, const size_t szGbDataLen, nfc_target_info_t *pnti)
 Select a target and request active or passive mode for DEP (Data Exchange Protocol).
bool nfc_initiator_deselect_target (nfc_device_t *pnd)
 Deselect a selected passive or emulated tag.
bool nfc_initiator_poll_targets (nfc_device_t *pnd, const nfc_target_type_t *pnttTargetTypes, const size_t szTargetTypes, const byte_t btPollNr, const byte_t btPeriod, nfc_target_t *pntTargets, size_t *pszTargetFound)
 Polling for NFC targets.
bool nfc_initiator_transceive_bits (nfc_device_t *pnd, const byte_t *pbtTx, const size_t szTxBits, const byte_t *pbtTxPar, byte_t *pbtRx, size_t *pszRxBits, byte_t *pbtRxPar)
 Transceive raw bit-frames.
bool nfc_initiator_transceive_bytes (nfc_device_t *pnd, const byte_t *pbtTx, const size_t szTxLen, byte_t *pbtRx, size_t *pszRxLen)
 Send raw data to target then retrieve raw data from target.
bool nfc_target_init (nfc_device_t *pnd, byte_t *pbtRx, size_t *pszRxBits)
 Initialize NFC device as an emulated tag.
bool nfc_target_receive_bits (nfc_device_t *pnd, byte_t *pbtRx, size_t *pszRxBits, byte_t *pbtRxPar)
 Receive bit-frames.
bool nfc_target_receive_bytes (nfc_device_t *pnd, byte_t *pbtRx, size_t *pszRxLen)
 Receive bytes and APDU frames.
bool nfc_target_send_bits (nfc_device_t *pnd, const byte_t *pbtTx, const size_t szTxBits, const byte_t *pbtTxPar)
 Send raw bit-frames.
bool nfc_target_send_bytes (nfc_device_t *pnd, const byte_t *pbtTx, const size_t szTxLen)
 Send bytes and APDU frames.
const char * nfc_strerror (const nfc_device_t *pnd)
 Return the PCD error string.
int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen)
 Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars.
void nfc_perror (const nfc_device_t *pnd, const char *pcString)
 Display the PCD error a-la perror.
const char * nfc_device_name (nfc_device_t *pnd)
 Returns the device name.
const char * nfc_version (void)
 Returns the library version.

Detailed Description

NFC library implementation.

Definition in file nfc.c.


Function Documentation

bool nfc_configure ( nfc_device_t pnd,
const nfc_device_option_t  ndo,
const bool  bEnable 
)

Configure advanced NFC device settings.

Returns:
Returns true if action was successfully performed; otherwise returns false.
Parameters:
pnd nfc_device_t struct pointer that represent currently used device
ndo nfc_device_option_t struct that contains options to set to device
bEnable boolean

Configures parameters and registers that control for example timing, modulation, frame and error handling. There are different categories for configuring the PN53X chip features (handle, activate, infinite and accept). These are defined to organize future settings that will become available when they are needed.

Definition at line 225 of file nfc.c.

nfc_device_t* nfc_connect ( nfc_device_desc_t pndd  ) 

Connect to a NFC device.

Parameters:
pndd Device description if specific device is wanted, NULL otherwise
Returns:
Returns pointer to a nfc_device_t struct if successfull; otherwise returns NULL value.

If pndd is NULL, the first available NFC device is claimed by libnfc. It will automatically search the system using all available drivers to determine a device is free.

If pndd is passed then libnfc will try to claim the right device using information provided by this struct.

When it has successfully claimed a NFC device, memory is allocated to save the device information. It will return a pointer to a nfc_device_t struct. This pointer should be supplied by every next function of libnfc that should perform an action with this device.

Definition at line 112 of file nfc.c.

const char* nfc_device_name ( nfc_device_t pnd  ) 

Returns the device name.

Returns:
Returns a string with the device name

Definition at line 620 of file nfc.c.

void nfc_disconnect ( nfc_device_t pnd  ) 

Disconnect from a NFC device.

Parameters:
pnd nfc_device_t struct pointer that represent currently used device

Initiator is disconnected and the device, including allocated nfc_device_t struct, is released.

Definition at line 201 of file nfc.c.

bool nfc_initiator_deselect_target ( nfc_device_t pnd  ) 

Deselect a selected passive or emulated tag.

Returns:
Returns true if action was successfully performed; otherwise returns false.
Parameters:
pnd nfc_device_t struct pointer that represent currently used device

After selecting and communicating with a passive tag, this function could be used to deactivate and release the tag. This is very useful when there are multiple tags available in the field. It is possible to use the nfc_initiator_select_passive_target() function to select the first available tag, test it for the available features and support, deselect it and skip to the next tag until the correct tag is found.

Definition at line 439 of file nfc.c.

bool nfc_initiator_init ( nfc_device_t pnd  ) 

Initialize NFC device as initiator (reader).

Returns:
Returns true if action was successfully performed; otherwise returns false.
Parameters:
pnd nfc_device_t struct pointer that represent currently used device

The NFC device is configured to function as RFID reader. After initialization it can be used to communicate to passive RFID tags and active NFC devices. The reader will act as initiator to communicate peer 2 peer (NFCIP) to other active NFC devices.

Definition at line 243 of file nfc.c.

bool nfc_initiator_poll_targets ( nfc_device_t pnd,
const nfc_target_type_t pnttTargetTypes,
const size_t  szTargetTypes,
const byte_t  btPollNr,
const byte_t  btPeriod,
nfc_target_t pntTargets,
size_t *  pszTargetFound 
)

Polling for NFC targets.

Parameters:
pnd nfc_device_t struct pointer that represent currently used device
pnttTargetTypes array of desired target types
szTargetTypes pnttTargetTypes count
btPollNr specifies the number of polling
Note:
one polling is a polling for each desired target type
Parameters:
btPeriod indicates the polling period in units of 150 ms
pntTargets pointer on array of 2 nfc_target_t (over)writables struct
pszTargetFound found targets count

Definition at line 458 of file nfc.c.

bool nfc_initiator_select_dep_target ( nfc_device_t pnd,
const nfc_modulation_t  nmInitModulation,
const byte_t *  pbtPidData,
const size_t  szPidDataLen,
const byte_t *  pbtNFCID3i,
const size_t  szNFCID3iDataLen,
const byte_t *  pbtGbData,
const size_t  szGbDataLen,
nfc_target_info_t pnti 
)

Select a target and request active or passive mode for DEP (Data Exchange Protocol).

Returns:
Returns true if action was successfully performed; otherwise returns false.
Parameters:
pnd nfc_device_t struct pointer that represent currently used device
nmInitModulation Desired modulation (NM_ACTIVE_DEP or NM_PASSIVE_DEP for active, respectively passive mode)
pbtPidData passive initiator data, 4 or 5 bytes long, (optional, only for NM_PASSIVE_DEP, can be NULL)
szPidDataLen size of pbtPidData
pbtNFCID3i the NFCID3, 10 bytes long, of the initiator (optional, can be NULL)
szNFCID3iDataLen size of pbtNFCID3i
pbtGbData generic data of the initiator, max 48 bytes long, (optional, can be NULL)
szGbDataLen size of pbtGbData
pnti is a nfc_target_info_t struct pointer where target information will be put.

The NFC device will try to find the available target. The standards (ISO18092 and ECMA-340) describe the modulation that can be used for reader to passive communications.

Note:
nfc_dep_info_t will be returned when the target was acquired successfully.

Definition at line 279 of file nfc.c.

bool nfc_initiator_transceive_bits ( nfc_device_t pnd,
const byte_t *  pbtTx,
const size_t  szTxBits,
const byte_t *  pbtTxPar,
byte_t *  pbtRx,
size_t *  pszRxBits,
byte_t *  pbtRxPar 
)

Transceive raw bit-frames.

Returns:
Returns true if action was successfully performed; otherwise returns false.
Parameters:
pbtTx contains a byte array of the frame that needs to be transmitted.
szTxBits contains the length in bits.
Note:
For example the REQA (0x26) command (first anti-collision command of ISO14443-A) must be precise 7 bits long. This is not possible by using nfc_initiator_transceive_bytes(). With that function you can only communicate frames that consist of full bytes. When you send a full byte (8 bits + 1 parity) with the value of REQA (0x26), a tag will simply not respond. More information about this can be found in the anti-colision example.
Parameters:
pbtTxPar parameter contains a byte array of the corresponding parity bits needed to send per byte.
Note:
For example if you send the SELECT_ALL (0x93, 0x20) = [ 10010011, 00100000 ] command, you have to supply the following parity bytes (0x01, 0x00) to define the correct odd parity bits. This is only an example to explain how it works, if you just are sending two bytes with ISO14443-A compliant parity bits you better can use the nfc_initiator_transceive_bytes() function.
Returns:
The received response from the tag will be stored in the parameters (pbtRx, pszRxBits and pbtRxPar). They work the same way as the corresponding parameters for transmission.

The NFC reader will transmit low-level messages where only the modulation is handled by the PN53X chip. Construction of the frame (data, CRC and parity) is completely done by libnfc. This can be very useful for testing purposes. Some protocols (e.g. MIFARE Classic) require to violate the ISO14443-A standard by sending incorrect parity and CRC bytes. Using this feature you are able to simulate these frames.

Definition at line 481 of file nfc.c.

bool nfc_initiator_transceive_bytes ( nfc_device_t pnd,
const byte_t *  pbtTx,
const size_t  szTxLen,
byte_t *  pbtRx,
size_t *  pszRxLen 
)

Send raw data to target then retrieve raw data from target.

Returns:
Returns true if action was successfully performed; otherwise returns false.

The reader will transmit the supplied bytes (pbtTx) to the target in raw mode: PN53x will not handle input neither output data. It waits for the response and stores the received bytes in the pbtRx byte array. The parity bits are handled by the PN53X chip. The CRC can be generated automatically or handled manually. Using this function, frames can be communicated very fast via the NFC reader to the tag.

Tests show that on average this way of communicating is much faster than using the regular driver/middle-ware (often supplied by manufacturers).

Warning:
The configuration option NDO_HANDLE_PARITY must be set to true (the default value).

Definition at line 503 of file nfc.c.

void nfc_list_devices ( nfc_device_desc_t  pnddDevices[],
size_t  szDevices,
size_t *  pszDeviceFound 
)

Probe for discoverable supported devices (ie. only available for some drivers).

Parameters:
pnddDevices Array of nfc_device_desc_t previously allocated by the caller.
szDevices size of the pnddDevices array.
pszDeviceFound number of devices found.

Definition at line 77 of file nfc.c.

nfc_device_desc_t * nfc_pick_device ( void   ) 

Probe for the first discoverable supported devices (ie. only available for some drivers).

Returns:
nfc_device_desc_t struct pointer

Definition at line 54 of file nfc.c.

const char* nfc_strerror ( const nfc_device_t pnd  ) 

Return the PCD error string.

Returns:
Returns a string

Definition at line 589 of file nfc.c.

int nfc_strerror_r ( const nfc_device_t pnd,
char *  pcStrErrBuf,
size_t  szBufLen 
)

Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen chars.

Returns:
Returns 0 upon success

Definition at line 599 of file nfc.c.

bool nfc_target_init ( nfc_device_t pnd,
byte_t *  pbtRx,
size_t *  pszRxBits 
)

Initialize NFC device as an emulated tag.

Returns:
Returns true if action was successfully performed; otherwise returns false.

This functionality allows the NFC device to act as an emulated tag. There seems to be quite some options available for this feature. Not all of the PN53X modulations are tested and documented at the moment. At the moment it could best be seen as a preliminary functionality.

Warning:
Be aware that this function will wait (hang) until a command is received that is not part of the anti-collision. The RATS command for example would wake up the emulator. After this is received, the send and receive functions can be used.

Definition at line 520 of file nfc.c.

bool nfc_target_receive_bits ( nfc_device_t pnd,
byte_t *  pbtRx,
size_t *  pszRxBits,
byte_t *  pbtRxPar 
)

Receive bit-frames.

Returns:
Returns true if action was successfully performed; otherwise returns false.

This function makes it possible to receive (raw) bit-frames. It returns all the messages that are stored in the FIFO buffer of the PN53X chip. It does not require to send any frame and thereby could be used to snoop frames that are transmitted by a nearby reader. Check out the NDO_ACCEPT_MULTIPLE_FRAMES configuration option to avoid losing transmitted frames.

Definition at line 534 of file nfc.c.

bool nfc_target_receive_bytes ( nfc_device_t pnd,
byte_t *  pbtRx,
size_t *  pszRxLen 
)

Receive bytes and APDU frames.

Returns:
Returns true if action was successfully performed; otherwise returns false.

The main receive function that returns the received frames from a nearby reader.

Definition at line 548 of file nfc.c.

bool nfc_target_send_bits ( nfc_device_t pnd,
const byte_t *  pbtTx,
const size_t  szTxBits,
const byte_t *  pbtTxPar 
)

Send raw bit-frames.

Returns:
Returns true if action was successfully performed; otherwise returns false.

This function can be used to transmit (raw) bit-frames to the reader.

Definition at line 562 of file nfc.c.

bool nfc_target_send_bytes ( nfc_device_t pnd,
const byte_t *  pbtTx,
const size_t  szTxLen 
)

Send bytes and APDU frames.

Returns:
Returns true if action was successfully performed; otherwise returns false.

To communicate byte frames and APDU responses to the reader, this function could be used.

Definition at line 577 of file nfc.c.

const char* nfc_version ( void   ) 

Returns the library version.

Returns:
Returns a string with the library version

Definition at line 632 of file nfc.c.