diff -r 9f5ae1728557 -r db3f5fa34ec7 messagingfw/wappushfw/tpush/DummyStack/dummyWapStack.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/wappushfw/tpush/DummyStack/dummyWapStack.cpp Wed Nov 03 22:41:46 2010 +0530 @@ -0,0 +1,868 @@ +// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include + +// +#include "Dummywapstd.h" +#include "dummywapstack.h" +#include "dummycapcodec.h" + +const TInt KWapStkArrayGranualarity=1; + + +/** + * Factory construction method + * Use this method to allocate and construct a new CDummyWapStack object + */ + EXPORT_C CDummyWapStack* CDummyWapStack::NewL(MDummyWapStackObserver& aObserver) + { + CDummyWapStack* self=new (ELeave) CDummyWapStack(aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + }; + +/** + * Constructor + */ +CDummyWapStack::CDummyWapStack(MDummyWapStackObserver& aObserver) :iObserver(aObserver),iSessionsArray(KWapStkArrayGranualarity) + { + } + +/** + * 2nd phase constructor + * If the server instance hasn't already been constructed, create one + * and store the pointer in thread local storage + */ +void CDummyWapStack::ConstructL() + { + if(!iInstance) + { + User::LeaveIfError(Dll::SetTls(this)); + iInstance = StackInstance(); + } + } + +/** + * Destructor + */ +CDummyWapStack::~CDummyWapStack() + { + FreeTls(); + iInstance =NULL; + iObserver.DWSOServerShutDown(); + + __ASSERT_DEBUG(iSessionsArray.Count()==0, User::Panic(_L("Session Not deleted != 0"), 0)); + iSessionsArray.Close(); + } + +/** + * Removes the pointer stored in TLS and zero it + */ +void CDummyWapStack::FreeTls() + { + Dll::FreeTls(); + Dll::SetTls(NULL); + } + +/** + * Return the newly created session + */ +EXPORT_C CDummyWapSession* CDummyWapStack::NewSessionL() + { + CDummyWapSession* Session = CDummyWapSession::NewL(); + CleanupStack::PushL(Session); + User::LeaveIfError(iSessionsArray.Append(Session)); + CleanupStack::Pop(); + return iSessionsArray[iSessionsArray.Count()-1]; + } + +/** + * Close the session with the server by removing it from the array + * of open sessions + * @param aDummyWapSession The session to be closed + */ +EXPORT_C void CDummyWapStack::CloseSession(CDummyWapSession* aDummyWapSession) + { + for(TInt loop=iSessionsArray.Count();--loop>=0;) + { + if (iSessionsArray[loop]==aDummyWapSession) + { + iSessionsArray.Remove(loop); + delete aDummyWapSession; + break; + } + } + } + +/** + * Return a reference to the MDummyWapStackObserver + */ +EXPORT_C MDummyWapStackObserver& CDummyWapStack::Observer() + { + return iObserver; + } + + + + + + + + + +/** + * Factory method to create new CDummyWapSession object + */ +CDummyWapSession* CDummyWapSession::NewL() + { + CDummyWapSession* self = new(ELeave) CDummyWapSession(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** + * 2nd phase constructor + */ +void CDummyWapSession::ConstructL() + { + } + +/** + * Destructor + */ +CDummyWapSession::~CDummyWapSession() + { + // check that all sessions have been closed + __ASSERT_ALWAYS(iReferenceCount==0,User::Invariant()); + } + +/** + * Creates a new CL connection + */ +CDummyWSPCLConn* CDummyWapSession::NewWSPCLConnL(TPort aPort) + { + CDummyWSPCLConn* dummyCL = new (ELeave) CDummyWSPCLConn(*this, aPort); + iReferenceCount++; + return dummyCL; + } + +/** + * Creates a new CO connection + */ +CDummyWSPCOConn* CDummyWapSession::NewWSPCOConnL() + { + CDummyWSPCOConn* dummyCO = new (ELeave) CDummyWSPCOConn(*this); + iReferenceCount++; + return dummyCO; + } + +/** + * Close a connection (subsession) + */ +void CDummyWapSession::Close() + { + // check that there is a session open to close + __ASSERT_ALWAYS(iReferenceCount>0, User::Invariant()); + + iReferenceCount--; + } + + + + + +/** + * Constructor + * @param aSession Wap stack client session that created the connection + */ +CDummyWSPConn::CDummyWSPConn(CDummyWapSession& aSession) : iSession(aSession) + { + } + + +/** + * Virtual close method for all "dummy" wap connections + */ +void CDummyWSPConn::Close() + { + iSession.Close(); + delete iWtls; + delete this; + } + +/** + * Get a pointer to the WTLS implementation from the testcode + */ +CDummyWTLS* CDummyWSPConn::WtlsL() + { + if (!iWtls) + { + iWtls = new (ELeave) CDummyWTLS(); + } + return iWtls; + } + + + + + + + + + + +/** + * simple constructor - call the base class + * @param aSession Wap stack client session that created the connection + */ +CDummyWSPCLConn::CDummyWSPCLConn(CDummyWapSession& aSession,TPort aLocalPort) : + CDummyWSPConn(aSession),iLocalPort(aLocalPort) + { + } + +/** + * Destructor + */ +CDummyWSPCLConn::~CDummyWSPCLConn() + { + delete iPushHeadersData; + delete iPushBodyData; + delete iServerAddr; + } + +TInt CDummyWSPCLConn::Connect(Wap::TBearer /*aBearer*/, Wap::TPort /*aPort*/, TBool /*aSecure*/) + { + TInt err = KErrNone; + return err; + } + + +TInt CDummyWSPCLConn::AwaitPush(TDes8& aPushHeaders, TDes8& aPushBody, TPckgBuf& aPushId, TRequestStatus& aReqStatus) + { + TPushID pushID; + pushID() = aPushId(); + TRAPD(err, UnitWaitPushL(aPushBody, aPushHeaders, pushID, aReqStatus)); + return err; + } + + +/** + * + */ +void CDummyWSPCLConn::UnitWaitPushL(TDes8& aBody,TDes8& aHeaders,TPushID& aID,TRequestStatus& aStatus) + { + __ASSERT_DEBUG(aBody.MaxSize()>0, User::Panic(_L("Msg Body Buffer Not Allocated"),0)); + __ASSERT_DEBUG(aHeaders.MaxSize()>0, User::Panic(_L("Msg Header Buffer Not Allocated"),0)); + + aStatus=KRequestPending; + //point to the Msg Buffers + iClientBody=&aBody; + iClientHeaders=&aHeaders; + iID = &aID; + iStatus=(&aStatus); + + //Initialise Buffers to zero Before Appending + iClientBody->Zero(); + iClientHeaders->Zero(); + *iID =0; + + //Invoke the dummy Observer UnitWaitPush + STATIC_CAST(CDummyWapStack* , Dll::Tls())->Observer().DWSOUnitWaitPushL(*this); + } + +TInt CDummyWSPCLConn::CancelAwaitPush() + { + return CancelUnitWaitPush(); + } + +/** + * Cancel a unit wait push + */ +TInt CDummyWSPCLConn::CancelUnitWaitPush() + { + if (iClientBody) + iClientBody->Zero(); + if (iClientHeaders) + iClientHeaders->Zero(); +// if (iID) +// *iID =0; + + STATIC_CAST(CDummyWapStack* , Dll::Tls())->Observer().DWSOCancelUnitWaitPush(*this); + + User::RequestComplete(iStatus,KErrCancel); + + return KErrNone; + } + +/** + * -Reads in the whole Msg. Header & Body From the WSS stack + * (i.e the test Harness) and Creates a Local Copy. + * -Copy the Msg. Header & Body to Watcher Buffers: + * if the Watcher Buffers are big enough to hold the message, + * then the whole Mgs is copied and we Complete with KErrNone. + * if the Watcher Buffers are smaller then the Msg is copied + * in blocks of size equal to the size of the Watcher Buffers + * completing with EMoreData every time until the watcher gets + * the whole Msg. At that point there is no more data to be + * copied then we complete with KErrNone. + */ +EXPORT_C void CDummyWSPCLConn::CompleteUnitWaitPushL(TDes8& aBody,TDes8& aHeaders) + { + TPushID id; + id=99; + // Only read data from the WSS stack the first call + if (iPushHeadersDataOffset == 0 && iPushBodyDataOffset == 0) + { + __ASSERT_DEBUG(iPushHeadersData == 0, User::Panic(_L("headers != 0"), 0)); + __ASSERT_DEBUG(iPushBodyData == 0, User::Panic(_L("body != 0"), 0)); + + TUint bodySize = aBody.Size(); + TUint headersSize =aHeaders.Size(); + + if (bodySize==0 && headersSize==0) + User::Leave(RWSPCLConn::EDataNotAvailable); + + iPushHeadersData= aHeaders.AllocL(); + iPushBodyData= aBody.AllocL(); + *iID=id;//**** Generate an Id per Msg, Not Supported in R1 + + iPushHeadersData->Des().SetLength(headersSize); + iPushBodyData->Des().SetLength(bodySize); + } + + TInt clientHeadersSize = iClientHeaders->MaxSize(); + TInt clientBodySize = iClientBody->MaxSize(); + + TInt headersRetSize = Min(clientHeadersSize, (iPushHeadersData->Size() - iPushHeadersDataOffset)); + TInt bodyRetSize = Min(clientBodySize, (iPushBodyData->Size() - iPushBodyDataOffset)); + + iClientHeaders->Append(iPushHeadersData->Mid(iPushHeadersDataOffset, headersRetSize)); + iClientBody->Append(iPushBodyData->Mid(iPushBodyDataOffset, bodyRetSize)); + + iPushHeadersDataOffset += headersRetSize; + iPushBodyDataOffset += bodyRetSize; + + __ASSERT_DEBUG(iPushBodyDataOffset <= iPushBodyData->Size(), User::Panic(_L("Body offset too big"), 0)); + __ASSERT_DEBUG(iPushHeadersDataOffset <= iPushHeadersData->Size(), User::Panic(_L("Headers offset too big"), 0)); + + // Are we done yet? + if (iPushHeadersDataOffset == iPushHeadersData->Size() && + iPushBodyDataOffset == iPushBodyData->Size() ) + { + delete iPushHeadersData; + delete iPushBodyData; + iPushHeadersData = 0; + iPushBodyData = 0; + iPushHeadersDataOffset = 0; + iPushBodyDataOffset = 0; + User::RequestComplete(iStatus,KErrNone); + } + else + User::RequestComplete(iStatus,RWAPConn::EMoreData); + } + +EXPORT_C TBool CDummyWSPCLConn::HasMsgBeenCompleted() + { + return (iPushHeadersDataOffset == 0 && iPushBodyDataOffset == 0); + } + +/** + * Sync Version + */ +TInt CDummyWSPCLConn::UnitWaitPushL(TDes8& /*aBody*/,TDes8& /*aHeaders*/,TPushID& /*aID*/) + { + return KErrNotSupported; + } + + + + + +/** + * simple constructor - call the base class + * @param aSession Wap stack client session that created the connection + */ +CDummyWSPCOConn::CDummyWSPCOConn(CDummyWapSession& aSession) : CDummyWSPConn(aSession), iSessionState(RWSPCOConn::EInit), iTransArray(1) + { + } + +/** + * Destructor + */ +CDummyWSPCOConn::~CDummyWSPCOConn() + { + // assert that the connection has been disconnected if it was connected? + __ASSERT_ALWAYS(iCapCodec==NULL,User::Invariant()); + __ASSERT_ALWAYS(iTransArray.Count()==0, User::Panic(_L("Transaction not closed"), 0)); + iTransArray.Close(); + } + +/** + * Establish a connection-orientated WSP session with the server + * + * Takes ownership of the aCap parameter (the client's capabilities) + * Informs the testcode (via the mixin) of the connect request so that + * it can decide whether to confirm the connection. + */ +TInt CDummyWSPCOConn::Connect(const TDesC8& aClientHeaders, class CCapCodec* /*aCap*/) + { + iClientHeaders=&aClientHeaders; + iSessionState=RWSPCOConn::EConnecting; + + static_cast(Dll::Tls())->Observer().DWSOConnect(*this); + return KErrNone; + } + +/** + * Disconnects the session and abort all pending transactions + */ +TInt CDummyWSPCOConn::Disconnect() + { + iSessionState=RWSPCOConn::EDisconnected; + + TInt numTrans=iTransArray.Count(); + while(numTrans>0) + { + CDummyWSPCOTrans* trans = iTransArray[0]; + trans->Abort(99); //TODO + iTransArray.Remove(0); + numTrans--; + } + + return KErrNone; + } + +/** + * Return the state of a session + */ +TInt CDummyWSPCOConn::GetSessionState(RWSPCOConn::TSessionState& aState) + { + aState=iSessionState; + return KErrNone; + } + +/** + * Gets the next session or transaction event on this session + * + * Stores the parameters supplied by the client and awaits callback from + * the testcode + */ +TInt CDummyWSPCOConn::GetEvent(RWSPCOConn::TEvent& aEvent, RWSPCOTrans& aTrans, TRequestStatus& aStatus) + { + aStatus=KRequestPending; + iStatus=&aStatus; + iEvent=&aEvent; + iTrans=&aTrans; + + //Invoke the dummy Observer GetEvent + static_cast(Dll::Tls())->Observer().DWSOGetEventL(*this); + + return KErrNone; + } + +/** + * Cancel a get event request + */ +EXPORT_C void CDummyWSPCOConn::CancelGetEvent() + { + static_cast(Dll::Tls())->Observer().DWSOCancelGetEvent(*this); + if (iStatus) + User::RequestComplete(iStatus,KErrCancel); + } + +/** + * Return the number of events pending for the session + */ +TInt CDummyWSPCOConn::GetNrOfEvents(TUint& aNrOfEvents) + { + //ask the testcode? + aNrOfEvents=0; + return KErrNone; + } + +/** + * Complete the GetEvent call + * Called by the test harness to indicate that the transaction handle + * has been set. Adds the dummy transaction to the array of transactions + * stored in the connection, then completes the asynchronous request. + * + */ +EXPORT_C void CDummyWSPCOConn::CompleteGetEventL(RWSPCOConn::TEvent& aEvent, CDummyWSPCOTrans& aDummyTrans) + { + *iEvent=aEvent; + iTrans->iCoTransHandle=&aDummyTrans; + User::LeaveIfError(iTransArray.Append(&aDummyTrans)); + //TInt count = iTransArray.Count(); //REMOVE THIS LINE! + User::RequestComplete(iStatus,KErrNone); + } + + +/** + * Remove a transaction pending on this connection. + * This should be called by the transaction if the transaction is aborted + * or released. It will remove the transaction from the list of transactions + */ +void CDummyWSPCOConn::RemoveTransaction(CDummyWSPCOTrans& aTrans) + { + RWSPCOTrans::TTransID id; + aTrans.Id(id); + RWSPCOTrans::TTransID transId; + TInt count = iTransArray.Count(); + + + TInt i=0; + while(iId(transId); + if (transId==id) + { + iTransArray.Remove(i); + delete trans; + count--; + } + else + i++; + } + + + } + + + + + +/** + * Trivial constructor for dummy transaction + * + * @param aConnection reference to the CO connection that created this transaction + */ +EXPORT_C CDummyWSPCOTrans::CDummyWSPCOTrans(CDummyWSPCOConn& aConnection) : iConnection(aConnection), iTransState(RWSPCOTrans::EInit) + { + iDataArray.Reset(); + iOffsetArray.Reset(); + for (TInt i = 0; i < 11; i++) + iOffsetArray[i] = new TInt(0); + } + +/** + * destructor + */ +EXPORT_C CDummyWSPCOTrans::~CDummyWSPCOTrans() + { + // DeleteAll can only be used for CBase derived classes in array + //iDataArray.DeleteAll(); + iOffsetArray.DeleteAll(); + } + +/** + * Acknowledge this transaction with the clients headers + * Stores a pointer to the headers used by the client to acknowledge + * this transaction, then informs the mixin so the testcode can + * check the headers + * @param aAckHeaders the headers to be ack'd + */ +TInt CDummyWSPCOTrans::Acknowledge(const TDesC8& aAckHeaders) + { + iClientAckHeaders=&aAckHeaders; + static_cast(Dll::Tls())->Observer().DWSOAckTransaction(*this); + return KErrNone; + } + +/** + * Get the data from the transaction + * + * Return the minimum of client buffer size and amount left to read + */ +TInt CDummyWSPCOTrans::GetData(TDes8& aBuffer, RWSPCOTrans::TDataType aDataType, TInt* aSizeLeft) const + { + __ASSERT_DEBUG(aBuffer.MaxSize()>0, User::Panic(_L("Client buffer not allocated"),0)); + + //const TDesC8* requestedData=*iDataArray[aDataType]; + const TDesC8* requestedData= iDataArray[aDataType]; + TInt bufferSize = aBuffer.MaxSize(); + TInt reqSize = requestedData->Size(); + TInt* offset = iOffsetArray.At(aDataType); + + TInt retSize = Min(bufferSize, (reqSize - *offset)); + + aBuffer.Zero(); + aBuffer.Append(requestedData->Mid(*offset, retSize)); + *offset += retSize; + + if (*offset==reqSize) + { + *aSizeLeft = 0; + *offset = 0; + return KErrNone; + } + else + { + *aSizeLeft = reqSize-*offset; + return RWAPConn::EMoreData; + } + } + + +/** + * Return the state of the transaction + */ +TInt CDummyWSPCOTrans::GetState(RWSPCOTrans::TState& aState) const + { + aState=iTransState; + return KErrNone; + } + +/** + * Abort the transaction + */ +TInt CDummyWSPCOTrans::Abort(RWSPCOTrans::TAbortReason /*aReason*/) + { + iTransState=RWSPCOTrans::EAborted; + iConnection.RemoveTransaction(*this); + // tell the testcode also? + return KErrNone; + } + +/** + * Release the transaction + * Inform the connection that the transaction has been released so + * that it won't abort the transaction if the connection is + * disconnected - or complain that the transaction hasn't been + * released + */ +TInt CDummyWSPCOTrans::Release() + { + iConnection.RemoveTransaction(*this); + // tell the testcode also? + return KErrNone; + } + +/** + * return the ID of this transaction + */ +TInt CDummyWSPCOTrans::Id(RWSPCOTrans::TTransID& aId) + { + aId=iId; + return KErrNone; + } + +/** + * Set the data to be returned by the transaction when RWSPCOTrans::GetData() is called + * + * Raises a USER 133 panic if aDataType isn't inside the enumeration range + * + * @param aBuffer a reference to the 8-bit descriptor containing the data + * @param aDataType the type of data being set + * + */ +EXPORT_C void CDummyWSPCOTrans::SetData(const TDesC8& aBuffer,RWSPCOTrans::TDataType aDataType) + { + iDataArray[aDataType]=&aBuffer; + } + + +/** + * Set the ID of this transaction + * This should be called by the testcode + * @param aId The transaction ID + */ +EXPORT_C void CDummyWSPCOTrans::SetId(TInt aId) + { + iId=aId; + } + + + + + + + +/** + * Constructor for dummy WTLS + * This should be called by the testcode using the stack + * CDummyWSPConn will ask the testcode for the dummy WTLS class to be used + * and set the pointer in RWTLS to point to it. + */ +CDummyWTLS::CDummyWTLS() : iSequenceNumMode(RWTLS::EImplicit), iKeyRefreshRate(4) + { + } + +CDummyWTLS::~CDummyWTLS() + { + } + +/** + * Adds a new key exchange suite to the list of allowed key exchange suites + * for the secure connection. Each time this function is called a new key + * exchange suite is added to the list. The first key exchange suite is the + * most preferred key exchange suite. + * + * The default list is {ERsa, ERsa768, ERsa512} + */ +TInt CDummyWTLS::SetKeyExchangeSuite(RWTLS::TKeyExchangeSuite /*aSuite*/,RWTLS::TIdType /*IdType*/,const TDesC8& /*aKeyId*/) + { + return KErrNone; + } + +/** + * Sets the supported cipher suites for the connection + */ +TInt CDummyWTLS::SetCipherSuites(const RWTLS::CipherSuiteArray& /*aCipherSuites*/) + { + return KErrNone; + } + +/** + * Set the proposed sequence number mode + */ +TInt CDummyWTLS::SetSequenceNumberMode(RWTLS::TSequenceNumberMode aMode) + { + iSequenceNumMode=aMode; + return KErrNone; + } + +/** + * Set the proposed key refresh rate + */ +TInt CDummyWTLS::SetKeyRefreshRate(TUint8 aRate) + { + iKeyRefreshRate=aRate; + return KErrNone; + } + +/** + * Set the shared secret + */ +TInt CDummyWTLS::SetSharedSecret(const TDesC8& /*aSharedSecret*/) + { + return KErrNone; + } + +/** + * Enables/disables record length usage + * If the record length usage is set to ETrue, each msg sent to the server + * will contain the msg length field. Record length usage should be turned + * on if the bearer is not able to provide the size of the transport SDU + */ +TInt CDummyWTLS::SetRecordLengthUsage(TBool aUsage) + { + iRecordLenUsage=aUsage; + return KErrNone; + } + +/** + * Make the handshake with the server to agree security parameters + * If called more than once, a renegotiation is done + * pre-condition: The connection must be opened in secure mode before this. + */ +void CDummyWTLS::Connect(TRequestStatus& aStatus, TBool aTwoPhaseHandshake) + { + aStatus=KRequestPending; + iConnect=&aStatus; + iTwoPhaseHandshake=aTwoPhaseHandshake; + //TODO: We need to use the Dummy Observer instead + User::RequestComplete(iConnect, RWTLS::EHandshakeOk); + } + +/** + * Stop processing a secure handshake + * This method can be used to abort a secure handshake if application + * validation of the certificate fails + */ +void CDummyWTLS::CancelConnect() + { + User::RequestComplete(iConnect,KErrCancel); + } + +/** + * Continues the processing of a secure handshake + */ +TInt CDummyWTLS::ConnectPhaseTwo(TRequestStatus& aStatus) + { + aStatus=KRequestPending; + iConnectPhaseTwo=&aStatus; + return KErrNone; + } + +/** + * Cancel second phase of connection + */ +void CDummyWTLS::CancelConnectPhaseTwo() + { + User::RequestComplete(iConnectPhaseTwo,KErrCancel); + } + +/** + * Get the current cipher suite + * + * The default is RC5+SHA_80,RC5+SHA_40,RC5+SHA,RC5_56+SHA,RC5_40+SHA_80,RC5_40+SHA + */ +TInt CDummyWTLS::GetCipherSuite(RWTLS::TCipherSuite& /*aCipherSuite*/) const + { + // + // need to set-up array with the default and return it + // + return KErrNone; + } + +/** + * Get the currently used sequence number mode + * Either of ENotUsed, EImplicit, EExplicit + * + * If the sequence number mode isn't set the default is EImplicit + */ +TInt CDummyWTLS::GetSequenceNumberMode(RWTLS::TSequenceNumberMode& aMode) const + { + aMode=iSequenceNumMode; + return KErrNone; + } + +/** + * Get the current key refresh rate + * Rate (0-15). The default is 4. + */ +TInt CDummyWTLS::GetKeyRefreshRate(TUint8& aRate) const + { + aRate = iKeyRefreshRate; + return KErrNone; + } +/** +Set the server address to the one read from the ini file. +@param aAddr Descriptor that hold the address read in from the ini file +*/ +EXPORT_C void CDummyWSPCLConn::SetServerAddressL(const TDesC8& aAddr) + { + delete iServerAddr; + iServerAddr = aAddr.AllocL(); + } + +const TDesC8& CDummyWSPCLConn::GetServerAddr() + { + if(!(iServerAddr)) + { + return KNullDesC8; + } + else + { + return (*(iServerAddr)); + } + } +