|         |      1 // Copyright (c) 2001-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 // System includes | 
|         |     17 #include <http/framework/crxdata.h> | 
|         |     18 #include <http/rhttpheaders.h> | 
|         |     19 #include <http/thttpevent.h> | 
|         |     20 #include <httpstringconstants.h> | 
|         |     21 #include <wsp/wsptypes.h> | 
|         |     22 #include <wsp/cwsptransporthandler.h> | 
|         |     23 #include <wsp/mwspcosessioninvoker.h> | 
|         |     24 #include <wsp/mwspcomethodinvoker.h> | 
|         |     25 #include <wspstringconstants.h> | 
|         |     26 #include <wspstdconstants.h> | 
|         |     27 #include <wsperror.h> | 
|         |     28  | 
|         |     29 // User includes | 
|         |     30 #include "cwspcotransaction.h" | 
|         |     31 #include "cwspcapabilityinfo.h" | 
|         |     32 #include "cwspproxyinfoprovider.h" | 
|         |     33 #include "cconnectiontimer.h" | 
|         |     34 #include "cwspprimitivesender.h" | 
|         |     35 #include "wsppanic.h" | 
|         |     36 #include "cwspheaderutils.h" | 
|         |     37 #include "cwspheadercodec.h" | 
|         |     38  | 
|         |     39 // Class signature | 
|         |     40 #include "cwspcoprotocolhandler.h" | 
|         |     41  | 
|         |     42 const TInt KDefaultConnectionTimeMicroSeconds	= 180000000;		// 3 minutes | 
|         |     43  | 
|         |     44 /* | 
|         |     45  * CWspCOProtocolHandler | 
|         |     46  */ | 
|         |     47  | 
|         |     48 CWspCOProtocolHandler* CWspCOProtocolHandler::NewL(TAny* aSession) | 
|         |     49 	{ | 
|         |     50 	RHTTPSession* session = REINTERPRET_CAST(RHTTPSession*, aSession); | 
|         |     51 	CWspCOProtocolHandler* self = new (ELeave) CWspCOProtocolHandler(*session); | 
|         |     52 	CleanupStack::PushL(self); | 
|         |     53 	self->ConstructL(); | 
|         |     54 	CleanupStack::Pop(self); | 
|         |     55 	return self; | 
|         |     56 	} | 
|         |     57  | 
|         |     58 CWspCOProtocolHandler::~CWspCOProtocolHandler() | 
|         |     59 	{ | 
|         |     60 	 | 
|         |     61 	if( iConnectionTimer ) | 
|         |     62 		iConnectionTimer->Cancel(); | 
|         |     63 	delete iConnectionTimer; | 
|         |     64  | 
|         |     65 	delete iClientSessionHeaders; | 
|         |     66 	delete iTransportHandler; | 
|         |     67 	delete iClientCapInfo; | 
|         |     68 	delete iNegotiatedCapInfo; | 
|         |     69 	delete iProxyInfoProvider; | 
|         |     70 	delete iPrimitiveSender; | 
|         |     71 	delete iHdrUtils; | 
|         |     72 	} | 
|         |     73  | 
|         |     74 CWspCOProtocolHandler::CWspCOProtocolHandler(RHTTPSession aSession) | 
|         |     75 : CProtocolHandler(aSession), /*iSessionState(ENull),*/ iTimedOutValue(KDefaultConnectionTimeMicroSeconds) | 
|         |     76 	{ | 
|         |     77 	__OPEN_LOG("WspProtocolHandler.txt") | 
|         |     78 	} | 
|         |     79  | 
|         |     80 void CWspCOProtocolHandler::ConstructL() | 
|         |     81 	{ | 
|         |     82 	CProtocolHandler::ConstructL(iSession); | 
|         |     83  | 
|         |     84 	// Open the WSP header field names table | 
|         |     85 	iSession.StringPool().OpenL(WSP::Table); | 
|         |     86  | 
|         |     87 	// Create the proposed client capability object and the negotiated session capability object | 
|         |     88 	iClientCapInfo = CWspCapabilityInfo::NewL(); | 
|         |     89 	iNegotiatedCapInfo = CWspCapabilityInfo::NewL(); | 
|         |     90  | 
|         |     91 	// Create the proxy info provider | 
|         |     92 	iProxyInfoProvider = CWspProxyInfoProvider::NewL(iSession); | 
|         |     93  | 
|         |     94 	// Create the connection timer object | 
|         |     95 	iConnectionTimer = CConnectionTimer::NewL(*this); | 
|         |     96  | 
|         |     97 	// Create the primitive sender active object | 
|         |     98 	iPrimitiveSender = CWspPrimitiveSender::NewL(*this); | 
|         |     99  | 
|         |    100 	// Create the transport handler | 
|         |    101 	CreateWspTransportHandlerL(); | 
|         |    102  | 
|         |    103 	// Create the WSP header utilities | 
|         |    104 	iHdrUtils = CWspHeaderUtils::NewL(*STATIC_CAST(CWspHeaderCodec*, iCodec)); | 
|         |    105 	} | 
|         |    106  | 
|         |    107 void CWspCOProtocolHandler::CreateWspTransportHandlerL() | 
|         |    108 	{ | 
|         |    109 	// Assert that the transport handler doesn't already exist | 
|         |    110 	__ASSERT_DEBUG(iTransportHandler == NULL, Panic(KWspPanicTransportHandlerAlreadyExists)); | 
|         |    111  | 
|         |    112 	// Pass through the session string pool when creating the transport handler | 
|         |    113 	RStringPool stringPool = iSession.StringPool(); | 
|         |    114 	iTransportHandler = CWspTransportHandler::NewL( | 
|         |    115 												  stringPool, | 
|         |    116 												  iSecurityPolicy, | 
|         |    117 												  *this,				// Session CB | 
|         |    118 												  *iProxyInfoProvider,	// Proxy info | 
|         |    119 												  *this,				// Capability info | 
|         |    120 												  *this					// Session headers info | 
|         |    121 												  ); | 
|         |    122  | 
|         |    123 	// Check the supported services | 
|         |    124 	CWspTransportHandler::TWspSupportedServices suppSvc = iTransportHandler->SupportedServices(); | 
|         |    125 	TBool sessionSupport = suppSvc & CWspTransportHandler::ECOSessionService; | 
|         |    126 	TBool methodSupport  = suppSvc & CWspTransportHandler::ECOMethodInvocationService; | 
|         |    127 	if( !sessionSupport || !methodSupport ) | 
|         |    128 		{ | 
|         |    129 		__LOG(_L("Session management facility or method invoke facility not supported by transport handler")); | 
|         |    130 		User::Leave(KWspErrRequiredServicesNotSupported); | 
|         |    131 		} | 
|         |    132 	// Configure the session invoker object | 
|         |    133 	iSessionInvoker = &iTransportHandler->COSessionInvoker(); | 
|         |    134 	} | 
|         |    135  | 
|         |    136  | 
|         |    137 void CWspCOProtocolHandler::CheckClientCapabilities() | 
|         |    138 	{ | 
|         |    139 	// Reset the proposed client properties - sets the capabilities to the  | 
|         |    140 	// default values. | 
|         |    141 	iClientCapInfo->Reset(); | 
|         |    142  | 
|         |    143 	// Check the session properties... | 
|         |    144 	RHTTPConnectionInfo	connInfo = iSession.ConnectionInfo(); | 
|         |    145 	RStringPool stringPool = iSession.StringPool(); | 
|         |    146  | 
|         |    147 	// ...client message size... | 
|         |    148 	THTTPHdrVal clientMessageSize; | 
|         |    149 	TBool hasClientMessageSize = connInfo.Property(stringPool.StringF(HTTP::EWspCapClientMessageSize, RHTTPSession::GetTable()), clientMessageSize); | 
|         |    150 	if( hasClientMessageSize ) | 
|         |    151 		{ | 
|         |    152 		// Initial attempt to negotiate message size and SDU size will attempt to go | 
|         |    153 		// for a single PDU transfers, so set them the same | 
|         |    154 		__ASSERT_DEBUG( clientMessageSize.Type() == THTTPHdrVal::KTIntVal, Panic(KWspPanicBadClientMessageSize) ); | 
|         |    155 		iClientCapInfo->SetClientMessageSize(clientMessageSize.Int()); | 
|         |    156 		iClientCapInfo->SetClientSDUSize(clientMessageSize.Int()); | 
|         |    157 		} | 
|         |    158 	// ... server message size... | 
|         |    159 	THTTPHdrVal serverMessageSize; | 
|         |    160 	TBool hasServerMessageSize = connInfo.Property(stringPool.StringF(HTTP::EWspCapServerMessageSize, RHTTPSession::GetTable()), serverMessageSize); | 
|         |    161 	if( hasServerMessageSize ) | 
|         |    162 		{ | 
|         |    163 		// Initial attempt to negotiate message size and SDU size will attempt to go | 
|         |    164 		// for a single PDU transfers, so set them the same | 
|         |    165 		__ASSERT_DEBUG( serverMessageSize.Type() == THTTPHdrVal::KTIntVal, Panic(KWspPanicBadServerMessageSize) ); | 
|         |    166 		iClientCapInfo->SetServerMessageSize(serverMessageSize.Int()); | 
|         |    167 		iClientCapInfo->SetServerSDUSize(serverMessageSize.Int()); | 
|         |    168 		} | 
|         |    169 	// ...method MOR... | 
|         |    170 	THTTPHdrVal methodMOR; | 
|         |    171 	TBool hasMethodMOR = connInfo.Property(stringPool.StringF(HTTP::EWspCapMaxOutstandingRequests, RHTTPSession::GetTable()), methodMOR); | 
|         |    172 	if( hasMethodMOR ) | 
|         |    173 		{ | 
|         |    174 		__ASSERT_DEBUG( methodMOR.Type() == THTTPHdrVal::KTIntVal, Panic(KWspPanicBadMethodMOR) ); | 
|         |    175 		__ASSERT_DEBUG( STATIC_CAST(TUint8, methodMOR.Int()) <= KMaxTUint8, Panic(KWspPanicBadMethodMOR) ); | 
|         |    176 		__ASSERT_DEBUG( STATIC_CAST(TUint8, methodMOR.Int()) > 0, Panic(KWspPanicBadMethodMOR) ); | 
|         |    177 		iClientCapInfo->SetMethodMOR( STATIC_CAST(TUint8, methodMOR.Int()) ); | 
|         |    178 		} | 
|         |    179 	// Sort out the protocol options - by default try to use Large Data Transfer | 
|         |    180 	TUint8 protocolOptions = ELargeDataTransfer; | 
|         |    181 	THTTPHdrVal notUsed; | 
|         |    182 	// ...use acknowledgements... | 
|         |    183 	TBool hasUseAcknowledgements = connInfo.Property(stringPool.StringF(HTTP::EWspCapUseAcknowledgements, RHTTPSession::GetTable()), notUsed); | 
|         |    184 	if( hasUseAcknowledgements ) | 
|         |    185 		{ | 
|         |    186 		protocolOptions |= EAcknowledgementHeaders; | 
|         |    187 		} | 
|         |    188 	// ...support suspend resume facilty... | 
|         |    189 	TBool hasSuspendResume = connInfo.Property(stringPool.StringF(HTTP::EWspCapSupportSuspendResume, RHTTPSession::GetTable()), notUsed); | 
|         |    190 	if( hasSuspendResume ) | 
|         |    191 		{ | 
|         |    192 		protocolOptions |= ESessionResumeFacility; | 
|         |    193 		} | 
|         |    194 	iClientCapInfo->SetProtocolOptions(protocolOptions); | 
|         |    195  | 
|         |    196 	// Get the connection time-out value | 
|         |    197 	THTTPHdrVal connectionTimeout; | 
|         |    198 	TBool hasConnectionTimeout = connInfo.Property(stringPool.StringF(HTTP::EWspProxyConnectionTimeout, RHTTPSession::GetTable()), connectionTimeout); | 
|         |    199 	if( hasConnectionTimeout ) | 
|         |    200 		{ | 
|         |    201 		__ASSERT_DEBUG((connectionTimeout.Type() == THTTPHdrVal::KTIntVal), Panic(KWspPanicBadConenctionTimeout)); | 
|         |    202 		iTimedOutValue = connectionTimeout.Int(); | 
|         |    203 		} | 
|         |    204 	else | 
|         |    205 		{ | 
|         |    206 		// Use the default value | 
|         |    207 		iTimedOutValue = KDefaultConnectionTimeMicroSeconds; | 
|         |    208 		} | 
|         |    209 	} | 
|         |    210  | 
|         |    211 TBool CWspCOProtocolHandler::UpdateNegotiatedCapabilitiesL() | 
|         |    212 	{ | 
|         |    213 	// Check the capabilities proposed by the client | 
|         |    214 	TBool capabilitiesReduced = EFalse; | 
|         |    215  | 
|         |    216 	RHTTPConnectionInfo	connInfo = iSession.ConnectionInfo(); | 
|         |    217 	RStringPool stringPool = iSession.StringPool(); | 
|         |    218  | 
|         |    219 	// ...client message size... | 
|         |    220 	TUint32 clientMessageSize = iNegotiatedCapInfo->GetClientMessageSize(); | 
|         |    221 	if( clientMessageSize != iClientCapInfo->GetClientMessageSize() ) | 
|         |    222 		{ | 
|         |    223 		// The server has reduced the client message size - update the return flag... | 
|         |    224 		capabilitiesReduced = ETrue; | 
|         |    225  | 
|         |    226 		// ...and the session property... | 
|         |    227 		THTTPHdrVal clientMessageSizeProperty = clientMessageSize; | 
|         |    228 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspCapClientMessageSize, RHTTPSession::GetTable()), clientMessageSizeProperty); | 
|         |    229 		} | 
|         |    230 	// ...server message size... | 
|         |    231 	TUint32 serverMessageSize = iNegotiatedCapInfo->GetServerMessageSize(); | 
|         |    232 	if( serverMessageSize != iClientCapInfo->GetServerMessageSize() ) | 
|         |    233 		{ | 
|         |    234 		// The server has reduced the server message size - update the return flag... | 
|         |    235 		capabilitiesReduced = ETrue; | 
|         |    236  | 
|         |    237 		// ...and the session property... | 
|         |    238 		THTTPHdrVal serverMessageSizeProperty = serverMessageSize; | 
|         |    239 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspCapServerMessageSize, RHTTPSession::GetTable()), serverMessageSizeProperty); | 
|         |    240 		} | 
|         |    241 	// ...method MOR... | 
|         |    242 	TUint32 methodMOR = iNegotiatedCapInfo->GetMethodMOR(); | 
|         |    243 	if( methodMOR != iClientCapInfo->GetMethodMOR() ) | 
|         |    244 		{ | 
|         |    245 		// The server has reduced the method MOR - update the return flag... | 
|         |    246 		capabilitiesReduced = ETrue; | 
|         |    247  | 
|         |    248 		// ...and the session property... | 
|         |    249 		THTTPHdrVal methodMORProperty = methodMOR; | 
|         |    250 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspCapMaxOutstandingRequests, RHTTPSession::GetTable()), methodMORProperty); | 
|         |    251 		} | 
|         |    252 	// Check the protocol options | 
|         |    253 	TUint8 protocolOptions = iNegotiatedCapInfo->GetProtocolOptions(); | 
|         |    254  | 
|         |    255 	// ...acknowledgements... | 
|         |    256 	if( (protocolOptions & EAcknowledgementHeaders) != (iClientCapInfo->GetProtocolOptions() & EAcknowledgementHeaders) ) | 
|         |    257 		{ | 
|         |    258 		// The server has cleared the use acknowledgement headers flag - update | 
|         |    259 		// the return flag... | 
|         |    260 		capabilitiesReduced = ETrue; | 
|         |    261  | 
|         |    262 		// ...and the session property... | 
|         |    263 		THTTPHdrVal notUsed = 0; | 
|         |    264 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspCapUseAcknowledgements, RHTTPSession::GetTable()), notUsed); | 
|         |    265 		} | 
|         |    266 	// ...suspend resume facility... | 
|         |    267 	if( (protocolOptions & ESessionResumeFacility) != (iClientCapInfo->GetProtocolOptions() & ESessionResumeFacility) ) | 
|         |    268 		{ | 
|         |    269 		// The server has cleared the support suspend/resume facility flag -  | 
|         |    270 		// update the return flag... | 
|         |    271 		capabilitiesReduced = ETrue; | 
|         |    272  | 
|         |    273 		// ...and the session property... | 
|         |    274 		THTTPHdrVal notUsed = 0; | 
|         |    275 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspCapSupportSuspendResume, RHTTPSession::GetTable()), notUsed); | 
|         |    276 		} | 
|         |    277  | 
|         |    278 	return capabilitiesReduced; | 
|         |    279 	} | 
|         |    280  | 
|         |    281 TBool CWspCOProtocolHandler::SupportSuspendResume() const | 
|         |    282 	{ | 
|         |    283 	return (iNegotiatedCapInfo->GetProtocolOptions() & ESessionResumeFacility); | 
|         |    284 	} | 
|         |    285  | 
|         |    286 TBool CWspCOProtocolHandler::CanResume() const | 
|         |    287 	{ | 
|         |    288 	TBool canResume = SupportSuspendResume(); | 
|         |    289  | 
|         |    290 	if( canResume && (iSessionState != EConnected && iSessionState != ESuspending && iSessionState != ESuspended) ) | 
|         |    291 		{ | 
|         |    292 		// In the wrong state | 
|         |    293 		canResume = EFalse; | 
|         |    294 		} | 
|         |    295 	return canResume; | 
|         |    296 	} | 
|         |    297  | 
|         |    298 TBool CWspCOProtocolHandler::CanSuspend() const | 
|         |    299 	{ | 
|         |    300 	TBool canSuspend = SupportSuspendResume(); | 
|         |    301  | 
|         |    302 	if( canSuspend && (iSessionState != EConnected && iSessionState != EResuming) ) | 
|         |    303 		{ | 
|         |    304 		// In the wrong state | 
|         |    305 		canSuspend = EFalse; | 
|         |    306 		} | 
|         |    307 	return canSuspend; | 
|         |    308 	} | 
|         |    309  | 
|         |    310 #if defined (_DEBUG) | 
|         |    311 void CWspCOProtocolHandler::ResetAll() | 
|         |    312 	{ | 
|         |    313 	// Delete helper objects and reset state | 
|         |    314 	delete iClientSessionHeaders; | 
|         |    315 	iClientSessionHeaders = NULL; | 
|         |    316 	//  | 
|         |    317 	if (iClientCapInfo) | 
|         |    318 		iClientCapInfo->Reset(); | 
|         |    319 	if (iNegotiatedCapInfo) | 
|         |    320 		iNegotiatedCapInfo->Reset(); | 
|         |    321 	if (iConnectionTimer) | 
|         |    322 		iConnectionTimer->Cancel(); | 
|         |    323 	if (iProxyInfoProvider) | 
|         |    324 		iProxyInfoProvider->ResetProxyInfo(); | 
|         |    325 	// | 
|         |    326 	iSessionState = ENull;  | 
|         |    327 	iTimedOutValue = 0; | 
|         |    328 	iConnectTimedOut = EFalse; | 
|         |    329 	iWaitingMethod  = EFalse; | 
|         |    330 	iDisconnectRequested = EFalse; | 
|         |    331 	iPendingCompletingMethods = 0; | 
|         |    332 	// | 
|         |    333 	// Reset the transport handler (stub only) | 
|         |    334 	iSessionInvoker->DisconnectReq((TWspReason)(-999)); | 
|         |    335 	} | 
|         |    336 #endif | 
|         |    337  | 
|         |    338 void CWspCOProtocolHandler::SessionConnectL() | 
|         |    339 	{ | 
|         |    340 	__ASSERT_DEBUG( iSessionState == ENull, Panic(KWspPanicSessionNotInValidState) ); | 
|         |    341  | 
|         |    342 	__LOG(_L("Initiating a session connect.")); | 
|         |    343  | 
|         |    344 	// Check for any client proposed capabilities | 
|         |    345 	CheckClientCapabilities(); | 
|         |    346  | 
|         |    347 	// Update the client session headers | 
|         |    348 	UpdateClientSessionHeadersL(); | 
|         |    349  | 
|         |    350 	// Update the proxy info | 
|         |    351 	iProxyInfoProvider->UpdateProxyInfoL(); | 
|         |    352  | 
|         |    353 	// Start connection timed-out timer | 
|         |    354 	iConnectionTimer->Start(iTimedOutValue); | 
|         |    355  | 
|         |    356 	// Send S-Connect.req primitive to transport handler | 
|         |    357 	__LOG(_L("---Sending S-Connect.req primitive.")); | 
|         |    358 	iSessionInvoker->ConnectReq(); | 
|         |    359  | 
|         |    360 	// Update session state | 
|         |    361 	__LOG(_L("---WSP Session in Connecting state.")); | 
|         |    362 	iSessionState = EConnecting; | 
|         |    363  | 
|         |    364 	// Check to see if there is a method transactions waiting. | 
|         |    365 	CheckWaitingMethod(); | 
|         |    366 	} | 
|         |    367  | 
|         |    368 void CWspCOProtocolHandler::SessionResumeL() | 
|         |    369 	{ | 
|         |    370 	__ASSERT_DEBUG( CanResume(), Panic(KWspPanicSessionNotInValidState) ); | 
|         |    371  | 
|         |    372 	__LOG(_L("Initiating a session resume.")); | 
|         |    373  | 
|         |    374 	// Check to see if the proxy info has not changed. | 
|         |    375 	if( iProxyInfoProvider->ProxyInfoChangedAndUpdateL() ) | 
|         |    376 		{ | 
|         |    377 		__LOG(_L("---Proxy has changed. Disconnect from the old proxy and connect to the new one.")); | 
|         |    378  | 
|         |    379 		// The client has specified a different - disconnect this session | 
|         |    380 		SessionDisconnect(EChangedProxyInSuspendedSession); | 
|         |    381 		} | 
|         |    382 	else | 
|         |    383 		{ | 
|         |    384 		// Check for any client proposed capabilities | 
|         |    385 		CheckClientCapabilities(); | 
|         |    386  | 
|         |    387 		// Update the client session headers | 
|         |    388 		UpdateClientSessionHeadersL(); | 
|         |    389  | 
|         |    390 		// Start connection timed-out timer | 
|         |    391 		iConnectionTimer->Start(iTimedOutValue); | 
|         |    392  | 
|         |    393 		// Send S-Resume.req primitive to transport handler | 
|         |    394 		__LOG(_L("---Sending S-Resume.req primitive.")); | 
|         |    395 		iSessionInvoker->ResumeReq(); | 
|         |    396  | 
|         |    397 		// Update session state | 
|         |    398 		__LOG(_L("---WSP Session in Resuming state.")); | 
|         |    399 		iSessionState = EResuming; | 
|         |    400  | 
|         |    401 		// Check to see if there is a method transactions waiting. | 
|         |    402 		CheckWaitingMethod(); | 
|         |    403 		} | 
|         |    404 	} | 
|         |    405  | 
|         |    406 void CWspCOProtocolHandler::SessionDisconnect(TWspReason aReason) | 
|         |    407 	{ | 
|         |    408 	__ASSERT_DEBUG( iSessionState != ENull && iSessionState != EClosing, Panic(KWspPanicSessionNotInValidState) ); | 
|         |    409  | 
|         |    410 	// Are there any methods waiting to send their final .res primitive | 
|         |    411 	if( iPendingCompletingMethods > 0 ) | 
|         |    412 		{ | 
|         |    413 		// Yep, need to wait until there are done. | 
|         |    414 		iDisconnectRequested = ETrue; | 
|         |    415 		return; | 
|         |    416 		} | 
|         |    417 	__LOG(_L("Disconnecting session.")); | 
|         |    418  | 
|         |    419 	// Need to cancel the connection timer | 
|         |    420 	iConnectionTimer->Cancel(); | 
|         |    421  | 
|         |    422 	// Send S-Disconnect.req primitive to transport handler | 
|         |    423 	__LOG1(_L("---Sending S-Disconnect.req primitive. Reason code : %d"), aReason); | 
|         |    424 	iSessionInvoker->DisconnectReq(aReason); | 
|         |    425  | 
|         |    426 	// Update session state | 
|         |    427 	__LOG(_L("---WSP Session in Closing state.")); | 
|         |    428 	iSessionState = EClosing; | 
|         |    429 	} | 
|         |    430  | 
|         |    431 void CWspCOProtocolHandler::SessionSuspend() | 
|         |    432 	{ | 
|         |    433 	__ASSERT_DEBUG( CanSuspend(), Panic(KWspPanicSessionNotInValidState) ); | 
|         |    434 	 | 
|         |    435 	// Are there any methods waiting to send their final .res primitive | 
|         |    436 	if( iPendingCompletingMethods > 0 ) | 
|         |    437 		{ | 
|         |    438 		// Yep, need to wait until there are done. | 
|         |    439 		iDisconnectRequested = ETrue; | 
|         |    440 		return; | 
|         |    441 		} | 
|         |    442 	__LOG(_L("Suspending session.")); | 
|         |    443  | 
|         |    444 	// Need to cancel the connection timer | 
|         |    445 	iConnectionTimer->Cancel(); | 
|         |    446  | 
|         |    447 	// Send S-Suspend.req primitive to transport handler | 
|         |    448 	__LOG(_L("---Sending S-Suspend.req primitive.")); | 
|         |    449 	iSessionInvoker->SuspendReq(); | 
|         |    450  | 
|         |    451 	// Update session state | 
|         |    452 	__LOG(_L("---WSP Session in Suspending state.")); | 
|         |    453 	iSessionState = ESuspending; | 
|         |    454 	} | 
|         |    455  | 
|         |    456 void CWspCOProtocolHandler::DoSessionConnectedL() | 
|         |    457 	{ | 
|         |    458 	// Cancel the connection timer | 
|         |    459 	iConnectionTimer->Cancel(); | 
|         |    460  | 
|         |    461 	// Check for the Encoding-Version header in the server session headers | 
|         |    462  	RHTTPHeaders headers = iSession.ResponseSessionHeadersL(); | 
|         |    463  	THTTPHdrVal negotiatedVersion; | 
|         |    464  	TInt err = headers.GetField( | 
|         |    465  							   iSession.StringPool().StringF(WSP::EEncodingVersion, WSP::Table), | 
|         |    466  							   0,		// Zero index -> first part | 
|         |    467  							   negotiatedVersion | 
|         |    468  							   ); | 
|         |    469 	 | 
|         |    470 	// Default version is 1.2 - this is the case if the header is missing. | 
|         |    471  	CWspHeaderCodec::TWspVersion version = CWspHeaderCodec::EVersion1_2; | 
|         |    472  | 
|         |    473 	if( (err != KErrNotFound) && (negotiatedVersion.Type() == THTTPHdrVal::KStrFVal) ) | 
|         |    474  		{ | 
|         |    475  		// Check what version the encoding is and set it accordingly in the codec | 
|         |    476 		switch(negotiatedVersion.StrF().Index(WSPStdConstants::Table) ) | 
|         |    477 			{ | 
|         |    478 			case WSPStdConstants::EWspVersion11: | 
|         |    479 				version = CWspHeaderCodec::EVersion1_1; | 
|         |    480 				break; | 
|         |    481 			case WSPStdConstants::EWspVersion13: | 
|         |    482 				version = CWspHeaderCodec::EVersion1_3; | 
|         |    483 				break; | 
|         |    484 			case WSPStdConstants::EWspVersion14: | 
|         |    485 				version = CWspHeaderCodec::EVersion1_4; | 
|         |    486 				break; | 
|         |    487 			default: | 
|         |    488 				// If the version is 1.2 or anything else, stay at 1.2 | 
|         |    489 				break; | 
|         |    490 			} | 
|         |    491  		} | 
|         |    492 	// Set the encoding value in the codec | 
|         |    493 	STATIC_CAST(CWspHeaderCodec*, iCodec)->SetWspVersion(version); | 
|         |    494  | 
|         |    495 	// Inform client that the session is connected - check negotiated capabilities | 
|         |    496 	THTTPSessionEvent connectEvent = THTTPSessionEvent::EConnectedOK; | 
|         |    497  | 
|         |    498 	// Check the negotiated capabilities | 
|         |    499  	TBool capabilitiesReduced = UpdateNegotiatedCapabilitiesL(); | 
|         |    500  | 
|         |    501 	if( capabilitiesReduced ) | 
|         |    502 		{ | 
|         |    503 		// At least one of the proposed client capabilities has been negotiated  | 
|         |    504 		// down or rejected - need to inform client of this event. | 
|         |    505 		connectEvent = THTTPSessionEvent::EConnectedWithReducedCapabilities; | 
|         |    506 		} | 
|         |    507 	SendSessionEvent(connectEvent); | 
|         |    508  | 
|         |    509 	// WSP session is connected - update state | 
|         |    510 	__LOG(_L("---WSP Session in Connected state")); | 
|         |    511 	iSessionState = EConnected; | 
|         |    512 	} | 
|         |    513  | 
|         |    514 void CWspCOProtocolHandler::SendSessionEvent(THTTPSessionEvent aEvent) | 
|         |    515 	{ | 
|         |    516 	// Send the event to the client - need to TRAPD | 
|         |    517 	TRAPD(error, iSession.SendSessionEventL(aEvent, THTTPSessionEvent::EIncoming, THTTPFilterHandle::EProtocolHandler)); | 
|         |    518 	if( error != KErrNone ) | 
|         |    519 		{ | 
|         |    520 		__LOG1(_L("Error - Could not send event to the client, error code %d"), error); | 
|         |    521 		iSession.FailSessionEvent(THTTPFilterHandle::EProtocolHandler); | 
|         |    522 		} | 
|         |    523 	} | 
|         |    524  | 
|         |    525 void CWspCOProtocolHandler::UpdateClientSessionHeadersL() | 
|         |    526 	{ | 
|         |    527 	// Check for Encoding-Version header | 
|         |    528 	RStringPool stringPool = iSession.StringPool(); | 
|         |    529 	RHTTPHeaders headers = iSession.RequestSessionHeadersL(); | 
|         |    530 	THTTPHdrVal version; | 
|         |    531 	RStringF encodingVersionField = stringPool.StringF(WSP::EEncodingVersion, WSP::Table); | 
|         |    532 	TInt err = headers.GetField(encodingVersionField, 0 /* Zero index -> first part*/, version); | 
|         |    533 	TBool foundHeader = EFalse; | 
|         |    534  | 
|         |    535 	// If the encoding-version header exists, check that it is valid | 
|         |    536 	if( err == KErrNone ) | 
|         |    537 		{ | 
|         |    538 		if( version.Type() == THTTPHdrVal::KStrFVal ) | 
|         |    539 			{ | 
|         |    540 			switch( version.StrF().Index(WSPStdConstants::Table) ) | 
|         |    541 				{ | 
|         |    542 				case WSPStdConstants::EWspVersion11: | 
|         |    543 				case WSPStdConstants::EWspVersion12: | 
|         |    544 				case WSPStdConstants::EWspVersion13: | 
|         |    545 				case WSPStdConstants::EWspVersion14: | 
|         |    546 					foundHeader = ETrue; | 
|         |    547 					break; | 
|         |    548 				default: | 
|         |    549 					break; | 
|         |    550 				} | 
|         |    551 			} | 
|         |    552 		} | 
|         |    553  | 
|         |    554 	// If the header is not found or is invalid, then use WSP encoding v1.4 | 
|         |    555 	if(!foundHeader) | 
|         |    556 		{ | 
|         |    557 		// Remove existing header first if its invalid, this won't do anything if it doesn't exist | 
|         |    558 		headers.RemoveField(encodingVersionField); | 
|         |    559 		THTTPHdrVal encodingVersionValue(stringPool.StringF(WSPStdConstants::EWspVersion14, WSPStdConstants::Table)); | 
|         |    560 		headers.SetFieldL(encodingVersionField, encodingVersionValue); | 
|         |    561 		__LOG(_L("---Updated WSP encoding version request to 1.4")); | 
|         |    562 		} | 
|         |    563  | 
|         |    564    	// Encode the headers... | 
|         |    565 	HBufC8* buf = iHdrUtils->EncodeHeadersL(stringPool, headers); | 
|         |    566  | 
|         |    567 	// Update the client session headers buffer; | 
|         |    568 	delete iClientSessionHeaders; | 
|         |    569 	iClientSessionHeaders = buf; | 
|         |    570 	} | 
|         |    571  | 
|         |    572 void CWspCOProtocolHandler::HandleConnectRequestL() | 
|         |    573 	{ | 
|         |    574 	// Check the WSP session state | 
|         |    575 	switch( iSessionState ) | 
|         |    576 		{ | 
|         |    577 	case ENull: | 
|         |    578 		{ | 
|         |    579 		// Initiate a session connect | 
|         |    580 		SessionConnectL(); | 
|         |    581 		} break; | 
|         |    582 	case ESuspended: | 
|         |    583 	case ESuspending: | 
|         |    584 		{ | 
|         |    585 		// In suspending or suspended state - this implies that the WSP  | 
|         |    586 		// session supports the Suspend Resume facility and was suspended  | 
|         |    587 		// rather than disconnected for a more efficient re-connection. | 
|         |    588  | 
|         |    589 		// Initiate a session resume | 
|         |    590 		SessionResumeL(); | 
|         |    591 		} break; | 
|         |    592 	case EConnecting: | 
|         |    593 	case EResuming: | 
|         |    594 		{ | 
|         |    595 		// A connect request has already been sent - inform the client | 
|         |    596 		SendSessionEvent(THTTPSessionEvent::EAlreadyConnecting); | 
|         |    597 		} break; | 
|         |    598 	case EConnected: | 
|         |    599 		{ | 
|         |    600 		// A connect request has already been sent and the session is  | 
|         |    601 		// connected - inform the client | 
|         |    602 		SendSessionEvent(THTTPSessionEvent::EAlreadyConnected); | 
|         |    603 		} break; | 
|         |    604 	case EClosing: | 
|         |    605 		{ | 
|         |    606 		// A disconnect request has already been sent - inform the client | 
|         |    607 		SendSessionEvent(THTTPSessionEvent::EAlreadyDisconnecting); | 
|         |    608 		} break; | 
|         |    609 	default: | 
|         |    610 		Panic(KWspPanicIllegalSessionState); | 
|         |    611 		break; | 
|         |    612 		} | 
|         |    613 	} | 
|         |    614  | 
|         |    615 void CWspCOProtocolHandler::HandleDisconnectRequest() | 
|         |    616 	{ | 
|         |    617 	// Disconnect has been requestd. Action depends of the WSP session state. | 
|         |    618 	switch( iSessionState ) | 
|         |    619 		{ | 
|         |    620 	case ENull: | 
|         |    621 	case ESuspended: | 
|         |    622 		{ | 
|         |    623 		// A disconnect request has already been fulfilled - inform the client | 
|         |    624 		SendSessionEvent(THTTPSessionEvent::EAlreadyDisconnected); | 
|         |    625 		} break; | 
|         |    626 	case EClosing: | 
|         |    627 	case ESuspending: | 
|         |    628 		{ | 
|         |    629 		// A disconnect request has already been sent - inform the client | 
|         |    630 		SendSessionEvent(THTTPSessionEvent::EAlreadyDisconnecting); | 
|         |    631 		} break; | 
|         |    632 	case EConnecting: | 
|         |    633 		{ | 
|         |    634 		// The WSP session is in the Connecting state, then the session should be | 
|         |    635 		// disconnected - do SessionDisconnect. This will issue the  | 
|         |    636 		// S-Disconnect.req primitive and tell the transport handler to stop the  | 
|         |    637 		// connection. The transport handler will send the S-Disconnect.ind  | 
|         |    638 		// primitive which results in the client being notified. | 
|         |    639 		SessionDisconnect(EUserReq); | 
|         |    640 		} break; | 
|         |    641 	case EResuming: | 
|         |    642 		{ | 
|         |    643 		// If the WSP session is resuming, then the Suspend Resume facility is | 
|         |    644 		// supported - can suspend the WSP session. This will issue the  | 
|         |    645 		// S-Suspend.req primitive and tell the transport handler to stop the  | 
|         |    646 		// session resume. The transport handler will send the S-Suspend.ind  | 
|         |    647 		// primitive to the protocol handler who will then inform the client. | 
|         |    648 		SessionSuspend(); | 
|         |    649 		} break; | 
|         |    650 	case EConnected: | 
|         |    651 		{ | 
|         |    652 		// Check if the Suspend Resume facility is supported. If so, then  | 
|         |    653 		// suspend the WSP session, rather then disconnect it. | 
|         |    654 		if( SupportSuspendResume() ) | 
|         |    655 			{ | 
|         |    656 			// Suspend the WSP session | 
|         |    657 			SessionSuspend(); | 
|         |    658 			} | 
|         |    659 		else | 
|         |    660 			{ | 
|         |    661 			// Disconnect the WSP session | 
|         |    662 			SessionDisconnect(EUserReq); | 
|         |    663 			} | 
|         |    664 		} break; | 
|         |    665 	default: | 
|         |    666 		Panic(KWspPanicIllegalSessionState); | 
|         |    667 		break; | 
|         |    668 		} | 
|         |    669 	} | 
|         |    670  | 
|         |    671 void CWspCOProtocolHandler::CheckWaitingMethod() | 
|         |    672 	{ | 
|         |    673 	if( iWaitingMethod ) | 
|         |    674 		{ | 
|         |    675 		// Self-complete the base class - this will start servicing the pending | 
|         |    676 		// transaction. | 
|         |    677 		CompleteSelf(); | 
|         |    678  | 
|         |    679 		// Clear the flag | 
|         |    680 		iWaitingMethod = EFalse; | 
|         |    681 		} | 
|         |    682 	} | 
|         |    683  | 
|         |    684 /* | 
|         |    685  * Methods from CProtocolHandler | 
|         |    686  */ | 
|         |    687  | 
|         |    688 void CWspCOProtocolHandler::CreateCodecL() | 
|         |    689 	{ | 
|         |    690 	iCodec = CWspHeaderCodec::NewL(iSession.StringPool(), WSP::Table); | 
|         |    691 	} | 
|         |    692  | 
|         |    693 CProtTransaction* CWspCOProtocolHandler::CreateProtTransactionL(RHTTPTransaction aTransaction) | 
|         |    694 	{ | 
|         |    695 	return CWspCOTransaction::NewL(aTransaction, iTransportHandler->COTransactionInvoker(), *iNegotiatedCapInfo, *this, *iHdrUtils); | 
|         |    696 	} | 
|         |    697  | 
|         |    698 TBool CWspCOProtocolHandler::ServiceL(CProtTransaction& aTrans) | 
|         |    699 	{ | 
|         |    700 	__LOG(_L("Attempting to invoke request.")); | 
|         |    701  | 
|         |    702 	// Check the WSP session state | 
|         |    703 	if( iSessionState == EClosing || iSessionState == ESuspending ) | 
|         |    704 		{ | 
|         |    705 		__LOG(_L("---Session is Closing or Suspending - cannot invoke methods.")); | 
|         |    706  | 
|         |    707 		// The WSP session is either disconnecting or suspending - leave | 
|         |    708 		User::Leave(KWspErrSessionClosingOrSuspending); | 
|         |    709 		} | 
|         |    710 	if( iSessionState == ENull || iSessionState == ESuspended ) | 
|         |    711 		{ | 
|         |    712 		__LOG(_L("---Session is Null or Suspended - cannot invoke methods. Wait for session connect initiation.")); | 
|         |    713 		 | 
|         |    714 		// Send back an event saying that session is not connected yet | 
|         |    715 		SendSessionEvent(THTTPSessionEvent::ENotConnected); | 
|         |    716  | 
|         |    717 		// Set a flag to indicate that there is a transaction waiting to be  | 
|         |    718 		// serviced - need to self-complete once connected. | 
|         |    719 		iWaitingMethod = ETrue; | 
|         |    720  | 
|         |    721 		//  Cannot service the method transaction now. | 
|         |    722 		return EFalse; | 
|         |    723 		} | 
|         |    724 	// Check to see if the method MOR has been reached. | 
|         |    725 	TUint32 activeTransactions = NumActiveTransactions(); | 
|         |    726 	if( activeTransactions == iNegotiatedCapInfo->GetMethodMOR() ) | 
|         |    727 		{ | 
|         |    728 		__LOG1(_L("---Have reached method MOR (=%d) - cannot invoke request."), iNegotiatedCapInfo->GetMethodMOR()); | 
|         |    729  | 
|         |    730 		// Have reached the method MOR - cannot service this method transaction. | 
|         |    731 		return EFalse; | 
|         |    732 		} | 
|         |    733 	// Have not yet reached the negotiated method MOR - can service this  | 
|         |    734 	// transaction. | 
|         |    735  | 
|         |    736 	// Create the Tx Data object for this transaction | 
|         |    737 	aTrans.CreateTxDataL(); | 
|         |    738  | 
|         |    739 	// Do the method invocation | 
|         |    740 	STATIC_CAST(CWspCOTransaction&, aTrans).InitRequestL(); | 
|         |    741  | 
|         |    742 	__LOG1(_L("---Initiated request - trans %d is active"), aTrans.Transaction().Id() ); | 
|         |    743  | 
|         |    744 	return ETrue; | 
|         |    745 	} | 
|         |    746  | 
|         |    747 void CWspCOProtocolHandler::ClosedTransactionHook(CProtTransaction* aTrans) | 
|         |    748 	{ | 
|         |    749 	__LOG1(_L("Trans %d has been closed"), aTrans->Transaction().Id() ); | 
|         |    750  | 
|         |    751 	// Down-cast the CProtTransaction | 
|         |    752 	CWspCOTransaction& wspTransaction = *STATIC_CAST(CWspCOTransaction*, aTrans); | 
|         |    753  | 
|         |    754 	// Abort this transaction | 
|         |    755 	wspTransaction.AbortRequest(); | 
|         |    756  | 
|         |    757 	// Tell the method transaction to suicide - the transaction will ensure that  | 
|         |    758 	// it deletes itself at the appropriate time. | 
|         |    759 	wspTransaction.Suicide(); | 
|         |    760 	} | 
|         |    761  | 
|         |    762 void CWspCOProtocolHandler::CancelTransactionHook(CProtTransaction& aTransaction) | 
|         |    763 	{ | 
|         |    764 	__LOG1(_L("Trans %d has been cancelled"), aTransaction.Transaction().Id() ); | 
|         |    765  | 
|         |    766 	// Abort this transaction | 
|         |    767 	STATIC_CAST(CWspCOTransaction&, aTransaction).AbortRequest(); | 
|         |    768 	} | 
|         |    769  | 
|         |    770 void CWspCOProtocolHandler::NotifyNewRequestBodyPart(CProtTransaction& aTransaction) | 
|         |    771 	{ | 
|         |    772 	__LOG(_L("Client has more request data...")); | 
|         |    773  | 
|         |    774 	// Send the S-MethodInvokeData primitive | 
|         |    775 	STATIC_CAST(CWspCOTransaction&, aTransaction).NotifyMoreRequestData(); | 
|         |    776 	} | 
|         |    777  | 
|         |    778 void CWspCOProtocolHandler::GetInterfaceL(TUid aInterfaceId, MProtHandlerInterface*& aInterfacePtr) | 
|         |    779 	{ | 
|         |    780 	switch(aInterfaceId.iUid) | 
|         |    781 		{ | 
|         |    782 	case KProtHandlerSessionServerCertUid: | 
|         |    783 		{ | 
|         |    784 		aInterfacePtr = this; | 
|         |    785 		break; | 
|         |    786 		} | 
|         |    787 	default: | 
|         |    788 		{ | 
|         |    789 		CProtocolHandler::GetInterfaceL(aInterfaceId, aInterfacePtr); | 
|         |    790 		break; | 
|         |    791 		} | 
|         |    792 		} | 
|         |    793 	} | 
|         |    794  | 
|         |    795 /* | 
|         |    796  * Methods from MHTTPFilterBase | 
|         |    797  */ | 
|         |    798  | 
|         |    799 void CWspCOProtocolHandler::MHFSessionRunL(const THTTPSessionEvent& aEvent) | 
|         |    800 	{ | 
|         |    801 	__ASSERT_DEBUG( iTransportHandler, Panic(KWspPanicTransportHandlerDoesNotExist) ); | 
|         |    802  | 
|         |    803 	// Check the session event | 
|         |    804 	switch(aEvent.iStatus) | 
|         |    805 		{ | 
|         |    806 	case THTTPSessionEvent::EConnect: | 
|         |    807 		{ | 
|         |    808 		__LOG(_L("Processing EConnect session event")); | 
|         |    809  | 
|         |    810 		// Handle the connect request | 
|         |    811 		HandleConnectRequestL(); | 
|         |    812 		} break; | 
|         |    813 	case THTTPSessionEvent::EDisconnect: | 
|         |    814 		{ | 
|         |    815 		__LOG(_L("Processing EDisconnect session event")); | 
|         |    816  | 
|         |    817 		// Handle the disconnect request | 
|         |    818 		HandleDisconnectRequest(); | 
|         |    819 		} break; | 
|         |    820 #if defined (_DEBUG) | 
|         |    821 	case -999: | 
|         |    822 		{ | 
|         |    823 		// This unpublished value is used in testing to cause a whole protocol | 
|         |    824 		// handler reset and to reset the transport handler. It should be used with caution! | 
|         |    825 		__LOG(_L("PROTOCOL HANDLER RESETTING!")); | 
|         |    826 		ResetAll(); | 
|         |    827  | 
|         |    828 		// Ack the owner | 
|         |    829 		SendSessionEvent(-999); | 
|         |    830 		} break; | 
|         |    831 #endif | 
|         |    832 	default: | 
|         |    833 		// Ignore the unknown session event. | 
|         |    834 		__LOG1(_L("Received unknown session event : %d"), aEvent.iStatus); | 
|         |    835 		break; | 
|         |    836 		} | 
|         |    837 	} | 
|         |    838  | 
|         |    839 TInt CWspCOProtocolHandler::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/) | 
|         |    840 	{ | 
|         |    841 	// Send the error as a session event. | 
|         |    842 	SendSessionEvent(aError); | 
|         |    843 	return KErrNone; | 
|         |    844 	} | 
|         |    845  | 
|         |    846 /* | 
|         |    847  * Methods from MWspCOSessionCallback | 
|         |    848  */ | 
|         |    849  | 
|         |    850 void CWspCOProtocolHandler::ConnectCnf() | 
|         |    851 	{ | 
|         |    852 	__LOG(_L("Received S-Connect.cnf primitive")); | 
|         |    853  | 
|         |    854 	// Did we connect to a secure proxy?  If so, send the 'authenticated OK' session event | 
|         |    855 	MWspProxyInfoProvider& proxyInfo = STATIC_CAST(MWspProxyInfoProvider&, *iProxyInfoProvider); | 
|         |    856 	if( proxyInfo.SecureConnection() ) | 
|         |    857 		{ | 
|         |    858 		__LOG(_L("---WTLS authentication was successful.")); | 
|         |    859  | 
|         |    860 		// Send EAuthenticatedOK event... | 
|         |    861 		SendSessionEvent(THTTPSessionEvent::EAuthenticatedOK); | 
|         |    862 		} | 
|         |    863  | 
|         |    864 	// Process the session connected event | 
|         |    865 	DoSessionConnected(); | 
|         |    866 	} | 
|         |    867  | 
|         |    868 void CWspCOProtocolHandler::ResumeCnf() | 
|         |    869 	{ | 
|         |    870 	__LOG(_L("Received S-Resume.cnf primitive")); | 
|         |    871  | 
|         |    872 	// Process the session connected event | 
|         |    873 	DoSessionConnected(); | 
|         |    874 	} | 
|         |    875  | 
|         |    876 void CWspCOProtocolHandler::DoSessionConnected() | 
|         |    877 	{ | 
|         |    878 	// Process the session connected event | 
|         |    879 	TRAPD(error, DoSessionConnectedL()); | 
|         |    880  	if( error != KErrNone ) | 
|         |    881  		{ | 
|         |    882  		__LOG(_L("Error - Could not process S-Connect.cnf/S-Resume.cnf. Disconnect the WSP session.")); | 
|         |    883   | 
|         |    884  		// Disconnect this session | 
|         |    885  		SessionDisconnect(EPeerReq); | 
|         |    886  		} | 
|         |    887 	} | 
|         |    888  | 
|         |    889 void CWspCOProtocolHandler::DisconnectInd(TWspReason					aReason,  | 
|         |    890 										  TBool							/*aRedirectSecurity*/,  | 
|         |    891 										  TWspRedirectedAddress&		aRedirectAddress,  | 
|         |    892 										  const TDesC8&					/*aErrorHeader*/,  | 
|         |    893 										  const TDesC8&					/*aErrorBody*/) | 
|         |    894 	{ | 
|         |    895 	__ASSERT_DEBUG( NumActiveTransactions() == 0, Panic(KWspPanicMethodsStillOutstanding) ); | 
|         |    896  | 
|         |    897 	__LOG(_L("Received S-Disconnect.ind primitive")); | 
|         |    898 	__LOG1(_L("---Reason code : %d"), aReason); | 
|         |    899  | 
|         |    900 	// Cancel the connection timer | 
|         |    901 	iConnectionTimer->Cancel(); | 
|         |    902  | 
|         |    903 	// Check the reason for the disconnect | 
|         |    904 	switch( aReason ) | 
|         |    905 		{ | 
|         |    906 	case EPermanentRedirectedProxy: | 
|         |    907 		{ | 
|         |    908 		__LOG(_L("---Permanent proxy redirection")); | 
|         |    909  | 
|         |    910 		// Update the proxy info with the redirected proxy addresses. This will | 
|         |    911 		// place the new address in the EWspProxyAddress session property. | 
|         |    912 		TRAPD(error, iProxyInfoProvider->SetPermanentRedirectedProxyL(aRedirectAddress) ); | 
|         |    913  | 
|         |    914 		if( error != KErrNone ) | 
|         |    915 			{ | 
|         |    916 			// Something went wrong - just disconnect | 
|         |    917 			SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |    918 			} | 
|         |    919 		else | 
|         |    920 			{ | 
|         |    921 			// Need to inform client that the proxy has been redirected permanently. | 
|         |    922 			SendSessionEvent(THTTPSessionEvent::ERedirected); | 
|         |    923  | 
|         |    924 			// Send the S-Connect primitive | 
|         |    925 			iPrimitiveSender->InitiateSend(ESConnect); | 
|         |    926 			} | 
|         |    927 		} break; | 
|         |    928 	case ETemporaryRedirectedProxy: | 
|         |    929 		{ | 
|         |    930 		__LOG(_L("---Temporary proxy redirection")); | 
|         |    931  | 
|         |    932 		// Update the proxy info with the redirected proxy addresses. | 
|         |    933 		TRAPD(error, iProxyInfoProvider->SetTemporaryRedirectedProxyL(aRedirectAddress) );; | 
|         |    934  | 
|         |    935 		if( error != KErrNone ) | 
|         |    936 			{ | 
|         |    937 			// Something went wrong - just disconnect | 
|         |    938 			SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |    939 			} | 
|         |    940 		else | 
|         |    941 			{ | 
|         |    942 			// Send the S-Connect primitive | 
|         |    943 			iPrimitiveSender->InitiateSend(ESConnect); | 
|         |    944 			} | 
|         |    945 		} break; | 
|         |    946 	case EChangedProxyInSuspendedSession: | 
|         |    947 		{ | 
|         |    948 		__LOG(_L("---Client changed proxy whilst suspended")); | 
|         |    949 		__LOG(_L("---Forced disconnect, then connection to new proxy")); | 
|         |    950  | 
|         |    951 		// The client had disconnected the session (resulting in the session | 
|         |    952 		// being suspended) and then did a connect, but with a different  | 
|         |    953 		// proxy. This resulted in the suspended session being disconnected. | 
|         |    954 		// Now need to initiate a session connect to the new proxy. | 
|         |    955 		iPrimitiveSender->InitiateSend(ESConnect); | 
|         |    956 		} break; | 
|         |    957 	case EWtlsConfigurationFailed: | 
|         |    958 	case EWtlsPhase1HandshakeFailed: | 
|         |    959 	case EWtlsPhase2HandshakeFailed: | 
|         |    960 	case EWtlsInvalidServerCert: | 
|         |    961 	case EWtlsUntrustedServerCert: | 
|         |    962 	case EWtlsNegotiatedConfigRejected: | 
|         |    963 		{ | 
|         |    964 		__LOG(_L("---WTLS handshake failure")); | 
|         |    965  | 
|         |    966 		// Various failure modes for the WTLS handshake.  All result in a | 
|         |    967 		// 'authentication failure' event being sent to the client, followed by | 
|         |    968 		// a 'disconnected' event. | 
|         |    969 		SendSessionEvent(THTTPSessionEvent::EAuthenticationFailure); | 
|         |    970 		SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |    971 		} break; | 
|         |    972 	case EOutOfMemory: | 
|         |    973 		{ | 
|         |    974 		// There was a memory allocation failure in the transport handler - inform | 
|         |    975 		// the client. | 
|         |    976 		SendSessionEvent(KErrNoMemory); | 
|         |    977  | 
|         |    978 		// Inform the client that the sesion is disconnected | 
|         |    979 		SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |    980 		} break; | 
|         |    981 	case ESessionStateFailure: | 
|         |    982 		{ | 
|         |    983 		// The session is effectively disconnected | 
|         |    984 		SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |    985  | 
|         |    986 		// The transport handler has entered an invalid or indeterminate state - possibly due | 
|         |    987 		// to a memory allocation failure - the session is no longer valid and should be | 
|         |    988 		// discontinued by the client - inform the client. | 
|         |    989 		__LOG(_L("Transport Handler has signalled a session state failure")); | 
|         |    990 		iSession.FailSessionEvent(THTTPFilterHandle::EProtocolHandler); | 
|         |    991 		} break; | 
|         |    992 	case EUserReq: | 
|         |    993 		{ | 
|         |    994 		// This is ind to a S-Disconnect.req. Was it due to a connect time-out? | 
|         |    995 		if( iConnectTimedOut ) | 
|         |    996 			{ | 
|         |    997 			__LOG(_L("---Connection has timed-out")); | 
|         |    998  | 
|         |    999 			// Inform the client that the resume timed-out | 
|         |   1000 			SendSessionEvent(THTTPSessionEvent::EConnectionTimedOut); | 
|         |   1001 			iConnectTimedOut = EFalse; | 
|         |   1002 			break; | 
|         |   1003 			} | 
|         |   1004 		// Drop-through if there was no connect time-out | 
|         |   1005 		}  | 
|         |   1006 	default: | 
|         |   1007 		// Session disconnected for some other reason. Inform the client, but  | 
|         |   1008 		// ignore the information in aErrorHeader and aErrorBody. The WSP  | 
|         |   1009 		// Specification states that the provider MAY choose not to communicate | 
|         |   1010 		// this information - the protocol handler is making that choice!! | 
|         |   1011 		SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |   1012 		break; | 
|         |   1013 		} | 
|         |   1014 	// WSP session is disconnected - update state | 
|         |   1015 	__LOG(_L("---WSP Session in Null state")); | 
|         |   1016 	iSessionState = ENull; | 
|         |   1017 	} | 
|         |   1018  | 
|         |   1019 void CWspCOProtocolHandler::SuspendInd(TWspReason /*aReason*/) | 
|         |   1020 	{ | 
|         |   1021 	__ASSERT_DEBUG( NumActiveTransactions() == 0, Panic(KWspPanicMethodsStillOutstanding) ); | 
|         |   1022  | 
|         |   1023 	__LOG(_L("Received S-Suspend.ind primitive")); | 
|         |   1024  | 
|         |   1025 	// Do not care about the reason, just inform the client. First check if this | 
|         |   1026 	// suspend is the result of a session resume timed-out. | 
|         |   1027 	if( iConnectTimedOut ) | 
|         |   1028 		{ | 
|         |   1029 		__LOG(_L("---Resume has timed-out")); | 
|         |   1030  | 
|         |   1031 		// Inform the client that the resume timed-out | 
|         |   1032 		SendSessionEvent(THTTPSessionEvent::EConnectionTimedOut); | 
|         |   1033 		iConnectTimedOut = EFalse; | 
|         |   1034 		} | 
|         |   1035 	else | 
|         |   1036 		{ | 
|         |   1037 		// Inform the client that the session is disconnected - this event is  | 
|         |   1038 		// sent as the the client does not understand suspend/resume and the  | 
|         |   1039 		// Suspend Resume facility is being used for efficiency. | 
|         |   1040 		SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |   1041 		} | 
|         |   1042 	// WSP session is suspended - update state | 
|         |   1043 	__LOG(_L("---WSP Session in Suspended state")); | 
|         |   1044 	iSessionState = ESuspended; | 
|         |   1045 	} | 
|         |   1046  | 
|         |   1047 void CWspCOProtocolHandler::ExceptionInd(const TDesC8& aExceptionData) | 
|         |   1048 	{ | 
|         |   1049 	RStringPool stringPool = iSession.StringPool(); | 
|         |   1050  | 
|         |   1051 	// Generic handling for exception data | 
|         |   1052 	__LOG(_L("Have received exception information.")); | 
|         |   1053  | 
|         |   1054 	// Add the exception data as the EWspProxyExceptionInfo property | 
|         |   1055 	RHTTPConnectionInfo	connInfo = iSession.ConnectionInfo(); | 
|         |   1056 	TRAP_IGNORE( | 
|         |   1057 		RStringF exceptionData = stringPool.OpenFStringL(aExceptionData); | 
|         |   1058 		CleanupClosePushL(exceptionData); | 
|         |   1059 		THTTPHdrVal exceptionProperty = exceptionData; | 
|         |   1060 		connInfo.SetPropertyL(stringPool.StringF(HTTP::EWspProxyExceptionInfo, RHTTPSession::GetTable()), exceptionProperty); | 
|         |   1061 		CleanupStack::PopAndDestroy(&exceptionData); | 
|         |   1062 		); | 
|         |   1063 	 | 
|         |   1064 	// Send the exception info event | 
|         |   1065 	SendSessionEvent(THTTPSessionEvent::EExceptionInfo); | 
|         |   1066 	} | 
|         |   1067  | 
|         |   1068 /* | 
|         |   1069  * Methods from MWspCapabilityInfoProvider | 
|         |   1070  */ | 
|         |   1071  | 
|         |   1072 const MWspCapabilityViewer& CWspCOProtocolHandler::ClientCapabilities() const | 
|         |   1073 	{ | 
|         |   1074 	return *iClientCapInfo; | 
|         |   1075 	} | 
|         |   1076  | 
|         |   1077 MWspCapabilitySetter& CWspCOProtocolHandler::ServerCapabilities() const | 
|         |   1078 	{ | 
|         |   1079 	return *iNegotiatedCapInfo; | 
|         |   1080 	} | 
|         |   1081  | 
|         |   1082 /* | 
|         |   1083  * Methods from MWspSessionHeadersProvider | 
|         |   1084  */ | 
|         |   1085  | 
|         |   1086 const TDesC8& CWspCOProtocolHandler::ClientHeaders() const | 
|         |   1087 	{ | 
|         |   1088 	return *iClientSessionHeaders; | 
|         |   1089 	} | 
|         |   1090  | 
|         |   1091 void CWspCOProtocolHandler::SetServerHeadersL(const TDesC8& aBuffer) | 
|         |   1092 	{ | 
|         |   1093 	RHTTPHeaders serverHeaders = iSession.ResponseSessionHeadersL(); | 
|         |   1094 	iHdrUtils->DecodeHeadersL(iSession.StringPool(), aBuffer, serverHeaders); | 
|         |   1095 	} | 
|         |   1096  | 
|         |   1097 /* | 
|         |   1098  *	Methods from MConnectionTimerCallback | 
|         |   1099  */ | 
|         |   1100  | 
|         |   1101 void CWspCOProtocolHandler::HandleConnectionTimedOut() | 
|         |   1102 	{ | 
|         |   1103 	__LOG(_L("Connection timed-out - appropriate action taken")); | 
|         |   1104  | 
|         |   1105 	// The connection has timed-out - flag | 
|         |   1106 	iConnectTimedOut = ETrue; | 
|         |   1107  | 
|         |   1108 	// Request a disconnect.  | 
|         |   1109 	HandleDisconnectRequest(); | 
|         |   1110 	} | 
|         |   1111  | 
|         |   1112 /* | 
|         |   1113  * Methods from MWspPrimitiveSenderCallback | 
|         |   1114  */ | 
|         |   1115  | 
|         |   1116 void CWspCOProtocolHandler::SendPrimitiveL(TWspPrimitive aPrimitive) | 
|         |   1117 	{ | 
|         |   1118 	// Check that the primitive is one that is supported | 
|         |   1119 	switch( aPrimitive ) | 
|         |   1120 		{ | 
|         |   1121 	case ESConnect: | 
|         |   1122 		{ | 
|         |   1123 		SessionConnectL(); | 
|         |   1124 		} break; | 
|         |   1125 	case ESDisconnect: | 
|         |   1126 	case ESSuspend: | 
|         |   1127 		{ | 
|         |   1128 		HandleDisconnectRequest(); | 
|         |   1129 		} break; | 
|         |   1130 	default: | 
|         |   1131 		// Unsupported primitive | 
|         |   1132 		User::Leave(KWspErrUnsupportedSendPrimitive); | 
|         |   1133 		break; | 
|         |   1134 		} | 
|         |   1135 	} | 
|         |   1136  | 
|         |   1137 TInt CWspCOProtocolHandler::WspPrimitiveSenderCallbackError(TInt /*aError*/) | 
|         |   1138 	{ | 
|         |   1139 	// The initiate session connect has failed. Need to unlock the proxy info. | 
|         |   1140 	iProxyInfoProvider->UnlockProxyInfo(); | 
|         |   1141  | 
|         |   1142 	// Inform the client - send disconnected signal | 
|         |   1143 	SendSessionEvent(THTTPSessionEvent::EDisconnected); | 
|         |   1144  | 
|         |   1145 	return KErrNone; | 
|         |   1146 	} | 
|         |   1147  | 
|         |   1148 /* | 
|         |   1149  * Methods from MWspCOMethodObserver | 
|         |   1150  */ | 
|         |   1151  | 
|         |   1152 void CWspCOProtocolHandler::HandleMethodAbort(CWspCOTransaction& aTransaction) | 
|         |   1153 	{ | 
|         |   1154 	// The CWspCOTransaction has failed the transaction - inform the base class | 
|         |   1155 	// protocol handler to change the state of this transaction. | 
|         |   1156 	TransactionFailed(aTransaction.Transaction()); | 
|         |   1157  | 
|         |   1158 	__LOG1(_L("Transaction %d has failed."), aTransaction.Transaction().Id() ); | 
|         |   1159 	} | 
|         |   1160  | 
|         |   1161 void CWspCOProtocolHandler::NotifyPendingCompletingMethod() | 
|         |   1162 	{ | 
|         |   1163 	// Increment the number of pending methods waiting to move from Completing | 
|         |   1164 	// to Null state. | 
|         |   1165 	++iPendingCompletingMethods; | 
|         |   1166  | 
|         |   1167 	__LOG1(_L("Number of methods waiting to send final .res primitive : %d"), iPendingCompletingMethods); | 
|         |   1168 	} | 
|         |   1169  | 
|         |   1170 void CWspCOProtocolHandler::NotifyMethodComplete() | 
|         |   1171 	{ | 
|         |   1172 	// The final .res primitive has been sent for one of the methods - decrement | 
|         |   1173 	// count. | 
|         |   1174 	--iPendingCompletingMethods; | 
|         |   1175  | 
|         |   1176 	__LOG1(_L("Number of methods waiting to send final .res primitive : %d"), iPendingCompletingMethods); | 
|         |   1177  | 
|         |   1178 	if( iPendingCompletingMethods == 0 && iDisconnectRequested ) | 
|         |   1179 		{ | 
|         |   1180 		__LOG(_L("---All methods have sent final .res primitive. Requesting disconnect.")); | 
|         |   1181  | 
|         |   1182 		// No more methods waiting to send the final .res primitive and the | 
|         |   1183 		// client has requested the session be disconnected - request it now. | 
|         |   1184 		iPrimitiveSender->InitiateSend(ESDisconnect); | 
|         |   1185 		} | 
|         |   1186 	} | 
|         |   1187  | 
|         |   1188  | 
|         |   1189 /* | 
|         |   1190  * Methods from MRxDataObserver | 
|         |   1191  */ | 
|         |   1192  | 
|         |   1193 void CWspCOProtocolHandler::SetStatusL(CRxData& aRxData, TInt aStatus) | 
|         |   1194 	{ | 
|         |   1195 	// Have received a status message from an Rx data object - check the status. | 
|         |   1196 	switch( aStatus ) | 
|         |   1197 		{ | 
|         |   1198 	case THTTPEvent::EResponseComplete: | 
|         |   1199 		{ | 
|         |   1200 		__LOG1(_L("Transaction %d has completed"), aRxData.ProtTrans().Transaction().Id() ); | 
|         |   1201 		// The response is complete - the client has been passed all the data | 
|         |   1202 		// and released it. It has no further use for the Rx data object. The | 
|         |   1203 		// transaction is now complete - inform the base class. | 
|         |   1204 		TransactionCompletedL(aRxData.ProtTrans().Transaction(), THTTPEvent::EResponseComplete); | 
|         |   1205 		} break; | 
|         |   1206 	default: | 
|         |   1207 		// Unknown status - do nothing. | 
|         |   1208 		__LOG1(_L("Received unknown status %d"), aStatus); | 
|         |   1209 		break; | 
|         |   1210 		} | 
|         |   1211 	} | 
|         |   1212  | 
|         |   1213 TInt CWspCOProtocolHandler::SessionServerCert(TCertInfo& aServerCert) | 
|         |   1214 	{ | 
|         |   1215 	return iTransportHandler->ServerCert(aServerCert); | 
|         |   1216 	} | 
|         |   1217  | 
|         |   1218 const CCertificate* CWspCOProtocolHandler::SessionServerCert() | 
|         |   1219 	{ | 
|         |   1220 	return iTransportHandler->ServerCert(); | 
|         |   1221 	} | 
|         |   1222  | 
|         |   1223 /* | 
|         |   1224  * Methods from MProtHandlerInterface | 
|         |   1225  */ | 
|         |   1226  | 
|         |   1227 TInt CWspCOProtocolHandler::TransactionServerCert(TCertInfo& /*aServerCert*/, RHTTPTransaction /*aTransaction*/) | 
|         |   1228 	{ | 
|         |   1229 	// Transaction Server certificate does not make sense for WSP | 
|         |   1230 	return KErrNotSupported; | 
|         |   1231 	} | 
|         |   1232  | 
|         |   1233 const CCertificate* CWspCOProtocolHandler::TransactionServerCert(RHTTPTransaction /*aTransaction*/) | 
|         |   1234  | 
|         |   1235 	{ | 
|         |   1236 	return NULL; | 
|         |   1237 	} |