networkprotocolmodules/suplprotocolmodule/SuplConnectionManager/src/suplconnectionmanager.cpp
changeset 0 9cfd9a3ee49c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkprotocolmodules/suplprotocolmodule/SuplConnectionManager/src/suplconnectionmanager.cpp	Tue Feb 02 01:50:39 2010 +0200
@@ -0,0 +1,540 @@
+#include <e32debug.h>
+// 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:
+//
+
+/**
+ @file
+ @internalComponent
+ @deprecated
+*/
+#include "suplconnectionmanager.h"
+#include "socketwriter.h"
+#include <lbs/lbshostsettingsclasstypes.h>
+#include "supldevloggermacros.h"
+
+EXPORT_C CSuplConnectionManager* CSuplConnectionManager::NewL()
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::NewL() Begin\n");
+	CSuplConnectionManager* self = new (ELeave)CSuplConnectionManager();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	SUPLLOG(ELogP1, "CSuplConnectionManager::NewL() End\n");
+	CleanupStack::Pop(self);
+	
+	return self;
+	}
+
+CSuplConnectionManager::CSuplConnectionManager() :
+	iSessionRecords(2), iSocketWriters(2), iSocketWriterNextIndex(0)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::CSuplConnectionManager() Begin\n");
+	SUPLLOG(ELogP1, "CSuplConnectionManager::CSuplConnectionManager() End\n");
+	}
+
+void CSuplConnectionManager::ConstructL()
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::ConstructL() Begin\n");
+	// Open socket server
+	User::LeaveIfError(iSocketServ.Connect());
+	SUPLLOG(ELogP1, "CSuplConnectionManager::ConstructL() End\n");
+	}
+
+CSuplConnectionManager::~CSuplConnectionManager()
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::~CSuplConnectionManager() Begin\n");
+	// Delete array allocations
+	for (TInt x = 0; x < iSessionRecords.Count(); ++x)
+		{
+		delete iSessionRecords[x];
+		}
+	for (TInt x = 0; x < iSocketWriters.Count(); ++x)
+		{
+		delete iSocketWriters[x];
+		}
+	
+	iSessionRecords.Close();
+	iSocketWriters.Close();
+
+	iSocketServ.Close();
+	SUPLLOG(ELogP1, "CSuplConnectionManager::~CSuplConnectionManager() End\n");
+	}
+
+EXPORT_C void CSuplConnectionManager::Connect(const TSuplLocalSessionId& aSessionId, 
+											  const TLbsHostSettingsId& aSlpId,
+											  const CSuplSessionRecord::TServiceType& aServiceType,
+											  MSuplConnectionManagerObserver& aConnMgrObserver)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() Begin\n");
+	Connect(aSessionId, aSlpId, aServiceType, aConnMgrObserver, EFalse);
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() End\n");
+	}
+
+void CSuplConnectionManager::Connect(const TSuplLocalSessionId& aSessionId, 
+		  							 const TLbsHostSettingsId& aSlpId,
+		  							 const CSuplSessionRecord::TServiceType& aServiceType,
+		  							 MSuplConnectionManagerObserver& aConnMgrObserver,
+		  							 TBool aForceNonSecure)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() Begin\n");
+	TInt ignore;
+	CSocketWriterBase* socketWriter = FindWriter(aSlpId, ignore);
+	if (socketWriter == NULL)
+		{
+		// Get host settings for auth mode
+		TLbsHostSettingsSupl settings;
+		TRAPD(err, GetHostSettingsL(aSlpId, settings))
+		if (err == KErrNone)
+			{
+			// Check that port value has been set
+			TInt portValueInSettings;
+			settings.GetPortId(portValueInSettings);
+			if(portValueInSettings <= 0) // If SetPortId() was never called...
+				{
+				settings.SetPortId(7275); // set it to be the OMA specified port
+				}
+			
+			// Get the security settings
+			TLbsHostSettingsSupl::TAuthModes mode;
+			if (aServiceType == CSuplSessionRecord::EServiceMolr)
+				{
+				settings.GetAuthModesMOLR(mode);
+				}
+			else
+				{
+				settings.GetAuthModesMTLR(mode);
+				}
+			
+			// If forced into non-secure mode then check that the server supports this mode
+			if (!(aForceNonSecure && (mode & TLbsHostSettingsSupl::EAuthNone) == 0))
+				{
+				// Which socket to use?
+				TInt err = KErrNone;
+				// If forced into non-secure then use a normal socket, otherwise check to see if the 
+				// server supports any secure mode as these take precedence
+				if (aForceNonSecure || ((mode | TLbsHostSettingsSupl::EAuthNone) == TLbsHostSettingsSupl::EAuthNone))
+					{
+					TRAP(err, socketWriter = CSocketWriter::NewL(aSlpId, ++iSocketWriterNextIndex, *this, iSocketServ, settings));
+					}
+				else
+					{
+					TRAP(err, socketWriter = CSecureSocketWriter::NewL(aSlpId, ++iSocketWriterNextIndex, *this, iSocketServ, settings, aServiceType));
+					}
+				
+				if (err == KErrNone)
+					{
+					// Add to array of socket writers
+					if (iSocketWriters.Append(socketWriter) != KErrNone)
+						{
+						delete socketWriter;
+						socketWriter = NULL;
+						}
+					}
+				}
+			}
+		}
+	
+	CSuplSessionRecord* suplRecord = NULL;
+	if (socketWriter != NULL)
+		{
+		TRAP_IGNORE(suplRecord = CSuplSessionRecord::NewL(aConnMgrObserver, aSessionId, aSlpId, aServiceType, socketWriter->CallbackId()));
+		}
+	
+	if (suplRecord == NULL)
+		{
+		SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() Error(EUndefinedConnectionError, 1)\n");
+		aConnMgrObserver.ConnectionError(MSuplConnectionManagerObserver::EUndefinedConnectionError);
+		}
+	else
+		{
+		if (iSessionRecords.Append(suplRecord) == KErrNone)
+			{
+			socketWriter->Connect(aSessionId);
+			}
+		else
+			{
+			delete suplRecord;
+			SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() Error(EUndefinedConnectionError, 2)\n");
+			aConnMgrObserver.ConnectionError(MSuplConnectionManagerObserver::EUndefinedConnectionError);
+			}
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connect() End\n");
+	}
+
+EXPORT_C void CSuplConnectionManager::Disconnect(const TSuplLocalSessionId& aSessionId)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Disconnect() Begin\n");
+	TInt at = 0;
+	CSuplSessionRecord* sessionRecord = FindSession(aSessionId, at);
+	if (sessionRecord != NULL) // Cant really do anything if it dont exist!
+		{
+		// Disconnect the socket writer
+		TInt ignore;
+		CSocketWriterBase* writer = FindWriter(sessionRecord->SocketWriter(), ignore);
+		if (writer != NULL)
+			{
+			writer->Disconnect();
+			}
+		
+		// Remove from array
+		delete iSessionRecords[at];
+		iSessionRecords.Remove(at);
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Disconnect() End\n");
+	}
+
+EXPORT_C void CSuplConnectionManager::SendMessage(const CSuplMessageBase* aMessage,
+												  const TSuplLocalSessionId& aSessionId)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::SendMessage() Begin\n");
+	TInt ignore;
+	CSuplSessionRecord* sessionRecord = FindSession(aSessionId, ignore);
+	if (sessionRecord != NULL)
+		{
+		CSocketWriterBase* socketWriter = FindWriter(sessionRecord->SocketWriter(), ignore);
+		if (socketWriter != NULL)
+			{
+			CSuplMessageBase* message = const_cast<CSuplMessageBase*>(aMessage);
+			TRAPD(err, socketWriter->SendMessageL(message, aSessionId));
+			if (err != KErrNone)
+				{
+				SUPLLOG(ELogP1, "CSuplConnectionManager::SendMessage Error(EFailedToSend, 1)\n");
+				sessionRecord->Observer().ConnectionError(MSuplConnectionManagerObserver::EFailedToSend);
+				}
+			}
+		else
+			{
+			SUPLLOG(ELogP1, "CSuplConnectionManager::SendMessage Error(EFailedToSend, 2)\n");
+			sessionRecord->Observer().ConnectionError(MSuplConnectionManagerObserver::EFailedToSend);
+			}
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::SendMessage() End\n");
+	}
+	
+void CSuplConnectionManager::Connected(const TSuplLocalSessionId& aSessionId, TInetAddr& aAddr)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connected() Begin\n");
+	TInt ignore;
+	CSuplSessionRecord* sessionRecord = FindSession(aSessionId, ignore);
+	if (sessionRecord != NULL)
+		{
+		sessionRecord->Observer().Connected(aAddr);
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::Connected() End\n");
+	}
+
+/**
+ * If final parameter(aDelete) is set to True on return then the calling object should delete itself, as
+ * it is no longer stored in the list of available connections.
+ */
+
+void CSuplConnectionManager::ConnectionError(const TInt& aError, const TInt aSocketWriterId, 
+											 const TSuplLocalSessionId& aSessionId, TBool& aDelete)
+	{
+	aDelete = EFalse;
+	SUPLLOG2(ELogP1, "CSuplConnectionManager::ConnectionError() Begin, aError: %d\n", aError);
+	switch (aError)
+		{
+		case MSuplSocketObserver::EDisconnected:
+			{
+			// Ignore this. The socket writer will have disconnected from the server, but we wish to keep the socket
+			// writer around as it stores connection information. 
+			break;
+			}
+		case MSuplSocketObserver::EFailedToSend:
+			{
+			TInt ignore;
+			CSuplSessionRecord* session = FindSession(aSessionId, ignore);
+			if (session != NULL)
+				{
+				session->Observer().ConnectionError(MSuplConnectionManagerObserver::EFailedToSend);
+				} // if
+			else
+				{
+				__ASSERT_DEBUG(EFalse, User::Invariant());
+				}
+			break;
+			}
+		case MSuplSocketObserver::EFailedToHandshake:
+		case MSuplSocketObserver::EFailedCertCheck:
+			{
+			// Attemp a non-secure connection
+			TInt sessionAt = 0;
+			CSuplSessionRecord* session = FindSession(aSessionId, sessionAt);
+			if (session != NULL)
+				{
+				// Delete Originals
+				TInt writerAt = 0;
+				CSocketWriterBase* socketWriter = FindWriter(aSocketWriterId, writerAt);
+				if (socketWriter != NULL)
+					{
+					aDelete = ETrue;
+					iSocketWriters.Remove(writerAt);
+					}
+				
+				iSessionRecords.Remove(sessionAt);
+				
+				Connect(aSessionId, session->SlpId(), session->ServiceMode(), session->Observer(), ETrue);
+				
+				delete session;
+				}
+			break;
+			}
+		case MSuplSocketObserver::ETimeOut:
+			{
+			TInt ignore;
+			CSuplSessionRecord* session = FindSession(aSessionId, ignore);
+			if (session != NULL)
+				{
+				session->Observer().ConnectionError(MSuplConnectionManagerObserver::EConnectionLost);
+				}
+			else
+				{
+				__ASSERT_DEBUG(EFalse, User::Invariant());
+				}
+			break;
+			}
+		case MSuplSocketObserver::EFailedToRead:
+			{
+			// Loop through the sessions and inform them of the error
+			for (TInt x = 0; x < iSessionRecords.Count(); ++x)
+				{
+				if (iSessionRecords[x]->SocketWriter() == aSocketWriterId)
+					{
+					iSessionRecords[x]->Observer().ConnectionError(MSuplConnectionManagerObserver::EUndefinedConnectionError);
+					} // if
+				} // for			
+			break;
+			}
+		case MSuplSocketObserver::EFailedToDecode:
+		case MSuplSocketObserver::ETooMuchDataRead:
+			{
+			TInt ignore;
+			CSuplSessionRecord* session = FindSession(aSessionId, ignore);
+			if (session != NULL)
+				{
+				session->Observer().ConnectionError(MSuplConnectionManagerObserver::EDecodeMessageFailed);
+				}
+			else
+				{
+				__ASSERT_DEBUG(EFalse, User::Invariant());
+				}
+			break;
+			}
+		case MSuplSocketObserver::ESocketError:
+		case KErrCouldNotConnect:
+		case KErrNotFound:
+		default:
+			{
+			TInt ignore;
+			CSuplSessionRecord* session = FindSession(aSessionId, ignore);
+			if (session != NULL)
+				{
+				session->Observer().ConnectionError(MSuplConnectionManagerObserver::EUndefinedConnectionError);
+				}
+			else
+				{
+				__ASSERT_DEBUG(EFalse, User::Invariant());
+				}			
+			break;
+			}
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::ConnectionError() End\n");
+	}
+
+void CSuplConnectionManager::MessageReceived(CSuplMessageBase* aSuplMessage)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::MessageReceived() Begin\n");
+	// Which session?
+	CSuplSessionId* sessionId = NULL;	
+	TRAPD(err, sessionId = CSuplSessionId::NewL());
+	if (err == KErrNone)
+		{
+		aSuplMessage->GetSessionId(*sessionId);
+		
+		TInt ignore;
+		CSuplSessionRecord* session = FindSession(sessionId->iSetSessionId->iSessionId, ignore);
+		if (session != NULL)
+			{
+			session->Observer().MessageReceived(aSuplMessage);
+			}
+		delete sessionId;
+		}
+	SUPLLOG(ELogP1, "CSuplConnectionManager::MessageReceived() End\n");
+	}
+
+CSuplSessionRecord* CSuplConnectionManager::FindSession(TLbsHostSettingsId aId, TInt& aIndex)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindSession() Begin\n");
+	for (TInt x = 0; x < iSessionRecords.Count(); ++x)
+		{
+		if (iSessionRecords[x]->SlpId() == aId)
+			{
+			aIndex = x;
+			return iSessionRecords[x]; 
+			}
+		}
+
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindSession() End\n");
+
+	return NULL;
+	}
+
+CSuplSessionRecord* CSuplConnectionManager::FindSession(TSuplLocalSessionId aSessionId, TInt& aIndex)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindSession() Begin\n");
+	for (TInt x = 0; x < iSessionRecords.Count(); ++x)
+		{
+		if (iSessionRecords[x]->SessionId() == aSessionId)
+			{
+			aIndex = x;
+			return iSessionRecords[x];
+			}
+		}
+
+
+    if (1 == iSessionRecords.Count())
+	    {
+	    // If only one session record exists, select it even
+	    // if the session Id doesn't match (possible corruption
+	    // of session ID. The observer will deal with the 
+	    // session mismatch).
+		aIndex = 0;
+		return iSessionRecords[0];	    
+	    }
+
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindSession() End\n");
+
+	return NULL;
+	}
+
+CSocketWriterBase* CSuplConnectionManager::FindWriter(TLbsHostSettingsId aId, TInt& aIndex)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindWriter() Begin\n");
+	for (TInt x = 0; x < iSocketWriters.Count(); ++x)
+		{
+		if (iSocketWriters[x]->HostSettingsId() == aId)
+			{
+			aIndex = x;
+			return iSocketWriters[x];
+			}
+		}
+
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindWriter() End\n");	
+	return NULL;
+	}
+
+CSocketWriterBase* CSuplConnectionManager::FindWriter(TInt aId, TInt& aIndex)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindWriter() Begin\n");
+	for (TInt x = 0; x < iSocketWriters.Count(); ++x)
+		{
+		if (iSocketWriters[x]->CallbackId() == aId)
+			{
+			aIndex = x;
+			return iSocketWriters[x];
+			}
+		}
+	
+	SUPLLOG(ELogP1, "CSuplConnectionManager::FindWriter() End\n");
+
+	return NULL;
+
+	}
+
+
+void CSuplConnectionManager::GetHostSettingsL(TLbsHostSettingsId aId, TLbsHostSettingsSupl& aSettings)
+	{
+	SUPLLOG(ELogP1, "CSuplConnectionManager::GetHostSettingsL() Begin\n");
+	// Open the host store
+	CLbsHostSettingsStore* pHostStore = CLbsHostSettingsStore::NewL(KLbsHostSettingsSuplStoreId);
+	CleanupStack::PushL(pHostStore);
+	
+	// Get the host settings
+	User::LeaveIfError(pHostStore->GetHostSettings(aId, aSettings));
+	
+	CleanupStack::PopAndDestroy(pHostStore);
+	SUPLLOG(ELogP1, "CSuplConnectionManager::GetHostSettingsL() End\n");
+	}
+
+
+
+
+/*
+ * CSuplSessionRecord 
+ */
+CSuplSessionRecord* CSuplSessionRecord::NewL(MSuplConnectionManagerObserver& aObserver,
+					   						 const TSuplLocalSessionId& aSessionId,
+					   						 const TLbsHostSettingsId& aSlpId,
+					   						 const TServiceType aServiceType,
+					   						 TUint  aSocketWriterIndex)
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::NewL()\n");
+	CSuplSessionRecord* self = new(ELeave) CSuplSessionRecord(aObserver, aSessionId, 
+															  aSlpId, aServiceType, aSocketWriterIndex);
+	return self;
+	}
+
+CSuplSessionRecord::~CSuplSessionRecord()
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::~CSuplSessionRecord() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::~CSuplSessionRecord() End\n");
+	}
+
+CSuplSessionRecord::CSuplSessionRecord(MSuplConnectionManagerObserver& aObserver,
+					   				   const TSuplLocalSessionId& aSessionId,
+					   				   const TLbsHostSettingsId& aSlpId,
+					   				   const TServiceType aServiceType,
+					   				   TUint aSocketWriterIndex) :
+	iObserver(aObserver), iSessionId(aSessionId),
+	iSlpId(aSlpId), iServiceType(aServiceType), iSocketWriterIndex(aSocketWriterIndex)	
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::CSuplSessionRecord() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::CSuplSessionRecord() End\n");
+	}
+
+MSuplConnectionManagerObserver& CSuplSessionRecord::Observer() const
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::Observer() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::Observer() End\n");
+	return iObserver;
+	}
+
+const TSuplLocalSessionId& CSuplSessionRecord::SessionId() const
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SessionId() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SessionId() End\n");
+	return iSessionId;
+	}
+
+const TLbsHostSettingsId CSuplSessionRecord::SlpId() const
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SlpId() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SlpId() End\n");
+	return iSlpId;
+	}
+
+TUint CSuplSessionRecord::SocketWriter() const
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SocketWriter() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::SocketWriter() End\n");
+	return iSocketWriterIndex;
+	}
+
+CSuplSessionRecord::TServiceType CSuplSessionRecord::ServiceMode() const
+	{
+	SUPLLOG(ELogP1, "CSuplSessionRecord::ServiceMode() Begin\n");
+	SUPLLOG(ELogP1, "CSuplSessionRecord::ServiceMode() End\n");
+	return iServiceType;
+	}