Revision: 201019 RCL_3
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 09 Jun 2010 10:16:57 +0300
branchRCL_3
changeset 13 26ce6fb6aee2
parent 12 f21293830889
child 15 bdd8a827a7de
Revision: 201019 Kit: 2010123
applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.cpp
applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.h
applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.cpp
applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.h
applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.cpp
applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.h
applayerpluginsandutils/httptransportplugins/httptransporthandler/mcommsinfoprovider.h
applayerprotocols/httptransportfw/core/CTransaction.cpp
applayerprotocols/httptransportfw/core/TFilterConfigurationIter.cpp
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.cpp	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.cpp	Wed Jun 09 10:16:57 2010 +0300
@@ -43,6 +43,21 @@
 	return self;
 	}
 
+CSocket* CSocket::New(MCommsInfoProvider& aCommsInfoProvider, TSocketType aSocketType)
+    {
+    CSocket* self = new CSocket(aCommsInfoProvider);
+    if(self)
+        {
+        TInt error = self->Construct(aSocketType);
+        if(error != KErrNone)
+            {
+            delete self;
+            self = NULL;
+            }
+        }
+    return self;
+    }
+
 CSocket::~CSocket()
 /**
 	Destructor.
@@ -70,54 +85,62 @@
 	@param		aSocketType	The type of the socket.
 */
 	{
-	switch( aSocketType )
-		{
-	case EProtocolSocket:
-		{
-		if ( iCommsInfoProvider.HasConnection() )
-			{
-			// Open a protocol socket with a RConnection
-			User::LeaveIfError(iSocket.Open(
-										   iCommsInfoProvider.SocketServer(),
-										   iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
-										   iCommsInfoProvider.ProtocolDescription().iSockType, 
-										   iCommsInfoProvider.ProtocolDescription().iProtocol,
-										   iCommsInfoProvider.Connection()
-										   ));				
-			}
-		else
-			{
-			// Open a protocol socket without a RConnection, we don't need one ( Loopback address )
-			User::LeaveIfError(iSocket.Open(
-										   iCommsInfoProvider.SocketServer(),
-										   iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
-										   iCommsInfoProvider.ProtocolDescription().iSockType, 
-										   iCommsInfoProvider.ProtocolDescription().iProtocol
-										   ));											
-			}
-		} break;
-	case EBlankSocket:
-		{
-		// Open a blank socket
-		User::LeaveIfError(iSocket.Open(iCommsInfoProvider.SocketServer()));
-		} break;
-	default:
-		User::Invariant();
-		}
-	TInt id = iCommsInfoProvider.SessionId();
-	if(id>=0) 
-		{
-		// set socket option
-		iSocket.SetOpt(KSOHttpSessionId, KSOLHttpSessionInfo, id);
-		iSocket.SetOpt(KSoTcpKeepAlive, KSolInetTcp, KTcpTriggeredKeepAlive);
-		}
-	if(aSocketType != EBlankSocket)
-	    {
-	    iSocket.SetOpt(KSoTcpNoDelay,KSolInetTcp,1);  // Disable the nagle.
-        iSocket.SetOpt(KSORecvBuf, KSOLSocket, KSocketRecvBufSize); // Set the socket recv buf to be 16K
-	    }
+    User::LeaveIfError(Construct(aSocketType));
 	}
 
+TInt CSocket::Construct(TSocketType aSocketType)
+    {
+    TInt error = KErrNone;
+    switch( aSocketType )
+        {
+    case EProtocolSocket:
+        {
+        if ( iCommsInfoProvider.HasConnection() )
+            {
+            // Open a protocol socket with a RConnection
+            error = iSocket.Open(iCommsInfoProvider.SocketServer(),
+                                 iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
+                                 iCommsInfoProvider.ProtocolDescription().iSockType, 
+                                 iCommsInfoProvider.ProtocolDescription().iProtocol,
+                                 iCommsInfoProvider.Connection()
+                                 );              
+            }
+        else
+            {
+            // Open a protocol socket without a RConnection, we don't need one ( Loopback address )
+            error = iSocket.Open(iCommsInfoProvider.SocketServer(),
+                                 iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
+                                 iCommsInfoProvider.ProtocolDescription().iSockType, 
+                                 iCommsInfoProvider.ProtocolDescription().iProtocol
+                                 );                                          
+            }
+        } break;
+    case EBlankSocket:
+        {
+        // Open a blank socket
+        error = iSocket.Open(iCommsInfoProvider.SocketServer());
+        } break;
+    default:
+        User::Invariant();
+        }
+    if(error == KErrNone)
+        {
+        TInt id = iCommsInfoProvider.SessionId();
+        if(id>=0) 
+            {
+            // set socket option
+            iSocket.SetOpt(KSOHttpSessionId, KSOLHttpSessionInfo, id);
+            iSocket.SetOpt(KSoTcpKeepAlive, KSolInetTcp, KTcpTriggeredKeepAlive);
+            }
+        if(aSocketType != EBlankSocket)
+            {
+            iSocket.SetOpt(KSoTcpNoDelay,KSolInetTcp,1);  // Disable the nagle.
+            iSocket.SetOpt(KSORecvBuf, KSOLSocket, KSocketRecvBufSize); // Set the socket recv buf to be 16K
+            }
+        }
+    return error;
+    }
+
 TInt CSocket::Listen(TUint aQSize, TUint16 aPort)
 /**	
 	Start the listen service. The socket is bound to the local port specified by
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.h	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocket.h	Wed Jun 09 10:16:57 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 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"
@@ -51,7 +51,9 @@
 public:	// methods
 
 	static CSocket* NewL(MCommsInfoProvider& aCommsInfoProvider, TSocketType aSocketType);
-
+	
+	static CSocket* New(MCommsInfoProvider& aCommsInfoProvider, TSocketType aSocketType);
+	
 	virtual ~CSocket();
 
 	TInt Listen(TUint aQSize, TUint16 aPort);
@@ -97,7 +99,8 @@
 	CSocket(MCommsInfoProvider& aCommsInfoProvider);
 
 	void ConstructL(TSocketType aSocketType);
-
+	
+	TInt Construct(TSocketType aSocketType);
 private:
 
 /**	The comms info provider
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.cpp	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.cpp	Wed Jun 09 10:16:57 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 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"
@@ -55,7 +55,6 @@
 	// Cleanup...
 	delete iHost;
 	delete iConnectingSocket;
-	iHostResolver.Close();
 
 //	__FLOG_CLOSE;
 	}
@@ -104,20 +103,33 @@
 	iHost = HBufC::NewL(aRemoteHost.Length());
 	iHost->Des().Copy(aRemoteHost);
 	iPort = aRemotePort;
-
+		
+	TInt error = KErrNone;
     // Move to the PendingDNSLookup state and self complete.
     if(aRemoteAddress == NULL)
         {
+        RDebug::Printf("RemoteAddress is NULL so doing a DNS lookup");
+        iState = EPendingDNSLookup;
         // Address is unknown / DNS lookup is needed
-        iState = EPendingDNSLookup;
+        error = DoPendingDNSLookup();
         }
     else
         {
+        RDebug::Printf("Remote address is known so doing a direct connect");
+        iState = EConnecting;
         // Address is know. No lookup is needed. Just go and connect.
         iHostDnsEntry().iAddr = *aRemoteAddress;
-        iState = EConnecting;
+        error = DoConnect();
         }
-	CompleteSelf();
+    
+    if(error != KErrNone)
+        {
+        iState = EPendingDNSLookup;
+        // Error the AO and handle the error in the normal path.
+        TRequestStatus* pStat = &iStatus;
+        User::RequestComplete(pStat, error);
+        SetActive();      
+        }
 	}
 
 void CSocketConnector::CompleteSelf()
@@ -193,80 +205,11 @@
 		{
 	case EPendingDNSLookup:
 		{
-#if defined (_DEBUG) && defined (_LOGGING)
-		TBuf8<KHostNameSize> host;
-		host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters
-
-		__FLOG_1(_T8("Doing DNS lookup -> searching for host %S"), &host);
-#endif
-
-		__OOM_LEAVE_TEST
-
-		if ( iCommsInfoProvider.HasConnection() )
-			{
-			// Open the host resolver session with the preffered connection
-			User::LeaveIfError(iHostResolver.Open(
-												 iCommsInfoProvider.SocketServer(),
-												 iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
-												 KProtocolInetUdp,
-												 iCommsInfoProvider.Connection()
-												 ));				
-			}
-		else
-			{							
-			// Open the host resolver session with no connection
-			User::LeaveIfError(iHostResolver.Open(
-												 iCommsInfoProvider.SocketServer(),
-												 iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
-												 KProtocolInetUdp
-												 ));				
-			}
-
-		// Start the DNS lookup for the remote host name.
-		iHostResolver.GetByName(*iHost, iHostDnsEntry, iStatus);
-
-		// Move to the Connecting state and go active
-		iState = EConnecting;
-		SetActive();
+		User::LeaveIfError(DoPendingDNSLookup());
 		} break;
 	case EConnecting:
 		{
-		__OOM_LEAVE_TEST
-
-		// DNS lookup successful - form the internet address object
-		iAddress = TInetAddr(iHostDnsEntry().iAddr);
-		iAddress.SetPort(iPort);
-
-#if defined (_DEBUG) && defined (_LOGGING)
-		TBuf8<KHostNameSize> host;
-		host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters
-
-		TBuf<KIpv6MaxAddrSize> ip16bit;
-		iAddress.Output(ip16bit);
-
-		TBuf8<KIpv6MaxAddrSize> ip;
-		ip.Copy(ip16bit);
-		
-		__FLOG_2(_T8("DNS lookup complete -> host %S has IP address %S"), &host, &ip);
-#endif
-		
-		// Start a default RConnection, if one is not started and not local loopback address		
-		if ( !iCommsInfoProvider.HasConnection() && !iAddress.IsLoopback() )
-			{
-			iCommsInfoProvider.StartDefaultCommsConnectionL ();				
-			}
-
-		// Create the connecting socket
-		iConnectingSocket = CSocket::NewL(iCommsInfoProvider, CSocket::EProtocolSocket);
-
-		// Start connecting to the remote client
-		iConnectingSocket->Connect(iAddress, iStatus);
-
-		__FLOG_2(_T8("Connecting -> to host %S on IP address %S"), &host, &ip);
-
-		// Move to the Connected state and go active
-		iState = EConnected;
-		SetActive();
+		User::LeaveIfError(DoConnect());
 		} break;
 	case EConnected:
 		{
@@ -334,6 +277,7 @@
 		{
 		// DNS lookup is pending - cancel
 		iHostResolver.Cancel();
+		iCommsInfoProvider.AddToHostResolverCache(iHostResolver); // Add to the cache.
 		} break;
 	case EConnected:
 		{
@@ -431,3 +375,103 @@
 
 	return error;
 	}
+
+TInt CSocketConnector::DoPendingDNSLookup()
+    {
+#if defined (_DEBUG) && defined (_LOGGING)
+        TBuf8<KHostNameSize> host;
+        host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters
+
+        __FLOG_1(_T8("Doing DNS lookup -> searching for host %S"), &host);
+#endif        
+     TInt error = KErrNone;
+     
+     iCommsInfoProvider.HostResolverFromCache(iHostResolver); // Get the RHostResolver from the cache
+     if(iHostResolver.SubSessionHandle() <= 0)
+         {
+         RDebug::Printf("No host resolver. Open a new one...");
+         if ( iCommsInfoProvider.HasConnection() )
+            {
+            // Open the host resolver session with the preffered connection
+            error = iHostResolver.Open(iCommsInfoProvider.SocketServer(),
+                                       iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
+                                       KProtocolInetUdp,
+                                       iCommsInfoProvider.Connection());                
+             }
+          else
+            {                           
+            // Open the host resolver session with no connection
+            error = iHostResolver.Open(iCommsInfoProvider.SocketServer(),
+                                       iCommsInfoProvider.ProtocolDescription().iAddrFamily, 
+                                       KProtocolInetUdp);                
+            }
+         }
+     
+     if(error != KErrNone)
+        {
+        return error;
+        }
+        
+    // Start the DNS lookup for the remote host name.
+    iHostResolver.GetByName(*iHost, iHostDnsEntry, iStatus);
+
+    // Move to the Connecting state and go active
+    iState = EConnecting;
+    SetActive();    
+    return error;
+    }
+
+TInt CSocketConnector::DoConnect()
+    {
+    // DNS lookup successful - form the internet address object
+    iAddress = TInetAddr(iHostDnsEntry().iAddr);
+    iAddress.SetPort(iPort);
+    
+    // Add the RHostResolver to the cache.
+    if(iHostResolver.SubSessionHandle() > 0)
+        {
+        iCommsInfoProvider.AddToHostResolverCache(iHostResolver);
+        }
+    
+#if defined (_DEBUG) && defined (_LOGGING)
+    TBuf8<KHostNameSize> host;
+    host.Copy((*iHost).Left(KHostNameSize)); //just get the KHostNameSize characters
+
+    TBuf<KIpv6MaxAddrSize> ip16bit;
+    iAddress.Output(ip16bit);
+
+    TBuf8<KIpv6MaxAddrSize> ip;
+    ip.Copy(ip16bit);
+    
+    __FLOG_2(_T8("DNS lookup complete -> host %S has IP address %S"), &host, &ip);
+#endif
+   
+    // Start a default RConnection, if one is not started and not local loopback address        
+    if ( !iCommsInfoProvider.HasConnection() && !iAddress.IsLoopback() )
+        {
+        // it is ok to TRAP here as the method will be called only once.
+        TRAPD(error, iCommsInfoProvider.StartDefaultCommsConnectionL ());
+        if(error != KErrNone)
+            {
+            return error;
+            }
+        }
+
+    // Create the connecting socket
+    iConnectingSocket = CSocket::New(iCommsInfoProvider, CSocket::EProtocolSocket);
+    if(!iConnectingSocket)
+        {
+        return KErrNoMemory;
+        }
+    
+    // Start connecting to the remote client
+    iConnectingSocket->Connect(iAddress, iStatus);
+    SetActive();
+    __FLOG_2(_T8("Connecting -> to host %S on IP address %S"), &host, &ip);
+
+    // Move to the Connected state and go active
+    iState = EConnected;
+    return KErrNone;
+    }
+
+
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.h	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/csocketconnector.h	Wed Jun 09 10:16:57 2010 +0300
@@ -101,7 +101,9 @@
 	void CompleteSelf();
 
 	void Suicide();
-
+	
+	TInt DoPendingDNSLookup();
+	TInt DoConnect();
 private:	// enums
 
 /**	
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.cpp	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.cpp	Wed Jun 09 10:16:57 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2001-2010 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"
@@ -25,6 +25,9 @@
 
 _LIT(KTcpProtName, "tcp");
 
+const TInt KMaxHostResolverCacheCount = 8; // 8 Should be sufficient here as we can have maximum of 8 connections
+                                           // at anytime to the host. And it is not neccassarly mean that 8 host resolvers
+                                           // will be operating simulataneously. 
 CTcpTransportLayer* CTcpTransportLayer::NewL(TAny* aTransportConstructionParams)
 /**	
 	The factory constructor.
@@ -54,7 +57,12 @@
 
 	// Delete the socket controllers
 	iControllerStore.ResetAndDestroy();
-
+	
+	
+	// Empty and close the host resolver cache.
+	EmptyHostResolverCache();
+	iHostResolverCache.Close();
+	
 	// Close the socket server session if owned
 	if( iOwnsConnection )
 		{
@@ -73,7 +81,7 @@
 	}
 
 CTcpTransportLayer::CTcpTransportLayer(MConnectionPrefsProvider& aTransLayerObserver)
-: CHttpTransportLayer(), iConnectionPrefsProvider(aTransLayerObserver)
+: CHttpTransportLayer(), iConnectionPrefsProvider(aTransLayerObserver), iHostResolverCache(KMaxHostResolverCacheCount)
 /**	
 	Constructor.
 */
@@ -191,6 +199,7 @@
                     // Socket and controller will be deleted by itself
                     }
                 iConnectorStore.ResetAndDestroy();
+                EmptyHostResolverCacheIfNeeded();
                 }
             }	        
         }		
@@ -332,6 +341,9 @@
 	// Remove the socket connector from the store and compress the store.
 	iConnectorStore.Remove(index);
 	iConnectorStore.Compress();
+	
+	// Empty the host resolver cache if needed
+	EmptyHostResolverCacheIfNeeded();
 	}
 
 /*
@@ -355,6 +367,9 @@
 	// Remove the socket controller from the store and compress the store.
 	iControllerStore.Remove(index);
 	iControllerStore.Compress();
+	
+   // Empty the host resolver cache if needed
+    EmptyHostResolverCacheIfNeeded();
 	}
 
 /*
@@ -474,4 +489,48 @@
 	return ( iConnection != NULL );
 	}
 
+void CTcpTransportLayer::HostResolverFromCache(RHostResolver& aResolver)
+    {
+    TInt count = iHostResolverCache.Count();
+    if(count > 0)
+        {
+        RDebug::Printf("Returning the host resolver from cache...");
+        // Returns the last host resolver that is added
+        aResolver = iHostResolverCache[count - 1];
+        iHostResolverCache.Remove(count - 1); // Remove from the cache.        
+        }
+    }
 
+void CTcpTransportLayer::AddToHostResolverCache(RHostResolver& aResolver)
+    {
+    if(iHostResolverCache.Append(aResolver) != KErrNone)
+        {
+        aResolver.Close();
+        }
+    }
+
+void CTcpTransportLayer::EmptyHostResolverCacheIfNeeded()
+    {
+    // Remove the host resolver if
+    // 1/ if the Connector store is empty and
+    // 2/ if the socket controller is empty
+    // This is important to get the mobility and one click connectivity cases working
+    // Otherwise the inconsistent behaviour will result as the RConnection & RSocketServ can be handled
+    // entirely outside of the HTTP stack, ie; from the application
+    if(iConnectorStore.Count() == 0 && iControllerStore.Count() == 0)
+        {
+        EmptyHostResolverCache();
+        }
+    }
+
+void CTcpTransportLayer::EmptyHostResolverCache()
+    {
+    TInt count = iHostResolverCache.Count();
+    while(count > 0)
+        {
+        // Close the RHostResolver and remove from the array
+        iHostResolverCache[count - 1].Close();
+        iHostResolverCache.Remove(--count);
+        }
+    iHostResolverCache.Compress();
+    }
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.h	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/ctcptransportlayer.h	Wed Jun 09 10:16:57 2010 +0300
@@ -103,7 +103,11 @@
 
 	virtual TBool HasConnection();
 	
-	void StartDefaultCommsConnectionL ();
+	virtual void StartDefaultCommsConnectionL ();
+
+	virtual void HostResolverFromCache(RHostResolver& aResolver);
+	
+	virtual void AddToHostResolverCache(RHostResolver& aResolver);
 
 private:	// methods
 
@@ -119,6 +123,10 @@
 
 	inline MCommsInfoProvider& CommsInfoProvider();
 	
+	void EmptyHostResolverCacheIfNeeded();
+	
+	void EmptyHostResolverCache();
+	
 private:	// attributes
 
 /** The connection preferences provider
@@ -157,6 +165,8 @@
 */
 	RPointerArray<CSocketController>	iControllerStore;
 	
+	RArray<RHostResolver>               iHostResolverCache;
+	
 	TBool iPriority;
 
 /** Logger handle
--- a/applayerpluginsandutils/httptransportplugins/httptransporthandler/mcommsinfoprovider.h	Tue May 25 13:17:20 2010 +0300
+++ b/applayerpluginsandutils/httptransportplugins/httptransporthandler/mcommsinfoprovider.h	Wed Jun 09 10:16:57 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 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"
@@ -78,6 +78,17 @@
 	Starts a default RConnection
 	*/
 	virtual void StartDefaultCommsConnectionL () =0;
+	
+	/**
+	 Returns the RHostResolver if available in cache.
+	 */
+	virtual void HostResolverFromCache(RHostResolver& aResolver) =0;
+	
+	/**
+	 Add the RHostResolver to cache. If the adding fails then the RHostResolver will be
+	 closed
+	 */
+	virtual void AddToHostResolverCache(RHostResolver& aResolver) =0;
 	};
 
 #endif	// __MCOMMSINFOPROVIDER_H__
--- a/applayerprotocols/httptransportfw/core/CTransaction.cpp	Tue May 25 13:17:20 2010 +0300
+++ b/applayerprotocols/httptransportfw/core/CTransaction.cpp	Wed Jun 09 10:16:57 2010 +0300
@@ -42,6 +42,7 @@
 	Cancel();
 	// And send the cancel event
 	SynchronousSendEvent(THTTPEvent::ECancel, THTTPEvent::EOutgoing, aStart);
+
 	if (iStatus != EInFilter && iStatus != ECancelled)
 		iStatus = EPassive;
 	else
--- a/applayerprotocols/httptransportfw/core/TFilterConfigurationIter.cpp	Tue May 25 13:17:20 2010 +0300
+++ b/applayerprotocols/httptransportfw/core/TFilterConfigurationIter.cpp	Wed Jun 09 10:16:57 2010 +0300
@@ -76,10 +76,10 @@
 		}
 	else
 		{
-		++iCurrentFilterIndex;
 		// If the next filter is a mandatory filter then move on to the next filter
 		if( iFilterInfoList[iCurrentFilterIndex]->iCategory == TSessionFilterInfo::EMandatory )
 			return Next();
+		++iCurrentFilterIndex;	
 		}
 
 	return KErrNone;