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;
    }