networkprotocolmodules/suplprotocolmodule/SuplConnectionManager/src/socketwriter.cpp
changeset 0 9cfd9a3ee49c
child 12 d8287cc0d36f
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19  @deprecated
       
    20 */
       
    21 #include "suplconnectionmanager.h"
       
    22 #include "socketwriter.h"
       
    23 #include "socketreader.h"
       
    24 #include <lbs/lbshostsettings.h>
       
    25 
       
    26 #include "suplmessagebase.h"
       
    27 
       
    28 #include "supldevloggermacros.h"
       
    29 #include <e32base.h>
       
    30 #include <es_sock.h>
       
    31 #include <in_sock.h>
       
    32 #include <commdbconnpref.h>
       
    33 
       
    34 // Timeout timer
       
    35 const TInt KTimeoutTime = 10; // Seconds, will convert to TTimeIntervalSeconds.
       
    36 
       
    37 CSocketWriterBase::CSocketWriterBase(const TLbsHostSettingsId& aSlpId,
       
    38 									 TInt aCallbackIndex,
       
    39 	   	  							 MSuplSocketObserver& aSocketObserver,
       
    40 	   	  							 RSocketServ& aSocketServer,
       
    41 	   	  							 const TLbsHostSettingsSupl& aHostSettings) :
       
    42     CActive(EPriorityStandard), iState(ENone), iSocketServ(aSocketServer), iObserver(aSocketObserver), 
       
    43     iCallbackId(aCallbackIndex), iSessionCount(0), iHostSettings(aHostSettings), iSlpSettings(aSlpId), iQueue(5)  
       
    44 	{
       
    45 	SUPLLOG(ELogP1, "CSocketWriterBase::CSocketWriterBase() Begin\n");
       
    46 	CActiveScheduler::Add(this);
       
    47 	SUPLLOG(ELogP1, "CSocketWriterBase::CSocketWriterBase() End\n");
       
    48 	}
       
    49 
       
    50 CSocketWriterBase::~CSocketWriterBase()
       
    51 	{
       
    52 	SUPLLOG(ELogP1, "CSocketWriterBase::~CSocketWriterBase() Begin\n");
       
    53 	Cancel();
       
    54 	iResolver.Close();
       
    55 	iSocket.Close();
       
    56 	iConnection.Close();
       
    57 	
       
    58 	delete iTimeout;
       
    59 	SUPLLOG(ELogP1, "CSocketWriterBase::~CSocketWriterBase() End\n");
       
    60 	}
       
    61 
       
    62 void CSocketWriterBase::BaseConstructL()
       
    63 	{
       
    64 	SUPLLOG(ELogP1, "CSocketWriterBase::BaseConstructL() Begin\n");
       
    65 	User::LeaveIfError(iConnection.Open(iSocketServ));
       
    66 	
       
    67 	iTimeout = CLbsCallbackTimer::NewL(*this);
       
    68 	SUPLLOG(ELogP1, "CSocketWriterBase::BaseConstructL() End\n");
       
    69 	}
       
    70 
       
    71 void CSocketWriterBase::Connect(const TSuplLocalSessionId aSessionId)
       
    72 	{
       
    73 	SUPLLOG(ELogP1, "CSocketWriterBase::Connect() Begin\n");
       
    74 	if (iSessionCount == 0)
       
    75 		{
       
    76 		++iSessionCount;
       
    77 		iLastSessionId = aSessionId;
       
    78 		
       
    79 		if (iState == ENone)
       
    80 			{
       
    81 			ConnectConnection();
       
    82 			}
       
    83 		else if(iState != EConnectingConnection)
       
    84 			{
       
    85 			DoConnectSocket();
       
    86 			}
       
    87 		}
       
    88 	else
       
    89 		{
       
    90 		++iSessionCount;
       
    91 
       
    92 		TInetAddr addr;
       
    93 		iSocket.LocalName(addr);
       
    94 		iObserver.Connected(aSessionId, addr);
       
    95 		}
       
    96 
       
    97 	SUPLLOG(ELogP1, "CSocketWriterBase::Connect() End\n");
       
    98 	}
       
    99 
       
   100 void CSocketWriterBase::Disconnect()
       
   101 	{
       
   102 	SUPLLOG(ELogP1, "CSocketWriterBase::Disconnect() Begin\n");
       
   103 	if (--iSessionCount == 0)
       
   104 		{
       
   105 		// Stop the timer incase it is active
       
   106 		StopTimer();
       
   107 
       
   108 		// Call the derived class disconnect 
       
   109 		DoDisconnect();
       
   110 		
       
   111 		// Close the socket
       
   112 		iSocket.Close();
       
   113 		
       
   114 		// Inform connection manager of shutdown to socket writer
       
   115 		TBool cleanup = EFalse;
       
   116 		iObserver.ConnectionError(MSuplSocketObserver::EDisconnected, iCallbackId, iLastSessionId, cleanup);
       
   117 		if (cleanup)
       
   118 			{
       
   119 			delete this;
       
   120 			}
       
   121 		}
       
   122 	SUPLLOG(ELogP1, "CSocketWriterBase::Disconnect() End\n");
       
   123 	}
       
   124 
       
   125 void CSocketWriterBase::SendMessageL(CSuplMessageBase* aMessage, 
       
   126 									 const TSuplLocalSessionId& aSessionId)
       
   127 
       
   128 	{
       
   129 	SUPLLOG(ELogP1, "CSocketWriterBase::SendMessageL() Begin\n");
       
   130 	iLastSessionId = aSessionId;
       
   131 	CleanupStack::PushL(aMessage); // As we clean it up
       
   132 	
       
   133 	if ((iState != EIdleConnected) && (iState != ESendingMessage))
       
   134 		{
       
   135 		SUPLLOG(ELogP1, "CSocketWriterBase::SendMessageL() Leave: KErrNotReady\n");
       
   136 		User::Leave(KErrNotReady);
       
   137 		}
       
   138 
       
   139 	// Encode the message
       
   140 	HBufC8* buffer = HBufC8::NewLC(KSuplMaxMessageLength);
       
   141 	TPtr8 ptr(buffer->Des());
       
   142 	TInt err = aMessage->EncodeToL(ptr);
       
   143 	if (err != KErrNone)
       
   144 		{
       
   145 		ASSERT(EFalse);
       
   146 		SUPLLOG(ELogP1, "CSocketWriterBase::SendMessageL() Leave: KErrGeneral\n");
       
   147 		User::Leave(KErrGeneral);
       
   148 		}
       
   149 	
       
   150 	// Add to queue
       
   151 	iQueue.AppendL(buffer);
       
   152 	
       
   153 	CheckQueue();
       
   154 	
       
   155 	CleanupStack::Pop(buffer);
       
   156 	CleanupStack::PopAndDestroy(aMessage);
       
   157 	SUPLLOG(ELogP1, "CSocketWriterBase::SendMessageL() End\n");
       
   158 	}
       
   159 
       
   160 TLbsHostSettingsId CSocketWriterBase::HostSettingsId()
       
   161 	{
       
   162 	SUPLLOG(ELogP1, "CSocketWriterBase::HostSettingsId() Begin\n");
       
   163 	SUPLLOG(ELogP1, "CSocketWriterBase::HostSettingsId() End\n");
       
   164 	return iSlpSettings;
       
   165 	}
       
   166 
       
   167 void CSocketWriterBase::ResolveHost()
       
   168 	{
       
   169 	SUPLLOG(ELogP1, "CSocketWriterBase::ResolveHost() Begin\n");
       
   170 	iResolver.Open(iSocketServ, KAfInet, KProtocolInetTcp, iConnection);
       
   171 	
       
   172 	TBuf8<256> hostname8;
       
   173 	iHostSettings.GetHostNameAddress(hostname8);
       
   174 	TBuf16<256> hostname16;
       
   175 	hostname16.Copy(hostname8);
       
   176 	iResolver.GetByName(hostname16, iNameEntry, iStatus);
       
   177 	
       
   178 	iState = EResolvingSlpAddress;
       
   179 	StartTimer();
       
   180 	SetActive();
       
   181 	SUPLLOG(ELogP1, "CSocketWriterBase::ResolveHost() End\n");
       
   182 	}
       
   183 
       
   184 void CSocketWriterBase::ConnectConnection()
       
   185 	{
       
   186 	SUPLLOG(ELogP1, "CSocketWriterBase::ConnectConnection() Begin\n");
       
   187 	// Override defaults
       
   188 	TInt ap;
       
   189 	TLbsHostSettingsSupl::TLbsConnectionType connectionType;
       
   190 	iHostSettings.GetConnectionPoint(ap, connectionType);
       
   191 	
       
   192 	if (connectionType == TLbsHostSettingsSupl::ELbsConnectionTypeInvalid)
       
   193 		{
       
   194 		iConnection.Start(iStatus);
       
   195 		}
       
   196 	else
       
   197 		{
       
   198 		TCommDbConnPref prefs;
       
   199 		prefs.SetIapId(ap);
       
   200 		prefs.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   201 		iConnection.Start(prefs, iStatus);
       
   202 		}
       
   203 
       
   204 	iState = EConnectingConnection;
       
   205 	StartTimer();
       
   206 	SetActive();
       
   207 	SUPLLOG(ELogP1, "CSocketWriterBase::ConnectConnection() End\n");
       
   208 	}
       
   209 
       
   210 void CSocketWriterBase::RunL()
       
   211 	{
       
   212 	SUPLLOG2(ELogP1, "CSocketWriterBase::RunL() Begin, iState: %d\n", iState );
       
   213 	StopTimer();
       
   214 	
       
   215 	TBool cleanup = EFalse;
       
   216 	
       
   217 	switch (iState)
       
   218 		{
       
   219 	case EConnectingConnection:
       
   220 		{
       
   221 		if (iStatus == KErrNone)
       
   222 			{
       
   223 			ResolveHost();
       
   224 			}
       
   225 		else
       
   226 			{
       
   227 			SUPLLOG(ELogP1, "CSocketWriterBase::RunL() Connection Error(KErrCouldNotConnect)\n");
       
   228 			iObserver.ConnectionError(KErrCouldNotConnect, iCallbackId, iLastSessionId, cleanup);
       
   229 			}
       
   230 		break;
       
   231 		} // case
       
   232 
       
   233 		case EResolvingSlpAddress:
       
   234 			{
       
   235 			if (iStatus == KErrNone)
       
   236 				{
       
   237 				// Fill in the actual iAddr
       
   238 				iAddr = TInetAddr::Cast(iNameEntry().iAddr);
       
   239 				TInt port = 0;
       
   240 				iHostSettings.GetPortId(port);
       
   241 				iAddr.SetPort(port);
       
   242 				
       
   243 				DoConnectSocket();
       
   244 				} // if
       
   245 			else
       
   246 				{
       
   247 				SUPLLOG(ELogP1, "CSocketWriterBase::RunL() Connection Error(KErrNotFound)\n");
       
   248 				iObserver.ConnectionError(KErrNotFound, iCallbackId, iLastSessionId, cleanup);
       
   249 				}
       
   250 			break;
       
   251 			} // case
       
   252 		case EConnectingSocket:
       
   253 			{
       
   254 			if (iStatus == KErrNone)
       
   255 				{
       
   256 				// Start the reader
       
   257 				TRAPD(err, DoStartReaderL());
       
   258 				if (err == KErrNone)
       
   259 					{
       
   260 					iState = EIdleConnected;
       
   261 					
       
   262 					TInetAddr addr;
       
   263 					iSocket.LocalName(addr);
       
   264 					iObserver.Connected(iLastSessionId, addr);
       
   265 					
       
   266 					SelfComplete();
       
   267 					}
       
   268 				else
       
   269 					{
       
   270 					SUPLLOG(ELogP1, "CSocketWriterBase::RunL() Connection Error(KErrCouldNotConnect,1)\n");
       
   271 					iObserver.ConnectionError(KErrCouldNotConnect, iCallbackId, iLastSessionId, cleanup);
       
   272 					}
       
   273 				}
       
   274 			else
       
   275 				{
       
   276 				SUPLLOG(ELogP1, "CSocketWriterBase::RunL() Connection Error(KErrCouldNotConnect,2)\n");
       
   277 				iObserver.ConnectionError(KErrCouldNotConnect, iCallbackId, iLastSessionId, cleanup);
       
   278 				}
       
   279 			break;
       
   280 			}
       
   281 		case ESendingMessage:
       
   282 			{
       
   283 			// Remove the message that was sent
       
   284 			HBufC8* buf = iQueue.At(0); 
       
   285 			delete buf;
       
   286 			iQueue.Delete(0);
       
   287 			
       
   288 			if (iStatus == KErrNone)
       
   289 				{
       
   290 				iState = EIdleConnected;
       
   291 				SelfComplete();
       
   292 				} // if
       
   293 			else
       
   294 				{
       
   295 				SUPLLOG(ELogP1, "CSocketWriterBase::RunL() Connection Error(EFailedToSend)\n");
       
   296 				iObserver.ConnectionError(MSuplSocketObserver::EFailedToSend, iCallbackId, iLastSessionId, cleanup);
       
   297 				} // else
       
   298 			break;
       
   299 			}
       
   300 		case EIdleConnected:
       
   301 			{
       
   302 			CheckQueue();
       
   303 			
       
   304 			break;
       
   305 			}
       
   306 		default:
       
   307 			{
       
   308 			// Nothing to do
       
   309 			break;
       
   310 			}
       
   311 		} // switch
       
   312 	
       
   313 	if (cleanup)
       
   314 		{
       
   315 		delete this;
       
   316 		}
       
   317 	SUPLLOG(ELogP1, "CSocketWriterBase::RunL() End\n");
       
   318 	}
       
   319 
       
   320 void CSocketWriterBase::DoCancel()
       
   321 	{
       
   322 	SUPLLOG(ELogP1, "CSocketWriterBase::DoCancel() Begin\n");
       
   323 	switch(iState)
       
   324 		{
       
   325 		case EResolvingSlpAddress:
       
   326 			iResolver.Cancel();
       
   327 			break;
       
   328 		case EConnectingConnection:
       
   329 			{
       
   330 			//Unfortunatelly there is no currently a cancel method for the RConnection::Start.
       
   331 			//This is a bug in the OS (see CR0028 for details). 
       
   332 			//As a workaround we use the following code.
       
   333 			iConnection.Close();
       
   334 			TInt err = iConnection.Open(iSocketServ);
       
   335 			__ASSERT_DEBUG(KErrNone==err, User::Invariant());
       
   336 			}
       
   337 			break;
       
   338 		case EConnectingSocket:
       
   339 			iSocket.CancelConnect();
       
   340 			break;
       
   341 		case ESendingMessage:
       
   342 			iSocket.CancelWrite();
       
   343 			break;
       
   344 		default:
       
   345 			//Intentionally left blank
       
   346 			break;
       
   347 		}
       
   348 	SUPLLOG(ELogP1, "CSocketWriterBase::DoCancel() End\n");
       
   349 	}
       
   350 
       
   351 TInt CSocketWriterBase::RunError(TInt aError)
       
   352 	{
       
   353 	SUPLLOG(ELogP1, "CSocketWriterBase::RunError() Begin\n");
       
   354 	__ASSERT_DEBUG(EFalse, User::Invariant());
       
   355 	
       
   356 	SUPLLOG(ELogP1, "CSocketWriterBase::RunError() End\n");
       
   357 	return aError;
       
   358 	}
       
   359 
       
   360 void CSocketWriterBase::CheckQueue()
       
   361 	{
       
   362 	SUPLLOG(ELogP1, "CSocketWriterBase::CheckQueue() Begin\n");
       
   363 	if (!IsActive() && (iQueue.Count() > 0))
       
   364 		{
       
   365 		DoSendMessage(*(iQueue.At(0)));
       
   366 		}
       
   367 	SUPLLOG(ELogP1, "CSocketWriterBase::CheckQueue() End\n");
       
   368 	}
       
   369 
       
   370 void CSocketWriterBase::DoConnect()
       
   371 	{
       
   372 	SUPLLOG(ELogP1, "CSocketWriterBase::DoConnect() Begin\n");
       
   373 	SUPLLOG(ELogP1, "CSocketWriterBase::DoConnect() End\n");
       
   374 	}
       
   375 
       
   376 void CSocketWriterBase::SelfComplete()
       
   377 	{
       
   378 	SUPLLOG(ELogP1, "CSocketWriterBase::SelfComplete() Begin\n");
       
   379 	TRequestStatus* temp = &iStatus;
       
   380 	User::RequestComplete(temp, KErrNone);
       
   381 	
       
   382 	StartTimer();
       
   383 	SetActive();
       
   384 	SUPLLOG(ELogP1, "CSocketWriterBase::SelfComplete() End\n");
       
   385 	}
       
   386 
       
   387 void CSocketWriterBase::StartTimer()
       
   388 	{
       
   389 	SUPLLOG(ELogP1, "CSocketWriterBase::StartTimer() Begin\n");
       
   390 	TTimeIntervalSeconds timeout = KTimeoutTime; 
       
   391 	iTimeout->EventAfter(timeout, 1);
       
   392 	SUPLLOG(ELogP1, "CSocketWriterBase::StartTimer() End\n");
       
   393 	}
       
   394 
       
   395 void CSocketWriterBase::StopTimer()
       
   396 	{
       
   397 	SUPLLOG(ELogP1, "CSocketWriterBase::StopTimer() Begin\n");
       
   398 	iTimeout->Cancel();
       
   399 	SUPLLOG(ELogP1, "CSocketWriterBase::StopTimer() End\n");
       
   400 	}
       
   401 
       
   402 void CSocketWriterBase::OnTimerEventL(TInt 
       
   403 #ifdef _DEBUG									  
       
   404 									 aTimerId
       
   405 #endif
       
   406 									  )
       
   407 	{
       
   408 	SUPLLOG(ELogP1, "CSocketWriterBase::OnTimerEventL() Begin\n");
       
   409 	__ASSERT_DEBUG(aTimerId == 1, User::Invariant());
       
   410 	
       
   411 	// Server has not responded. The error will result in the connection being closed
       
   412 	TBool cleanup = EFalse;
       
   413 	iObserver.ConnectionError(MSuplSocketObserver::ETimeOut, iCallbackId, iLastSessionId, cleanup);
       
   414 	if (cleanup)
       
   415 		{
       
   416 		delete this;
       
   417 		}
       
   418 	SUPLLOG(ELogP1, "CSocketWriterBase::OnTimerEventL() End\n");
       
   419 	}
       
   420 
       
   421 TInt CSocketWriterBase::OnTimerError(TInt /*aTimerId*/, TInt aError)
       
   422 	{
       
   423 	SUPLLOG(ELogP1, "CSocketWriterBase::OnTimerEventL() Begin\n");
       
   424 	__ASSERT_DEBUG(EFalse, User::Invariant());
       
   425 	
       
   426 	SUPLLOG(ELogP1, "CSocketWriterBase::OnTimerEventL() End\n");
       
   427 	return aError;
       
   428 	}
       
   429 
       
   430 TInt CSocketWriterBase::CallbackId()
       
   431 	{
       
   432 	SUPLLOG(ELogP1, "CSocketWriterBase::CallbackId() Begin\n");
       
   433 	SUPLLOG(ELogP1, "CSocketWriterBase::CallbackId() End\n");
       
   434 	return iCallbackId;
       
   435 	}
       
   436 
       
   437 
       
   438 
       
   439 /**
       
   440  * CSocketWriter
       
   441  */
       
   442 CSocketWriter* CSocketWriter::NewL(const TLbsHostSettingsId& aSlpId, 
       
   443 								   TInt aCallbackIndex,
       
   444 								   MSuplSocketObserver& aSocketObserver,
       
   445 								   RSocketServ& aSocketServer,
       
   446 								   TLbsHostSettingsSupl& aHostSettings)
       
   447 	{
       
   448 	SUPLLOG(ELogP1, "CSocketWriter::NewL() Begin\n");
       
   449 	CSocketWriter* self = new(ELeave) CSocketWriter(aSlpId, aCallbackIndex, aSocketObserver, aSocketServer, aHostSettings);
       
   450 	CleanupStack::PushL(self);
       
   451 	self->BaseConstructL();
       
   452 	CleanupStack::Pop(self);
       
   453 	
       
   454 	SUPLLOG(ELogP1, "CSocketWriter::NewL() End\n");
       
   455 	return self;
       
   456 	}
       
   457 
       
   458 CSocketWriter::~CSocketWriter()
       
   459 	{
       
   460 	SUPLLOG(ELogP1, "CSocketWriter::~CSocketWriter() Begin\n");
       
   461 	delete iSocketReader;
       
   462 	SUPLLOG(ELogP1, "CSocketWriter::~CSocketWriter() End\n");
       
   463 	}
       
   464 
       
   465 CSocketWriter::CSocketWriter(const TLbsHostSettingsId& aSlpId,
       
   466 							 TInt aCallbackIndex,
       
   467 							 MSuplSocketObserver& aSocketObserver,
       
   468 			   	  			 RSocketServ& aSocketServer,
       
   469 			   	  			 TLbsHostSettingsSupl& aHostSettings) :
       
   470     CSocketWriterBase(aSlpId, aCallbackIndex, aSocketObserver, aSocketServer, aHostSettings)
       
   471 	{
       
   472 	SUPLLOG(ELogP1, "CSocketWriter::CSocketWriter() Begin\n");
       
   473 	SUPLLOG(ELogP1, "CSocketWriter::CSocketWriter() End\n");
       
   474 	}
       
   475 
       
   476 void CSocketWriter::DoConnectSocket()
       
   477 	{
       
   478 	SUPLLOG(ELogP1, "CSocketWriter::DoConnectSocket() Begin\n");
       
   479 	TInt err = iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iConnection); 
       
   480 	if (err == KErrNone)
       
   481 		{
       
   482 		iSocket.Connect(iAddr, iStatus);
       
   483 		
       
   484 		iState = EConnectingSocket;
       
   485 		StartTimer();
       
   486 		SetActive();
       
   487 		}
       
   488 	else
       
   489 		{
       
   490 		SUPLLOG(ELogP1, "CSocketWriter::DoConnectSocket() Error: ESocketError\n");
       
   491 		TBool cleanup = EFalse;
       
   492 		iObserver.ConnectionError(MSuplSocketObserver::ESocketError, iCallbackId, iLastSessionId, cleanup);
       
   493 		if (cleanup)
       
   494 			{
       
   495 			delete this;
       
   496 			}
       
   497 		}
       
   498 	SUPLLOG(ELogP1, "CSocketWriter::DoConnectSocket() End\n");
       
   499 	}
       
   500 
       
   501 void CSocketWriter::DoDisconnect()
       
   502 	{
       
   503 	SUPLLOG(ELogP1, "CSocketWriter::DoDisconnect() Begin\n");
       
   504 	if(IsActive())
       
   505 		{
       
   506 		Cancel();
       
   507 		}
       
   508 	delete iSocketReader;
       
   509 	iSocketReader = NULL;
       
   510 	if((iState == EResolvingSlpAddress) || (iState ==EConnectingConnection))
       
   511 		{
       
   512 		iState = ENone;
       
   513 		}
       
   514 
       
   515 	SUPLLOG(ELogP1, "CSocketWriter::DoDisconnect() End\n");
       
   516 	}
       
   517 	
       
   518 void CSocketWriter::DoSendMessage(TDesC8& aMessage)
       
   519 	{
       
   520 	SUPLLOG(ELogP1, "CSocketWriter::DoSendMessage() Begin\n");
       
   521 	iState = ESendingMessage;
       
   522 	
       
   523 	iSocket.Write(aMessage, iStatus);
       
   524 	StartTimer();
       
   525 	SetActive();
       
   526 	SUPLLOG(ELogP1, "CSocketWriter::DoSendMessage() End\n");
       
   527 	}
       
   528 
       
   529 void CSocketWriter::DoStartReaderL()
       
   530 	{
       
   531 	SUPLLOG(ELogP1, "CSocketWriter::DoStartReaderL() Begin\n");
       
   532 	iSocketReader = CSocketReader::NewL(iSocket, iObserver, iCallbackId);
       
   533 	SUPLLOG(ELogP1, "CSocketWriter::DoStartReaderL() End\n");
       
   534 	}
       
   535 
       
   536 /**
       
   537  * CSecureSocketWriter
       
   538  */
       
   539 CSecureSocketWriter* CSecureSocketWriter::NewL(const TLbsHostSettingsId& aSlpId, 
       
   540 								   		 	   TInt aCallbackIndex,
       
   541 								   		 	   MSuplSocketObserver& aSocketObserver,
       
   542 								   		 	   RSocketServ& aSocketServer,
       
   543 								   		 	   TLbsHostSettingsSupl& aHostSettings,
       
   544 								   	  		   const CSuplSessionRecord::TServiceType& aServiceType)
       
   545 	{
       
   546 	SUPLLOG(ELogP1, "CSecureSocketWriter::NewL() Begin\n");
       
   547 	CSecureSocketWriter* self = new(ELeave) CSecureSocketWriter(aSlpId, aCallbackIndex, aSocketObserver, aSocketServer, aHostSettings, aServiceType);
       
   548 	CleanupStack::PushL(self);
       
   549 	self->BaseConstructL();
       
   550 	CleanupStack::Pop(self);
       
   551 	
       
   552 	SUPLLOG(ELogP1, "CSecureSocketWriter::NewL() End\n");
       
   553 	return self;
       
   554 	}
       
   555 
       
   556 CSecureSocketWriter::~CSecureSocketWriter()
       
   557 	{
       
   558 	SUPLLOG(ELogP1, "CSecureSocketWriter::~CSecureSocketWriter() Begin\n");
       
   559 	delete iSocketReader;
       
   560 	delete iSecureSocket;
       
   561 	SUPLLOG(ELogP1, "CSecureSocketWriter::~CSecureSocketWriter() End\n");
       
   562 	}
       
   563 
       
   564 CSecureSocketWriter::CSecureSocketWriter(const TLbsHostSettingsId& aSlpId,
       
   565 							 			 TInt aCallbackIndex,
       
   566 							 			 MSuplSocketObserver& aSocketObserver,
       
   567 							 			 RSocketServ& aSocketServer,
       
   568 							 			 TLbsHostSettingsSupl& aHostSettings,
       
   569 							   	  		 const CSuplSessionRecord::TServiceType& aServiceType) :
       
   570     CSocketWriterBase(aSlpId, aCallbackIndex, aSocketObserver, aSocketServer, aHostSettings),
       
   571     iSecureSocket(NULL), iServiceType(aServiceType)
       
   572 	{
       
   573 	SUPLLOG(ELogP1, "CSecureSocketWriter::CSecureSocketWriter() Begin\n");
       
   574 	SUPLLOG(ELogP1, "CSecureSocketWriter::CSecureSocketWriter() End\n");
       
   575 	}
       
   576 
       
   577 void CSecureSocketWriter::RunL()
       
   578 	{
       
   579 	TBool cleanup = EFalse;
       
   580 	
       
   581 	SUPLLOG2(ELogP1, "CSecureSocketWriter::RunL() Begin, iState: %d\n", iState);
       
   582 	switch (iState)
       
   583 		{
       
   584 		case EConnectingSocket:
       
   585 			{
       
   586 			StopTimer();
       
   587 			if (iStatus == KErrNone)
       
   588 				{
       
   589 				StartSecureSocketL();
       
   590 				}
       
   591 			else
       
   592 				{
       
   593 				SUPLLOG(ELogP1, "CSecureSocketWriter::RunL() Error(KErrCoundNotConnect)\n");
       
   594 				iObserver.ConnectionError(KErrCouldNotConnect, iCallbackId, iLastSessionId, cleanup);
       
   595 				}		
       
   596 			break;
       
   597 			}
       
   598 		case ETlsHandshaking:
       
   599 			{
       
   600 			StopTimer();
       
   601 			if (iStatus == KErrNone)
       
   602 				{
       
   603 				// Check the certificate if we are running in TLS_ACA mode
       
   604 				TBool isSecure = EFalse;
       
   605 				TRAPD(err, isSecure = CheckTlsSecureL());
       
   606 				if ((err == KErrNone) && isSecure)
       
   607 					{
       
   608 					TRAP(err, DoStartReaderL());
       
   609 					if (err == KErrNone)
       
   610 						{
       
   611 						iState = EIdleConnected;
       
   612 
       
   613 						TInetAddr addr;
       
   614 						iSocket.LocalName(addr);
       
   615 						iObserver.Connected(iLastSessionId, addr);
       
   616 
       
   617 						SelfComplete();
       
   618 						}
       
   619 					else
       
   620 						{
       
   621 						SUPLLOG(ELogP1, "CSecureSocketWriter::RunL() Error(KErrCoundNotConnect)\n");
       
   622 						iObserver.ConnectionError(KErrCouldNotConnect, iCallbackId, iLastSessionId, cleanup);
       
   623 						}
       
   624 					}
       
   625 				else
       
   626 					{
       
   627 					SUPLLOG(ELogP1, "CSecureSocketWriter::RunL() Error(EFailedCertCheck)\n");
       
   628 					iObserver.ConnectionError(MSuplSocketObserver::EFailedCertCheck, iCallbackId, iLastSessionId, cleanup);
       
   629 					}
       
   630 				}
       
   631 			else
       
   632 				{
       
   633 				SUPLLOG(ELogP1, "CSecureSocketWriter::RunL() Error(EFailedToHandshake)\n");
       
   634 				iObserver.ConnectionError(MSuplSocketObserver::EFailedToHandshake, iCallbackId, iLastSessionId, cleanup);
       
   635 				}
       
   636 			break;
       
   637 			}
       
   638 		default:
       
   639 			{
       
   640 			CSocketWriterBase::RunL();
       
   641 			break;
       
   642 			}
       
   643 		}
       
   644 	
       
   645 	if (cleanup)
       
   646 		{
       
   647 		delete this;
       
   648 		}
       
   649 	SUPLLOG(ELogP1, "CSecureSocketWriter::RunL() End\n");
       
   650 	}
       
   651 
       
   652 
       
   653 void CSecureSocketWriter::DoCancel()
       
   654 	{
       
   655 	switch(iState)
       
   656 		{
       
   657 		case ETlsHandshaking:
       
   658 			__ASSERT_DEBUG(iSecureSocket!=NULL, User::Invariant());
       
   659 			if(iSecureSocket)
       
   660 				{
       
   661 				iSecureSocket->CancelHandshake();
       
   662 				}
       
   663 			break;
       
   664 		default:
       
   665 			CSocketWriterBase::DoCancel();
       
   666 			break;
       
   667 		}
       
   668 	}
       
   669 
       
   670 void CSecureSocketWriter::DoConnectSocket()
       
   671 	{
       
   672 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoConnectSocket() Begin\n");
       
   673 	TInt err = iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iConnection); 
       
   674 	if (err == KErrNone)
       
   675 		{
       
   676 		iSocket.Connect(iAddr, iStatus);
       
   677 		
       
   678 		iState = EConnectingSocket;
       
   679 		StartTimer();
       
   680 		SetActive();
       
   681 		}
       
   682 	else
       
   683 		{
       
   684 		SUPLLOG(ELogP1, "CSecureSocketWriter::DoConnectSocket() Error(ESocketError)\n");
       
   685 		TBool cleanup = EFalse;
       
   686 		iObserver.ConnectionError(MSuplSocketObserver::ESocketError, iCallbackId, iLastSessionId, cleanup);
       
   687 		if (cleanup)
       
   688 			{
       
   689 			delete this;
       
   690 			}
       
   691 		}
       
   692 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoConnectSocket() End\n");
       
   693 	}
       
   694 
       
   695 void CSecureSocketWriter::DoDisconnect()
       
   696 	{
       
   697 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoDisconnect() Begin\n");
       
   698 	if(IsActive())
       
   699 		{
       
   700 		Cancel();
       
   701 		}
       
   702 
       
   703 	delete iSocketReader;
       
   704 	iSocketReader = NULL;
       
   705 	
       
   706 	// If we cant resovle the host we wont have a secure connection yet
       
   707 	if (iSecureSocket != NULL)
       
   708 		{
       
   709 		iSecureSocket->Close();
       
   710 		}
       
   711 	if((iState == EResolvingSlpAddress) || (iState ==EConnectingConnection))
       
   712 		{
       
   713 		iState = ENone;
       
   714 		}
       
   715 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoDisconnect() End\n");
       
   716 	}
       
   717 	
       
   718 void CSecureSocketWriter::DoSendMessage(TDesC8& aMessage)
       
   719 	{
       
   720 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoSendMessage() Begin\n");
       
   721 	iState = ESendingMessage;
       
   722 	
       
   723 	iSecureSocket->Send(aMessage, iStatus);
       
   724 	StartTimer();
       
   725 	SetActive();
       
   726 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoSendMessage() End\n");
       
   727 	}
       
   728 
       
   729 void CSecureSocketWriter::DoStartReaderL()
       
   730 	{
       
   731 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoStartReaderL() Begin\n");
       
   732 	iSocketReader = CSecureSocketReader::NewL(*iSecureSocket, iObserver, iCallbackId);
       
   733 	SUPLLOG(ELogP1, "CSecureSocketWriter::DoStartReaderL() End\n");
       
   734 	}
       
   735 
       
   736 void CSecureSocketWriter::StartSecureSocketL()
       
   737 	{
       
   738 	SUPLLOG(ELogP1, "CSecureSocketWriter::StartSecureSocketL() Begin\n");
       
   739 	_LIT(KSSLProtocol,"TLS1.0");
       
   740 	
       
   741  	iState = ETlsHandshaking;
       
   742 	
       
   743 	// Create the secure socket
       
   744 	iSecureSocket = CSecureSocket::NewL(iSocket, KSSLProtocol());
       
   745 	iSecureSocket->FlushSessionCache();
       
   746 
       
   747 	// Do the handshake
       
   748 	iSecureSocket->StartClientHandshake(iStatus);
       
   749 	StartTimer();
       
   750 	SetActive();
       
   751 	SUPLLOG(ELogP1, "CSecureSocketWriter::StartSecureSocketL() End\n");
       
   752 	}
       
   753 
       
   754 TBool CSecureSocketWriter::CheckTlsSecureL()
       
   755 	{
       
   756 	SUPLLOG(ELogP1, "CSecureSocketWriter::CheckTlsSecureL() Begin\n");
       
   757 	TBool ret = ETrue;
       
   758 	
       
   759 	// Get the auth mode to check
       
   760 	TLbsHostSettingsSupl::TAuthModes authMode;
       
   761 	if (iServiceType == CSuplSessionRecord::EServiceMtlr)
       
   762 		{
       
   763 		iHostSettings.GetAuthModesMTLR(authMode);
       
   764 		}
       
   765 	else
       
   766 		{
       
   767 		iHostSettings.GetAuthModesMOLR(authMode);
       
   768 		}
       
   769 	
       
   770 	// If we are using AuthAcaTls then we need to check that the certificate is from the
       
   771 	// provisioned host. We dont bother with the check if we will accept AuthTLs as we simply
       
   772 	// fall back to that if we fail anyway.
       
   773 	if (((authMode & TLbsHostSettingsSupl::EAuthAcaTls) == TLbsHostSettingsSupl::EAuthAcaTls) && 
       
   774 		((authMode & TLbsHostSettingsSupl::EAuthTls)  != TLbsHostSettingsSupl::EAuthTls))
       
   775 		{
       
   776 		ret = EFalse;
       
   777 
       
   778 		// Get server name from certificate
       
   779 		const CX509Certificate* cert = iSecureSocket->ServerCert();
       
   780 		if (cert != NULL)
       
   781 			{
       
   782 			HBufC* commonName = cert->SubjectName().DisplayNameL();
       
   783 			
       
   784 			// Host provisioned
       
   785 			TBuf8<256> hostname8;
       
   786 			iHostSettings.GetHostNameAddress(hostname8);
       
   787 			TBuf16<256> hostname16;
       
   788 			hostname16.Copy(hostname8);
       
   789 
       
   790 			if (commonName->CompareF(hostname16) == 0)
       
   791 				{
       
   792 				// Certificate is from provisioned host
       
   793 				ret = ETrue;
       
   794 				}
       
   795 			else
       
   796 				{
       
   797 				SUPLLOG(ELogP1, "CSecureSocketWriter::CheckTlsSecureL() Error(FailedACATest)\n");
       
   798 				}
       
   799 			}
       
   800 		}
       
   801 	
       
   802 	SUPLLOG(ELogP1, "CSecureSocketWriter::CheckTlsSecureL() End\n");
       
   803 
       
   804 	return ret;
       
   805 	}