Near Field Communication (NFC)
Tizen enables you to use Near Field Communication (NFC) functionalities, such as reading and writing tags, and emulating a smartcard. NFC is an international standard (ISO/IEC 18092) that specifies an interface and a protocol for simple wireless interconnection of closely coupled devices. For more information, see the NFC Forum.
The main features of the Tizen.Network.Nfc namespace includes the following:
-
NFC management
You can activate or deactivate NFC, monitor NFC events, and retrieve adapters for various NFC modes.
-
NDEF support
The NFC Data Exchange Format (NDEF) is a packet message format used in the reader/writer and peer-to-peer modes.
You can create NDEF records and messages.
-
Tag mode
You can manage tag events and read and write NDEF messages from and to an NFC tag.
-
Peer-to-peer mode
You can manage peer-to-peer (P2P) events and send and receive NDEF messages between peer devices.
-
Card emulation mode
The card emulation mode allows an NFC device to function as a smart card.
You can enable and disable the card emulation mode, register an AID value, manage secure element events, manage HCE events from the NFC reader, and send HCE responses to the NFC reader.
Card emulation
The card emulation mode can be broadly divided into 2 categories, which are described below:
-
Traditional card emulation
In traditional card emulation, the NFC controller in the device routes data from the NFC reader directly to the secure element (SE), and an applet handles all of the data in the SE. The user does not participate in the operation at all.
Tizen supports eSE and UICC as SEs.
Figure: Traditional card emulation
-
Host-based card emulation (HCE)
HCE is an on-device technology that permits a phone to perform card emulation on an NFC-enabled device without relying on access to a secure element (SE). The data is routed to the user space on which Tizen applications reside, instead of routing the data to a secure element.
Figure: Card emulation with HCE
HCE allows you to create your own card emulation system and bypass the SE. This approach brings 2 advantages:
- For UICC-type SE, the mobile service provider is involved in the card emulation behavior. With HCE, you are independent of the service provider.
- You do not need SE hardware chips within the device.
To understand HCE behavior, mainly how data is internally routed to the correct application, consider how Tizen handles NFC routing by following these steps:
-
Assume that the user has an HCE application or installs one.
The application has an “AID” value, which is stored in the NFC routing table (blue arrow in the following figure).
-
When the NFC reader attempts card emulation, the NFC controller checks the routing table to find the application to which the data is sent for emulation (red arrows in the following figure).
-
When the application is uninstalled, the AID value is deleted from the routing table.
Figure: HCE routing
Prerequisites
To enable your application to use the NFC functionality, follow the steps below:
-
To use the Tizen.Network.Nfc namespace, the application has to request permission by adding the following privileges to the
tizen-manifest.xml
file:XMLCopy<privileges> <privilege>http://tizen.org/privilege/nfc</privilege> <privilege>http://tizen.org/privilege/nfc.cardemulation</privilege> </privileges>
-
To use the methods and properties of the
Tizen.Network.Nfc
namespace, include it in your application:C#Copyusing Tizen.Network.Nfc;
Activate and deactivate NFC
To activate and deactivate NFC, follow the steps below:
-
To use the following NFC activation method, the application has to request permission by adding the following privileges to the
tizen-manifest.xml
file:XMLCopy<privileges> <privilege>http://tizen.org/privilege/nfc.admin</privilege> </privileges>
Note
To be able to use this privilege, your application must be signed with a platform-level certificate.
-
To activate NFC, use the
SetActivationAsync()
method of the Tizen.Network.Nfc.NfcManager class with thetrue
parameter:C#CopyNfcManager.SetActivationAsync(true);
-
To deactivate NFC, use the
SetActivationAsync()
method with thefalse
parameter:C#CopyNfcManager.SetActivationAsync(false);
Monitor NFC state changes
To monitor NFC state changes using event handlers, follow these steps:
-
Define an event handler to be triggered when the NFC activation state changes:
C#Copypublic static void ActivationStatusChanged(object sender, ActivationChangedEventArgs e) { isActivated = e.Activated; flagStateChanged = true; }
-
Register the event handler for the
ActivationChanged
event of the Tizen.Network.Nfc.NfcManager class:C#CopyNfcManager.ActivationChanged += ActivationStatusChanged;
-
When it is no longer needed, deregister the event handler:
C#CopyNfcManager.ActivationChanged -= ActivationStatusChanged;
Retrieve the connection adapter
Before any NFC operations, retrieve the appropriate connection adapter with the corresponding GetXXXAdapter()
method of the Tizen.Network.Nfc.NfcManager class.
For example, to retrieve the NFC tag mode adapter, use the GetTagAdapter()
method:
C#
Copy
public static void GetTagAdapter_RETURN_VALUE()
{
try
{
/// Test code
Assert.IsInstanceOf<NfcTagAdapter>(NfcManager.GetTagAdapter(), "GetTagAdapter return value is not of the type NfcTagAdapter");
}
catch (NotSupportedException)
{
Assert.IsTrue(isNfcSupported == false || isTagSupported == false, "GetTagAdapter throws the NotSupportedException, but Tizen supports the NFC Tag operation");
}
}
Create NDEF records and messages
To create an NDEF record and attach it to an NDEF message, follow these steps:
-
To create an NDEF record, create a new instance of the Tizen.Network.Nfc.NfcNdefRecord class and give it the required values.
In the following example, a record is created with 3 bytes of binary data as a payload:
C#Copypublic static void AppendRecord_RETURN_VALUE() { /// Test code try { byte[] type = new byte[1]{0x02}; byte[] id = new byte[1]{0x01}; byte[] payload = new byte[3]{0x04, 0x05, 0x06}; NfcNdefRecord record = new NfcNdefRecord(NfcRecordTypeNameFormat.WellKnown, type, id, payload, 3);
You can also create NDEF records to store different kinds of data, such as text or images, by using different parameters when creating the
Tizen.Network.Nfc.NfcNdefRecord
instance. -
Create the NDEF message as a new instance of the Tizen.Network.Nfc.NfcNdefMessage class and add the record to it using the
AppendRecord()
method:C#CopyNfcNdefMessage msg = new NfcNdefMessage(); int previousMsgRecordCount = msg.RecordCount; bool success = msg.AppendRecord(record); Assert.IsTrue(success, "Failed to append record to NdefMessage"); int currentMsgRecordCount = msg.RecordCount; Assert.IsTrue(previousMsgRecordCount + 1 == currentMsgRecordCount, "currentMsgRecordCount should be greater than previousMsgRecordCount"); } catch (NotSupportedException) { Assert.IsTrue(isSupported == false, "Method throws the NotSupportedException, but Tizen supports the NFC operation"); } }
Manage tag events
To keep track of NFC tag events through event handlers, follow these steps:
-
Define an event handler to trigger whenever a new NFC tag is found:
C#Copypublic static void TagDiscoveredCallback(object sender, TagDiscoveredEventArgs e) { _eventArgs = e; }
-
Register the event handler for the
TagDiscovered
event of the Tizen.Network.Nfc.NfcTagAdapter class:C#Copypublic static async Task TagDiscovered_EVENT_LISTEN() { try { /// Precondition /// 1. Retrieve the tag adapter /// 2. Register the event handler _tagAdapter = NfcManager.GetTagAdapter(); _tagAdapter.TagDiscovered += TagDiscoveredCallback; /// Test code await WaitTagDiscovered();
-
When it is no longer needed, deregister the event handler:
C#CopyAssert.IsNotNull(_eventArgs, "_eventArgs should not be null"); Assert.IsNotNull(_eventArgs.Tag, "Tag should not be null"); /// Postcondition /// 1. Unregister the event handler /// 2. Reset variables Assert.IsNotNull(_tagAdapter, "_tagAdapter should not be null"); _tagAdapter.TagDiscovered -= TagDiscoveredCallback; _tagAdapter = null; _eventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _tagFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC Tag operation"); } }
Read and write NDEF messages
To read NDEF messages from an NFC tag and write them to a tag:
-
To read an NDEF message, follow the steps below:
-
Retrieve the NFC tag adapter and register a
TagDiscovered
event handler for it:C#Copypublic static async Task ReadNdefMessageAsync_METHOD_RETURN() { try { /// Precondition /// 1. Retrieve the tag adapter /// 2. Register the event handler _tagAdapter = NfcManager.GetTagAdapter(); _tagAdapter.TagDiscovered += TagDiscoveredCallback;
-
Once the tag is discovered, read the message with the
ReadNdefMessageAsync()
method of the Tizen.Network.Nfc.NfcTag class:C#Copy/// Test code await WaitTagDiscovered(); Assert.IsNotNull(_eventArgs, "_eventArgs should not be null"); Assert.IsNotNull(_eventArgs.Tag, "Tag should not be null"); NfcNdefMessage ndefMessage = await _eventArgs.Tag.ReadNdefMessageAsync(); Assert.IsTrue(ndefMessage.RecordCount > 0, "RecordCount should be greater than 0"); /// Postcondition /// 1. Unregister the event handler /// 2. Reset variables Assert.IsNotNull(_tagAdapter, "_tagAdapter should not be null"); _tagAdapter.TagDiscovered -= TagDiscoveredCallback; _tagAdapter = null; _eventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _tagFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC Tag operation"); } }
-
-
To write an NDEF message, follow the steps below:
-
Retrieve the NFC tag adapter and register a
TagDiscovered
event handler for it:C#Copypublic static async Task WriteNdefMessageAsync_METHOD_RETURN() { try { /// Precondition /// 1. Retrieve the tag adapter /// 2. Register the event handler _tagAdapter = NfcManager.GetTagAdapter(); _tagAdapter.TagDiscovered += TagDiscoveredCallback;
-
Once the tag is discovered, create a new NDEF message as an instance of the Tizen.Network.Nfc.NfcNdefMessage class and a new NDEF record as an instance of the Tizen.Network.Nfc.NfcNdefRecord class. Then append the record into the message with the
AppendRecord()
method of theTizen.Network.Nfc.NfcNdefMessage
class:C#Copy/// Test code await WaitTagDiscovered(); Assert.IsNotNull(_eventArgs, "_eventArgs should not be null"); Assert.IsNotNull(_eventArgs.Tag, "Tag should not be null"); NfcNdefMessage ndefMessage = new NfcNdefMessage(); NfcNdefRecord ndefRecord = new NfcNdefRecord("123", "KR", NfcEncodeType.Utf8); ndefMessage.AppendRecord(ndefRecord);
-
Write the message to the NFC tag with the
WriteNdefMessageAsync()
method of theTizen.Network.Nfc.NfcTag
class:C#CopyNfcError nfcError = await _eventArgs.Tag.WriteNdefMessageAsync(ndefMessage); Assert.IsTrue(nfcError == NfcError.None, "nfcError should be no error"); /// Postcondition /// 1. Unregister the event handler /// 2. Reset variables Assert.IsNotNull(_tagAdapter, "_tagAdapter should not be null"); _tagAdapter.TagDiscovered -= TagDiscoveredCallback; _tagAdapter = null; _eventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _tagFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC Tag operation"); } }
-
Manage P2P events
To keep track of P2P events through event handlers, follow the steps below:
-
Define an event handler to trigger whenever a new P2P target has been found:
C#Copypublic static void P2pTargetDiscoveredCallback(object sender, P2pTargetDiscoveredEventArgs e) { _p2pTargetDiscoveredEventArgs = e; }
-
Register the event handler for the
P2pTargetDiscovered
event of the Tizen.Network.Nfc.NfcP2pAdapter class:C#Copypublic static async Task P2pTargetDiscovered_EVENT_LISTEN() { try { /// Precondition /// 1. Retrieve the P2P adapter /// 2. Register the event handler _p2pAdapter = NfcManager.GetP2pAdapter(); _p2pAdapter.P2pTargetDiscovered += P2pTargetDiscoveredCallback; /// Test code await WaitTargetDiscovered();
-
When it is no longer needed, deregister the event handler:
C#CopyAssert.IsNotNull(_p2pTargetDiscoveredEventArgs, "P2pTargetDiscoveredEventArgs should not be null"); /// Postcondition /// 1. Unregister event handler /// 2. Reset variables Assert.IsNotNull(_p2pAdapter, "_tagAdapter should not be null"); _p2pAdapter.P2pTargetDiscovered -= P2pTargetDiscoveredCallback; _p2pAdapter = null; _p2pTargetDiscoveredEventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _p2pFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC P2P operation"); } }
Send and Receive NDEF messages between peer devices
You can both send and receive NDEF devices between peer devices in P2P mode.
-
To send an NDEF message to a peer device, follow these steps:
-
Retrieve the P2P adapter and register a
P2pTargetDiscovered
event handler for it:C#Copypublic static async Task SendNdefMessageAsync_METHOD_RETURN() { try { /// Precondition /// 1. Retrieve the P2P adapter /// 2. Register the event handler _p2pAdapter = NfcManager.GetP2pAdapter(); _p2pAdapter.P2pTargetDiscovered += P2pTargetDiscoveredCallback;
-
Create a new NDEF message as an instance of the Tizen.Network.Nfc.NfcNdefMessage class and a new NDEF record as an instance of the Tizen.Network.Nfc.NfcNdefRecord class. Then append the record into the message with the
AppendRecord()
method of theTizen.Network.Nfc.NfcNdefMessage
class:C#Copy/// Test code await WaitTargetDiscovered(); Assert.IsNotNull(_p2pTargetDiscoveredEventArgs, "P2pTargetDiscoveredEventArgs should not be null"); NfcP2p currentP2p = _p2pAdapter.GetConnectedTarget(); Assert.IsNotNull(currentP2p, "currentP2p should not be null"); NfcNdefMessage ndefMessage = new NfcNdefMessage(); NfcNdefRecord ndefRecord = new NfcNdefRecord("123", "KR", NfcEncodeType.Utf8); ndefMessage.AppendRecord(ndefRecord);
-
Send the NDEF message with the
SendNdefMessageAsync()
method of the Tizen.Network.Nfc.NfcP2p class:C#CopyNfcError nfcError = await currentP2p.SendNdefMessageAsync(ndefMessage); Assert.IsTrue(nfcError == NfcError.None, "nfcError should be no error"); /// Postcondition /// 1. Unregister the event handler /// 2. Reset variables Assert.IsNotNull(_p2pAdapter, "_tagAdapter should not be null"); _p2pAdapter.P2pTargetDiscovered -= P2pTargetDiscoveredCallback; _p2pAdapter = null; _p2pTargetDiscoveredEventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _p2pFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC P2P operation"); } }
-
-
To receive an NDEF message from a peer device, follow the steps below:
-
Define an event handler to trigger whenever P2P data is received:
C#Copypublic static void P2pDataReceivedCallback(object sender, P2pDataReceivedEventArgs e) { _p2pDataReceivedEventArgs = e; }
-
Once a P2P connection has been made, retrieve the connected P2P target with the
GetConnectedTarget()
method of the Tizen.Network.Nfc.NfcP2pAdapter class, and add the new event handler for theP2pDataReceived
event of the newly-created instance of the Tizen.Network.Nfc.NfcP2p class:C#Copypublic static async Task NdefMessage_READ_ONLY() { try { /// Precondition /// 1. Retrieve the P2P adapter /// 2. Register the event handler _p2pAdapter = NfcManager.GetP2pAdapter(); _p2pAdapter.P2pTargetDiscovered += P2pTargetDiscoveredCallback; /// Test code await WaitTargetDiscovered(); Assert.IsNotNull(_p2pTargetDiscoveredEventArgs, "P2pTargetDiscoveredEventArgs should not be null"); NfcP2p p2pTarget = _p2pAdapter.GetConnectedTarget(); p2pTarget.P2pDataReceived += P2pDataReceivedCallback;
-
The received NDEF message can be read through the newly-created instance of the Tizen.Network.Nfc.P2pDataReceivedEventArgs class:
C#Copyawait WaitDataReceived(); Assert.IsNotNull(_p2pDataReceivedEventArgs, "P2pDataReceivedEventArgs should not be null"); Assert.IsInstanceOf<NfcNdefMessage>(_p2pDataReceivedEventArgs.NdefMessage, "NdefMessage value is not of the type NfcNdefMessage"); /// Postcondition /// 1. Unregister event handlers /// 2. Reset variables Assert.IsNotNull(p2pTarget, "p2pTarget should not be null"); p2pTarget.P2pDataReceived -= P2pDataReceivedCallback; Assert.IsNotNull(_p2pAdapter, "_p2pAdapter should not be null"); _p2pAdapter.P2pTargetDiscovered -= P2pTargetDiscoveredCallback; _p2pAdapter = null; _p2pTargetDiscoveredEventArgs = null; _p2pDataReceivedEventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _p2pFeature == false, "Method throws the NotSupportedException, but Tizen supports the Nfc P2P operation"); } }
-
Enable and Disable the card emulation mode
To enable and disable the smart card emulation mode, follow the steps below:
-
Retrieve the card emulation adapter with the
GetCardEmulationAdapter()
method of the Tizen.Network.Nfc.NfcManager class:C#Copypublic static void EnableCardEmulation_CHECK_CARD_EMULATION_STATUS() { try { NfcCardEmulationAdapter ceAdapter = NfcManager.GetCardEmulationAdapter();
-
Enable and disable the card emulation mode with the
EnableCardEmulation()
andDisableCardEmulation()
methods of the Tizen.Network.Nfc.NfcCardEmulationAdapter class:C#CopyceAdapter.DisableCardEmulation(); ceAdapter.EnableCardEmulation(); NfcSecureElementCardEmulationMode ceMode = ceAdapter.GetCardEmulationMode(); Assert.IsTrue(ceMode == NfcSecureElementCardEmulationMode.On, "The card emulation mode should be true."); } catch (NotSupportedException) { Assert.IsTrue(isNfcSupported == false || isCeSupported == false, "Method throws the NotSupportedException, but Tizen supports the NFC operation"); } }
Register AID
To register an AID value, follow the steps below:
-
Retrieve the card emulation adapter with the
GetCardEmulationAdapter()
method of the Tizen.Network.Nfc.NfcManager class:C#Copypublic static void RegisterAid_METHOD_CALL_WITH_HCE_PAYMENT() { try { NfcCardEmulationAdapter ceAdapter = NfcManager.GetCardEmulationAdapter();
-
Register the AID with the
RegisterAid()
method of the Tizen.Network.Nfc.NfcCardEmulationAdapter class:C#CopyceAdapter.RegisterAid(NfcSecureElementType.Hce, NfcCardEmulationCategoryType.Payment, "325041592E5359532E4444463031"); } catch (NotSupportedException) { Assert.IsTrue(isNfcSupported == false || isHceSupported == false, "Method throws the NotSupportedException, but Tizen supports the NFC operation"); } }
Manage secure element events
To manage secure element (SE) events, follow the steps below:
-
Define an event handler to be triggered when an SE event occurs:
C#Copypublic static void SecureElementCallback(object sender, SecureElementEventArgs e) { _seEventArgs = e; }
-
Retrieve the card emulation adapter with the
GetCardEmulationAdapter()
method of the Tizen.Network.Nfc.NfcManager class, and register the SE event handler for itsSecureElementEvent
event:C#Copypublic static async Task SecureElementEvent() { try { /// Precondition /// 1. Retrieve the card emulation adapter /// 2. Register the SE event handler _cardEmulationAdapter = NfcManager.GetCardEmulationAdapter(); _cardEmulationAdapter.SecureElementEvent += SecureElementCallback; /// Test code await WaitSeEvent(); Assert.IsNotNull(_seEventArgs, "The _seEventArgs should not be null when HCE event callback is called"); Assert.IsTrue(_checkFlag == true, "isChecked should be true");
-
When it is no longer needed, deregister the event handler:
C#Copy/// Postcondition /// 1. Unregister the SE event handler /// 2. Reset variables Assert.IsNotNull(_cardEmulationAdapter, "_cardEmulationAdapter should not be null"); _cardEmulationAdapter.SecureElementEvent -= SecureElementCallback; _cardEmulationAdapter = null; _seEventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _ceFeature == false || _hceFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC card emulation operation"); } }
Manage HCE events from the NFC reader
To manage HCE events from the NFC reader, follow the steps below:
-
Define an event handler to be triggered when an HCE event occurs:
C#Copypublic static void HostCardEmulationCallback(object sender, HostCardEmulationEventArgs e) { _hceEventArgs = e; }
-
Retrieve the card emulation adapter with the
GetCardEmulationAdapter()
method of the Tizen.Network.Nfc.NfcManager class, and register the HCE event handler for itsHostCardEmulationEvent
event:C#Copypublic static async Task HostCardEmulationEvent_HOST_CARD_EMULATION_EVENT_LISTEN_TYPE_ACTIVATED() { try { /// Precondition /// 1. Retrieve the card emulation adapter /// 2. Register the HCE event handler _cardEmulationAdapter = NfcManager.GetCardEmulationAdapter(); _cardEmulationAdapter.HostCardEmulationEvent += HostCardEmulationCallback; /// Test code await WaitHceEventActivated(); Assert.IsNotNull(_hceEventArgs, "The _hceEventArgs should not be null when HCE event callback is called"); Assert.IsTrue(_checkFlag == true, "isChecked should be true");
-
When it is no longer needed, deregister the event handler:
C#Copy/// Postcondition /// 1. Unregister the HCE event handler /// 2. Reset variables Assert.IsNotNull(_cardEmulationAdapter, "_cardEmulationAdapter should not be null"); _cardEmulationAdapter.HostCardEmulationEvent -= HostCardEmulationCallback; _cardEmulationAdapter = null; _hceEventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _ceFeature == false || _hceFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC host card emulation operation"); } }
Send HCE responses to the NFC reader
To send HCE responses to the NFC reader, follow the steps below:
-
Retrieve the card emulation adapter with the
GetCardEmulationAdapter()
method of the Tizen.Network.Nfc.NfcManager class, and register the HCE event handler for itsHostCardEmulationEvent
event:C#Copypublic static async Task HceSendApduResponse_METHOD_RETURN() { try { /// Precondition /// 1. Retrieve the card emulation adapter /// 2. Register the HCE event handler _cardEmulationAdapter = NfcManager.GetCardEmulationAdapter(); _cardEmulationAdapter.HostCardEmulationEvent += HostCardEmulationCallback;
-
Once the HCE event triggers, send the response with the
HceSendApduResponse()
method of the Tizen.Network.Nfc.NfcSecureElement class:C#Copy/// Test code byte[] responseBuffer = {0x90, 0x00}; await WaitHceEvent(); Assert.IsNotNull(_eventArgs, "The _eventArgs should not be null when HCE event callback is called"); Assert.IsNotNull(_eventArgs.SecureElement, "The SecureElement property of _eventArgs should not be null when HCE event callback is called"); Assert.IsInstanceOf<NfcSecureElement>(_eventArgs.SecureElement, "SecureElement value is not of the type NfcSecureElement"); _eventArgs.SecureElement.HceSendApduResponse(responseBuffer, 2); /// Postcondition /// 1. Unregister the HCE event handler /// 2. Reset variables _cardEmulationAdapter.HostCardEmulationEvent -= HostCardEmulationCallback; _cardEmulationAdapter = null; _eventArgs = null; } catch (NotSupportedException) { Assert.IsTrue(_nfcFeature == false || _ceFeature == false || _hceFeature == false, "Method throws the NotSupportedException, but Tizen supports the NFC host card emulation operation"); } }
Related information
- Dependencies
- Tizen 4.0 and Higher