wapstack/wapmessageapi/sws/ActiveSocket.cpp
branchRCL_3
changeset 18 50bae5c5c85f
--- /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;
+	}