This tutorial describes how to detect specific NFC Forum tags using NFC Discovery API.
The NFC
Discovery API provides a mechanism to discover NFC tags at the device's
near field using the CNfcTagDiscovery
class.
Before you begin, refer to the following:
nfcserver.h, RNfcServer
nfctagdiscovery.h, CNfcTagDiscovery
nfcconnection.h, MNfcConnection
nfctagconnectionlistener.h, MNfcTagConnectionListener
nfctagsubscription.h, CNfcTagSubscription
nfcconnection.h, MNfcConnection
nfctag.h, MNfcTag
Create a
class that inherits from the MNfcTagConnectionListener
and CBase
classes. For example,
class CMyTagInitializer : public CBase, public MNfcTagConnectionListener
Register
for receiving notifications when the specified tag is detected in
the proximity of the device using the CNfcTagDiscovery::AddTagConnectionListener()
method.
Note: Only one listener can be added at a time.
CNfcTagDiscovery* iNfcTagDiscovery; iNfcTagDiscovery = CNfcTagDiscovery::NewL( aServer ); iNfcTagDiscovery->AddTagConnectionListener( MNfcTagConnectionListener& aListener);
Subscribe
to the NFC server using the CNfcTagDiscovery::AddTagSubscriptionL()
method by specifying the interested tag type.
iSubscription = CNfcTagSubscription::NewL(); iSubscription->AddConnectionModeL(TNfcConnectionInfo::ENfcType1); iNfcTagDiscovery->AddTagSubscriptionL( *iSubscription );
When the tag of the interested type is detected, MNfcTagConnectionListener::TagDetected()
is called back.
The returned tag is used to open the connection.
The sequence diagram below illustrates how the tag discovery works:
The following example illustrates how to detect and open a connection to the NFC Forum Type 2 tag.
#include <nfctag.h> #include <nfctagsubscription.h> #include <nfctagconnectionlistener.h> #include <nfcconnectioninfo.h> // FORWARD DECLARATIONS class CNfcTagDiscovery; class MNfcConnection; class RNfcServer; class CMyTagInitializer; class CNfcType2Connection; // CLASS DECLARATION // A Class that waits for a tag and then opens a connection to it. class CMyTagInitializer : public CBase, public MNfcTagConnectionListener { public: static CMyTagInitializer* NewL( RNfcServer& aServer ); static CMyTagInitializer* NewLC( RNfcServer& aServer ); virtual ~CMyTagInitializer(); /* * @param aConnection Connection variable that is initialized and opened. * @param aMode Type of connection mode that is to be initialized. */ TInt InitConnectionL( MNfcConnection* aConnection, TNfcConnectionInfo::TNfcConnectionMode aMode ); public: // From MNfcTagConnectionListener void TagDetected( MNfcTag* aNfcTag ); void TagLost(); private: CMyTagInitializer( RNfcServer& aServer ); void ConstructL( RNfcServer& aServer ); CActiveScheduler* iScheduler; CNfcTagDiscovery* iNfcTagDiscovery; MNfcConnection* iTagConnection; CNfcTagSubscription* iSubscription; RNfcServer& iServer; TNfcConnectionInfo::TNfcConnectionMode iMode; MNfcTag* iNfcTag; }; void CMyTagInitializer::ConstructL( RNfcServer& aServer ) { iScheduler = new (ELeave) CActiveScheduler(); CActiveScheduler::Install( iScheduler ); iNfcTagDiscovery = CNfcTagDiscovery::NewL( aServer ); // Add tag connection listener. iNfcTagDiscovery->AddTagConnectionListener( *this ); iSubscription = CNfcTagSubscription::NewL(); } TInt CMyTagInitializer::InitConnectionL( MNfcConnection* aConnection, TNfcConnectionInfo::TNfcConnectionMode aMode ) { iTagConnection = aConnection; iSubscription->AddConnectionModeL( aMode, 100 ); // Add tag subscription. iNfcTagDiscovery->AddTagSubscriptionL( *iSubscription ); CActiveScheduler::Start(); return KErrNone; } void CMyTagInitializer::TagDetected( MNfcTag* aNfcTag ) { iNfcTag = aNfcTag; // Open connection to the tag. iNfcTag->OpenConnection( *iTagConnection ); CActiveScheduler::Stop(); } void CMyTagInitializer::TagLost() { // No step required here, next attempt to use the connection will fail with an error } CMyTagInitializer::CMyTagInitializer( RNfcServer& aServer ) : iScheduler( NULL ), iNfcTagDiscovery( NULL), iTagConnection( NULL ), iSubscription( NULL ), iServer( aServer ), iNfcTag( NULL ) { } CMyTagInitializer* CMyTagInitializer::NewL( RNfcServer& aServer ) { CMyTagInitializer* self = NewLC( aServer ); CleanupStack::Pop( self ); return self; } CMyTagInitializer* CMyTagInitializer::NewLC( RNfcServer& aServer ) { CMyTagInitializer* self = new (ELeave) CMyTagInitializer( aServer ); CleanupStack::PushL( self ); self->ConstructL( aServer ); return self; } CMyTagInitializer::~CMyTagInitializer() { if ( iNfcTagDiscovery ) { iNfcTagDiscovery->RemoveTagConnectionListener(); iNfcTagDiscovery->RemoveTagSubscription(); } delete iNfcTag; delete iSubscription; delete iNfcTagDiscovery; delete iScheduler; } void mainDoL() { // Open handle to NFC server RNfcServer server; server.Open(); CleanupClosePushL( server ); // Create and start TagConnectionInitializer. Implementation below. CMyTagInitializer* initializer = CMyTagInitializer::NewLC( server ); CNfcType2Connection* connection = CNfcType2Connection::NewLC( server ); initializer->InitConnectionL( connection, TNfcConnectionInfo::ENfcType2); // // In this point of execution the connection is open and can be used. // CleanupStack::PopAndDestroy( connection ); CleanupStack::PopAndDestroy( initializer ); CleanupStack::PopAndDestroy(); // server } TInt E32Main() { CTrapCleanup* cleanup = CTrapCleanup::New(); TRAPD( err, mainDoL() ); delete cleanup; return err; }