zeroconf/server/src/mdnsserversession.cpp
changeset 14 da856f45b798
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zeroconf/server/src/mdnsserversession.cpp	Thu Jun 24 19:09:47 2010 +0530
@@ -0,0 +1,732 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// mdnsserversession.cpp
+// 
+//
+/**
+@file
+@internalTechnology
+*/
+
+#include "mdnsserversession.h"
+#include <s32mem.h>
+#include <utf.h>
+#include "mdnsserver.h"
+#include <mdns/cmdnsserverconstants.h>
+#include <f32file.h>
+__FLOG_STMT(_LIT8(KComponent,"MDNSServer");)
+/*
+ * Two phase constructor.
+ */
+CMdnsServerSession* CMdnsServerSession::NewL(const CMdnsServer& aServer)
+	{
+	CMdnsServerSession* self = CMdnsServerSession::NewLC(aServer);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+/*
+ * Two phase constructor
+ * @param aServer reference to the server.
+ */
+CMdnsServerSession* CMdnsServerSession::NewLC(const CMdnsServer& aServer)
+	{
+	CMdnsServerSession* self = new (ELeave) CMdnsServerSession(aServer);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+/*
+ * @param aMessage RMessage object.
+ */
+void CMdnsServerSession::ServiceL(const RMessage2& aMessage)
+	{
+	__FLOG(_L8("CMdnsServerSession::ServiceL - Entry"));
+	switch (aMessage.Function())
+		{
+	case EZeroconfServerMessageVersion:
+		break;
+		
+	case EMdnsServerQueryMessages:
+		{
+		if(NULL != iClientQuery.Handle())
+			{
+			aMessage.Complete(KErrInUse);	
+			}
+		else if (iServer.IsHostProbing() )
+            {
+            iServer.MessageQueue()->AppendMessageL(EQueryMessage,aMessage,SessionId());
+            }
+		else	
+			{
+			ServiceQueryL(aMessage);
+			}	
+		}
+		break;
+		
+	case EMdnsServerRecieveMessages:
+		{
+		HBufC8* buffer = HBufC8::NewLC(KDnsBufferlength);
+		TPtr8 bufferPointer(buffer->Des());
+		iResponseBundle.Store(bufferPointer);	
+		aMessage.Write(0,bufferPointer);	
+		CleanupStack::PopAndDestroy();//delete buffer
+		aMessage.Complete(KErrNone);
+		iResponseBundle.Close();
+		}	
+		break;
+	
+	case EMndsServerPublishMessages:
+	    {
+	    if( iServer.IsHostProbing() || iServer.IsPublishingService())
+	        {
+	        iServer.MessageQueue()->AppendMessageL(EPublishMessage,aMessage,SessionId());
+	        }
+	    else
+	        {
+	        iServer.SetPublishingService(ETrue);
+	        PublishL(aMessage);
+	        }
+	    break;
+	    }
+	case EMdnsServerStartNotifyMessages:
+	    {
+	    RegisterNotifyL(aMessage);
+	    aMessage.Complete(KErrNone);
+	    break;
+	    }
+	    
+	case EMdnsServerStopNotifyMessages:
+	    {
+	    StopNotifyL(aMessage);
+	    aMessage.Complete(KErrNone);
+	    break;
+	    }
+	    
+	case EMdnsServerRecieveNotifyMessages:
+	    {
+	    iNotifyMessageRequest = aMessage;
+	    break;
+	    }
+	default:
+		User::Leave(KErrUnknown);
+		break;
+		}
+	
+	__FLOG(_L8("CMdnsServerSession::ServiceL - Exit"));
+	}
+	
+void CMdnsServerSession::ServiceError(const RMessage2& aMessage, TInt aError)
+	{
+	__FLOG(_L8("CMdnsServerSession::ServiceError - Entry Exit"));
+	aMessage.Complete(aError);
+	}
+
+
+
+void CMdnsServerSession::CleanUp()
+    {
+    __FLOG(_L8("CMdnsServerSession::CleanUp - Entry"));
+    // First thing is to send bye-bye packets to the services that we have published.
+    
+    RPointerArray <CCacheEntry> cacheEntries;
+    iServer.MessageHandler().DnsCache().AuthoritativeEntriesL(cacheEntries);
+    
+    for(TInt index =0; index < cacheEntries.Count();index++)
+        {               
+        CCacheEntry* entry = cacheEntries[index];
+        if(entry->SessionId()==iSessionId)
+            {
+            // To filter out address records.
+            if(entry->ServiceRecord())
+                {
+                
+                // found the entry to be deleted
+                if(entry->ServiceRecord())
+                    entry->ServiceRecord()->SetTtl(0);
+                if(entry->TxtRecord())
+                    entry->TxtRecord()->SetTtl(0);
+                if(entry->PtrRecord())
+                    entry->PtrRecord()->SetTtl(0);
+                
+                // delete the entry in the cache
+                
+                // !!!!!! Assuming that the entry will always contain a srv record.
+                iServer.MessageHandler().DnsCache().DeleteEntryL(entry->ServiceRecord()->Name());
+                
+                CDnsMessage* message = CDnsMessage::NewL(0,EFalse);
+                CleanupStack::PushL(message);    
+                
+                TDnsHeader header(message->Header());
+                header.SetAuthoritative(ETrue);
+                message->SetHeader(header);
+                
+                if(entry->ServiceRecord())
+                message->AppendAnswerL(entry->ServiceRecord()->CloneL());
+                if(entry->PtrRecord())
+                message->AppendAnswerL(entry->PtrRecord()->CloneL());
+                if(entry->TxtRecord())
+                message->AppendAnswerL(entry->TxtRecord()->CloneL());
+    
+                // bye-bye packet on the way to the network !!!
+                iServer.MessageHandler().SendQueryL(message,iServer);
+                CleanupStack::Pop(); //message   
+                }
+            
+            }
+        }       
+    
+    
+    cacheEntries.ResetAndDestroy();
+    cacheEntries.Close();   
+    __FLOG(_L8("CMdnsServerSession::CleanUp - Exit"));
+    }
+/*
+ * Destructor
+ */
+CMdnsServerSession::~CMdnsServerSession()
+	{
+	__FLOG(_L8("CMdnsServerSession::~CMdnsServerSession - Entry"));
+	CleanUp();
+	iQueryBundle.Close();
+	iResponseBundle.Close();
+	iServer.DropSession();
+	for(TInt i =0 ; i<iRegisterNotifyArray.Count();i++ )
+	    {
+	    iRegisterNotifyArray[i].Close();
+	    }
+	iRegisterNotifyArray.Close();
+	__FLOG(_L8("CMdnsServerSession::~CMdnsServerSession - Exit"));
+	__FLOG_CLOSE;
+	}
+/*
+ * Constructor
+ */
+CMdnsServerSession::CMdnsServerSession(const CMdnsServer& aServer)
+	: iServer(const_cast<CMdnsServer&>(aServer))
+	{
+	iSessionId = iServer.NewSession();
+	}
+	
+/*
+ * Two phase constructor
+ */
+void CMdnsServerSession::ConstructL()
+	{
+	__FLOG_OPEN(KMDNSSubsystem, KComponent);
+	}
+
+//TODO
+TInt CMdnsServerSession::CountResources()
+	{
+	return 3;
+	}
+
+void CMdnsServerSession::ServerVersionL(const RMessage2& aMessage)
+	{
+	__FLOG(_L8("CMdnsServerSession::ServerVersionL - Entry"));
+	TVersion mdnsServerVersion(0, 8, 0);
+	TPckgC<TVersion> pkg(mdnsServerVersion);
+	aMessage.WriteL(0, pkg);
+	aMessage.Complete(KErrNone);
+	__FLOG(_L8("CMdnsServerSession::ServerVersionL - Exit"));
+
+	}
+/*
+ * Service any query rom the client
+ */
+void CMdnsServerSession::ServiceQueryL(const RMessage2& aMessage)
+	{
+	__FLOG(_L8("CMdnsServerSession::ServiceQueryL - Entry"));
+	iQueryBundle.Close();
+	iClientQuery = aMessage;
+	TInt len = aMessage.GetDesLengthL(0);
+	HBufC8* query = HBufC8::NewLC(aMessage.GetDesLengthL(0));
+	TPtr8 loadPtr = query->Des();
+	aMessage.ReadL(0,loadPtr);
+	iQueryBundle.CreateL();
+	TInt retOnLoad = iQueryBundle.Load(loadPtr);
+	User::LeaveIfError(retOnLoad);
+	RParameterFamily pnpFamily = iQueryBundle.GetFamilyAtIndex(0);
+	TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+	CDnsMessage* message = CDnsMessage::NewL(0,ETrue );
+	CleanupStack::PushL(message);
+	for ( TInt paramIndex = count - 1; paramIndex >= 0; paramIndex-- )
+		{ 
+		CMDnsQueryRequestParamSet* queryParam = static_cast<CMDnsQueryRequestParamSet*> (pnpFamily.GetParameterSetAtIndex ( paramIndex, RParameterFamily::ERequested ));
+		HBufC8* name = HBufC8::NewL(256);
+		CleanupStack::PushL(name);
+		TPtr8 ptrName(name->Des());
+		ptrName.Append(queryParam->InstanceName());
+		if(queryParam->InstanceName().Length() > 0)
+			{
+			ptrName.Append(_L8("."));	
+			}
+		ptrName.Append(queryParam->ServiceType());
+		if(queryParam->QueryType() != EDnsType_A)
+			{
+			ptrName.Append(1 == queryParam->Protocol() ? KTcpProtocolType : KUdpProtocolType);	
+			}
+		ptrName.Append(KLocalTld);
+		ptrName.Append(_L8("."));
+		CDnsQuestion* question = CDnsQuestion::NewL();
+		CleanupStack::PushL(question);
+		question->SetNameL(ptrName);
+		question->SetClass(EDnsClass_IN);
+		question->SetType(queryParam->QueryType());
+		question->SetUnicast(EFalse);
+		message->AppendQueryL(question);
+		CleanupStack::Pop();
+		CleanupStack::PopAndDestroy();//name
+		}
+	iServer.MessageHandler().ServiceClientQueryL(message,aMessage.Handle());	
+	CleanupStack::Pop();//message
+	CleanupStack::PopAndDestroy();//query
+	__FLOG(_L8("CMdnsServerSession::ServiceQueryL - Exit"));
+	}
+
+TInt CMdnsServerSession::OutStandQueryClientHandle()const
+	{
+	return iClientQuery.Handle();	
+	}
+	
+void CMdnsServerSession::SendResponseL()
+	{
+	__FLOG(_L8("CMdnsServerSession::SendResponseL - Entry"));
+	RParameterFamily pnpFamily = iQueryBundle.GetFamilyAtIndex(0);
+	TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+	//Open a new reference to ResponseBundle 
+	iResponseBundle.Open ();
+	CleanupClosePushL( iResponseBundle );
+	for(TInt index =0 ;index <count ; index++)
+		{
+		CMDnsQueryRequestParamSet* queryParam = static_cast<CMDnsQueryRequestParamSet*> (pnpFamily.GetParameterSetAtIndex ( index, RParameterFamily::ERequested ));
+		HBufC8* name = HBufC8::NewL(KDnsBufferlength);
+		CleanupStack::PushL(name);
+		TPtr8 ptrName(name->Des());
+		ptrName.Append(queryParam->InstanceName());
+		if(queryParam->InstanceName().Size()>0)
+		    ptrName.Append(_L8("."));
+		ptrName.Append(queryParam->ServiceType());
+		if(queryParam->QueryType() != EDnsType_A)
+			{
+			ptrName.Append(1 == queryParam->Protocol() ? KTcpProtocolType : KUdpProtocolType);	
+			}
+		ptrName.Append(KLocalTld);
+		ptrName.Append(_L8("."));	
+		RPointerArray<CCacheEntry> records;
+		iServer.MessageHandler().DnsCache().FindServiceL(records,ptrName,(TDnsType)queryParam->QueryType());
+		TInt count = records.Count();
+		switch((TDnsType)queryParam->QueryType())	
+			{
+				case EDnsType_PTR:
+					{
+					RParameterFamily pnpFamily = iResponseBundle.CreateFamilyL (EMdnsPtrParamset);
+					while(count -- > 0 )
+						{
+						iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+						CMDnsPtrParamSet* responseParam = CMDnsPtrParamSet::NewL(pnpFamily);
+						responseParam->SetInstanceNameL(records[count]->PtrRecord()->Name());
+						responseParam->SetDomainNameL(records[count]->PtrRecord()->DomainName());
+						//responseParam->SetTtlL(records[count]->PtrRecord()->Ttl());
+						}
+					break;
+					}
+				case EDnsType_SRV:
+					{
+					RParameterFamily pnpFamily = iResponseBundle.CreateFamilyL (EMdnsSrvParamset);
+					while(count -- > 0 )
+						{
+						iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+						CMDnsSrvParamSet* responseParam = CMDnsSrvParamSet::NewL(pnpFamily);
+						responseParam->SetDomainNameL(records[count]->ServiceRecord()->Name());
+						responseParam->SetTargetL(records[count]->ServiceRecord()->Target());
+						responseParam->SetPriority(records[count]->ServiceRecord()->Priority());
+						responseParam->SetWeight(records[count]->ServiceRecord()->Weight());
+						responseParam->SetPort(records[count]->ServiceRecord()->Port());	
+						}
+					break;	
+					}
+				case EDnsType_TXT:
+					{
+					RParameterFamily pnpFamily = iResponseBundle.CreateFamilyL (EMdnsTxtParamset);
+					while(count -- > 0 )
+						{
+						iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+						CMDnsTxtParamSet* responseParam = CMDnsTxtParamSet::NewL(pnpFamily);
+						responseParam->SetDomainNameL(records[count]->TxtRecord()->Name());
+						RArray<RBuf8> txtData = records[count]->TxtRecord()->Text();
+						
+						for(TInt j=0;j<txtData.Count();j++)
+						    {
+						    responseParam->AppendTxtData(txtData[j]);
+						    }
+						}
+					break;
+					}
+				case EDnsType_A:
+					{
+					RParameterFamily pnpFamily = iResponseBundle.CreateFamilyL (EMdnsAddrParamset);
+					while(count -- > 0 )
+						{
+						iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+						CMDnsAddrParamSet* responseParam = CMDnsAddrParamSet::NewL(pnpFamily);
+						responseParam->SetDomainNameL(records[count]->AddressRecord()->Name());	
+						responseParam->SetAddress(records[count]->AddressRecord()->Address());
+						}
+					break;
+					}
+				case EDnsQType_Any:
+				    {
+				    iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+                    while(count -- > 0 )
+                         {
+                         CreateAnyQueryResponseL(*records[count]);
+                         }
+				    break;
+				    }
+					
+			}
+		records.ResetAndDestroy();
+		records.Close();	
+		CleanupStack::PopAndDestroy();//name	
+		}//end of for loop
+		
+		HBufC8* buffer = HBufC8::NewLC(KDnsBufferlength);	
+		TPtr8 bufferPointer(buffer->Des());
+		iResponseBundle.Store(bufferPointer);
+		TInt len = bufferPointer.Length();
+		TPckgC<TInt> lenbuf(len); 
+		iClientQuery.Write(1,lenbuf);
+		CleanupStack::PopAndDestroy();//buffer
+		iClientQuery.Complete(KErrNone);
+		CleanupStack::Pop();//iResponseBundle
+		__FLOG(_L8("CMdnsServerSession::SendResponseL - Exit"));	
+	}
+
+void CMdnsServerSession::PublishL(const RMessage2& aMessage)
+    {
+    __FLOG(_L8("CMdnsServerSession::PublishL - Entry"));
+    TBool isUpdate = aMessage.Int2();
+    iPublishRequest = aMessage;
+    TInt len = aMessage.GetDesLengthL(0);
+    HBufC8* query = HBufC8::NewLC(aMessage.GetDesLengthL(0));
+    TPtr8 loadPtr = query->Des();
+    aMessage.ReadL(0,loadPtr);
+    iPublishBundle.CreateL();
+    TInt retOnLoad = iPublishBundle.Load(loadPtr);
+    TInt familyCount = iPublishBundle.CountParameterFamilies();
+    RPointerArray<CDnsResourceData> publishRecordArray;
+    for(TInt i =0 ; i< familyCount; i++)
+        {
+        RParameterFamily pnpFamily = iPublishBundle.GetFamilyAtIndex(i);
+        switch (pnpFamily.Id())
+            {
+            case EMdnsSrvParamset:
+                {
+                TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+                for (TInt index= 0; index < count ; index++ )
+                    {
+                    CMDnsSrvParamSet* srvParamSet = static_cast<CMDnsSrvParamSet*> (pnpFamily.GetParameterSetAtIndex ( index, RParameterFamily::ERequested ));
+                    CRdTypeSrv* srvRecord = CRdTypeSrv::NewL();
+                    CleanupStack::PushL(srvRecord);
+                    srvRecord->SetNameL(srvParamSet->DomainName());
+                    srvRecord->SetClass(EDnsClass_IN);
+                    srvRecord->SetFlushBit(EFalse);
+                    srvRecord->SetPort(srvParamSet->Port()); 
+                    srvRecord->SetPriority(srvParamSet->Priority() );
+                    srvRecord->SetTargetL(iServer.HostName());
+                    srvRecord->SetTtl(120);
+                    srvRecord->SetType(EDnsType_SRV);
+                    srvRecord->SetWeight(srvParamSet->Weight());
+                    publishRecordArray.AppendL(srvRecord);
+                    CleanupStack::Pop();//CRdtypeSrv
+                    //Ptr Record
+                    /*
+                    CRdTypePtr* ptrRecord = CRdTypePtr::NewL();
+                    CleanupStack::PushL(ptrRecord);
+                    TInt pos = srvParamSet->DomainName().Locate('.');
+                    ptrRecord->SetNameL(srvParamSet->DomainName().Mid(pos+1));
+                    ptrRecord->SetClass(EDnsClass_IN);
+                    ptrRecord->SetFlushBit(EFalse);
+                    ptrRecord->SetTtl(120);
+                    ptrRecord->SetType(EDnsType_PTR);
+                    ptrRecord->SetDomainNameL(srvParamSet->DomainName());
+                    publishRecordArray.AppendL(ptrRecord);
+                    CleanupStack::Pop();
+                    */
+                    }
+                break;
+                }
+            case EMdnsPtrParamset:
+                {
+                //do nothing
+                TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+                for (TInt index= 0; index < count ; index++ )
+                     {
+                     CMDnsPtrParamSet* ptrParamSet = static_cast<CMDnsPtrParamSet*>(pnpFamily.GetParameterSetAtIndex( index, RParameterFamily::ERequested ));
+                     CRdTypePtr* ptrRecord = CRdTypePtr::NewL();
+                     CleanupStack::PushL(ptrRecord);
+                     ptrRecord->SetNameL(ptrParamSet->InstanceName());
+                     ptrRecord->SetClass(EDnsClass_IN);
+                     ptrRecord->SetFlushBit(EFalse);
+                     ptrRecord->SetTtl(120);
+                     ptrRecord->SetType(EDnsType_PTR);
+                     ptrRecord->SetDomainNameL(ptrParamSet->DomainName());
+                     publishRecordArray.AppendL(ptrRecord);
+                     CleanupStack::Pop();//Remove Ptr Record from the queue..
+                     }
+                break;
+                }
+            case EMdnsAddrParamset:
+                {
+                TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+                for (TInt index= 0; index < count ; index++ )
+                     {
+                     CMDnsAddrParamSet* addrParamSet = static_cast<CMDnsAddrParamSet*>(pnpFamily.GetParameterSetAtIndex( index, RParameterFamily::ERequested ));
+                     CRdTypeA* addrRecord = CRdTypeA::NewL();
+                     CleanupStack::PushL(addrRecord);
+                     addrRecord->SetAddr(addrParamSet->Address());
+                     addrRecord->SetNameL(addrParamSet->DomainName());
+                     addrRecord->SetClass(EDnsClass_IN);
+                     addrRecord->SetFlushBit(EFalse);
+                     addrRecord->SetTtl(120);
+                     addrRecord->SetType(EDnsType_A);
+                     publishRecordArray.AppendL(addrRecord);
+                     CleanupStack::Pop();//remove addrecord from the queue
+                     }
+                break;
+                }
+            case EMdnsTxtParamset:
+                {
+                TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+                for (TInt index= 0; index < count ; index++ )
+                     {
+                     CMDnsTxtParamSet* txtParamSet = static_cast<CMDnsTxtParamSet*>(pnpFamily.GetParameterSetAtIndex( index, RParameterFamily::ERequested ));
+                     CRdTypeTxt* txtRecord = CRdTypeTxt::NewL();
+                     CleanupStack::PushL(txtRecord);
+                     txtRecord->SetNameL(txtParamSet->DomainName());
+                     txtRecord->SetClass(EDnsClass_IN);
+                     txtRecord->SetFlushBit(EFalse);
+                     txtRecord->SetTtl(120);
+                     txtRecord->SetType(EDnsType_TXT);
+                     RArray<RBuf8> txtArray ;
+                     txtParamSet->TxtDataL(txtArray);
+                     TInt txtCnt = txtArray.Count();
+                     for(TInt count = 0; count < txtCnt ; count ++ )
+                         {
+                         txtRecord->AppendTextDataL(txtArray[count]);
+                         }
+                     txtArray.Close();
+                     publishRecordArray.AppendL(txtRecord);
+                     CleanupStack::Pop();//remove txtRecord from the queue..
+                     }
+                break;
+                }
+            }
+        
+        }
+    TRAPD(publishError ,iServer.MessageHandler().AdvertizePacketL(publishRecordArray,iSessionId , isUpdate));
+    if(publishError == KErrNotFound)
+        {
+        aMessage.Complete(KErrNotFound);
+        }
+    publishRecordArray.Close();
+    iPublishBundle.Close();
+    CleanupStack::PopAndDestroy(query);
+    __FLOG(_L8("CMdnsServerSession::PublishL - Exit"));
+    }
+    
+void CMdnsServerSession::HandleServiceNameConflictL(const RBuf8& aName,TInt aError)
+    {
+    __FLOG(_L8("CMdnsServerSession::HandleServiceNameConflictL - Entry"));
+    iResponseBundle.Open ();
+    CleanupClosePushL( iResponseBundle );
+    
+    RParameterFamily pnpFamily = iResponseBundle.CreateFamilyL (EMdnsPublishResponseParamset);
+    iResponseBundle.SetPnPObserver((MPnPObserver*)NULL);
+    
+    CMDnsPublishResponseParamSet* responseParam = CMDnsPublishResponseParamSet::NewL(pnpFamily);
+    responseParam->SetDomainNameL(aName);
+    responseParam->SetError(aError);
+
+    
+    TInt len = iResponseBundle.Length();
+    TPckgC<TInt> lenbuf(len); 
+    iPublishRequest.Write(1,lenbuf);
+    
+    iPublishRequest.Complete(KErrNone);
+    CleanupStack::Pop();//iResponseBundle
+    __FLOG(_L8("CMdnsServerSession::HandleServiceNameConflictL - Exit"));
+    }
+   
+void CMdnsServerSession::RegisterNotifyL(const RMessage2& aMessage)
+    {
+    __FLOG(_L8("CMdnsServerSession::RegisterNotifyL - Entry"));
+    iIsNotifyRequested = ETrue;
+    RPnPParameterBundle registerBundle;
+    TInt size = aMessage.GetDesLength(0);
+    HBufC8* registerbuf = HBufC8::NewLC(aMessage.GetDesLengthL(0));
+    TPtr8 loadPtr = registerbuf->Des();
+    aMessage.ReadL(0,loadPtr);
+    registerBundle.CreateL();
+    registerBundle.Load(loadPtr);
+    RParameterFamily pnpFamily = registerBundle.GetFamilyAtIndex(0);
+    TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+    for(TInt index =0 ; index<count ; index++)
+        {
+        CMDnsRegisterNotifyParamSet* registerParamSet = static_cast<CMDnsRegisterNotifyParamSet*>(pnpFamily.GetParameterSetAtIndex( index, RParameterFamily::ERequested ));
+        RBuf8 instanceName;
+        instanceName.CreateL(registerParamSet->InstanceName());
+        iRegisterNotifyArray.AppendL(instanceName);
+        }
+    registerBundle.Close();
+    CleanupStack::PopAndDestroy();//registerbuffer
+    __FLOG(_L8("CMdnsServerSession::RegisterNotifyL - Exit"));
+    }
+
+void CMdnsServerSession::StopNotifyL(const RMessage2& aMessage)
+    {
+    __FLOG(_L8("CMdnsServerSession::StopNotifyL - Entry"));
+    RPnPParameterBundle registerBundle;
+    TInt size = aMessage.GetDesLength(0);
+    HBufC8* registerbuf = HBufC8::NewLC(aMessage.GetDesLengthL(0));
+    TPtr8 loadPtr = registerbuf->Des();
+    aMessage.ReadL(0,loadPtr);
+    registerBundle.CreateL();
+    registerBundle.Load(loadPtr);
+    RParameterFamily pnpFamily = registerBundle.GetFamilyAtIndex(0);
+    TUint count = pnpFamily.CountParameterSets ( RParameterFamily::ERequested ) ;
+    for(TInt index =0 ; index< count; index++)
+        {
+        CMDnsRegisterNotifyParamSet* registerParamSet = static_cast<CMDnsRegisterNotifyParamSet*>(pnpFamily.GetParameterSetAtIndex( index, RParameterFamily::ERequested ));
+        RBuf8 instanceName;
+        instanceName.CreateL(registerParamSet->InstanceName());
+        for(TInt i =0 ; i< iRegisterNotifyArray.Count();i++)
+                {
+                if(instanceName.Compare(iRegisterNotifyArray[i]) == 0)
+                    {
+                    RBuf8& temp = iRegisterNotifyArray[i];
+                    iRegisterNotifyArray.Remove(i);
+                    temp.Close();
+                    }
+                }
+        instanceName.Close();
+        }
+    if(iRegisterNotifyArray.Count() == 0 )
+        {
+        iIsNotifyRequested =EFalse;
+        }
+    registerBundle.Close();
+    CleanupStack::PopAndDestroy();//registerbuffer
+    __FLOG(_L8("CMdnsServerSession::StopNotifyL - Exit"));
+    }
+
+TInt CMdnsServerSession::SessionId()
+    {
+    __FLOG(_L8("CMdnsServerSession::SessionId - Exit"));
+    return iSessionId;
+    }
+void CMdnsServerSession::NewServiceL(const RArray<RBuf8>& aName)
+    {
+    __FLOG(_L8("CMdnsServerSession::NewServiceL - Entry"));
+    if(iIsNotifyRequested && iNotifyMessageRequest.Handle())
+        {
+        RPnPParameterBundle publishBundle;
+        publishBundle.CreateL();
+        RParameterFamily pnpFamily = publishBundle.CreateFamilyL (EMdnsPtrParamset);
+        publishBundle.SetPnPObserver((MPnPObserver*)NULL);
+        for(TInt i =0 ; i < aName.Count();i++)
+            {
+            for(TInt j= 0 ; j< iRegisterNotifyArray.Count(); j++)
+                {
+                TInt pos = aName[i].Find(iRegisterNotifyArray[j]);
+                if(pos != KErrNotFound)
+                    {
+                    CMDnsPtrParamSet* responseParam = CMDnsPtrParamSet::NewL(pnpFamily);
+                    responseParam->SetInstanceNameL(iRegisterNotifyArray[j]);
+                    responseParam->SetDomainNameL(aName[i]); 
+                    // have to fill up the ttl field, query the cache
+                    RPointerArray <CCacheEntry>  aEntries;
+                    iServer.MessageHandler().DnsCache().FindServiceL(aEntries,aName[i],EDnsType_SRV);
+                    responseParam->SetTtlL(0);
+                    if(aEntries.Count()==0)
+                        {
+                        // already deleted from cache
+                        responseParam->SetTtlL(0);
+                        }
+                    else if(aEntries[0]->PtrRecord()!=NULL)
+                        {
+                        responseParam->SetTtlL(aEntries[0]->PtrRecord()->Ttl());
+                        }
+                    aEntries.ResetAndDestroy();
+                    aEntries.Close();    
+                    break;
+                    }
+                }
+            }
+        HBufC8* buffer = HBufC8::NewLC(KDnsBufferlength);   
+        TPtr8 bufferPointer(buffer->Des());
+        publishBundle.Store(bufferPointer);
+        iNotifyMessageRequest.Write(0,bufferPointer);
+        iNotifyMessageRequest.Complete(KErrNone);
+        CleanupStack::PopAndDestroy(buffer);//buffer
+        publishBundle.Close();
+        }
+    __FLOG(_L8("CMdnsServerSession::NewServiceL - Exit"));
+    }
+
+
+void CMdnsServerSession::CreateAnyQueryResponseL(CCacheEntry& aEntry)
+    {
+    RParameterFamily ptrFamily = iResponseBundle.CreateFamilyL (EMdnsPtrParamset);
+    RParameterFamily srvFamily = iResponseBundle.CreateFamilyL (EMdnsSrvParamset);
+    RParameterFamily txtFamily = iResponseBundle.CreateFamilyL (EMdnsTxtParamset);
+    RParameterFamily AFamily = iResponseBundle.CreateFamilyL (EMdnsAddrParamset);
+    if(aEntry.AddressRecord()!= NULL)
+        {
+        CMDnsAddrParamSet* responseParam = CMDnsAddrParamSet::NewL(AFamily);
+        responseParam->SetDomainNameL(aEntry.AddressRecord()->Name()); 
+        responseParam->SetAddress(aEntry.AddressRecord()->Address());
+        }
+    if(aEntry.ServiceRecord()!= NULL)
+        {
+        CMDnsSrvParamSet* responseParam = CMDnsSrvParamSet::NewL(srvFamily);
+        responseParam->SetDomainNameL(aEntry.ServiceRecord()->Name());
+        responseParam->SetTargetL(aEntry.ServiceRecord()->Target());
+        responseParam->SetPriority(aEntry.ServiceRecord()->Priority());
+        responseParam->SetWeight(aEntry.ServiceRecord()->Weight());
+        responseParam->SetPort(aEntry.ServiceRecord()->Port());
+        }
+    if(aEntry.PtrRecord()!= NULL)
+        {
+        CMDnsPtrParamSet* responseParam = CMDnsPtrParamSet::NewL(ptrFamily);
+        responseParam->SetInstanceNameL(aEntry.PtrRecord()->Name());
+        responseParam->SetDomainNameL(aEntry.PtrRecord()->DomainName());
+        //responseParam->SetTtlL(aEntry.PtrRecord()->Ttl());
+        }
+    if(aEntry.TxtRecord()!= NULL)
+        {
+        CMDnsTxtParamSet* responseParam = CMDnsTxtParamSet::NewL(txtFamily);
+        responseParam->SetDomainNameL(aEntry.TxtRecord()->Name());
+        RArray<RBuf8> txtData = aEntry.TxtRecord()->Text();
+        for(TInt txtCount = 0 ;txtCount < txtData.Count();txtCount++)
+            {
+            responseParam->AppendTxtData(txtData[txtCount]);
+            }
+        }
+    
+    }