smsprotocols/smsstack/wapprot/Src/ws_prtcl.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
--- /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