|         |      1 // Copyright (c) 2000-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 #include <e32std.h> | 
|         |     17  | 
|         |     18 // | 
|         |     19 #include "Dummywapstd.h" | 
|         |     20 #include "dummywapstack.h" | 
|         |     21 #include "dummycapcodec.h" | 
|         |     22   | 
|         |     23 const TInt KWapStkArrayGranualarity=1; | 
|         |     24  | 
|         |     25  | 
|         |     26 /** | 
|         |     27  * Factory construction method | 
|         |     28  * Use this method to allocate and construct a new CDummyWapStack object | 
|         |     29  */ | 
|         |     30  EXPORT_C CDummyWapStack* CDummyWapStack::NewL(MDummyWapStackObserver& aObserver) | 
|         |     31 	{ | 
|         |     32 	CDummyWapStack* self=new (ELeave) CDummyWapStack(aObserver); | 
|         |     33 	CleanupStack::PushL(self);	 | 
|         |     34 	self->ConstructL(); | 
|         |     35 	CleanupStack::Pop(self); | 
|         |     36 	return self; | 
|         |     37 	}; | 
|         |     38  | 
|         |     39 /** | 
|         |     40  * Constructor | 
|         |     41  */ | 
|         |     42 CDummyWapStack::CDummyWapStack(MDummyWapStackObserver& aObserver) :iObserver(aObserver),iSessionsArray(KWapStkArrayGranualarity) | 
|         |     43 	{ | 
|         |     44 	} | 
|         |     45  | 
|         |     46 /** | 
|         |     47  * 2nd phase constructor | 
|         |     48  * If the server instance hasn't already been constructed, create one | 
|         |     49  * and store the pointer in thread local storage | 
|         |     50  */ | 
|         |     51 void CDummyWapStack::ConstructL() | 
|         |     52 	{ | 
|         |     53 	if(!iInstance) | 
|         |     54 		{ | 
|         |     55 		User::LeaveIfError(Dll::SetTls(this)); | 
|         |     56 		iInstance = StackInstance(); | 
|         |     57 		} | 
|         |     58 	} | 
|         |     59  | 
|         |     60 /** | 
|         |     61  * Destructor | 
|         |     62  */ | 
|         |     63 CDummyWapStack::~CDummyWapStack() | 
|         |     64 	{ | 
|         |     65 	FreeTls(); | 
|         |     66 	iInstance =NULL; | 
|         |     67 	iObserver.DWSOServerShutDown(); | 
|         |     68  | 
|         |     69 	__ASSERT_DEBUG(iSessionsArray.Count()==0, User::Panic(_L("Session Not deleted  != 0"), 0)); | 
|         |     70 	iSessionsArray.Close(); | 
|         |     71 	} | 
|         |     72  | 
|         |     73 /** | 
|         |     74  * Removes the pointer stored in TLS and zero it | 
|         |     75  */ | 
|         |     76 void  CDummyWapStack::FreeTls() | 
|         |     77 	{ | 
|         |     78 	Dll::FreeTls(); | 
|         |     79 	Dll::SetTls(NULL); | 
|         |     80 	} | 
|         |     81  | 
|         |     82 /** | 
|         |     83  * Return the newly created session | 
|         |     84  */ | 
|         |     85 EXPORT_C CDummyWapSession* CDummyWapStack::NewSessionL() | 
|         |     86 	{ | 
|         |     87 	CDummyWapSession* Session = CDummyWapSession::NewL(); | 
|         |     88 	CleanupStack::PushL(Session); | 
|         |     89 	User::LeaveIfError(iSessionsArray.Append(Session)); | 
|         |     90 	CleanupStack::Pop(); 	   | 
|         |     91 	return iSessionsArray[iSessionsArray.Count()-1]; | 
|         |     92 	} | 
|         |     93  | 
|         |     94 /** | 
|         |     95  * Close the session with the server by removing it from the array  | 
|         |     96  * of open sessions  | 
|         |     97  * @param aDummyWapSession The session to be closed | 
|         |     98  */ | 
|         |     99 EXPORT_C void CDummyWapStack::CloseSession(CDummyWapSession* aDummyWapSession) | 
|         |    100 	{ | 
|         |    101 	for(TInt loop=iSessionsArray.Count();--loop>=0;) | 
|         |    102 		{ | 
|         |    103 		if (iSessionsArray[loop]==aDummyWapSession) | 
|         |    104 			{ | 
|         |    105 			iSessionsArray.Remove(loop); | 
|         |    106 			delete aDummyWapSession; | 
|         |    107 			break; | 
|         |    108 			} | 
|         |    109 		} | 
|         |    110 	} | 
|         |    111  | 
|         |    112 /** | 
|         |    113  * Return a reference to the MDummyWapStackObserver  | 
|         |    114  */ | 
|         |    115 EXPORT_C MDummyWapStackObserver& CDummyWapStack::Observer() | 
|         |    116 	{ | 
|         |    117 	return iObserver; | 
|         |    118 	} | 
|         |    119  | 
|         |    120  | 
|         |    121  | 
|         |    122  | 
|         |    123  | 
|         |    124  | 
|         |    125  | 
|         |    126  | 
|         |    127  | 
|         |    128 /** | 
|         |    129  *  Factory method to create new CDummyWapSession object | 
|         |    130  */ | 
|         |    131 CDummyWapSession* CDummyWapSession::NewL() | 
|         |    132 	{ | 
|         |    133 	CDummyWapSession* self = new(ELeave) CDummyWapSession(); | 
|         |    134 	CleanupStack::PushL(self); | 
|         |    135 	self->ConstructL(); | 
|         |    136 	CleanupStack::Pop(self);  | 
|         |    137 	return self; | 
|         |    138 	} | 
|         |    139  | 
|         |    140 /** | 
|         |    141  * 2nd phase constructor | 
|         |    142  */ | 
|         |    143 void CDummyWapSession::ConstructL() | 
|         |    144 	{ | 
|         |    145 	} | 
|         |    146  | 
|         |    147 /** | 
|         |    148  * Destructor | 
|         |    149  */ | 
|         |    150 CDummyWapSession::~CDummyWapSession() | 
|         |    151 	{ | 
|         |    152 	// check that all sessions have been closed | 
|         |    153 	__ASSERT_ALWAYS(iReferenceCount==0,User::Invariant()); | 
|         |    154 	} | 
|         |    155  | 
|         |    156 /** | 
|         |    157  * Creates a new CL connection | 
|         |    158  */ | 
|         |    159 CDummyWSPCLConn*  CDummyWapSession::NewWSPCLConnL(TPort aPort) | 
|         |    160 	{ | 
|         |    161 	CDummyWSPCLConn* dummyCL = new (ELeave) CDummyWSPCLConn(*this, aPort); | 
|         |    162 	iReferenceCount++; | 
|         |    163 	return dummyCL; | 
|         |    164 	} | 
|         |    165  | 
|         |    166 /** | 
|         |    167  * Creates a new CO connection | 
|         |    168  */ | 
|         |    169 CDummyWSPCOConn* CDummyWapSession::NewWSPCOConnL() | 
|         |    170 	{ | 
|         |    171 	CDummyWSPCOConn* dummyCO = new (ELeave) CDummyWSPCOConn(*this); | 
|         |    172 	iReferenceCount++; | 
|         |    173 	return dummyCO; | 
|         |    174 	} | 
|         |    175  | 
|         |    176 /** | 
|         |    177  * Close a connection (subsession) | 
|         |    178  */ | 
|         |    179 void CDummyWapSession::Close() | 
|         |    180 	{ | 
|         |    181 	// check that there is a session open to close | 
|         |    182 	__ASSERT_ALWAYS(iReferenceCount>0, User::Invariant()); | 
|         |    183  | 
|         |    184 	iReferenceCount--; | 
|         |    185 	} | 
|         |    186  | 
|         |    187  | 
|         |    188  | 
|         |    189  | 
|         |    190  | 
|         |    191 /** | 
|         |    192  * Constructor  | 
|         |    193  * @param aSession Wap stack client session that created the connection | 
|         |    194  */ | 
|         |    195 CDummyWSPConn::CDummyWSPConn(CDummyWapSession& aSession) : iSession(aSession) | 
|         |    196 	{ | 
|         |    197 	} | 
|         |    198  | 
|         |    199  | 
|         |    200 /** | 
|         |    201  * Virtual close method for all "dummy" wap connections | 
|         |    202  */ | 
|         |    203 void CDummyWSPConn::Close() | 
|         |    204 	{ | 
|         |    205 	iSession.Close(); | 
|         |    206 	delete iWtls; | 
|         |    207 	delete this; | 
|         |    208 	} | 
|         |    209  | 
|         |    210 /**  | 
|         |    211  * Get a pointer to the WTLS implementation from the testcode | 
|         |    212  */ | 
|         |    213 CDummyWTLS* CDummyWSPConn::WtlsL() | 
|         |    214 	{ | 
|         |    215 	if (!iWtls) | 
|         |    216 		{ | 
|         |    217 		iWtls = new (ELeave) CDummyWTLS(); | 
|         |    218 		} | 
|         |    219 	return iWtls; | 
|         |    220 	} | 
|         |    221  | 
|         |    222  | 
|         |    223  | 
|         |    224  | 
|         |    225  | 
|         |    226  | 
|         |    227  | 
|         |    228  | 
|         |    229  | 
|         |    230  | 
|         |    231 /** | 
|         |    232  * simple constructor - call the base class | 
|         |    233  * @param aSession Wap stack client session that created the connection | 
|         |    234  */ | 
|         |    235 CDummyWSPCLConn::CDummyWSPCLConn(CDummyWapSession& aSession,TPort aLocalPort) : | 
|         |    236 	CDummyWSPConn(aSession),iLocalPort(aLocalPort) | 
|         |    237 	{ | 
|         |    238 	} | 
|         |    239  | 
|         |    240 /** | 
|         |    241  * Destructor | 
|         |    242  */ | 
|         |    243 CDummyWSPCLConn::~CDummyWSPCLConn() | 
|         |    244 	{ | 
|         |    245 	delete iPushHeadersData; | 
|         |    246 	delete iPushBodyData; | 
|         |    247 	delete iServerAddr; | 
|         |    248 	} | 
|         |    249  | 
|         |    250 TInt CDummyWSPCLConn::Connect(Wap::TBearer /*aBearer*/, Wap::TPort /*aPort*/, TBool /*aSecure*/) | 
|         |    251 	{ | 
|         |    252 	TInt err = KErrNone; | 
|         |    253 	return err; | 
|         |    254 	} | 
|         |    255  | 
|         |    256  | 
|         |    257 TInt CDummyWSPCLConn::AwaitPush(TDes8& aPushHeaders, TDes8& aPushBody, TPckgBuf<TUint8>& aPushId, TRequestStatus& aReqStatus) | 
|         |    258 	{ | 
|         |    259 	TPushID pushID; | 
|         |    260 	pushID() = aPushId(); | 
|         |    261 	TRAPD(err, UnitWaitPushL(aPushBody, aPushHeaders, pushID, aReqStatus)); | 
|         |    262 	return err; | 
|         |    263 	} | 
|         |    264  | 
|         |    265  | 
|         |    266 /** | 
|         |    267  *  | 
|         |    268  */ | 
|         |    269 void CDummyWSPCLConn::UnitWaitPushL(TDes8& aBody,TDes8& aHeaders,TPushID& aID,TRequestStatus& aStatus) | 
|         |    270 	{ | 
|         |    271 	__ASSERT_DEBUG(aBody.MaxSize()>0, User::Panic(_L("Msg Body Buffer Not Allocated"),0)); | 
|         |    272 	__ASSERT_DEBUG(aHeaders.MaxSize()>0, User::Panic(_L("Msg Header Buffer Not Allocated"),0)); | 
|         |    273 	 | 
|         |    274 	aStatus=KRequestPending; | 
|         |    275 	//point to the Msg Buffers | 
|         |    276 	iClientBody=&aBody; | 
|         |    277 	iClientHeaders=&aHeaders; | 
|         |    278 	iID = &aID; | 
|         |    279 	iStatus=(&aStatus); | 
|         |    280  | 
|         |    281 	//Initialise Buffers to zero Before Appending  | 
|         |    282 	iClientBody->Zero(); | 
|         |    283 	iClientHeaders->Zero(); | 
|         |    284 	*iID =0; | 
|         |    285  | 
|         |    286 	//Invoke the dummy Observer UnitWaitPush | 
|         |    287 	STATIC_CAST(CDummyWapStack* , Dll::Tls())->Observer().DWSOUnitWaitPushL(*this); | 
|         |    288 	} | 
|         |    289  | 
|         |    290 TInt CDummyWSPCLConn::CancelAwaitPush() | 
|         |    291 	{ | 
|         |    292 	return CancelUnitWaitPush(); | 
|         |    293 	} | 
|         |    294  | 
|         |    295 /** | 
|         |    296  * Cancel a unit wait push | 
|         |    297  */ | 
|         |    298 TInt CDummyWSPCLConn::CancelUnitWaitPush() | 
|         |    299 	{ | 
|         |    300  	if (iClientBody) | 
|         |    301 		iClientBody->Zero(); | 
|         |    302 	if (iClientHeaders) | 
|         |    303 		iClientHeaders->Zero(); | 
|         |    304 //	if (iID) | 
|         |    305 //		*iID =0; | 
|         |    306  | 
|         |    307 	STATIC_CAST(CDummyWapStack* , Dll::Tls())->Observer().DWSOCancelUnitWaitPush(*this); | 
|         |    308 	 | 
|         |    309 	User::RequestComplete(iStatus,KErrCancel); | 
|         |    310  | 
|         |    311 	return KErrNone; | 
|         |    312 	} | 
|         |    313  | 
|         |    314 /** | 
|         |    315  * -Reads in the whole Msg. Header & Body From the WSS stack  | 
|         |    316  * (i.e the test Harness) and Creates a Local Copy. | 
|         |    317  * -Copy the Msg. Header & Body to Watcher Buffers: | 
|         |    318  *		if the Watcher Buffers are big enough to hold the message, | 
|         |    319  *		then the whole Mgs is copied and we Complete with KErrNone. | 
|         |    320  *		if the Watcher Buffers are smaller then the Msg is copied  | 
|         |    321  *      in blocks of size equal to the size of the Watcher Buffers | 
|         |    322  *      completing with EMoreData every time until the watcher gets | 
|         |    323  *		the whole Msg. At that point there is no more data to be  | 
|         |    324  *		copied then we complete with KErrNone. | 
|         |    325  */ | 
|         |    326 EXPORT_C void CDummyWSPCLConn::CompleteUnitWaitPushL(TDes8& aBody,TDes8& aHeaders) | 
|         |    327 	{ | 
|         |    328 	TPushID id; | 
|         |    329 	id=99; | 
|         |    330 	// Only read data from the WSS stack the first call | 
|         |    331 	if (iPushHeadersDataOffset == 0 && iPushBodyDataOffset == 0)  | 
|         |    332 		{ | 
|         |    333 		__ASSERT_DEBUG(iPushHeadersData == 0, User::Panic(_L("headers != 0"), 0)); | 
|         |    334 		__ASSERT_DEBUG(iPushBodyData == 0, User::Panic(_L("body != 0"), 0)); | 
|         |    335 		 | 
|         |    336 		TUint bodySize = aBody.Size(); | 
|         |    337 		TUint headersSize =aHeaders.Size();		 | 
|         |    338 		 | 
|         |    339 		if (bodySize==0 && headersSize==0)  | 
|         |    340 			User::Leave(RWSPCLConn::EDataNotAvailable); | 
|         |    341 		 | 
|         |    342 		iPushHeadersData= aHeaders.AllocL(); | 
|         |    343 		iPushBodyData= aBody.AllocL(); | 
|         |    344 		*iID=id;//**** Generate an Id per Msg, Not Supported in R1 | 
|         |    345 		 | 
|         |    346 		iPushHeadersData->Des().SetLength(headersSize); | 
|         |    347 		iPushBodyData->Des().SetLength(bodySize); | 
|         |    348 		} | 
|         |    349  | 
|         |    350 	TInt clientHeadersSize = iClientHeaders->MaxSize(); | 
|         |    351 	TInt clientBodySize = iClientBody->MaxSize(); | 
|         |    352 	 | 
|         |    353 	TInt headersRetSize = Min(clientHeadersSize, (iPushHeadersData->Size() - iPushHeadersDataOffset)); | 
|         |    354 	TInt bodyRetSize = Min(clientBodySize, (iPushBodyData->Size() - iPushBodyDataOffset)); | 
|         |    355  | 
|         |    356 	iClientHeaders->Append(iPushHeadersData->Mid(iPushHeadersDataOffset, headersRetSize)); | 
|         |    357 	iClientBody->Append(iPushBodyData->Mid(iPushBodyDataOffset, bodyRetSize)); | 
|         |    358  | 
|         |    359 	iPushHeadersDataOffset += headersRetSize; | 
|         |    360 	iPushBodyDataOffset += bodyRetSize; | 
|         |    361 	 | 
|         |    362 	__ASSERT_DEBUG(iPushBodyDataOffset <= iPushBodyData->Size(), User::Panic(_L("Body offset too big"), 0)); | 
|         |    363 	__ASSERT_DEBUG(iPushHeadersDataOffset <= iPushHeadersData->Size(), User::Panic(_L("Headers offset too big"), 0)); | 
|         |    364 	 | 
|         |    365 	// Are we done yet? | 
|         |    366 	if (iPushHeadersDataOffset == iPushHeadersData->Size() && | 
|         |    367 		iPushBodyDataOffset == iPushBodyData->Size() ) | 
|         |    368 		{ | 
|         |    369 		delete iPushHeadersData; | 
|         |    370 		delete iPushBodyData; | 
|         |    371 		iPushHeadersData = 0; | 
|         |    372 		iPushBodyData = 0; | 
|         |    373 		iPushHeadersDataOffset = 0; | 
|         |    374 		iPushBodyDataOffset = 0; | 
|         |    375 		User::RequestComplete(iStatus,KErrNone); | 
|         |    376 		} | 
|         |    377 	else | 
|         |    378 		User::RequestComplete(iStatus,RWAPConn::EMoreData); | 
|         |    379 	} | 
|         |    380  | 
|         |    381 EXPORT_C TBool CDummyWSPCLConn::HasMsgBeenCompleted() | 
|         |    382 	{ | 
|         |    383 	return (iPushHeadersDataOffset == 0 && iPushBodyDataOffset == 0); | 
|         |    384 	} | 
|         |    385  | 
|         |    386 /** | 
|         |    387  * Sync Version | 
|         |    388  */ | 
|         |    389 TInt CDummyWSPCLConn::UnitWaitPushL(TDes8& /*aBody*/,TDes8& /*aHeaders*/,TPushID& /*aID*/) | 
|         |    390 	{ | 
|         |    391 	return KErrNotSupported; | 
|         |    392 	} | 
|         |    393  | 
|         |    394  | 
|         |    395  | 
|         |    396  | 
|         |    397  | 
|         |    398 /** | 
|         |    399  * simple constructor - call the base class | 
|         |    400  * @param aSession Wap stack client session that created the connection | 
|         |    401  */ | 
|         |    402 CDummyWSPCOConn::CDummyWSPCOConn(CDummyWapSession& aSession) : CDummyWSPConn(aSession), iSessionState(RWSPCOConn::EInit), iTransArray(1) | 
|         |    403 	{ | 
|         |    404 	} | 
|         |    405  | 
|         |    406 /** | 
|         |    407  * Destructor | 
|         |    408  */ | 
|         |    409 CDummyWSPCOConn::~CDummyWSPCOConn() | 
|         |    410 	{ | 
|         |    411 	// assert that the connection has been disconnected if it was connected? | 
|         |    412 	__ASSERT_ALWAYS(iCapCodec==NULL,User::Invariant()); | 
|         |    413 	__ASSERT_ALWAYS(iTransArray.Count()==0, User::Panic(_L("Transaction not closed"), 0)); | 
|         |    414 	iTransArray.Close(); | 
|         |    415 	} | 
|         |    416  | 
|         |    417 /** | 
|         |    418  * Establish a connection-orientated WSP session with the server | 
|         |    419  * | 
|         |    420  * Takes ownership of the aCap parameter (the client's capabilities) | 
|         |    421  * Informs the testcode (via the mixin) of the connect request so that | 
|         |    422  * it can decide whether to confirm the connection.  | 
|         |    423  */ | 
|         |    424 TInt CDummyWSPCOConn::Connect(const TDesC8& aClientHeaders, class CCapCodec* /*aCap*/) | 
|         |    425 	{ | 
|         |    426 	iClientHeaders=&aClientHeaders; | 
|         |    427 	iSessionState=RWSPCOConn::EConnecting; | 
|         |    428 	 | 
|         |    429 	static_cast<CDummyWapStack*>(Dll::Tls())->Observer().DWSOConnect(*this); | 
|         |    430 	return KErrNone; | 
|         |    431 	} | 
|         |    432  | 
|         |    433 /** | 
|         |    434  * Disconnects the session and abort all pending transactions | 
|         |    435  */ | 
|         |    436 TInt CDummyWSPCOConn::Disconnect() | 
|         |    437 	{ | 
|         |    438 	iSessionState=RWSPCOConn::EDisconnected; | 
|         |    439  | 
|         |    440 	TInt numTrans=iTransArray.Count(); | 
|         |    441 	while(numTrans>0) | 
|         |    442 		{ | 
|         |    443 		CDummyWSPCOTrans* trans = iTransArray[0]; | 
|         |    444 		trans->Abort(99); //TODO | 
|         |    445 		iTransArray.Remove(0); | 
|         |    446 		numTrans--; | 
|         |    447 		} | 
|         |    448  | 
|         |    449 	return KErrNone; | 
|         |    450 	} | 
|         |    451  | 
|         |    452 /** | 
|         |    453  * Return the state of a session | 
|         |    454  */ | 
|         |    455 TInt CDummyWSPCOConn::GetSessionState(RWSPCOConn::TSessionState& aState) | 
|         |    456 	{ | 
|         |    457 	aState=iSessionState; | 
|         |    458 	return KErrNone; | 
|         |    459 	} | 
|         |    460  | 
|         |    461 /** | 
|         |    462  * Gets the next session or transaction event on this session | 
|         |    463  *  | 
|         |    464  * Stores the parameters supplied by the client and awaits callback from  | 
|         |    465  * the testcode | 
|         |    466  */ | 
|         |    467 TInt CDummyWSPCOConn::GetEvent(RWSPCOConn::TEvent& aEvent, RWSPCOTrans& aTrans, TRequestStatus& aStatus) | 
|         |    468 	{ | 
|         |    469 	aStatus=KRequestPending; | 
|         |    470 	iStatus=&aStatus; | 
|         |    471 	iEvent=&aEvent; | 
|         |    472 	iTrans=&aTrans; | 
|         |    473  | 
|         |    474 	//Invoke the dummy Observer GetEvent | 
|         |    475 	static_cast<CDummyWapStack*>(Dll::Tls())->Observer().DWSOGetEventL(*this); | 
|         |    476  | 
|         |    477 	return KErrNone; | 
|         |    478 	} | 
|         |    479  | 
|         |    480 /** | 
|         |    481  * Cancel a get event request | 
|         |    482  */ | 
|         |    483 EXPORT_C void CDummyWSPCOConn::CancelGetEvent() | 
|         |    484 	{ | 
|         |    485 	static_cast<CDummyWapStack*>(Dll::Tls())->Observer().DWSOCancelGetEvent(*this); | 
|         |    486 	if (iStatus) | 
|         |    487 		User::RequestComplete(iStatus,KErrCancel); | 
|         |    488 	} | 
|         |    489  | 
|         |    490 /** | 
|         |    491  * Return the number of events pending for the session | 
|         |    492  */ | 
|         |    493 TInt CDummyWSPCOConn::GetNrOfEvents(TUint& aNrOfEvents) | 
|         |    494 	{ | 
|         |    495 	//ask the testcode? | 
|         |    496 	aNrOfEvents=0; | 
|         |    497 	return KErrNone; | 
|         |    498 	} | 
|         |    499  | 
|         |    500 /** | 
|         |    501  * Complete the GetEvent call | 
|         |    502  * Called by the test harness to indicate that the transaction handle  | 
|         |    503  * has been set. Adds the dummy transaction to the array of transactions | 
|         |    504  * stored in the connection, then completes the asynchronous request. | 
|         |    505  *  | 
|         |    506  */ | 
|         |    507 EXPORT_C void CDummyWSPCOConn::CompleteGetEventL(RWSPCOConn::TEvent& aEvent, CDummyWSPCOTrans& aDummyTrans) | 
|         |    508 	{ | 
|         |    509 	*iEvent=aEvent; | 
|         |    510 	iTrans->iCoTransHandle=&aDummyTrans; | 
|         |    511 	User::LeaveIfError(iTransArray.Append(&aDummyTrans)); | 
|         |    512 	//TInt count = iTransArray.Count(); //REMOVE THIS LINE! | 
|         |    513 	User::RequestComplete(iStatus,KErrNone);  | 
|         |    514 	} | 
|         |    515  | 
|         |    516  | 
|         |    517 /** | 
|         |    518  * Remove a transaction pending on this connection.  | 
|         |    519  * This should be called by the transaction if the transaction is aborted | 
|         |    520  * or released. It will remove the transaction from the list of transactions | 
|         |    521  */ | 
|         |    522 void CDummyWSPCOConn::RemoveTransaction(CDummyWSPCOTrans& aTrans) | 
|         |    523 	{ | 
|         |    524 	RWSPCOTrans::TTransID id; | 
|         |    525 	aTrans.Id(id); | 
|         |    526 	RWSPCOTrans::TTransID transId; | 
|         |    527 	TInt count = iTransArray.Count(); | 
|         |    528 	 | 
|         |    529  | 
|         |    530 	TInt i=0; | 
|         |    531 	while(i<count) | 
|         |    532 		{ | 
|         |    533 		CDummyWSPCOTrans* trans = iTransArray[i]; | 
|         |    534 		trans->Id(transId); | 
|         |    535 		if (transId==id) | 
|         |    536 			{ | 
|         |    537 			iTransArray.Remove(i); | 
|         |    538 			delete trans;  | 
|         |    539 			count--;  | 
|         |    540 			} | 
|         |    541 		else | 
|         |    542 			i++; | 
|         |    543 		} | 
|         |    544  | 
|         |    545  | 
|         |    546 	} | 
|         |    547  | 
|         |    548  | 
|         |    549  | 
|         |    550  | 
|         |    551  | 
|         |    552 /** | 
|         |    553  * Trivial constructor for dummy transaction | 
|         |    554  * | 
|         |    555  * @param aConnection reference to the CO connection that created this transaction | 
|         |    556  */ | 
|         |    557 EXPORT_C CDummyWSPCOTrans::CDummyWSPCOTrans(CDummyWSPCOConn& aConnection) : iConnection(aConnection), iTransState(RWSPCOTrans::EInit) | 
|         |    558 	{ | 
|         |    559 	iDataArray.Reset(); | 
|         |    560 	iOffsetArray.Reset(); | 
|         |    561 	for (TInt i = 0; i < 11; i++) | 
|         |    562 		iOffsetArray[i] = new TInt(0); | 
|         |    563 	} | 
|         |    564  | 
|         |    565 /** | 
|         |    566  * destructor | 
|         |    567  */ | 
|         |    568 EXPORT_C CDummyWSPCOTrans::~CDummyWSPCOTrans() | 
|         |    569 	{ | 
|         |    570 	// DeleteAll can only be used for CBase derived classes in array | 
|         |    571 	//iDataArray.DeleteAll(); | 
|         |    572 	iOffsetArray.DeleteAll(); | 
|         |    573 	} | 
|         |    574  | 
|         |    575 /** | 
|         |    576  * Acknowledge this transaction with the clients headers | 
|         |    577  * Stores a pointer to the headers used by the client to acknowledge | 
|         |    578  * this transaction, then informs the mixin so the testcode can  | 
|         |    579  * check the headers | 
|         |    580  * @param aAckHeaders the headers to be ack'd | 
|         |    581  */ | 
|         |    582 TInt CDummyWSPCOTrans::Acknowledge(const TDesC8& aAckHeaders) | 
|         |    583 	{ | 
|         |    584 	iClientAckHeaders=&aAckHeaders; | 
|         |    585 	static_cast<CDummyWapStack*>(Dll::Tls())->Observer().DWSOAckTransaction(*this); | 
|         |    586 	return KErrNone; | 
|         |    587 	} | 
|         |    588  | 
|         |    589 /**  | 
|         |    590  * Get the data from the transaction | 
|         |    591  *  | 
|         |    592  * Return the minimum of client buffer size and amount left to read | 
|         |    593  */ | 
|         |    594 TInt CDummyWSPCOTrans::GetData(TDes8& aBuffer, RWSPCOTrans::TDataType aDataType, TInt* aSizeLeft) const | 
|         |    595 	{	 | 
|         |    596 	__ASSERT_DEBUG(aBuffer.MaxSize()>0, User::Panic(_L("Client buffer not allocated"),0)); | 
|         |    597  | 
|         |    598 	//const TDesC8* requestedData=*iDataArray[aDataType]; | 
|         |    599 	const TDesC8* requestedData= iDataArray[aDataType]; | 
|         |    600 	TInt bufferSize = aBuffer.MaxSize(); | 
|         |    601 	TInt reqSize = requestedData->Size(); | 
|         |    602 	TInt* offset = iOffsetArray.At(aDataType); | 
|         |    603  | 
|         |    604 	TInt retSize = Min(bufferSize, (reqSize - *offset));	 | 
|         |    605  | 
|         |    606 	aBuffer.Zero(); | 
|         |    607 	aBuffer.Append(requestedData->Mid(*offset, retSize)); | 
|         |    608 	*offset += retSize; | 
|         |    609  | 
|         |    610 	if (*offset==reqSize) | 
|         |    611 		{ | 
|         |    612 		*aSizeLeft = 0; | 
|         |    613 		*offset = 0; | 
|         |    614 		return KErrNone; | 
|         |    615 		} | 
|         |    616 	else | 
|         |    617 		{ | 
|         |    618 		*aSizeLeft = reqSize-*offset; | 
|         |    619 		return RWAPConn::EMoreData; | 
|         |    620 		} | 
|         |    621 	} | 
|         |    622  | 
|         |    623  | 
|         |    624 /**  | 
|         |    625  * Return the state of the transaction | 
|         |    626  */ | 
|         |    627 TInt CDummyWSPCOTrans::GetState(RWSPCOTrans::TState& aState) const | 
|         |    628 	{	 | 
|         |    629 	aState=iTransState; | 
|         |    630 	return KErrNone; | 
|         |    631 	} | 
|         |    632  | 
|         |    633 /**  | 
|         |    634  * Abort the transaction | 
|         |    635  */ | 
|         |    636 TInt CDummyWSPCOTrans::Abort(RWSPCOTrans::TAbortReason /*aReason*/) | 
|         |    637 	{ | 
|         |    638 	iTransState=RWSPCOTrans::EAborted; | 
|         |    639 	iConnection.RemoveTransaction(*this); | 
|         |    640 	// tell the testcode also? | 
|         |    641 	return KErrNone; | 
|         |    642 	} | 
|         |    643  | 
|         |    644 /** | 
|         |    645  * Release the transaction | 
|         |    646  * Inform the connection that the transaction has been released so  | 
|         |    647  * that it won't abort the transaction if the connection is  | 
|         |    648  * disconnected - or complain that the transaction hasn't been  | 
|         |    649  * released | 
|         |    650  */ | 
|         |    651 TInt CDummyWSPCOTrans::Release() | 
|         |    652 	{ | 
|         |    653 	iConnection.RemoveTransaction(*this); | 
|         |    654 	// tell the testcode also? | 
|         |    655 	return KErrNone; | 
|         |    656 	} | 
|         |    657  | 
|         |    658 /**  | 
|         |    659  * return the ID of this transaction | 
|         |    660  */ | 
|         |    661 TInt CDummyWSPCOTrans::Id(RWSPCOTrans::TTransID& aId) | 
|         |    662 	{ | 
|         |    663 	aId=iId; | 
|         |    664 	return KErrNone; | 
|         |    665 	} | 
|         |    666  | 
|         |    667 /** | 
|         |    668  * Set the data to be returned by the transaction when RWSPCOTrans::GetData() is called | 
|         |    669  * | 
|         |    670  * Raises a USER 133 panic if aDataType isn't inside the enumeration range | 
|         |    671  * | 
|         |    672  * @param aBuffer a reference to the 8-bit descriptor containing the data | 
|         |    673  * @param aDataType the type of data being set | 
|         |    674  * | 
|         |    675  */ | 
|         |    676 EXPORT_C void CDummyWSPCOTrans::SetData(const TDesC8& aBuffer,RWSPCOTrans::TDataType aDataType) | 
|         |    677 	{ | 
|         |    678 	iDataArray[aDataType]=&aBuffer; | 
|         |    679 	} | 
|         |    680  | 
|         |    681  | 
|         |    682 /**  | 
|         |    683  * Set the ID of this transaction | 
|         |    684  * This should be called by the testcode  | 
|         |    685  * @param aId The transaction ID | 
|         |    686  */ | 
|         |    687 EXPORT_C void CDummyWSPCOTrans::SetId(TInt aId) | 
|         |    688 	{ | 
|         |    689 	iId=aId; | 
|         |    690 	} | 
|         |    691  | 
|         |    692  | 
|         |    693  | 
|         |    694  | 
|         |    695  | 
|         |    696  | 
|         |    697  | 
|         |    698 /** | 
|         |    699  * Constructor for dummy WTLS | 
|         |    700  * This should be called by the testcode using the stack | 
|         |    701  * CDummyWSPConn will ask the testcode for the dummy WTLS class to be used | 
|         |    702  * and set the pointer in RWTLS to point to it. | 
|         |    703  */ | 
|         |    704 CDummyWTLS::CDummyWTLS() : iSequenceNumMode(RWTLS::EImplicit), iKeyRefreshRate(4) | 
|         |    705 	{ | 
|         |    706 	} | 
|         |    707  | 
|         |    708 CDummyWTLS::~CDummyWTLS() | 
|         |    709 	{ | 
|         |    710 	} | 
|         |    711  | 
|         |    712 /** | 
|         |    713  * Adds a new key exchange suite to the list of allowed key exchange suites  | 
|         |    714  * for the secure connection. Each time this function is called a new key | 
|         |    715  * exchange suite is added to the list. The first key exchange suite is the | 
|         |    716  * most preferred key exchange suite.  | 
|         |    717  *  | 
|         |    718  * The default list is {ERsa, ERsa768, ERsa512} | 
|         |    719  */ | 
|         |    720 TInt CDummyWTLS::SetKeyExchangeSuite(RWTLS::TKeyExchangeSuite /*aSuite*/,RWTLS::TIdType /*IdType*/,const TDesC8& /*aKeyId*/) | 
|         |    721 	{ | 
|         |    722 	return KErrNone; | 
|         |    723 	} | 
|         |    724  | 
|         |    725 /** | 
|         |    726  * Sets the supported cipher suites for the connection | 
|         |    727  */ | 
|         |    728 TInt CDummyWTLS::SetCipherSuites(const RWTLS::CipherSuiteArray& /*aCipherSuites*/) | 
|         |    729 	{ | 
|         |    730 	return KErrNone; | 
|         |    731 	} | 
|         |    732  | 
|         |    733 /** | 
|         |    734  * Set the proposed sequence number mode | 
|         |    735  */ | 
|         |    736 TInt CDummyWTLS::SetSequenceNumberMode(RWTLS::TSequenceNumberMode aMode) | 
|         |    737 	{ | 
|         |    738 	iSequenceNumMode=aMode;  | 
|         |    739 	return KErrNone; | 
|         |    740 	} | 
|         |    741  | 
|         |    742 /** | 
|         |    743  * Set the proposed key refresh rate | 
|         |    744  */ | 
|         |    745 TInt CDummyWTLS::SetKeyRefreshRate(TUint8 aRate) | 
|         |    746 	{ | 
|         |    747 	iKeyRefreshRate=aRate; | 
|         |    748 	return KErrNone; | 
|         |    749 	} | 
|         |    750  | 
|         |    751 /**  | 
|         |    752  * Set the shared secret | 
|         |    753  */ | 
|         |    754 TInt CDummyWTLS::SetSharedSecret(const TDesC8& /*aSharedSecret*/) | 
|         |    755 	{ | 
|         |    756 	return KErrNone; | 
|         |    757 	} | 
|         |    758  | 
|         |    759 /**  | 
|         |    760  * Enables/disables record length usage | 
|         |    761  * If the record length usage is set to ETrue, each msg sent to the server | 
|         |    762  * will contain the msg length field. Record length usage should be turned | 
|         |    763  * on if the bearer is not able to provide the size of the transport SDU | 
|         |    764  */ | 
|         |    765 TInt CDummyWTLS::SetRecordLengthUsage(TBool aUsage) | 
|         |    766 	{ | 
|         |    767 	iRecordLenUsage=aUsage; | 
|         |    768 	return KErrNone; | 
|         |    769 	} | 
|         |    770  | 
|         |    771 /**  | 
|         |    772  * Make the handshake with the server to agree security parameters | 
|         |    773  * If called more than once, a renegotiation is done | 
|         |    774  * pre-condition: The connection must be opened in secure mode before this. | 
|         |    775  */ | 
|         |    776 void CDummyWTLS::Connect(TRequestStatus& aStatus, TBool aTwoPhaseHandshake) | 
|         |    777 	{ | 
|         |    778 	aStatus=KRequestPending; | 
|         |    779 	iConnect=&aStatus; | 
|         |    780 	iTwoPhaseHandshake=aTwoPhaseHandshake; | 
|         |    781 	//TODO: We need to use the Dummy Observer instead  | 
|         |    782 	User::RequestComplete(iConnect, RWTLS::EHandshakeOk); | 
|         |    783 	} | 
|         |    784  | 
|         |    785 /**  | 
|         |    786  * Stop processing a secure handshake | 
|         |    787  * This method can be used to abort a secure handshake if application  | 
|         |    788  * validation of the certificate fails | 
|         |    789  */ | 
|         |    790 void CDummyWTLS::CancelConnect() | 
|         |    791 	{ | 
|         |    792 	User::RequestComplete(iConnect,KErrCancel); | 
|         |    793 	} | 
|         |    794  | 
|         |    795 /** | 
|         |    796  * Continues the processing of a secure handshake | 
|         |    797  */ | 
|         |    798 TInt CDummyWTLS::ConnectPhaseTwo(TRequestStatus& aStatus) | 
|         |    799 	{ | 
|         |    800 	aStatus=KRequestPending; | 
|         |    801 	iConnectPhaseTwo=&aStatus; | 
|         |    802 	return KErrNone; | 
|         |    803 	} | 
|         |    804  | 
|         |    805 /**  | 
|         |    806  * Cancel second phase of connection | 
|         |    807  */ | 
|         |    808 void CDummyWTLS::CancelConnectPhaseTwo() | 
|         |    809 	{ | 
|         |    810 	User::RequestComplete(iConnectPhaseTwo,KErrCancel); | 
|         |    811 	} | 
|         |    812  | 
|         |    813 /** | 
|         |    814  * Get the current cipher suite | 
|         |    815  * | 
|         |    816  * The default is RC5+SHA_80,RC5+SHA_40,RC5+SHA,RC5_56+SHA,RC5_40+SHA_80,RC5_40+SHA | 
|         |    817  */ | 
|         |    818 TInt CDummyWTLS::GetCipherSuite(RWTLS::TCipherSuite& /*aCipherSuite*/) const | 
|         |    819 	{ | 
|         |    820 	// | 
|         |    821 	// need to set-up array with the default and return it | 
|         |    822 	// | 
|         |    823 	return KErrNone; | 
|         |    824 	} | 
|         |    825  | 
|         |    826 /**  | 
|         |    827  * Get the currently used sequence number mode | 
|         |    828  * Either of ENotUsed, EImplicit, EExplicit | 
|         |    829  *  | 
|         |    830  * If the sequence number mode isn't set the default is EImplicit | 
|         |    831  */ | 
|         |    832 TInt CDummyWTLS::GetSequenceNumberMode(RWTLS::TSequenceNumberMode& aMode) const | 
|         |    833 	{ | 
|         |    834 	aMode=iSequenceNumMode; | 
|         |    835 	return KErrNone; | 
|         |    836 	} | 
|         |    837  | 
|         |    838 /**  | 
|         |    839  * Get the current key refresh rate | 
|         |    840  * Rate (0-15). The default is 4. | 
|         |    841  */ | 
|         |    842 TInt CDummyWTLS::GetKeyRefreshRate(TUint8& aRate) const | 
|         |    843 	{ | 
|         |    844 	aRate = iKeyRefreshRate; | 
|         |    845 	return KErrNone; | 
|         |    846 	} | 
|         |    847 /** | 
|         |    848 Set the server address to the one read from the ini file. | 
|         |    849 @param aAddr Descriptor that hold the address read in from the ini file | 
|         |    850 */ | 
|         |    851 EXPORT_C void CDummyWSPCLConn::SetServerAddressL(const TDesC8& aAddr) | 
|         |    852 	{ | 
|         |    853 	delete iServerAddr; | 
|         |    854 	iServerAddr = aAddr.AllocL(); | 
|         |    855 	} | 
|         |    856 	 | 
|         |    857 const TDesC8& CDummyWSPCLConn::GetServerAddr()  | 
|         |    858 	{ | 
|         |    859 	if(!(iServerAddr)) | 
|         |    860 		{ | 
|         |    861 		return KNullDesC8; | 
|         |    862 		} | 
|         |    863 	else | 
|         |    864 		{ | 
|         |    865 		return (*(iServerAddr));	 | 
|         |    866 		} | 
|         |    867 	} | 
|         |    868  |