--- /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 <e32base.h>
+#include <f32file.h>
+#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<CWapSmsProvider> 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<TWapPortNumber>(addr8.Port()));
+
+ return found;
+ } // CWapSmsProtocol::AllocateLocalAddress
+
+
+//
+// Find the provider who wants the message
+//
+CWapSmsProvider* CWapSmsProtocol::LookupSAP(CWapDatagram* aMsg)
+ {
+ LOGWAPPROT1("CWapSmsProtocol::LookupSAP");
+
+ TBuf8<KMaxSockAddrSize> 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<TWapPortNumber>(toPort));
+
+ TDblQueIter<CWapSmsProvider> 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<CWapSmsProvider> 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