--- a/smsprotocols/smsstack/wapprot/Src/ws_prvdr.cpp Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/wapprot/Src/ws_prvdr.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,737 +1,737 @@
-// Copyright (c) 1999-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:
-// Implements CWapSmsProvider and CWapSmsProviderWrite
-//
-//
-
-/**
- @file
-*/
-
-#include <e32std.h>
-#include <wap_sock.h>
-#include "ws_main.h"
-#include "es_wsms.h"
-#include "WAPDGRM.H"
-#include "ws_obsvr.h"
-#include "smsprot.h"
-#include <es_mbuf.h>
-
-//
-// implementation of CWapSmsProvider
-//
-
- // CWapSmsProvider policies
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetLocalNamePolicy, ECapabilityNetworkServices );
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetOptionPolicy, ECapability_None);
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetLengthIoctlPolicy,ECapability_None);
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParamLengthIoctlPolicy,ECapability_None);
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParametersIoctlPolicy,ECapabilityReadDeviceData);
- static _LIT_SECURITY_POLICY_C1(wapSmsProviderWritePolicy,ECapabilityNetworkServices);
-
-
-/**
- * Factory
- */
-CWapSmsProvider* CWapSmsProvider::NewL(CWapSmsProtocol* aProtocol)
- {
- LOGWAPPROT1("CWapSmsProvider::NewL()");
-
- CWapSmsProvider* provider=new(ELeave) CWapSmsProvider(aProtocol);
- CleanupStack::PushL(provider);
- provider->iWapSmsProviderWrite = CWapSmsProviderWrite::NewL(*provider);
- CleanupStack::Pop();
- return provider;
- } // CWapSmsProvider::NewL
-
-
-/**
- * Constructor
- */
-CWapSmsProvider::CWapSmsProvider(CWapSmsProtocol* aProtocol)
- :iMessageType(ESmartMessage)
- ,iProtocol(aProtocol)
- ,iSendPending(EFalse)
- ,iIoctlOutstanding(EFalse)
- ,iIsNewStyleClient(EFalse)
- ,iStatusReportScheme(EWapSmsDefault)
- {
- iRecvdMsgQueue.SetOffset(CWapDatagram::LinkOffset());
- } // CWapSmsProvider::CWapSmsProvider
-
-
-/**
- * Destructor
- */
-CWapSmsProvider::~CWapSmsProvider()
- {
- iSAPLink.Deque();
-
- while(!iRecvdMsgQueue.IsEmpty())
- {
- CWapDatagram* msg = iRecvdMsgQueue.First();
- iRecvdMsgQueue.Remove(*msg);
- delete msg;
- }
-
- delete iWapSmsProviderWrite;
- } // CWapSmsProvider::~CWapSmsProvider
-
-
-/**
- * Return WAPSMS options
- */
-TInt CWapSmsProvider::GetOption(TUint aLevel,TUint aName, TDes8& aOption)const
- {
- LOGWAPPROT1("CWapSmsProvider::GetOption");
-
- TInt ret=KErrNone;
- if (TInt(aLevel)==KWapSmsOptionLevel && TInt(aName)==KWapSmsOptionNameDCS)
- aOption = TPtrC8((TText8*)&iDataCodingScheme,sizeof(TWapSmsDataCodingScheme));
- else
- ret=iProtocol->GetOption(aLevel,aName,aOption,NULL);
- return ret;
- } // CWapSmsProvider::GetOption
-
-
-/**
- * Set WAPSMS options
- *
- * @capability None
- *
- */
-TInt CWapSmsProvider::SetOption(TUint aLevel, TUint aName, const TDesC8& aOption)
- {
- LOGWAPPROT1("CWapSmsProvider::SetOption");
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetOptionPolicy,"CWapSmsProvider SetOption policy check") != KErrNone))
- {
- return KErrPermissionDenied;
- }
-
- TInt ret=KErrNone;
- if (TInt(aLevel)==KWapSmsOptionLevel)
- {
- switch(TInt(aName))
- {
- case KWapSmsOptionNameDCS:
- {
- iDataCodingScheme = static_cast<TWapSmsDataCodingScheme>(*aOption.Ptr());
- break;
- }
- case KWapSmsOptionWapDatagram:
- {
- iMessageType=EWapDatagram;
- break;
- }
- case KWapSmsStatusReportScheme:
- {
- iStatusReportScheme = static_cast<TWapSmsStatusReportScheme>(*aOption.Ptr());
- break;
- }
- case KWapSmsOptionNewStyleClient:
- {
- iIsNewStyleClient = ETrue;
- break;
- }
- case KWapSmsOptionOKToDeleteMessage:
- {
- //Get the first message from the queue
- CWapDatagram* msg = iRecvdMsgQueue.First();
- //Find and delete from SAR
- TBool found=iProtocol->FindAndDeleteMsg(*msg);
- if(!found)
- {
- LOGWAPPROT1("CWapSmsProvider::SetOption: Error. Couldn't find the message in the SAR for deletion");
- break;
- }
- //Remove from the queue
- iRecvdMsgQueue.Remove(*msg);
- delete msg;
- break;
- }
- default:
- ret=KErrNotSupported;
- }
-
- }
- else
- {
- ret=iProtocol->SetOption(aLevel,aName,aOption,NULL);
- }
- return ret;
- } // CWapSmsProvider::SetOption
-
-
-/**
- * Shutdown the SAP
- */
-void CWapSmsProvider::Shutdown(TCloseType aType)
- {
- LOGWAPPROT1("CWapSmsProvider::Shutdown");
- if (aType!=CServProviderBase::EImmediate)
- iSocket->CanClose();
- } // CWapSmsProvider::Shutdown
-
-
-/**
- * Setup datagram with socket specific options and forward to protocol
- * Return zero to block the send - will be completed by CWapSapMessageSender
- *
- * @capability NetworkServices
- */
-TInt CWapSmsProvider::Write(RMBufChain& aBufChain, TUint /*options*/, TSockAddr* aAddr)
- {
- LOGWAPPROT1("CWapSmsProvider::Write()");
-
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderWritePolicy,"CWapSmsProvider Write policy check") != KErrNone))
- {
- return KErrPermissionDenied;
- }
- // @note: LOGIFH2A2 macro for logging esock write
-#ifdef SMSLOGGERIF
- TInt length = aBufChain.Length();
- LOGWAPPROT2("CWapSmsProvider::Write [%d bytes]", length);
- TBuf8<0x100> dumpBuf;
- if(length > 0x100)
- {
-
- TInt parts=0;
- TInt offset = 0;
- while (offset < length)
- {
- aBufChain.CopyOut(dumpBuf, offset);
- offset += length;
- LOGIF2(_L8("ESock WAP concantonated part: %d"),parts++);
- LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
- LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
- }
-
- }
- else
- {
- aBufChain.CopyOut(dumpBuf, 0);
- LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
- LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
- }
-#endif
-
- // Note that if this fails somehow it still frees the buf chain and sets itself active - it's
- // not clear to me whether this is good behaviour but it's the pre-mbuf behaviour too
- iWapSmsProviderWrite->Start(aBufChain, *aAddr);
- return KErrNone;
- } // CWapSmsProvider::Write
-
-
-/**
- * Read a datagram off the queue
- */
-TInt CWapSmsProvider::GetData(RMBufChain& aBufChain, TUint aLength, TUint /*options*/,TSockAddr* aAddr)
- {
- LOGWAPPROT1("CWapSmsProvider::GetData()");
-
- CWapDatagram* msg = iRecvdMsgQueue.First();
- if(!iIsNewStyleClient)
- {
- iRecvdMsgQueue.Remove(*msg);
- }
- TInt err = msg->WapDatagram(aBufChain, aLength);
-
- //@note: LOGIFH2A2 macro for logging esock getdata
- LOGWAPPROT1("CWapSmsProvider::GetData");
- // Logging migrated to WapDatagram() for ease of descriptor ref
-
- if (err > 0 && aAddr)
- {
- TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(aAddr);
- TInt toPort,fromPort;
- msg->Ports(fromPort,toPort);
- wapAddr->SetWapPort(static_cast<TWapPortNumber>(fromPort));
- TBuf8<KMaxSockAddrSize> addrBuf;
- addrBuf.Copy(msg->FromAddress());
- wapAddr->SetWapAddress(addrBuf);
- }
- if(!iIsNewStyleClient)
- {
- delete msg;
- }
- return err > 0? 1: err; // datagrams are atoms not byte counts
- } // CWapSmsProvider::GetData
-
-
-/**
- * New data has arrived notify ESOCK.
- */
-void CWapSmsProvider::NewData(CWapDatagram* aMsg)
- {
- TBool notifyEsock = EFalse;
- LOGWAPPROT1("CWapSmsProvider::NewData");
-
- if(iIoctlOutstanding && iName==KSOGetLength && iIsNewStyleClient)
- {
- TPckgBuf<TInt> buf= aMsg->WapDatagramLength();
- iSocket->IoctlComplete(&buf);
- iIoctlOutstanding= EFalse;
- iName= NULL;
- notifyEsock = ETrue;
- }
- else if(iIoctlOutstanding && iName==KSOGetMessageParametersLength && iIsNewStyleClient)
- {
- CBufFlat* buffer = aMsg->SmsExternalisedStream();
- TPckgBuf<TInt> buf = buffer->Size();
- iSocket->IoctlComplete(&buf);
- iIoctlOutstanding= EFalse;
- iName= NULL;
- notifyEsock = ETrue;
- }
- else if(iIoctlOutstanding && iName==KSOGetMessageParameters && iIsNewStyleClient)
- {
- CBufFlat* buffer = aMsg->SmsExternalisedStream();
- TPtr8 buf = buffer->Ptr(0);
- iSocket->IoctlComplete(&buf);
- iIoctlOutstanding= EFalse;
- iName= NULL;
- notifyEsock = ETrue;
- }
- else if(iName!=KSOGetLength && iName!=KSOGetMessageParametersLength && iName!=KSOGetMessageParameters && iIsNewStyleClient)
- {
- notifyEsock= EFalse;
- }
-
- if(!iIsNewStyleClient || notifyEsock)
- iSocket->NewData(1);
- //else we notify ESock in IOCTL for new client
- } // CWapSmsProvider::NewData
-
-
-/**
- * Error happened, notify ESOCK
- */
-void CWapSmsProvider::Error(TInt aError, TUint aOperationMask)
- {
- LOGWAPPROT3("CWapSmsProvider::Error [aError=%d, mask=%d] ", aError, aOperationMask);
-
- iSocket->Error(aError, aOperationMask);
- } // CWapSmsProvider::Error
-
-
-/**
- * Return the offset to the dblquelink
- */
-TInt CWapSmsProvider::LinkOffset()
- {
- LOGWAPPROT1("CWapSmsProvider::LinkOffset");
-
- return _FOFF(CWapSmsProvider,iSAPLink);
- } // CWapSmsProvider::LinkOffset
-
-
-/**
- * Return the address associated with the sap
- */
-void CWapSmsProvider::LocalName(TSockAddr& aAddr) const
- {
- LOGWAPPROT1("CWapSmsProvider::LocalName");
-
- Mem::Copy(&aAddr,&iLocalAddress,sizeof(TSockAddr));
- } // CWapSmsProvider::LocalName
-
-
-/**
- * Set the local address of the sap - called by RSocket::Bind
- *
- * @capability NetworkServices
- */
-TInt CWapSmsProvider::SetLocalName(TSockAddr& aAddr)
- {
- LOGWAPPROT1("CWapSmsProvider::SetLocalName()");
-
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetLocalNamePolicy,"CWapSmsProvider SetLocalName policy check") != KErrNone))
- {
- return KErrPermissionDenied;
- }
- TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(&aAddr);
- LOGWAPPROT2("CWapSmsProvider::SetLocalName %d",wapAddr->WapPort());
- // Due ESOCK interface port EWapPortUnspecified value (-1) can be transferred as a maximum unsigned 16 int
- if (wapAddr->WapPort()==EWapPortUnspecified || wapAddr->WapPort()==static_cast<TUint16>(EWapPortUnspecified))
- {
- if(!iProtocol->AllocateLocalAddress(iLocalAddress))
- return KErrInUse;
- else return KErrNone;
- }
-
-
- TInt ret=iProtocol->AddrAlreadyUsedByWAP(*wapAddr,this);
- if(ret == KErrInUse) return ret;
- else if(ret == KErrAlreadyExists) return KErrNone;
-
- TSmsAddr addr;
- if(wapAddr->Port() <=255)
- addr.SetSmsAddrFamily(ESmsAddrApplication8BitPort);
- else
- addr.SetSmsAddrFamily(ESmsAddrApplication16BitPort);
-
- addr.SetPort(wapAddr->Port());
-
- if((iProtocol->SmsProtocol()->SmsAddrIsAlreadyUsed(NULL,addr)))
- return KErrInUse;
-
- Mem::Copy(&iLocalAddress,&aAddr,sizeof(TSockAddr));
- TInt err;
- TRAP(err,ret = iProtocol->CheckSarL(*wapAddr,this));
- if(err!=KErrNone)
- return err;
- if(ret!=KErrNone)
- {
- Error(ret,MSocketNotify::EErrorAllOperations);
- }
- return KErrNone;
- } // RSocket::Bind
-
-
-/**
- * Returns true if aAddr matches the local address of the sap
- */
-TBool CWapSmsProvider::MatchesLocalAddress(const TWapAddr& aAddr)
- {
- LOGWAPPROT1("CWapSmsProvider::MatchesLocalAddress");
-
- return (iLocalAddress == aAddr);
- } // CWapSmsProvider::MatchesLocalAddress
-
-//
-
-
-/**
- * Called to perform specific IO control by the client (i.e. Wap Messaging API).The client is able
- * to get the size of the datagram once it has been received or confirm the receipt
- * of the message.
- *
- * Only one ioctl request may be outstanding at any one time.
- *
- * Implementation of pure virtual CServProviderBase::Ioctl().
- *
- * @param aLevel the IOCTL level. // Can be only KSolWapProv
- * @param aName the IOCTL name.
- * @param aOption the IOCTL option.
- *
- */
-void CWapSmsProvider::Ioctl(TUint aLevel,TUint aName,TDes8 * /*aOption*/)
- {
- LOGWAPPROT3("CWapSmsProvider::Ioctl [aLevel=%d, aName=%d]", aLevel, aName);
- LOGWAPPROT2("CWapSmsProtocol::Ioctl [provider=0x%08x]",this);
-
- iName=aName;
- switch (aLevel)
- {
- case KSolWapProv:
- {
- if(iIoctlOutstanding || !iIsNewStyleClient)
- {
- Error(KErrInUse,MSocketNotify::EErrorIoctl);
- break;
- }
- switch (iName)
- {
- case KSOGetLength:
- //
- // Get the length
- //
- {
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetLengthIoctlPolicy,"CWapSmsProvider GetLength Ioctl policy check") != KErrNone))
- {
- Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
- return;
- }
- iIoctlOutstanding = ETrue;
- //check the queue for any other message for this client and call new data if any exist
- if(!iRecvdMsgQueue.IsEmpty())
- {
- CWapDatagram* msg = iRecvdMsgQueue.First();
- //check the datagram.
- if(msg->IsComplete())
- {
- NewData(msg);
- }
- else
- {
- // else notify the client with error.
- // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
- Error(KErrGeneral,MSocketNotify::EErrorIoctl);
- iIoctlOutstanding = EFalse;
- }
-
- }
- break;
- }
-
- case KSOGetMessageParametersLength:
- //
- // Get the Message Parameters Length
- //
- {
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParamLengthIoctlPolicy,"CWapSmsProvider KSOGetMessageParametersLength Ioctl policy check") != KErrNone))
- {
- Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
- return;
- }
- iIoctlOutstanding = ETrue;
- //check the queue for any other message for this client and call new data if any exist
- if(!iRecvdMsgQueue.IsEmpty())
- {
- CWapDatagram* msg = iRecvdMsgQueue.First();
- //check the datagram.
- if(msg->IsComplete())
- {
- NewData(msg);
- }
- else
- {
- // else notify the client with error.
- // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
- Error(KErrGeneral,MSocketNotify::EErrorIoctl);
- iIoctlOutstanding = EFalse;
- }
-
- }
- break;
- }
-
- case KSOGetMessageParameters:
- //
- // Get the Message Parameters
- //
- {
- if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParametersIoctlPolicy,"CWapSmsProvider GetMessageParameters Ioctl policy check") != KErrNone))
- {
- Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
- return;
- }
- iIoctlOutstanding = ETrue;
- //check the queue for any other message for this client and call new data if any exist
- if(!iRecvdMsgQueue.IsEmpty())
- {
- CWapDatagram* msg = iRecvdMsgQueue.First();
- //check the datagram.
- if(msg->IsComplete())
- {
- NewData(msg);
- }
- else
- {
- // else notify the client with error.
- // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
- Error(KErrGeneral,MSocketNotify::EErrorIoctl);
- iIoctlOutstanding = EFalse;
- }
-
- }
- break;
- }
-
-
- default:
- //
- // Unsupported ioctl name
- //
- {
- // Error gracefully
- Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
- }
- }
- break;
- }
- default:
- // Gracefully error in release build
- Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
- }
- } // CServProviderBase::Ioctl
-
-
-/**
- * Cancel IOCTL- can only have one outstanding IOCTL at a time
- */
-void CWapSmsProvider::CancelIoctl(TUint aLevel,TUint aName)
- {
- LOGWAPPROT1("CWapSmsProvider::CancelIoctl()");
-
- if(!iIoctlOutstanding || (aName!=iName) || (aLevel!=KSolWapProv))
- {
- Error(KErrNotFound,MSocketNotify::EErrorIoctl);
- }
- else
- {
- iIoctlOutstanding=EFalse;
- }
- } // CWapSmsProvider::CancelIoctl
-
-
-/**
- * Start the provider- does nothing
- */
-void CWapSmsProvider::Start()
- {
- LOGWAPPROT1("CWapSmsProvider::Start()");
-
- } // CWapSmsProvider::Start
-
-void CWapSmsProvider::AddToQueue(CWapDatagram* aMsg)
-/**
- * Adding the datagram to received messages queue
- */
- {
- LOGWAPPROT1("CWapSmsProvider::AddToQueue...");
-
- iRecvdMsgQueue.AddLast(*aMsg);
- NewData(aMsg);
- } // CWapSmsProvider::AddToQueue
-
-
-TInt CWapSmsProvider::SecurityCheck(MProvdSecurityChecker* aSecurityChecker)
- {
- LOGWAPPROT1("CWapSmsProvider::SecurityCheck()");
-
- iSecurityChecker=aSecurityChecker;
- return KErrNone;
- } // CWapSmsProvider::SecurityCheck
-
-
-TWapSmsStatusReportScheme CWapSmsProvider::GetStatusReportScheme()
- {
- return iStatusReportScheme;
- }
-
-
-TWapSmsDataCodingScheme CWapSmsProvider::GetDataCodingScheme()
- {
- return iDataCodingScheme;
- }
-
-
-//
-// implementation of CWapSmsProviderWrite
-//
-
-
-/**
- * 2 phase constructor
- */
-CWapSmsProviderWrite* CWapSmsProviderWrite::NewL(CWapSmsProvider& aWapSmsProvider)
- {
- LOGWAPPROT1("CWapSmsProviderWrite::NewL");
- CWapSmsProviderWrite* self = new (ELeave) CWapSmsProviderWrite(aWapSmsProvider);
- CleanupStack::PushL(self);
- self->iMsgSender = CWapSapMessageSender::NewL(aWapSmsProvider.iProtocol->SmsProtocol(), &aWapSmsProvider);
- CleanupStack::Pop(self);
- return self;
- } // CWapSmsProviderWrite::NewL
-
-
-/**
- * Constructor
- */
-CWapSmsProviderWrite::CWapSmsProviderWrite(CWapSmsProvider& aWapSmsProvider)
- :CActive(EPriorityStandard)
- ,iWapSmsProvider(aWapSmsProvider)
- {
- LOGWAPPROT1("CWapSmsProviderWrite::CWapSmsProviderWrite()");
-
- CActiveScheduler::Add(this);
- } // CWapSmsProviderWrite::CWapSmsProviderWrite
-
-
-/**
- * Destructor
- */
-CWapSmsProviderWrite::~CWapSmsProviderWrite()
- {
- Cancel();
- delete iMsgSender;
- delete iDes;
- } // CWapSmsProviderWrite::~CWapSmsProviderWrite
-
-
-void CWapSmsProviderWrite::Start(RMBufChain& aBufChain, TSockAddr& aAddr)
- {
- LOGWAPPROT1("CWapSmsProviderWrite::Start");
- iWapAddr = reinterpret_cast<TWapAddr&>(aAddr);
- delete iDes;
- iDes = NULL;
- TRAPD(err, (iDes = HBufC8::NewL(aBufChain.Length())) );
- if(err == KErrNone)
- {
- TPtr8 desBuf(iDes->Des());
- desBuf.SetLength(aBufChain.Length());
- aBufChain.CopyOut(desBuf, 0);
- // Logging migrated from CWapSmsProvider::GetData
- LOGSMSIF2("ESOCK READ: \"%S\"", iDes);
- LOGSMSIFHEXBUF(_L8("ESOCK READ"), *iDes);
- LOGSMSIFTIMESTAMP();
- }
- aBufChain.Free();
-
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, err);
- SetActive();
- } // CWapSmsProviderWrite::Start
-
-
-void CWapSmsProviderWrite::RunL()
- {
- LOGWAPPROT1("CWapSmsProviderWrite::RunL");
- User::LeaveIfError(iStatus.Int());
-
- //no need to use cleanup stack
- CWapDatagram* datagram = CWapDatagram::NewL(*iDes);
-
- if (iWapSmsProvider.iDataCodingScheme == EWapSms7BitDCS)
- datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet7Bit);
- else
- datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
-
- if (iWapSmsProvider.iStatusReportScheme == EWapSmsTPSRR)
- {
- datagram->SetStatusReportScheme(ETPSRRScheme);
- }
- else
- {
- datagram->SetStatusReportScheme(EDefaultScheme);
- }
-
- TBuf<KMaxSockAddrSize> addrBuf;
- addrBuf.Copy(iWapAddr.WapAddress());
- datagram->SetToAddress(addrBuf);
- TInt fromPort = iWapSmsProvider.iLocalAddress.WapPort();
- datagram->SetPorts(fromPort, iWapAddr.WapPort());
-
- iMsgSender->SendDatagramL(datagram); // takes ownership of datagram
- } // CWapSmsProviderWrite::RunL
-
-
-TInt CWapSmsProviderWrite::RunError(TInt aError)
- {
- LOGWAPPROT1("CWapSmsProviderWrite::RunError");
- iWapSmsProvider.Error(aError, MSocketNotify::EErrorSend);
- return KErrNone;
- } // CWapSmsProviderWrite::RunError
-
-
-void CWapSmsProviderWrite::DoCancel()
- {
- LOGWAPPROT1("CWapSmsProviderWrite::DoCancel");
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status, KErrCancel);
- } // CWapSmsProviderWrite::DoCancel
-
-
-// EOF - WS_PRVDR.CPP
+// Copyright (c) 1999-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:
+// Implements CWapSmsProvider and CWapSmsProviderWrite
+//
+//
+
+/**
+ @file
+*/
+
+#include <e32std.h>
+#include <wap_sock.h>
+#include "ws_main.h"
+#include "es_wsms.h"
+#include "WAPDGRM.H"
+#include "ws_obsvr.h"
+#include "smsprot.h"
+#include <es_mbuf.h>
+
+//
+// implementation of CWapSmsProvider
+//
+
+ // CWapSmsProvider policies
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetLocalNamePolicy, ECapabilityNetworkServices );
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetOptionPolicy, ECapability_None);
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetLengthIoctlPolicy,ECapability_None);
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParamLengthIoctlPolicy,ECapability_None);
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParametersIoctlPolicy,ECapabilityReadDeviceData);
+ static _LIT_SECURITY_POLICY_C1(wapSmsProviderWritePolicy,ECapabilityNetworkServices);
+
+
+/**
+ * Factory
+ */
+CWapSmsProvider* CWapSmsProvider::NewL(CWapSmsProtocol* aProtocol)
+ {
+ LOGWAPPROT1("CWapSmsProvider::NewL()");
+
+ CWapSmsProvider* provider=new(ELeave) CWapSmsProvider(aProtocol);
+ CleanupStack::PushL(provider);
+ provider->iWapSmsProviderWrite = CWapSmsProviderWrite::NewL(*provider);
+ CleanupStack::Pop();
+ return provider;
+ } // CWapSmsProvider::NewL
+
+
+/**
+ * Constructor
+ */
+CWapSmsProvider::CWapSmsProvider(CWapSmsProtocol* aProtocol)
+ :iMessageType(ESmartMessage)
+ ,iProtocol(aProtocol)
+ ,iSendPending(EFalse)
+ ,iIoctlOutstanding(EFalse)
+ ,iIsNewStyleClient(EFalse)
+ ,iStatusReportScheme(EWapSmsDefault)
+ {
+ iRecvdMsgQueue.SetOffset(CWapDatagram::LinkOffset());
+ } // CWapSmsProvider::CWapSmsProvider
+
+
+/**
+ * Destructor
+ */
+CWapSmsProvider::~CWapSmsProvider()
+ {
+ iSAPLink.Deque();
+
+ while(!iRecvdMsgQueue.IsEmpty())
+ {
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ iRecvdMsgQueue.Remove(*msg);
+ delete msg;
+ }
+
+ delete iWapSmsProviderWrite;
+ } // CWapSmsProvider::~CWapSmsProvider
+
+
+/**
+ * Return WAPSMS options
+ */
+TInt CWapSmsProvider::GetOption(TUint aLevel,TUint aName, TDes8& aOption)const
+ {
+ LOGWAPPROT1("CWapSmsProvider::GetOption");
+
+ TInt ret=KErrNone;
+ if (TInt(aLevel)==KWapSmsOptionLevel && TInt(aName)==KWapSmsOptionNameDCS)
+ aOption = TPtrC8((TText8*)&iDataCodingScheme,sizeof(TWapSmsDataCodingScheme));
+ else
+ ret=iProtocol->GetOption(aLevel,aName,aOption,NULL);
+ return ret;
+ } // CWapSmsProvider::GetOption
+
+
+/**
+ * Set WAPSMS options
+ *
+ * @capability None
+ *
+ */
+TInt CWapSmsProvider::SetOption(TUint aLevel, TUint aName, const TDesC8& aOption)
+ {
+ LOGWAPPROT1("CWapSmsProvider::SetOption");
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetOptionPolicy,"CWapSmsProvider SetOption policy check") != KErrNone))
+ {
+ return KErrPermissionDenied;
+ }
+
+ TInt ret=KErrNone;
+ if (TInt(aLevel)==KWapSmsOptionLevel)
+ {
+ switch(TInt(aName))
+ {
+ case KWapSmsOptionNameDCS:
+ {
+ iDataCodingScheme = static_cast<TWapSmsDataCodingScheme>(*aOption.Ptr());
+ break;
+ }
+ case KWapSmsOptionWapDatagram:
+ {
+ iMessageType=EWapDatagram;
+ break;
+ }
+ case KWapSmsStatusReportScheme:
+ {
+ iStatusReportScheme = static_cast<TWapSmsStatusReportScheme>(*aOption.Ptr());
+ break;
+ }
+ case KWapSmsOptionNewStyleClient:
+ {
+ iIsNewStyleClient = ETrue;
+ break;
+ }
+ case KWapSmsOptionOKToDeleteMessage:
+ {
+ //Get the first message from the queue
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ //Find and delete from SAR
+ TBool found=iProtocol->FindAndDeleteMsg(*msg);
+ if(!found)
+ {
+ LOGWAPPROT1("CWapSmsProvider::SetOption: Error. Couldn't find the message in the SAR for deletion");
+ break;
+ }
+ //Remove from the queue
+ iRecvdMsgQueue.Remove(*msg);
+ delete msg;
+ break;
+ }
+ default:
+ ret=KErrNotSupported;
+ }
+
+ }
+ else
+ {
+ ret=iProtocol->SetOption(aLevel,aName,aOption,NULL);
+ }
+ return ret;
+ } // CWapSmsProvider::SetOption
+
+
+/**
+ * Shutdown the SAP
+ */
+void CWapSmsProvider::Shutdown(TCloseType aType)
+ {
+ LOGWAPPROT1("CWapSmsProvider::Shutdown");
+ if (aType!=CServProviderBase::EImmediate)
+ iSocket->CanClose();
+ } // CWapSmsProvider::Shutdown
+
+
+/**
+ * Setup datagram with socket specific options and forward to protocol
+ * Return zero to block the send - will be completed by CWapSapMessageSender
+ *
+ * @capability NetworkServices
+ */
+TInt CWapSmsProvider::Write(RMBufChain& aBufChain, TUint /*options*/, TSockAddr* aAddr)
+ {
+ LOGWAPPROT1("CWapSmsProvider::Write()");
+
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderWritePolicy,"CWapSmsProvider Write policy check") != KErrNone))
+ {
+ return KErrPermissionDenied;
+ }
+ // @note: LOGIFH2A2 macro for logging esock write
+#ifdef SMSLOGGERIF
+ TInt length = aBufChain.Length();
+ LOGWAPPROT2("CWapSmsProvider::Write [%d bytes]", length);
+ TBuf8<0x100> dumpBuf;
+ if(length > 0x100)
+ {
+
+ TInt parts=0;
+ TInt offset = 0;
+ while (offset < length)
+ {
+ aBufChain.CopyOut(dumpBuf, offset);
+ offset += length;
+ LOGIF2(_L8("ESock WAP concantonated part: %d"),parts++);
+ LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
+ LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
+ }
+
+ }
+ else
+ {
+ aBufChain.CopyOut(dumpBuf, 0);
+ LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
+ LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
+ }
+#endif
+
+ // Note that if this fails somehow it still frees the buf chain and sets itself active - it's
+ // not clear to me whether this is good behaviour but it's the pre-mbuf behaviour too
+ iWapSmsProviderWrite->Start(aBufChain, *aAddr);
+ return KErrNone;
+ } // CWapSmsProvider::Write
+
+
+/**
+ * Read a datagram off the queue
+ */
+TInt CWapSmsProvider::GetData(RMBufChain& aBufChain, TUint aLength, TUint /*options*/,TSockAddr* aAddr)
+ {
+ LOGWAPPROT1("CWapSmsProvider::GetData()");
+
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ if(!iIsNewStyleClient)
+ {
+ iRecvdMsgQueue.Remove(*msg);
+ }
+ TInt err = msg->WapDatagram(aBufChain, aLength);
+
+ //@note: LOGIFH2A2 macro for logging esock getdata
+ LOGWAPPROT1("CWapSmsProvider::GetData");
+ // Logging migrated to WapDatagram() for ease of descriptor ref
+
+ if (err > 0 && aAddr)
+ {
+ TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(aAddr);
+ TInt toPort,fromPort;
+ msg->Ports(fromPort,toPort);
+ wapAddr->SetWapPort(static_cast<TWapPortNumber>(fromPort));
+ TBuf8<KMaxSockAddrSize> addrBuf;
+ addrBuf.Copy(msg->FromAddress());
+ wapAddr->SetWapAddress(addrBuf);
+ }
+ if(!iIsNewStyleClient)
+ {
+ delete msg;
+ }
+ return err > 0? 1: err; // datagrams are atoms not byte counts
+ } // CWapSmsProvider::GetData
+
+
+/**
+ * New data has arrived notify ESOCK.
+ */
+void CWapSmsProvider::NewData(CWapDatagram* aMsg)
+ {
+ TBool notifyEsock = EFalse;
+ LOGWAPPROT1("CWapSmsProvider::NewData");
+
+ if(iIoctlOutstanding && iName==KSOGetLength && iIsNewStyleClient)
+ {
+ TPckgBuf<TInt> buf= aMsg->WapDatagramLength();
+ iSocket->IoctlComplete(&buf);
+ iIoctlOutstanding= EFalse;
+ iName= NULL;
+ notifyEsock = ETrue;
+ }
+ else if(iIoctlOutstanding && iName==KSOGetMessageParametersLength && iIsNewStyleClient)
+ {
+ CBufFlat* buffer = aMsg->SmsExternalisedStream();
+ TPckgBuf<TInt> buf = buffer->Size();
+ iSocket->IoctlComplete(&buf);
+ iIoctlOutstanding= EFalse;
+ iName= NULL;
+ notifyEsock = ETrue;
+ }
+ else if(iIoctlOutstanding && iName==KSOGetMessageParameters && iIsNewStyleClient)
+ {
+ CBufFlat* buffer = aMsg->SmsExternalisedStream();
+ TPtr8 buf = buffer->Ptr(0);
+ iSocket->IoctlComplete(&buf);
+ iIoctlOutstanding= EFalse;
+ iName= NULL;
+ notifyEsock = ETrue;
+ }
+ else if(iName!=KSOGetLength && iName!=KSOGetMessageParametersLength && iName!=KSOGetMessageParameters && iIsNewStyleClient)
+ {
+ notifyEsock= EFalse;
+ }
+
+ if(!iIsNewStyleClient || notifyEsock)
+ iSocket->NewData(1);
+ //else we notify ESock in IOCTL for new client
+ } // CWapSmsProvider::NewData
+
+
+/**
+ * Error happened, notify ESOCK
+ */
+void CWapSmsProvider::Error(TInt aError, TUint aOperationMask)
+ {
+ LOGWAPPROT3("CWapSmsProvider::Error [aError=%d, mask=%d] ", aError, aOperationMask);
+
+ iSocket->Error(aError, aOperationMask);
+ } // CWapSmsProvider::Error
+
+
+/**
+ * Return the offset to the dblquelink
+ */
+TInt CWapSmsProvider::LinkOffset()
+ {
+ LOGWAPPROT1("CWapSmsProvider::LinkOffset");
+
+ return _FOFF(CWapSmsProvider,iSAPLink);
+ } // CWapSmsProvider::LinkOffset
+
+
+/**
+ * Return the address associated with the sap
+ */
+void CWapSmsProvider::LocalName(TSockAddr& aAddr) const
+ {
+ LOGWAPPROT1("CWapSmsProvider::LocalName");
+
+ Mem::Copy(&aAddr,&iLocalAddress,sizeof(TSockAddr));
+ } // CWapSmsProvider::LocalName
+
+
+/**
+ * Set the local address of the sap - called by RSocket::Bind
+ *
+ * @capability NetworkServices
+ */
+TInt CWapSmsProvider::SetLocalName(TSockAddr& aAddr)
+ {
+ LOGWAPPROT1("CWapSmsProvider::SetLocalName()");
+
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetLocalNamePolicy,"CWapSmsProvider SetLocalName policy check") != KErrNone))
+ {
+ return KErrPermissionDenied;
+ }
+ TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(&aAddr);
+ LOGWAPPROT2("CWapSmsProvider::SetLocalName %d",wapAddr->WapPort());
+ // Due ESOCK interface port EWapPortUnspecified value (-1) can be transferred as a maximum unsigned 16 int
+ if (wapAddr->WapPort()==EWapPortUnspecified || wapAddr->WapPort()==static_cast<TUint16>(EWapPortUnspecified))
+ {
+ if(!iProtocol->AllocateLocalAddress(iLocalAddress))
+ return KErrInUse;
+ else return KErrNone;
+ }
+
+
+ TInt ret=iProtocol->AddrAlreadyUsedByWAP(*wapAddr,this);
+ if(ret == KErrInUse) return ret;
+ else if(ret == KErrAlreadyExists) return KErrNone;
+
+ TSmsAddr addr;
+ if(wapAddr->Port() <=255)
+ addr.SetSmsAddrFamily(ESmsAddrApplication8BitPort);
+ else
+ addr.SetSmsAddrFamily(ESmsAddrApplication16BitPort);
+
+ addr.SetPort(wapAddr->Port());
+
+ if((iProtocol->SmsProtocol()->SmsAddrIsAlreadyUsed(NULL,addr)))
+ return KErrInUse;
+
+ Mem::Copy(&iLocalAddress,&aAddr,sizeof(TSockAddr));
+ TInt err;
+ TRAP(err,ret = iProtocol->CheckSarL(*wapAddr,this));
+ if(err!=KErrNone)
+ return err;
+ if(ret!=KErrNone)
+ {
+ Error(ret,MSocketNotify::EErrorAllOperations);
+ }
+ return KErrNone;
+ } // RSocket::Bind
+
+
+/**
+ * Returns true if aAddr matches the local address of the sap
+ */
+TBool CWapSmsProvider::MatchesLocalAddress(const TWapAddr& aAddr)
+ {
+ LOGWAPPROT1("CWapSmsProvider::MatchesLocalAddress");
+
+ return (iLocalAddress == aAddr);
+ } // CWapSmsProvider::MatchesLocalAddress
+
+//
+
+
+/**
+ * Called to perform specific IO control by the client (i.e. Wap Messaging API).The client is able
+ * to get the size of the datagram once it has been received or confirm the receipt
+ * of the message.
+ *
+ * Only one ioctl request may be outstanding at any one time.
+ *
+ * Implementation of pure virtual CServProviderBase::Ioctl().
+ *
+ * @param aLevel the IOCTL level. // Can be only KSolWapProv
+ * @param aName the IOCTL name.
+ * @param aOption the IOCTL option.
+ *
+ */
+void CWapSmsProvider::Ioctl(TUint aLevel,TUint aName,TDes8 * /*aOption*/)
+ {
+ LOGWAPPROT3("CWapSmsProvider::Ioctl [aLevel=%d, aName=%d]", aLevel, aName);
+ LOGWAPPROT2("CWapSmsProtocol::Ioctl [provider=0x%08x]",this);
+
+ iName=aName;
+ switch (aLevel)
+ {
+ case KSolWapProv:
+ {
+ if(iIoctlOutstanding || !iIsNewStyleClient)
+ {
+ Error(KErrInUse,MSocketNotify::EErrorIoctl);
+ break;
+ }
+ switch (iName)
+ {
+ case KSOGetLength:
+ //
+ // Get the length
+ //
+ {
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetLengthIoctlPolicy,"CWapSmsProvider GetLength Ioctl policy check") != KErrNone))
+ {
+ Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ iIoctlOutstanding = ETrue;
+ //check the queue for any other message for this client and call new data if any exist
+ if(!iRecvdMsgQueue.IsEmpty())
+ {
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ //check the datagram.
+ if(msg->IsComplete())
+ {
+ NewData(msg);
+ }
+ else
+ {
+ // else notify the client with error.
+ // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
+ Error(KErrGeneral,MSocketNotify::EErrorIoctl);
+ iIoctlOutstanding = EFalse;
+ }
+
+ }
+ break;
+ }
+
+ case KSOGetMessageParametersLength:
+ //
+ // Get the Message Parameters Length
+ //
+ {
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParamLengthIoctlPolicy,"CWapSmsProvider KSOGetMessageParametersLength Ioctl policy check") != KErrNone))
+ {
+ Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ iIoctlOutstanding = ETrue;
+ //check the queue for any other message for this client and call new data if any exist
+ if(!iRecvdMsgQueue.IsEmpty())
+ {
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ //check the datagram.
+ if(msg->IsComplete())
+ {
+ NewData(msg);
+ }
+ else
+ {
+ // else notify the client with error.
+ // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
+ Error(KErrGeneral,MSocketNotify::EErrorIoctl);
+ iIoctlOutstanding = EFalse;
+ }
+
+ }
+ break;
+ }
+
+ case KSOGetMessageParameters:
+ //
+ // Get the Message Parameters
+ //
+ {
+ if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParametersIoctlPolicy,"CWapSmsProvider GetMessageParameters Ioctl policy check") != KErrNone))
+ {
+ Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
+ return;
+ }
+ iIoctlOutstanding = ETrue;
+ //check the queue for any other message for this client and call new data if any exist
+ if(!iRecvdMsgQueue.IsEmpty())
+ {
+ CWapDatagram* msg = iRecvdMsgQueue.First();
+ //check the datagram.
+ if(msg->IsComplete())
+ {
+ NewData(msg);
+ }
+ else
+ {
+ // else notify the client with error.
+ // Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
+ Error(KErrGeneral,MSocketNotify::EErrorIoctl);
+ iIoctlOutstanding = EFalse;
+ }
+
+ }
+ break;
+ }
+
+
+ default:
+ //
+ // Unsupported ioctl name
+ //
+ {
+ // Error gracefully
+ Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ }
+ }
+ break;
+ }
+ default:
+ // Gracefully error in release build
+ Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+ }
+ } // CServProviderBase::Ioctl
+
+
+/**
+ * Cancel IOCTL- can only have one outstanding IOCTL at a time
+ */
+void CWapSmsProvider::CancelIoctl(TUint aLevel,TUint aName)
+ {
+ LOGWAPPROT1("CWapSmsProvider::CancelIoctl()");
+
+ if(!iIoctlOutstanding || (aName!=iName) || (aLevel!=KSolWapProv))
+ {
+ Error(KErrNotFound,MSocketNotify::EErrorIoctl);
+ }
+ else
+ {
+ iIoctlOutstanding=EFalse;
+ }
+ } // CWapSmsProvider::CancelIoctl
+
+
+/**
+ * Start the provider- does nothing
+ */
+void CWapSmsProvider::Start()
+ {
+ LOGWAPPROT1("CWapSmsProvider::Start()");
+
+ } // CWapSmsProvider::Start
+
+void CWapSmsProvider::AddToQueue(CWapDatagram* aMsg)
+/**
+ * Adding the datagram to received messages queue
+ */
+ {
+ LOGWAPPROT1("CWapSmsProvider::AddToQueue...");
+
+ iRecvdMsgQueue.AddLast(*aMsg);
+ NewData(aMsg);
+ } // CWapSmsProvider::AddToQueue
+
+
+TInt CWapSmsProvider::SecurityCheck(MProvdSecurityChecker* aSecurityChecker)
+ {
+ LOGWAPPROT1("CWapSmsProvider::SecurityCheck()");
+
+ iSecurityChecker=aSecurityChecker;
+ return KErrNone;
+ } // CWapSmsProvider::SecurityCheck
+
+
+TWapSmsStatusReportScheme CWapSmsProvider::GetStatusReportScheme()
+ {
+ return iStatusReportScheme;
+ }
+
+
+TWapSmsDataCodingScheme CWapSmsProvider::GetDataCodingScheme()
+ {
+ return iDataCodingScheme;
+ }
+
+
+//
+// implementation of CWapSmsProviderWrite
+//
+
+
+/**
+ * 2 phase constructor
+ */
+CWapSmsProviderWrite* CWapSmsProviderWrite::NewL(CWapSmsProvider& aWapSmsProvider)
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::NewL");
+ CWapSmsProviderWrite* self = new (ELeave) CWapSmsProviderWrite(aWapSmsProvider);
+ CleanupStack::PushL(self);
+ self->iMsgSender = CWapSapMessageSender::NewL(aWapSmsProvider.iProtocol->SmsProtocol(), &aWapSmsProvider);
+ CleanupStack::Pop(self);
+ return self;
+ } // CWapSmsProviderWrite::NewL
+
+
+/**
+ * Constructor
+ */
+CWapSmsProviderWrite::CWapSmsProviderWrite(CWapSmsProvider& aWapSmsProvider)
+ :CActive(EPriorityStandard)
+ ,iWapSmsProvider(aWapSmsProvider)
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::CWapSmsProviderWrite()");
+
+ CActiveScheduler::Add(this);
+ } // CWapSmsProviderWrite::CWapSmsProviderWrite
+
+
+/**
+ * Destructor
+ */
+CWapSmsProviderWrite::~CWapSmsProviderWrite()
+ {
+ Cancel();
+ delete iMsgSender;
+ delete iDes;
+ } // CWapSmsProviderWrite::~CWapSmsProviderWrite
+
+
+void CWapSmsProviderWrite::Start(RMBufChain& aBufChain, TSockAddr& aAddr)
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::Start");
+ iWapAddr = reinterpret_cast<TWapAddr&>(aAddr);
+ delete iDes;
+ iDes = NULL;
+ TRAPD(err, (iDes = HBufC8::NewL(aBufChain.Length())) );
+ if(err == KErrNone)
+ {
+ TPtr8 desBuf(iDes->Des());
+ desBuf.SetLength(aBufChain.Length());
+ aBufChain.CopyOut(desBuf, 0);
+ // Logging migrated from CWapSmsProvider::GetData
+ LOGSMSIF2("ESOCK READ: \"%S\"", iDes);
+ LOGSMSIFHEXBUF(_L8("ESOCK READ"), *iDes);
+ LOGSMSIFTIMESTAMP();
+ }
+ aBufChain.Free();
+
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, err);
+ SetActive();
+ } // CWapSmsProviderWrite::Start
+
+
+void CWapSmsProviderWrite::RunL()
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::RunL");
+ User::LeaveIfError(iStatus.Int());
+
+ //no need to use cleanup stack
+ CWapDatagram* datagram = CWapDatagram::NewL(*iDes);
+
+ if (iWapSmsProvider.iDataCodingScheme == EWapSms7BitDCS)
+ datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet7Bit);
+ else
+ datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
+
+ if (iWapSmsProvider.iStatusReportScheme == EWapSmsTPSRR)
+ {
+ datagram->SetStatusReportScheme(ETPSRRScheme);
+ }
+ else
+ {
+ datagram->SetStatusReportScheme(EDefaultScheme);
+ }
+
+ TBuf<KMaxSockAddrSize> addrBuf;
+ addrBuf.Copy(iWapAddr.WapAddress());
+ datagram->SetToAddress(addrBuf);
+ TInt fromPort = iWapSmsProvider.iLocalAddress.WapPort();
+ datagram->SetPorts(fromPort, iWapAddr.WapPort());
+
+ iMsgSender->SendDatagramL(datagram); // takes ownership of datagram
+ } // CWapSmsProviderWrite::RunL
+
+
+TInt CWapSmsProviderWrite::RunError(TInt aError)
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::RunError");
+ iWapSmsProvider.Error(aError, MSocketNotify::EErrorSend);
+ return KErrNone;
+ } // CWapSmsProviderWrite::RunError
+
+
+void CWapSmsProviderWrite::DoCancel()
+ {
+ LOGWAPPROT1("CWapSmsProviderWrite::DoCancel");
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrCancel);
+ } // CWapSmsProviderWrite::DoCancel
+
+
+// EOF - WS_PRVDR.CPP