--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wapstack/wapmessageapi/sws/ActiveSocket.cpp Tue Apr 20 17:00:49 2010 +0100
@@ -0,0 +1,1126 @@
+// Copyright (c) 2003-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 "ActiveSocket.h"
+#include <es_wsms.h>
+#include "CLWSPPduHandler.h"
+#include "wapmsgerr.h"
+#include <wap_sock.h>
+#include "WapMessageApiAgent.h"
+#include "WapSwsLog.h"
+#include "WapMsgUtils.h"
+
+using namespace Wap;
+
+void CActiveSocket::NewL(RSocketServ& aSocketServ, RPointerArray<CActiveSocket>& aActiveSockets, Wap::TBearer aBearer, TWapMessageType aType, MProgressNotify* aNotify, Wap::TPort aLocalPort, RConnection* aConnection)
+/**
+The static new function instanciates corresponding Bearers in terms of the input bearer type.
+This function is used by Bound Wap APIs which listen the incoming packet to a specific port.
+@internalComponent
+@released
+@since v8.0
+@param aSocketServ the shared RSocketServ instance used in the Wap messaging API which owns this bearer
+@param aActiveSockets the bearer array used in the Wap messaging API which owns the bearer
+@param aBearer the bearer to listen on (use EAll for all bearers)
+@param aType the type of the wap message that will received
+@param aNotify the instance to be notified when a wap message is received
+@param aLocalPort the port to listen on
+@param aConnection the shared connection from Wap messaging API client
+*/
+ {
+ //Instanciate the corresponding
+ switch(aBearer)
+ {
+ case Wap::ESMS7:
+ case Wap::ESMS:
+ case Wap::EWAPSMS7:
+ case Wap::EWAPSMS:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketSMS(aSocketServ, aNotify, aBearer, aLocalPort);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ case Wap::EIP:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketUDP(aSocketServ, aNotify, aBearer, aLocalPort, aConnection);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ case Wap::EAll:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketUDP(aSocketServ, aNotify, Wap::EIP, aLocalPort, aConnection);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ CActiveSocket* me1 = new(ELeave) CActiveSocketSMS(aSocketServ, aNotify, Wap::ESMS, aLocalPort);
+ CleanupStack::PushL(me1);
+ me1->ConstructL(aType);
+ aActiveSockets.ReserveL(2); // pre-allocate the memory
+ aActiveSockets.AppendL(me1);
+ CleanupStack::Pop(me1);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ default:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocket::NewL Unknown Bearer Type"));)
+ User::Leave(Wap::EBearerError);
+ }
+ }
+ }
+
+void CActiveSocket::NewL(RSocketServ& aSocketServ, RPointerArray<CActiveSocket>& aActiveSockets, Wap::TBearer aBearer, TWapMessageType aType, MProgressNotify* aNotify, const TSockAddr& aRemoteAddr, RConnection* aConnection)
+/**
+The static new function instanciates corresponding Bearers in terms of the input bearer type.
+This function is used by Fully specified Wap APIs which will open a socket with a single, named remote host.
+@internalComponent
+@released
+@since v8.0
+@param aSocketServ the shared RSocketServ instance used in the Wap messaging API which owns this bearer
+@param aActiveSockets the bearer array used in the Wap messaging API which owns the bearer
+@param aBearer the bearer to listen on (use EAll for all bearers)
+@param aType the type of the wap message that will received
+@param aNotify the instance to be notified when a wap message is received
+@param aRemoteAddr the remote host to be communicate with
+@param aConnection the shared connection from Wap messaging API client
+*/
+ {
+ //Instanciate the corresponding
+ switch(aBearer)
+ {
+ case Wap::ESMS7:
+ case Wap::ESMS:
+ case Wap::EWAPSMS7:
+ case Wap::EWAPSMS:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketSMS(aSocketServ, aNotify, aBearer, aRemoteAddr);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ case Wap::EIP:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketUDP(aSocketServ, aNotify, aBearer, aRemoteAddr, aConnection);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ case Wap::EAll:
+ {
+ CActiveSocket* me = new(ELeave) CActiveSocketUDP(aSocketServ, aNotify, aBearer, aRemoteAddr, aConnection);
+ CleanupStack::PushL(me);
+ me->ConstructL(aType);
+ CActiveSocket* me1 = new(ELeave) CActiveSocketSMS(aSocketServ, aNotify, aBearer, aRemoteAddr);
+ CleanupStack::PushL(me1);
+ me1->ConstructL(aType);
+ aActiveSockets.ReserveL(2); // pre-allocate the memory
+ aActiveSockets.AppendL(me1);
+ CleanupStack::Pop(me1);
+ aActiveSockets.AppendL(me);
+ CleanupStack::Pop(me);
+ break;
+ }
+ default:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocket::NewL Unknown Bearer Type"));)
+ User::Leave(Wap::EBearerError);
+ }
+ }
+ }
+
+CActiveSocket::CActiveSocket(RSocketServ& aSocketServ, Wap::TBearer aBearerType, MProgressNotify* aNotify, Wap::TPort aLocalPort)
+:CActive(EPriorityStandard), iLocalAddr(0), iSocketServ(aSocketServ), iBearerType(aBearerType), iLocalPort(aLocalPort), iSocketState(ESocketIdle),iNotify(aNotify), iBuf(0,0), iRxlength(0), iBufCon(0,0)
+/**
+Constructor of bearer base class for Bound Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CActiveSocket::CActiveSocket(RSocketServ& aSocketServ, Wap::TBearer aBearerType, MProgressNotify* aNotify, const TSockAddr& aRemoteAddr, Wap::TPort aLocalPort): CActive(EPriorityStandard),
+iRemoteAddr(aRemoteAddr), iLocalAddr(0), iSocketServ(aSocketServ), iBearerType(aBearerType), iLocalPort(aLocalPort), iSocketState(ESocketIdle), iNotify(aNotify), iBuf(0,0), iRxlength(0), iBufCon(0,0)
+/**
+Constructor of bearer base class for fully specified Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CActiveSocket::~CActiveSocket()
+/**
+Destructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ Cancel();
+ iSocket.Close();
+ if (iMessageRecord)
+ {
+ delete iMessageRecord;
+ }
+ }
+
+void CActiveSocket::ConstructL(TWapMessageType aType)
+/**
+Second Phase Constructor
+@internalComponent
+@released
+@param aType the type of Wap message which is received.
+@since v8.0
+*/
+ {
+ iMessageRecord=CWapMessageRecord::NewL(aType);
+ }
+
+RSocket& CActiveSocket::Socket()
+/**
+To get the RSocket instance ownd by this bearer
+@internalComponent
+@released
+@since v8.0
+@returns the reference of the RSocket instance.
+*/
+ {
+ return iSocket;
+ }
+
+Wap::TBearer CActiveSocket::GetBearerType()
+/**
+To get the bearer type of this bearer
+@internalComponent
+@released
+@since v8.0
+@returns the bearer type
+*/
+ {
+ return iBearerType;
+ }
+
+TSockAddr& CActiveSocket::GetLocalAddress()
+/**
+To get the local address of this bearer
+@internalComponent
+@released
+@since v8.0
+@returns the lcoal address instance
+*/
+ {
+ iSocket.LocalName(iLocalAddr);
+ return iLocalAddr;
+ }
+
+TSockAddr& CActiveSocket::GetRemoteAddress()
+/**
+To get the remote address of the last received packet
+@internalComponent
+@released
+@since v8.0
+@returns the remote address instance
+*/
+ {
+ return iRemoteAddr;
+ }
+
+TInt CActiveSocket::GetRemoteAddress(HBufC8*& aAddr)
+/**
+To get the remote address of the last received packet
+@internalComponent
+@released
+@since v8.0
+@param aAddr the remote host name
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ TRAPD(err, aAddr=iRemoteAddr.AllocL())
+ if (err==KErrNone)
+ {
+ Wap::TPort port;
+ TPtr8 des=aAddr->Des();
+ TRAP(err, CSWSWapMsgUtils::AnalyseAddrL(iRemoteAddr, iBearerType, des, port))
+ }
+ else
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocketUDP::GetServerAddress: Alloc Memory Err=%d"), err);)
+ }
+ return err;
+ }
+
+TInt CActiveSocket::GetLocalPort(Wap::TPort& aLocalPort)
+/**
+To get the lcoal port of this bearer
+@internalComponent
+@released
+@since v8.0
+@param aLocalPort the local port of this bearer
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ GetLocalAddress();
+ aLocalPort=Wap::TPort(iLocalAddr.Port());
+ return KErrNone;
+ }
+
+TUint32 CActiveSocket::GetPduSize()
+/**
+To get the received Wdp Pdu length
+@internalComponent
+@released
+@since v8.0
+@returns the length of the received Wdp pdu.
+*/
+ {
+ return iMessageRecord->GetPduSize();
+ }
+
+TWapMessageState CActiveSocket::GetDataState()
+/**
+To get the state of the data that is being received
+@internalComponent
+@released
+@since v8.0
+@returns the state of the data that is being received
+*/
+ {
+ return iMessageRecord->GetDataState();
+ }
+
+void CActiveSocket::SetDataState(TWapMessageState aState)
+/**
+To set the state of the data that is being received
+@internalComponent
+@released
+@since v8.0
+@param aState the state of the data that is being received
+*/
+ {
+ iMessageRecord->SetDataState(aState);
+ }
+
+TInt CActiveSocket::GetPduData(TDes8& aBuffer, TBool& aTruncated)
+/**
+To get the received Wdp pdu.
+@internalComponent
+@released
+@since v8.0
+@param aBuffer the buffer to read the received WDP pdu
+@param aTruncated the flag to represent if the data has be truncated or not
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ return iMessageRecord->GetPduData(aBuffer, aTruncated);
+ }
+
+TInt CActiveSocket::GetWspData(TDes8& aWspHeader, TDes8& aWspBody, TUint8& aTransactionId, TWSPStatus& aStatus)
+/**
+To get the received Wsp header, body, tranaction ID and Wsp status.
+@internalComponent
+@released
+@since v8.0
+@param aWspHeader the buffer to read the received Wsp header
+@param aWspBody the buffer to read the received Wsp body
+@param aTransactionId the transaction ID of the received Wsp Message
+@param aStatus the Wsp status of the received Wsp Message
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ return iMessageRecord->GetWspData(aWspHeader, aWspBody, aTransactionId, aStatus);
+ }
+void CActiveSocket::UnpackPduToWspDataL()
+/**
+To extract the Wsp header, body, transaction ID and status from the received WDP pdu
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ iMessageRecord->UnpackPduToWspDataL();
+ }
+
+void CActiveSocket::CleanUpData()
+ {
+ TPtr8 zero(0,0);
+ iBuf.Set(zero);
+ iBufCon.Set(zero);
+ iMessageRecord->CleanUpData();
+ }
+
+/** SMS active socket
+*/
+CActiveSocketSMS::CActiveSocketSMS(RSocketServ& aSocketServ, MProgressNotify* aNotify, Wap::TBearer aBearer, Wap::TPort aLocalPort)
+:CActiveSocket(aSocketServ, aBearer, aNotify, aLocalPort)
+/**
+Constructor of SMS bearer for Bound Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CActiveSocketSMS::CActiveSocketSMS(RSocketServ& aSocketServ, MProgressNotify* aNotify, Wap::TBearer aBearer, const TSockAddr& aRemoteAddr)
+:CActiveSocket(aSocketServ, aBearer, aNotify, aRemoteAddr, (Wap::TPort)EWapPortUnspecified)
+/**
+Constructor of SMS bearer for fully specified Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CActiveSocketSMS::~CActiveSocketSMS()
+/**
+Destructor of SMS bearer for fully specified Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+void CActiveSocketSMS::ConstructL(TWapMessageType aType)
+/**
+Second Phase Constructor
+@internalComponent
+@released
+@param aType the type of Wap message which is received.
+@since v8.0
+*/
+ {
+ CActiveSocket::ConstructL(aType);
+ User::LeaveIfError(iSocket.Open(iSocketServ, KWAPSMSAddrFamily, KSockDatagram, KWAPSMSDatagramProtocol));
+ User::LeaveIfError(iSocket.SetOpt(KWapSmsOptionNewStyleClient,KWapSmsOptionLevel, 0));
+ TWapAddr wapAddr;
+ wapAddr.SetWapPort(TWapPortNumber(iLocalPort));
+ TInt err=iSocket.Bind(wapAddr);
+ if (err==KErrInUse)
+ {
+ User::Leave(Wap::EPortAlreadyBound);
+ }
+ }
+
+TInt CActiveSocketSMS::AwaitRecvDataSize()
+/**
+Read the received Wdp pdu length.
+@internalComponent
+@released
+@since v8.0
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ TPckgBuf<TUint32>* length=iMessageRecord->GetPduSizeRef();
+ iSocket.Ioctl(KSOGetLength, iStatus, length, KSolWapProv);
+ iMessageRecord->SetDataState(ERequestingLength);
+ iSocketState=ESocketWaitingForLength;
+ SetActive();
+ return KErrNone;
+ }
+
+TInt CActiveSocketSMS::Receive()
+/**
+Read the received Wdp pdu.
+@internalComponent
+@released
+@since v8.0
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ TInt err=KErrNone;
+ TRAP(err, iMessageRecord->CreatePduBufferL(EFalse))
+ if (err!=KErrNone)
+ {
+ return err;
+ }
+ HBufC8*& pdu=iMessageRecord->GetPduPtr();
+ iBuf.Set(pdu->Des());
+ iSocket.RecvFrom(iBuf, iRemoteAddr, 0, iStatus);
+ iMessageRecord->SetDataState(ERequestingData);
+ iSocketState=ESocketWaitingForData;
+ SetActive();
+ return KErrNone;
+ }
+
+void CActiveSocketSMS::RunL()
+/**
+Overload the CActive virtual methods
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ switch (iSocketState)
+ {
+ case ESocketWaitingForLength:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocketSMS::RunL() ESocketWaitingForLength"));)
+ iMessageRecord->SetDataState(EPendingLength);
+ iSocketState=ESocketIdle;
+ TWapNotificationInfo info(iBearerType, iStatus.Int());
+ TWapNotificationInfoBuf infoBuf(info);
+ iNotify->Notification(EPduLengthReceived, infoBuf);
+ break;
+ }
+ case ESocketWaitingForData:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocketSMS::RunL() ESocketWaitingForData"));)
+ iMessageRecord->SetDataState(EPendingData);
+ iSocketState=ESocketIdle;
+ TWapNotificationInfo info(iBearerType, iStatus.Int());
+ TWapNotificationInfoBuf infoBuf(info);
+ iNotify->Notification(EPduReceived, infoBuf);
+ iSocket.SetOpt(KWapSmsOptionOKToDeleteMessage,KWapSmsOptionLevel, 0);
+ break;
+ }
+ default:
+ LOG(SwsLog::Printf(_L("CActiveSocketSMS::RunL() Unknown State")););
+ }
+ }
+void CActiveSocketSMS::DoCancel()
+/**
+Overload the CActive virtual methods
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ switch (iSocketState)
+ {
+ case ESocketWaitingForLength:
+ {
+ iSocket.CancelIoctl();
+ break;
+ }
+ case ESocketWaitingForData:
+ {
+ iSocket.CancelRecv();
+ break;
+ }
+ default:
+ LOG(SwsLog::Printf(_L("CActiveSocketSMS::DoCancel() Unknown State")););
+ }
+ }
+
+//
+// UDP active socket
+//
+CActiveSocketUDP::CActiveSocketUDP(RSocketServ& aSocketServ, MProgressNotify* aNotify, Wap::TBearer aBearer, Wap::TPort aLocalPort, RConnection* aConnection)
+:CActiveSocket(aSocketServ, aBearer, aNotify, aLocalPort),iConnection(aConnection)
+/**
+Constructor for Bound Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CActiveSocketUDP::CActiveSocketUDP(RSocketServ& aSocketServ, MProgressNotify* aNotify, Wap::TBearer aBearer, const TSockAddr& aRemoteAddr, RConnection* aConnection)
+:CActiveSocket(aSocketServ, aBearer, aNotify, aRemoteAddr,0), iConnection(aConnection)
+/**
+Constructor for FullySpec Wap APIs
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+void CActiveSocketUDP::ConstructL(TWapMessageType aType)
+/**
+Second Phase constructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ CActiveSocket::ConstructL(aType);
+ if (!iConnection)
+ {
+ User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp));
+ }
+ else
+ {
+ User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockDatagram, KProtocolInetUdp, *iConnection));
+ }
+ TInetAddr inetAddr(iLocalPort);
+ TInt err=iSocket.Bind(inetAddr);
+ if (err==KErrInUse)
+ {
+ User::Leave(Wap::EPortAlreadyBound);
+ }
+ }
+
+CActiveSocketUDP::~CActiveSocketUDP()
+/**
+Destructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+TInt CActiveSocketUDP::AwaitRecvDataSize()
+/**
+Wait for Pdu data size
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ iRxlength=0;
+ TRAPD(err, iMessageRecord->CreatePduBufferL(ETrue))
+ if (err!=KErrNone)
+ {
+ return err;
+ }
+ HBufC8*& pdu=iMessageRecord->GetPduPtr();
+ iBuf.Set(pdu->Des());
+ iSocket.RecvFrom(iBuf, iRemoteAddr, 0, iStatus, iRxlength);
+ iMessageRecord->SetDataState(ERequestingLength);
+ iSocketState=ESocketWaitingForLength;
+ SetActive();
+ return KErrNone;
+ }
+
+TInt CActiveSocketUDP::Receive()
+/**
+Receive the pdu
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ if(iMessageRecord->GetDataState()==EContinuous)
+ {
+ TRAPD(err, iMessageRecord->CreatePduBufferL(ETrue))
+ if (err!=KErrNone)
+ {
+ return err;
+ }
+ HBufC8*& pdu=iMessageRecord->GetPduPtr();
+ iBuf.Set(pdu->Des());
+ iBuf.SetLength(iBuf.Length()+1);
+ iBufCon.Set(&iBuf[iBuf.Length()-1],0,iBuf.MaxLength()-iBuf.Length());
+ iBuf.SetLength(iBuf.Length()+iRxlength()-1);
+ iSocket.RecvFrom(iBufCon, iRemoteAddr, KSockReadContinuation, iStatus,iRxlength);
+ iMessageRecord->SetDataState(ERequestingData);
+ iSocketState=ESocketWaitingForData;
+ SetActive();
+ }
+ else
+ {
+ iMessageRecord->SetDataState(ERequestingData);
+ iSocketState=ESocketWaitingForData;
+ iStatus = KRequestPending;
+ SetActive();
+ TRequestStatus* reqStatus=&iStatus;
+ User::RequestComplete(reqStatus, KErrNone);
+ }
+ return KErrNone;
+ }
+
+void CActiveSocketUDP::RunL()
+/**
+RunL()
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ switch (iSocketState)
+ {
+ case ESocketWaitingForLength:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocketUDP::RunL() ESocketWaitingForLength"));)
+ iMessageRecord->SetPduSize(iBuf.Length()+ iRxlength());
+ if(iRxlength() > 0)
+ {
+ iMessageRecord->SetDataState(EContinuous);
+ }
+ else
+ {
+ iMessageRecord->SetDataState(EPendingLength);
+ }
+ iSocketState=ESocketIdle;
+ TWapNotificationInfo info(iBearerType, iStatus.Int());
+ TWapNotificationInfoBuf infoBuf(info);
+ iNotify->Notification(EPduLengthReceived, infoBuf);
+ break;
+ }
+ case ESocketWaitingForData:
+ {
+ LOG(SwsLog::Printf(_L("CActiveSocketUDP::RunL() ESocketWaitingForData"));)
+ iMessageRecord->SetDataState(EPendingData);
+ iSocketState=ESocketIdle;
+ TWapNotificationInfo info(iBearerType, iStatus.Int());
+ TWapNotificationInfoBuf infoBuf(info);
+ iNotify->Notification(EPduReceived, infoBuf);
+ break;
+ }
+ default:
+ LOG(SwsLog::Printf(_L("CActiveSocketUDP::RunL() Unknown State"));)
+ break;
+ }
+ }
+
+void CActiveSocketUDP::DoCancel()
+/**
+Cancel the outstanding request on UDP bearer
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ switch (iSocketState)
+ {
+ case ESocketWaitingForLength:
+ {
+ iSocket.CancelRecv();
+ break;
+ }
+ case ESocketWaitingForData:
+ {
+ break;
+ }
+ default:
+ LOG(SwsLog::Printf(_L("CActiveSocketUDP::DoCancel() Unknown State")););
+ }
+ }
+
+//
+//CWapMessageRecord
+//
+CWapMessageRecord* CWapMessageRecord::NewL(TWapMessageType aType)
+/**
+The static funtion to instanciate the Pdu data record
+@internalComponent
+@released
+@since v8.0
+@param aType the type of Wap message which is received.
+@returns the data record instance.
+*/
+ {
+ CWapMessageRecord* me;
+ if (aType==EWapWsp)
+ {
+ me = new(ELeave) CWspMessageRecord();
+ }
+ else
+ {
+ me = new(ELeave) CWdpMessageRecord();
+ }
+ return me;
+ }
+
+CWapMessageRecord::CWapMessageRecord()
+/**
+Constructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CWapMessageRecord::~CWapMessageRecord()
+/**
+Destructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ if (iPdu)
+ {
+ delete iPdu;
+ }
+ }
+
+TWapMessageState CWapMessageRecord::GetDataState()
+/**
+To get the state of the data that is being received
+@internalComponent
+@released
+@since v8.0
+returns the state of the data that is being received
+*/
+ {
+ return iState;
+ }
+
+void CWapMessageRecord::SetDataState(TWapMessageState aState)
+/**
+To set the state of the data that is being received
+@internalComponent
+@released
+@since v8.0
+@param the state of the data that is being received
+*/
+ {
+ iState=aState;
+ }
+
+TPckgBuf<TUint32>* CWapMessageRecord::GetPduSizeRef()
+/**
+To get the buffer which is used to contain the received data length
+@internalComponent
+@released
+@since v8.0
+@returns the pointer to the buffer length
+*/
+ {
+ return &iDataLength;
+ }
+
+void CWapMessageRecord::SetPduSize(TUint32 aLength)
+ {
+ iDataLength=aLength;
+ }
+
+TUint32 CWapMessageRecord::GetPduSize()
+/**
+To get the received wdp pdu length
+@internalComponent
+@released
+@since v8.0
+@returns the received wdp pdu length
+*/
+ {
+ iState=EGotLength;
+ return iDataLength();
+ }
+
+HBufC8*& CWapMessageRecord::GetPduPtr()
+/**
+To get the received wdp pdu.
+@internalComponent
+@released
+@since v8.0
+@returns the pointer the received wdp buffer
+*/
+ {
+ return iPdu;
+ }
+
+void CWapMessageRecord::CreatePduBufferL(TBool aFixLengthFlag)
+/**
+create the wdp pdu buffer according to the length
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ if (iState==EContinuous)
+ {
+ iPdu->ReAllocL(iDataLength());
+ }
+ else if (!aFixLengthFlag)
+ {
+ iPdu=HBufC8::NewL(iDataLength());
+ }
+ else
+ {
+ iPdu=HBufC8::NewL(KMaxUdpBearerDataBufferLength);
+ }
+ }
+
+void CWapMessageRecord::CleanUpData()
+/**
+clean up the receive buffer.
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ if (iPdu)
+ {
+ delete iPdu;
+ iPdu=NULL;
+ }
+ iDataLength.FillZ();
+ iState=EIdle;
+ }
+
+//
+//CWspMessageRecord methods
+//
+CWspMessageRecord::CWspMessageRecord()
+/**
+Constructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CWspMessageRecord::~CWspMessageRecord()
+/**
+Destructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ if (iWspHeader)
+ {
+ delete iWspHeader;
+ }
+ if (iWspBody)
+ {
+ delete iWspBody;
+ }
+ }
+
+void CWspMessageRecord::UnpackPduToWspDataL()
+/**
+To unpack the received wdp pdu to wsp message.
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ TWSPPduType type;
+ CCLWSPPduHandler::UnpackWSPPduL(iPdu, type, iWspHeader, iWspBody, iTransactionId, iWspStatus);
+ }
+
+TInt CWspMessageRecord::GetWspData(TDes8& aWspHeader, TDes8& aWspBody, TUint8& aTransactionId, TWSPStatus& aWspStatus)
+/**
+To read the wsp message from the buffer
+@internalComponent
+@released
+@since v8.0
+@param aWspHeader the buffer to contain the wsp header
+@param aWspBody the buffer to contain the wsp body
+@param iTransactionId the received transaction ID
+@param aWspStatus the received wsp status
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ if (!iWspHeader && !iWspBody)
+ {
+ // if no data, should not be here at all
+ LOG(SwsLog::Printf(_L("CWspMessageRecord::GetWspData() No Data Available"));)
+ CleanUpData();
+ return KErrBadDescriptor;
+ }
+ TInt ret=KErrNone;
+ //Copy the transaction ID
+ aTransactionId=iTransactionId;
+ aWspStatus=iWspStatus;
+ //Copy the header
+ TInt bufferLength;
+ if (iWspHeader)
+ {
+ bufferLength=aWspHeader.MaxLength();
+ TPtrC8 remainHeader=iWspHeader->Mid(iHeaderOffset);
+ //Client Header buffer is not long enough
+ if (bufferLength<remainHeader.Length())
+ {
+ aWspHeader.Copy(remainHeader.Ptr(), bufferLength);
+ iHeaderOffset+=bufferLength;
+ iState=EReading;
+ ret=Wap::EMoreData;
+ }
+ else
+ {
+ aWspHeader.Copy(remainHeader);
+ iHeaderOffset=0;
+ delete iWspHeader;
+ iWspHeader=NULL;
+ }
+ }
+ if (iWspBody)
+ {
+ //Copy the Body
+ bufferLength=aWspBody.MaxLength();
+ TPtrC8 remainBody=iWspBody->Mid(iBodyOffset);
+
+ //Client Header buffer is not long enough
+ if (bufferLength<remainBody.Length())
+ {
+ aWspBody.Copy(remainBody.Ptr(), bufferLength);
+ iBodyOffset+=bufferLength;
+ iState=EReading;
+ ret=Wap::EMoreData;
+ }
+ else
+ {
+ aWspBody.Copy(remainBody);
+ iBodyOffset=0;
+ delete iWspBody;
+ iWspBody=NULL;
+ }
+ }
+ //All Wsp Data has been read.
+ if (ret==KErrNone)
+ {
+ delete iPdu;
+ iPdu=NULL;
+ iDataLength.FillZ();
+ iState=EIdle;
+ }
+ return ret;
+ }
+
+TInt CWspMessageRecord::GetPduData(TDes8& /*aBuffer*/, TBool& /*aTruncated*/)
+/**
+Not supported
+@internalComponent
+@released
+@since v8.0
+*/
+ {//Should not be used
+ return KErrNotSupported;
+ }
+
+void CWspMessageRecord::CleanUpData()
+/**
+To clean up the wsp related data
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ CWapMessageRecord::CleanUpData();
+ if (iWspHeader)
+ {
+ delete iWspHeader;
+ iWspHeader=NULL;
+ }
+ if (iWspBody)
+ {
+ delete iWspBody;
+ iWspBody=NULL;
+ }
+ iTransactionId=0;
+ iHeaderOffset=0;
+ iBodyOffset=0;
+ }
+//
+//CWspMessageRecord method
+//
+CWdpMessageRecord::CWdpMessageRecord()
+/**
+Constructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+CWdpMessageRecord::~CWdpMessageRecord()
+/**
+Destructor
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ }
+
+TInt CWdpMessageRecord::GetPduData(TDes8& aBuffer, TBool& aTruncated)
+/**
+To read the received Wdp pdu
+@internalComponent
+@released
+@since v8.0
+@param aBuffer the buffer to contain the received wdp pdu
+@param aTruncated the flag to represent if the data is truncated or not
+@returns KErrNone on successful completion, or one of the system error codes on failure.
+*/
+ {
+ if (!iPdu)
+ {
+ //Should not be here at all
+ LOG(SwsLog::Printf(_L("CWdpMessageRecord::GetPduData No Data Available"));)
+ CleanUpData();
+ return KErrBadDescriptor;
+ }
+ TInt ret=KErrNone;
+ TInt bufLength=aBuffer.MaxLength();
+ TPtrC8 remainPdu=iPdu->Mid(iPduOffset);
+ if (bufLength<remainPdu.Length())
+ {
+ aBuffer.Copy(remainPdu.Ptr(), bufLength);
+ iPduOffset+=bufLength;
+ iState=EReading;
+ aTruncated=ETrue;
+ ret=Wap::EMoreData;
+ }
+ else
+ {
+ aBuffer.Copy(remainPdu);
+ aTruncated=EFalse;
+ CleanUpData();
+ }
+ return ret;
+ }
+
+void CWdpMessageRecord::UnpackPduToWspDataL()
+/**
+Not supported
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ //Should not be used
+ User::Leave(KErrNotSupported);
+ }
+
+TInt CWdpMessageRecord::GetWspData(TDes8& /*aWspHeader*/, TDes8& /*aWspBody*/, TUint8& /*aTransactionId*/, TWSPStatus& /*aWspStatus*/)
+/**
+Not supported
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ //Should not be used
+ return KErrNotSupported;
+ }
+
+void CWdpMessageRecord::CleanUpData()
+/**
+To clean up the wdp related data
+@internalComponent
+@released
+@since v8.0
+*/
+ {
+ CWapMessageRecord::CleanUpData();
+ iPduOffset=0;
+ }