diff -r 000000000000 -r 3553901f7fa8 smsprotocols/smsstack/wapprot/Src/ws_prtcl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsprotocols/smsstack/wapprot/Src/ws_prtcl.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,560 @@ +// 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 +#include +#include "smsprot.h" +#include "WAPDGRM.H" +#include "wappstor.h" +#include "ws_main.h" +#include "es_wsms.h" +#include "ws_obsvr.h" +#include "SmsuBackup.h" + +// +// Sets the values used for the local wap ports +// Limits the number of simultaneously open SAPs to 254 +// +const TInt KMaxWapPortNumber = 255; +const TInt KMinWapPortNumber = 1; + +const TInt KMax8BitPortNumber = 255; +const TInt KMax16BitPortNumber = 65535; + + +/** + * Constructor + */ +CWapSmsProtocol::CWapSmsProtocol() + { + iSAPList.SetOffset(CWapSmsProvider::LinkOffset()); + } // CWapSmsProtocol::CWapSmsProtocol + + +// +// Factory +// +CWapSmsProtocol* CWapSmsProtocol::NewL() + { + LOGWAPPROT1("CWapSmsProtocol::NewL()"); + + CWapSmsProtocol* p=new(ELeave) CWapSmsProtocol; + CleanupStack::PushL(p); + User::LeaveIfError(p->iFs.Connect()); + p->iObserver[0]=CWapProtocolObserver::NewL(p); + p->iObserver[1]=CWapProtocolObserver::NewL(p); + p->iObserver[2]=CWapProtocolObserver::NewL(p); + p->iWapStore=CWapReassemblyStore::NewL(p->iFs); + + p->iBackupRestoreSession=CBackupAndRestore::NewL(*p); + CleanupStack::Pop(); + return p; + } // CWapSmsProtocol::NewL + + +void CWapSmsProtocol::HandleBackupOrRestoreStartingL() + { + LOGWAPPROT1("CWapSmsProtocol::HandleBackupOrRestoreStartingL"); + iWapStore->Close(); + } // CWapSmsProtocol::HandleBackupOrRestoreStartingL + + +void CWapSmsProtocol::HandleBackupOrRestoreCompleteL() + { + LOGWAPPROT1("CWapSmsProtocol::HandleBackupOrRestoreCompleteL "); + iWapStore->DoOpenL(); + } // CWapSmsProtocol::HandleBackupOrRestoreCompleteL + + +/** + * Destructor + */ +CWapSmsProtocol::~CWapSmsProtocol() + { + delete iBackupRestoreSession; + + RemoveObserversFromSmsProtocol(); + delete iObserver[0]; + delete iObserver[1]; + delete iObserver[2]; + delete iWapStore; + + if (iSmsProtocol) + { + iSmsProtocol->Close(); + } + + iFs.Close(); + } // CWapSmsProtocol::~CWapSmsProtocol + + +// +// Socket server asking for a new sap +// +CServProviderBase *CWapSmsProtocol::NewSAPL(TUint aSocketType) + { + LOGWAPPROT1("*CWapSmsProtocol::NewSAPL"); + + if (aSocketType!=KSockDatagram) + User::Leave(KErrNotSupported); + CWapSmsProvider *pSAP = CWapSmsProvider::NewL(this); + AddSAP(pSAP, aSocketType); + return pSAP; + } // CWapSmsProtocol::NewSAPL + + +// +// InitL call from socket server. +// +void CWapSmsProtocol::InitL(TDesC& /*aTag*/) + { + } + + +// +// Called by another protocol that runs on top of WAP +// +void CWapSmsProtocol::BindL(CProtocolBase* /*aProtocol*/, TUint /*aId*/) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGWAPPROT1("CWapSmsProtocol::BindL"); + Panic(EWapSmsCantBind); + BULLSEYE_RESTORE + } + +// +// StartL call from socket server. +// Open lower layers +// +void CWapSmsProtocol::StartL() + { + } + + +// +// Identify request from SOCKET server +// +void CWapSmsProtocol::Identify(TServerProtocolDesc *aDes) const + { + LOGWAPPROT1("CWapSmsProtocol::Identify"); + + aDes->iName=KWAPSMSProtocolId; + aDes->iAddrFamily=KWAPSMSAddrFamily; + aDes->iSockType=KSockDatagram; + aDes->iProtocol=KWAPSMSDatagramProtocol; + + aDes->iVersion=TVersion(KWapSmsMajorVersionNumber,KWapSmsMinorVersionNumber,KWapSmsBuildVersionNumber); + aDes->iByteOrder=ELittleEndian; + aDes->iServiceInfo=KWAPSMSDatagramServiceInfo; + aDes->iNamingServices=0; + aDes->iSecurity=KSocketNoSecurity; + aDes->iMessageSize=KWAPSMSMaxDatagramSize; + aDes->iServiceTypeInfo=0; + aDes->iNumSockets=KWAPSMSNumberSockets; + } // CWapSmsProtocol::Identify + + +// +// Called by socket server to initiate bind to SMS protocol +// +void CWapSmsProtocol::BindToL(CProtocolBase* aProtocol) + { + LOGWAPPROT1("CWapSmsProtocol::BindToL"); + + TServerProtocolDesc info; + aProtocol->Identify(&info); + TUint theirId = info.iProtocol; + Identify(&info); + TUint ourId = info.iProtocol; + + if (theirId==ourId) + User::Leave(KErrGeneral); // Nutter! + + if (theirId!=KSMSDatagramProtocol) + User::Leave(KErrGeneral); + + iSmsProtocol = (CSmsProtocol*)aProtocol; + iSmsProtocol->Open(); + iSmsProtocol->StartL(); + BindObserversToSmsL(); + } // CWapSmsProtocol::BindToL + + +// +// Register the observers with sms.prt +// +void CWapSmsProtocol::BindObserversToSmsL() + { + LOGWAPPROT1("CWapSmsProtocol::BindObserversToSmsL"); + + iNextSapPort=KMinWapPortNumber; + TSmsAddr addr0; + TSmsAddr addr1; + TSmsAddr addr2; + + addr0.SetSmsAddrFamily(ESmsAddrMatchIEI); + addr0.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit); + addr1.SetSmsAddrFamily(ESmsAddrMatchIEI); + addr1.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit); + addr2.SetSmsAddrFamily(ESmsAddrMatchText); + addr2.SetTextMatch(_L8("//SCK")); + + iSmsProtocol->AddSmsMessageObserverL(*iObserver[0]); + TInt ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[0],addr0); + User::LeaveIfError(ret); + + iSmsProtocol->AddSmsMessageObserverL(*iObserver[1]); + ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[1],addr1); + User::LeaveIfError(ret); + + iSmsProtocol->AddSmsMessageObserverL(*iObserver[2]); + ret=iSmsProtocol->BindSmsMessageObserver(*iObserver[2],addr2); + User::LeaveIfError(ret); + } // CWapSmsProtocol::BindObserversToSmsL + + +// +// Deregister the observers +// +void CWapSmsProtocol::RemoveObserversFromSmsProtocol() + { + LOGWAPPROT1("CWapSmsProtocol::RemoveObserversFromSmsProtocol"); + + if (iSmsProtocol==NULL) + return; + iSmsProtocol->RemoveSmsMessageObserver(*iObserver[0]); + iSmsProtocol->RemoveSmsMessageObserver(*iObserver[1]); + iSmsProtocol->RemoveSmsMessageObserver(*iObserver[2]); + } // CWapSmsProtocol::RemoveObserversFromSmsProtocol + + +// +// Send a datagram originating from a higher protocol +// Can never be called as we don't implement BindL +// +// +TInt CWapSmsProtocol::Send(TDes8 &, TSockAddr* /*to*/,TSockAddr* /*from*/,CProtocolBase* /*aSourceProtocol*/) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGWAPPROT1("CWapSmsProtocol::Send"); + Panic(EWapSmsSendCallCantBind); + return KErrNone; + BULLSEYE_RESTORE + } + +// +// Receive an SMS +// +void CWapSmsProtocol::ProcessSmsL(const CSmsMessage& aSmsMessage) + { + LOGWAPPROT1("CWapSmsProtocol::ProcessSmsL"); + TInt index=0; + TBool storeDatagramComplete = EFalse; + TBool isNewStyleClient = EFalse; + + __ASSERT_DEBUG(aSmsMessage.IsComplete(),Panic(EWapSmsIncompleteSms)); + + CWapDatagram* wapDatagram = CWapDatagram::NewL(aSmsMessage); + + CleanupStack::PushL(wapDatagram); + TBool isCompleteDatagram = wapDatagram->IsComplete(); + if (!isCompleteDatagram) + { + + storeDatagramComplete = iWapStore->AddMessageL(index,*wapDatagram); + if (!storeDatagramComplete) + { + CleanupStack::PopAndDestroy(wapDatagram); + return; + } + iWapStore->GetDatagramL(index,*wapDatagram); + } + + CWapSmsProvider* wapsmsProvider = LookupSAP(wapDatagram); + + if (wapsmsProvider) + { + isNewStyleClient= wapsmsProvider->IsNewStyleClient(); + if(isCompleteDatagram && isNewStyleClient)//8 bit datagram or complete messages, Need to store it for new clients + { + storeDatagramComplete = iWapStore->AddMessageL(index,*wapDatagram); + if (!storeDatagramComplete) + { + CleanupStack::PopAndDestroy(wapDatagram); + return; + } + } + if(!isNewStyleClient && !isCompleteDatagram) + { + iWapStore->BeginTransactionLC(); + iWapStore->DeleteEntryL(index); + iWapStore->CommitTransactionL(); + } + CleanupStack::Pop(wapDatagram); + wapsmsProvider->AddToQueue(wapDatagram); + return; + } + else if(!isCompleteDatagram) + { + iWapStore->BeginTransactionLC(); + iWapStore->DeleteEntryL(index); + iWapStore->CommitTransactionL(); + } + + CleanupStack::PopAndDestroy(wapDatagram); + User::Leave(KErrNotFound); + } // CWapSmsProtocol::ProcessSmsL + + +// +// Get Wap Protocol options +// If none match the level/name pass the query on to SMS +// +TInt CWapSmsProtocol::GetOption(TUint aLevel, TUint aName, TDes8& aOption, CProtocolBase* /*aSourceProtocol*/) + { + LOGWAPPROT1("CWapSmsProtocol::GetOption"); + + TInt ret = iSmsProtocol->GetOption(aLevel, aName, aOption,this); + return ret; + } // CWapSmsProtocol::GetOption + + +// +// Set Wap Protocol options +// If none match the level/name pass the query on to SMS +// +TInt CWapSmsProtocol::SetOption(TUint aLevel, TUint aName, const TDesC8& aOption, CProtocolBase* /*aSourceProtocol*/) + { + LOGWAPPROT1("CWapSmsProtocol::SetOption"); + + TInt ret= iSmsProtocol->SetOption(aLevel,aName,aOption,this); + return ret; + } // CWapSmsProtocol::SetOption + + +// +// Inform all SAPs of error. +// +void CWapSmsProtocol::Error(TInt aError, CProtocolBase* /*aSourceProtocol*/) + { + LOGWAPPROT1("CWapSmsProtocol::Error"); + + TDblQueIter iter(iSAPList); + CWapSmsProvider* sap; + while (sap = iter++, sap!=NULL) + sap->Error(aError,MSocketNotify::EErrorAllOperations); + } + +// +// Socket server asking for a host resolver +// +CHostResolvProvdBase *CWapSmsProtocol::NewHostResolverL() + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGWAPPROT1("*CWapSmsProtocol::NewHostResolverL"); + Panic(EWapSmsCantCreateHostResolver); + return NULL; + BULLSEYE_RESTORE + } + +// +// Socket server asking for a service resolver +// +CServiceResolvProvdBase *CWapSmsProtocol::NewServiceResolverL() + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGWAPPROT1("*CWapSmsProtocol::NewServiceResolverL"); + Panic(EWapSmsCantCreateServiceResolver); + return NULL; + BULLSEYE_RESTORE + } + +// +// Socket server asking for a net data base +// +CNetDBProvdBase* CWapSmsProtocol::NewNetDatabaseL() + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGWAPPROT1("CWapSmsProtocol::NewNetDatabaseL"); + Panic(EWapSmsCantCreateNetDatabase); + return NULL; + BULLSEYE_RESTORE + } + +// +// Add a SAP to the SAP list and checks the SAR store for this SAP's entries +// +void CWapSmsProtocol::AddSAP(CWapSmsProvider* aSAP, TUint /*aSockType*/) + { + LOGWAPPROT1("CWapSmsProtocol::AddSAP"); + + iSAPList.AddLast(*aSAP); + } // CWapSmsProtocol::AddSAP + + +// +// Set the sap port number +// +TBool CWapSmsProtocol::AllocateLocalAddress(TWapAddr& aAddr) + { + LOGWAPPROT1("CWapSmsProtocol::AllocateLocalAddressL"); + // + TBool found=EFalse; + TUint count=0,attempts=0; + count =KMaxWapPortNumber-KMinWapPortNumber+1; + + TSmsAddr addr8; + addr8.SetSmsAddrFamily(ESmsAddrApplication8BitPort); + + for(;!found && attempts < count;attempts++) + { + addr8.SetPort(iNextSapPort++); + if(iNextSapPort > KMaxWapPortNumber)iNextSapPort=KMinWapPortNumber; + if(!iSmsProtocol->SmsAddrIsAlreadyUsed(NULL,addr8))found=ETrue; + } + if(found) + aAddr.SetWapPort(static_cast(addr8.Port())); + + return found; + } // CWapSmsProtocol::AllocateLocalAddress + + +// +// Find the provider who wants the message +// +CWapSmsProvider* CWapSmsProtocol::LookupSAP(CWapDatagram* aMsg) + { + LOGWAPPROT1("CWapSmsProtocol::LookupSAP"); + + TBuf8 addrBuf; + addrBuf.Copy(aMsg->FromAddress()); + TInt toPort=0; + TInt fromPort=0; + TInt Is16BitPorts = ETrue; + aMsg->Ports(fromPort,toPort,&Is16BitPorts); + + // Modification to relax port checking to allow 16 bit port number < KMax8BitPortNumber + if(toPort < 0 || (!Is16BitPorts && toPort > KMax8BitPortNumber) || (Is16BitPorts && toPort > KMax16BitPortNumber) ) + { + return NULL; + } + + TWapAddr addr; + addr.SetWapAddress(addrBuf); + addr.SetWapPort(static_cast(toPort)); + + TDblQueIter iter(iSAPList); + CWapSmsProvider* sap; + while (sap = iter++, sap!=NULL) + { + if (sap->MatchesLocalAddress(addr)) + return sap; + } + + return NULL; + } // CWapSmsProtocol::LookupSAP + + +// +// Check for duplicate address +// +TInt CWapSmsProtocol::AddrAlreadyUsedByWAP(const TWapAddr &aAddr, const CWapSmsProvider* aSap) + { + LOGWAPPROT1("CWapSmsProtocol::AddrAlreadyUsedByWAP"); + + TDblQueIter iter(iSAPList); + CWapSmsProvider* sap; + + while ((sap = iter++)!=NULL) + { + if (sap->MatchesLocalAddress(aAddr)) + { + if(sap==aSap) + return KErrAlreadyExists; + else + return KErrInUse; + } + } + LOGWAPPROT1("CWapSmsProtocol::AddrAlreadyUsedByWAP not used by WAP"); + return KErrNone; + } // CWapSmsProtocol::AddrAlreadyUsedByWAP + + +// +// Return a pointer to the sms protocol +// +CSmsProtocol* CWapSmsProtocol::SmsProtocol() + { + LOGWAPPROT1("CWapSmsProtocol::SmsProtocol()"); + + return iSmsProtocol; + } // CWapSmsProtocol::SmsProtocol + + +// +// Search the store for particular datagram, if found the entry is deleted +// +TBool CWapSmsProtocol::FindAndDeleteMsg(CWapDatagram& aDatagram) + { + LOGWAPPROT1("CWapSmsProtocol::FindAndDeleteMsg()"); + + TInt err; + TInt ret = EFalse; + TRAP(err,ret=iWapStore->FindAndDeleteDatagramL(aDatagram)); + __ASSERT_DEBUG(!err,Panic(EWapSmsNotFoundInStore)); + if(!err && ret) + return ETrue; + else + return EFalse; + } // CWapSmsProtocol::FindAndDeleteMsg + + +// +// Search for SAR for this SAP entries. If found any, adds it to message queue +// Note: This retrieves stored but not acked messages for this SAP +// Is called when client's socket binds to address +// +TInt CWapSmsProtocol::CheckSarL(const TWapAddr& aAddr,CWapSmsProvider* aSap) + { + LOGWAPPROT1("CWapSmsProtocol::CheckSarL()"); + + TInt count=0; + TInt err = KErrNone; + count = iWapStore->Entries().Count(); + TWapReassemblyEntry entry; + + + TWapPortNumber portNumber = aAddr.WapPort() ; + for(TInt index=0;index< count; index++) + { + entry = (TWapReassemblyEntry&)iWapStore->Entries()[index]; + if(entry.ToPort()==portNumber) + { + CWapDatagram* wapDatagram = NULL; + wapDatagram = CWapDatagram::NewL(KNullDesC8); + CleanupStack::PushL(wapDatagram); + TRAP(err,iWapStore->GetDatagramL( index,*wapDatagram)); + __ASSERT_DEBUG(!err,Panic(EWapSmsBadGetDataCall)); + CleanupStack::Pop(wapDatagram); + aSap->AddToQueue(wapDatagram); + } + } + return err; + } // CWapSmsProtocol::CheckSarL