Main Content

NFC Application Layer

This example demonstrates exchange of data between application layers of two Near Field Communication (NFC) devices.

Introduction

The example demonstrates a Near Field Communication (NFC) smart poster, which is an NFC feature used by retailers, advertising agencies, transportation authorities, health care providers, and various industries who want to interact with consumers. Since NFC requires the user to take action, the opt-in nature of the technology creates an engaged user leading to a much more meaningful interaction with a brand.

An NFC smart poster is a magazine advertisement, flier, billboard, or other physical medium that includes embedded or affixed NFC tags. When an NFC device is placed within a few centimeters of the NFC tag, information is transferred to the device or a task is launched on the device.

Depending on the smart poster and environment, the consumer can receive targeted information about their current location. Examples of NFC smart poster use include:

  • A poster that contains an NFC tag that instructs the receiving NFC device to launch a map application with directions to help a lost tourist find a nearby landmark.

  • In a retail setting, a poster that offers coupons, information about a product, or loyalty points. The consumer's phone acts as the loyalty card and stores the information, thus eliminating the need to keep track of multiple cards.

The data to transfer is encoded in the NFC Tag in the NDEF (NFC Data Exchange Format) format and is stored into the Tag data structure. The NDEF is a data format for NFC Devices and Tags to construct a valid NDEF message. The NDEF file consists of NDEF Messages, which consist of NDEF Records. The NDEF format is used to store and exchange information like URI (Uniform Resource Identifier), plain text, encrypted data, image data like GIF and JPEG files, etc.

System Setup

The application layer of the NFC Tag stores the data in the NDEF file. This example illustrates the NFC protocols and commands required to transfer data between the application layers of an NFC Device and an NFC Tag for an application like an NFC smart poster.

NDEF is a lightweight, binary message format that can be used to encapsulate one or more application-defined payloads of arbitrary type and size into a single message construct. Each payload is described by a type, a length, and an optional identifier. Type identifiers may be URIs, MIME media types, or NFC-specific types. NDEF payloads may include nested NDEF messages or chains of linked data chunks of length unknown at the time the data is generated [ 5 ].

txURL = 'mathworks.com';
targetRecord = ndefRecord('Type', 'U', 'URIID', '01', ...
    'ActualText', txURL)
targetRecord = 
  ndefRecord with properties:

       TypeNameFormat: 'NFC Forum well-known type'
    IsIDLengthPresent: '0'
        IsShortRecord: '1'
              IsChunk: '0'
       IsMessageBegin: '1'
         IsMessageEnd: '1'
           TypeLength: ''
        PayloadLength: ''
             IDLength: '00'
                 Type: 'U'
                   ID: ''
              Payload: ''
          StatusBytes: '02'
         LanguageCode: 'en'
                URIID: '01'
           ActualText: 'mathworks.com'

The NFC Tag containing the URI in the NDEF file is a Type 4 Tag in this example, as specified in the Type 4 Tag Operation Specification [ 6 ]. An nfcTarget object models this tag. It contains an nfcApp object that models the application layer and contains the data to be exchanged.

targetAppLayer = nfcApp();
targetAppLayer.AppData = create(targetRecord)
targetAppLayer = 
  nfcApp with properties:

       AppName: 'D2760000850101'
      CCFileID: 'E103'
    NDEFFileID: 'E104'
           CLA: '00'
           INS: 'A4'
            P1: '04'
            P2: '00'
            Lc: ''
            Le: ''
           SW1: '90'
           SW2: '00'
       AppData: 'D1010E55016D617468776F726B732E636F6D'

target = nfcTarget('AppLayer', targetAppLayer, 'EnableVisualization', false)
target = 
                     Fc: 13560000
                     Fs: 847500
       SamplesPerSymbol: 64
                    UID: '11aa22bb'
               AppLayer: [1x1 nfcApp]
       ReceivedUserData: ''
    EnableVisualization: 0

The consumer device is modeled by an nfcInitiator object, which also contains an nfcApp object to model its application layer.

initiator = nfcInitiator('AppLayer', nfcApp(), 'UserData', '', ...
    'EnableVisualization', false)
initiator = 
                     Fc: 13560000
       SamplesPerSymbol: 64
                     t1: 32
               AppLayer: [1x1 nfcApp]
               UserData: ''
    EnableVisualization: 0

% Signal to noise ratio, in dB
snrdB = 50;
% Reset the RNG for reproducible results 
s = rng(0);

The Initialization and Anticollision sequences are as described in Near Field Communication (NFC) example. The application data is exchanged using half-duplex block transmission protocol, as described in ISO®/IEC 14443-4 [ 4 ]. The example prints the status and actions of Initiator and Target devices, along with important information that is exchanged, to indicate the flow of commands.

nfcPrint.Message('URL to transmit:');
URL to transmit:
nfcPrint.Message(sprintf('%s%s', 'http://www.', txURL));
http://www.mathworks.com
nfcPrint.Start();
Start of NFC Communication between Initiator and Target
nfcInitialization(initiator, target, snrdB);
	Initiator transmitted REQA
	Target received REQA
		Target transmitted ATQA in response to REQA
	Initiator received ATQA
		Target supports bit frame anticollision
		Target's UID size: single
nfcAnticollisionLoop(initiator, target, snrdB);
	Start of Anticollision loop
		Cascade Level-1
			Initiator transmitted ANTICOLLISION command
			Target received Cascade Level-1 SEL code
				Target transmitted full UID
			Initiator received CL1 UID without collision
				Complete UID received: 0x11aa22bb
				Initiator transmitted SELECT command
			Target received Cascade Level-1 SEL code
				Target selection confirmed
				Target transmitted SAK with UID complete flag
			Initiator received SAK
				UID complete. Exit Anticollision loop.
	End of Anticollision loop

	Target compliant with NFCIP-1. Continue with Transport Protocol Activation
nfcProtocolActivation(initiator, target, snrdB);
	Start of Protocol Activation
		Initiator transmitted RATS
		Target received RATS
			Target transmitted ATS in response to RATS
		Initiator received ATS
	End of Protocol Activation
nfcBlockTransmissionProtocol(initiator, target, snrdB);
	Start of Half-Duplex Block Transmission Protocol
		Initiator transmitted SELECT command for APP NAME
		Target received SELECT command for APP NAME
			Target transmitted STATUS Bytes for APP NAME
		Initiator received valid STATUS Bytes for APP NAME
			Initiator transmitted SELECT command for CC File
		Target received SELECT command for CC File
			Target transmitted STATUS Bytes for CC File
		Initiator received valid STATUS Bytes for CC File
			Initiator transmitted READ command for CC File
		Target received READ command for CC File
			Target transmitted CCFILE CONTENT and STATUS Bytes for CC File
		Initiator received valid CCFILE CONTENT and STATUS Bytes for CC File
			Initiator transmitted SELECT command for NDEF File
		Target received SELECT command for NDEF File
			Target transmitted STATUS Bytes for NDEF File
		Initiator received valid STATUS Bytes for NDEF File
			Initiator transmitted READ command for NDEF NLEN
		Target received READ command for NDEF NLEN
			Target transmitted NLEN and STATUS Bytes for NDEF
		Initiator received NLEN and valid STATUS Bytes
			Initiator transmitted READ command for NDEF File
		Target received READ command for NDEF File
			Target transmitted NDEF CONTENT and STATUS Bytes for NDEF File
		Initiator received NDEF File content and valid STATUS Bytes
	End of Half-Duplex Block Transmission Protocol
nfcProtocolDeactivation(initiator, target, snrdB)
	Start of Protocol Deactivation
		Initiator transmitted DESELECT
		Target received DESELECT
			Target transmitted DESELECT response
		Initiator received DESELECT response
			Target released
	End of Protocol Deactivation
nfcPrint.End();
End of NFC Communication between Initiator and Target
recDataType = getReceivedNDEFType(initiator.AppLayer);
recData = getReceivedNDEFData(initiator.AppLayer);
if strcmpi(recDataType, 'U')
    nfcPrint.Message('Received URL:');
else
    nfcPrint.Message('Received telephone number:');
end
Received URL:
nfcPrint.Message(recData);
http://www.mathworks.com
nfcPrint.NewLine;

% Restore RNG state 
rng(s);
function nfcInitialization(initiator, target, snrdB)
    % Initialization and anticollision
    % Reference: ISO/IEC 14443-3, section 6

    txREQA = transmitREQA(initiator);
    rxREQA = awgn(txREQA, snrdB, 'measured');

    txATQA = receiveREQA(target, rxREQA);
    rxATQA = awgn(txATQA, snrdB, 'measured');

    [isATQAValid, isCollisionDetected, isTargetCompliant] = ...
        receiveATQA(initiator, rxATQA);

    coder.internal.errorIf(~isATQAValid, 'comm:NFC:InvalidATQA');
    coder.internal.errorIf(isCollisionDetected, 'comm:NFC:CollisionATQA');
    coder.internal.errorIf(~isTargetCompliant, 'comm:NFC:TargetNotCompliant');    
end

function nfcAnticollisionLoop(initiator, target, snrdB)
    % Anticollision Loop
    % Reference: ISO/IEC 14443-3, section 6
    
    nfcPrint.NewLine;
    nfcPrint.Heading1('Start of Anticollision loop');
    
    % Start anticollision loop
    cascadeLevel = 1;
    targetRxAC = [];
    nfcPrint.CascadeLevel(cascadeLevel);
    [initiatorTxAC, newCascadeLevel, uidComplete, isoCompliantTarget] = ...
        antiCollisionLoop(initiator, targetRxAC, cascadeLevel);
    
    while (newCascadeLevel <= 3) && ~uidComplete
        
        nfcPrint.CascadeLevel(newCascadeLevel, cascadeLevel);
        cascadeLevel = newCascadeLevel;
        
        targetRxAC = awgn(initiatorTxAC, snrdB, 'measured');
        % Target's anticollision loop
        targetTxAC = antiCollisionLoop(target, targetRxAC);
        initiatorRxAC = awgn(targetTxAC, snrdB, 'measured');
        % Initiator's anticollision loop
        [initiatorTxAC, newCascadeLevel, uidComplete, isoCompliantTarget] = ...
            antiCollisionLoop(initiator, initiatorRxAC, cascadeLevel);
    end
    
    coder.internal.errorIf(~uidComplete, 'comm:NFC:IncompleteUID');
    coder.internal.errorIf(~isoCompliantTarget, ...
        'comm:NFC:TargetNotCompliantWithNFCIP1');
    
    nfcPrint.Heading1('End of Anticollision loop');
    nfcPrint.NewLine;    
    nfcPrint.Heading1(['Target compliant with NFCIP-1. '...
        'Continue with Transport Protocol Activation']);    
end

function nfcProtocolActivation(initiator, target, snrdB)
    % ISO/IEC 14443-4 Protocol Activation
    % Reference: ISO/IEC 14443-4, section 5
    
    nfcPrint.NewLine;
    nfcPrint.Heading1('Start of Protocol Activation');

    txRATS = transmitRATS(initiator);
    rxRATS = awgn(txRATS, snrdB, 'measured');
    
    txATS = receiveRATS(target, rxRATS);
    rxATS = awgn(txATS, snrdB, 'measured');
    
    status = receiveATS(initiator, rxATS);
    coder.internal.errorIf(~status, 'comm:NFC:ProtocolActivationFailed');
    
    nfcPrint.Heading1('End of Protocol Activation');    
end

function nfcBlockTransmissionProtocol(initiator, target, snrdB)
    % Half-duplex Block Transmission Protocol
    % Reference: ISO/IEC 14443-4, section 7
    
    nfcPrint.NewLine;
    nfcPrint.Heading1('Start of Half-Duplex Block Transmission Protocol');
    
    nfcTransmissionProtocol(initiator, target, snrdB);
    
    nfcPrint.Heading1('End of Half-Duplex Block Transmission Protocol');
    nfcPrint.NewLine;    
end

function nfcProtocolDeactivation(initiator, target, snrdB)
    % Protocol Deactivation
    % Reference: ISO/IEC 14443-4, section 8

    nfcPrint.NewLine;
    nfcPrint.Heading1('Start of Protocol Deactivation');

    txDESLECT = transmitDESELECT(initiator);
    rxDESELECT = awgn(txDESLECT, snrdB, 'measured');
    
    txDESELECT_RES = receiveDESELECT(target, rxDESELECT);
    rxDESELECT_RES = awgn(txDESELECT_RES, snrdB, 'measured');
    
    status = receiveDESELECT_RES(initiator, rxDESELECT_RES);
    coder.internal.errorIf(~status, 'comm:NFC:ProtocolDeactivationFailed');
    
    nfcPrint.Heading1('End of Protocol Deactivation');
end

Exploration

Explore various methods of nfcInitiator, nfcTarget, nfcApp, and ndefRecord objects, and various functions used in this example to understand various commands and protocols described by NFC standards. Experiment with various system parameters like SNR, NDEF messages to see how they impact the system.

References

1. https://nfc-forum.org/

2. ISO/IEC 14443-2 Identification cards - Contactless integrated circuit cards - Proximity cards - Part 2: Radio frequency power and signal interface

3. ISO/IEC 14443-3 Identification cards - Contactless integrated circuit cards - Proximity cards - Part 3: Initialization and anticollision

4. ISO/IEC 14443-4 Identification cards - Contactless integrated circuit cards - Proximity cards - Part 4: Transmission protocol

5. NFC Data Exchange Format (NDEF) Technical Specification 1.0

6. Type 4 Tag Operation Specification Technical Specification 2.0