linux_libnfc-nci
repository·master·Indexed 41 days ago
https://github.com/nxpnfclinux/linux_libnfc-nciA Linux-based NFC stack optimized for NXP NCI-based NFC controllers, such as the PN7150 and PN7120. It supports Tag interaction, Peer-to-Peer (SNEP), and Host Card Emulation (HCE) modes, providing APIs for NDEF data exchange and raw transceive operations.
What's inside libnfc-nci
- linux_libnfc-nci is a Linux NFC stack designed specifically for NXP NFC Controllers that utilize the NCI (NFC Controller Interface) protocol. It is primarily intended for use with NXP hardware such as the PN7150 and PN7120 controllers.
How the NFC configuration loading works
masterThe NFC adaptation layer uses a singleton
CNfcConfigto manage settings. It searches for configuration files in a specific order of precedence:- Primary Config: It first attempts to load
libnfc-nci.conffrom the path defined byCONFIG_PATH(thealternative_config_path). - Secondary Config: If the primary file is not found or empty, it attempts to load
libnfc-nci.conffrom/etc/(thetransport_config_path).
Configuration File Format: Settings are defined in a
key=valueformat. Supported value types include:- Strings: Enclosed in double quotes (e.g.,
KEY="VALUE"). - Decimals: Standard base-10 numbers (e.g.,
KEY=123). - Hexadecimal: Prefixed with
0x(e.g.,KEY=0xAB). - Hex-encoded Strings: Using curly braces
{}to represent raw byte sequences (e.g.,KEY={0xDE, 0xAD, 0xBE, 0xEF}).
Comments are supported using the
#character.- Primary Config: It first attempts to load
NXP Configuration File Formats and Paths
masterThe NXP configuration system uses
.conffiles. The files are named using the patternlibnfc-nxp-[type].confwhere[type]isinit,pn547, orpn548.Search Order:
- The system first looks in the
alternative_config_path(e.g.,/data/nfc/on generic targets or a definedCONFIG_PATH). - If not found, it looks in the
transport_config_path(e.g.,/etc/).
File Syntax:
- Comments: Lines starting with
#are ignored. - Key-Value Pairs:
key = value - String Values: Enclosed in double quotes:
key = "value" - Hexadecimal/Numeric Values: Supports standard numbers and hex notation (e.g.,
0x1234). - Hex-encoded Byte Arrays: Can be represented using
{}syntax (e.g.,{0xDE, 0xAD, 0xBE, 0xEF}).
- The system first looks in the
Cleanup and Deinitialize NFC Services
masterTo release resources and stop NFC polling, you should deregister all callbacks and disable discovery. The following sequence is recommended:
- Stop the SNEP server:
nfcSnep_stopServer(). - Disable discovery:
nfcManager_disableDiscovery(). - Deregister all callbacks:
nfcSnep_deregisterClientCallback()nfcManager_deregisterTagCallback()nfcHce_deregisterHceCallback()
- Stop the SNEP server:
Use the NFC demo application modes
masterThe demo application provides four primary operational modes via CLI arguments:
- poll: Activates polling mode to scan for nearby NFC tags.
- Command:
nfcDemoApp poll
- Command:
- write: Activates write mode to write NDEF data to a tag.
- Command:
nfcDemoApp write --type=Text -l en -r "Test"
- Command:
- push: Activates push mode to send NDEF data to a P2P device.
- Command:
nfcDemoApp push -t URI -u http://www.nxp.com - Command (MIME):
nfcDemoApp push --type=mime -m "application/vnd.bluetooth.ep.oob" -d "2200AC597405AF1C0E0947616C617879204E6F74652033040D0C024005031E110B11"
- Command:
- share: Activates Tag Emulation (HCE) mode to emulate a tag.
- Command:
nfcDemoApp share -t URI -u http://www.nxp.com
- Command:
- poll: Activates polling mode to scan for nearby NFC tags.
Initialize the NFC Service and Discovery
masterTo start using the NFC stack, you must first initialize the NFC manager and then enable discovery for the desired technologies. You can configure the service to operate in Tag, P2P (SNEP), or HCE (Host Card Emulation) modes.
Key steps:
- Call
nfcManager_doInitialize()to start the service. - Register callbacks for the specific modes you intend to use (Tag, SNEP Client, or HCE).
- Call
nfcManager_enableDiscovery()with a technology mask to begin polling for NFC devices.
// Example initialization sequence res = nfcManager_doInitialize(); if(0x00 == res) { // Register Tag callbacks nfcManager_registerTagCallback(&g_TagCB); // Register SNEP Client callbacks nfcSnep_registerClientCallback(&g_SnepClientCB); // Register HCE callbacks nfcHce_registerHceCallback(&g_HceCB); // Enable discovery (hce is passed as a parameter to enable HCE mode) nfcManager_enableDiscovery(DEFAULT_NFA_TECH_MASK, 0x00, hce_enabled, 0); // Start SNEP Server if P2P is required if(p2p_enabled) { nfcSnep_startServer(&g_SnepServerCB); } }- Call
Requirements for LLCP1.3 support
masterIf your implementation requires LLCP1.3 support, you must have the OpenSSL Cryptography and SSL/TLS Toolkit installed, specifically version 1.0.1j or later.Register Host Card Emulation (HCE) Callbacks
masterTo use the device as an NFC tag (Host Card Emulation), register a
nfc_host_card_emulation_callback_tstructure usingnfcHce_registerHceCallback. This allows your application to respond to reader interactions.Required callback members:
onDataReceived: Triggered when the NFC reader sends data to the emulated card.onHostCardEmulationActivated: Triggered when HCE mode is activated by a reader.onHostCardEmulationDeactivated: Triggered when the reader interaction ends.
// Define the callback structure nfc_host_card_emulation_callback_t g_HceCB; // Assign functions g_HceCB.onDataReceived = my_on_hce_data; g_HceCB.onHostCardEmulationActivated = my_on_hce_activated; g_HceCB.onHostCardEmulationDeactivated = my_on_hce_deactivated; // Register with the HCE module nfcHce_registerHceCallback(&g_HceCB);Retrieve configuration numerical values with GetNumValue
masterUse the
GetNumValueC API to retrieve numerical settings (unsigned long, unsigned short, or unsigned char) from the configuration files.Parameters:
name: The name of the configuration parameter.pValue: A pointer to the memory where the value should be stored.len: The size of the memory pointed to bypValue(must match the size of the type you are requesting).
Supported Types (based on
len):sizeof(unsigned long)sizeof(unsigned short)sizeof(unsigned char)
Returns:
true(non-zero) on success.false(0) if the parameter is not found or the requested length is invalid.
unsigned long val; if (GetNumValue("NXP_SOME_NUMERIC_SETTING", &val, sizeof(unsigned long))) { // Success: val contains the value }Perform raw transceive with nfcTag_transceive()
masterFor specific tag types like
TARGET_TYPE_MIFARE_CLASSICorTARGET_TYPE_MIFARE_UL, you can usenfcTag_transceiveto send custom command buffers and receive responses. This is useful for low-level authentication or reading specific blocks that are not part of the standard NDEF structure.res = nfcTag_transceive(TagInfo.handle, MifareAuthCmd, 12, MifareAuthResp, 255, 500);Retrieve NXP configuration string values
masterUse
GetNxpStrValueto retrieve a string-based configuration parameter from the NXP configuration files. This function searches for the specifiednameand copies the value into the provided bufferpValueup to the specifiedlen.// Returns 1 if found, 0 otherwise int GetNxpStrValue(const char* name, char* pValue, unsigned long len);Retrieve NXP configuration numerical values
masterUse
GetNxpNumValueto retrieve a numerical setting. The function supports different output types based on thelenparameter provided. It can handle standard decimal numbers or hex-encoded strings that represent byte sequences.Supported
lenvalues forpValue:sizeof(unsigned long)sizeof(unsigned short)sizeof(unsigned char)
// Returns 1 if successful, 0 otherwise int GetNxpNumValue(const char* name, void* pValue, unsigned long len);