--- a/smsprotocols/smsstack/smsprot/Src/smsprot.cpp Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/smsprot/Src/smsprot.cpp Thu May 06 15:10:38 2010 +0100
@@ -1,2140 +1,2140 @@
-// 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:
-// Implements the CSmsProtocol and its helper classes.
-//
-//
-
-/**
- @file
-*/
-
-#include <commsdattypesv1_1.h>
-#include <logwrap.h>
-#include "Gsmumsg.h"
-#include "gsmubuf.h"
-#include "Gsmuelem.h"
-#include "gsmunonieoperations.h"
-
-#include "smsprot.h"
-#include "smspfacadestor.h"
-#include "smspmodm.h"
-#include "smspenum.h"
-#include "smspread.h"
-#include "smspdel.h"
-#include "smspproc.h"
-#include "smspmondsk.h"
-#include "smspmain.h"
-#include "smspver.h"
-#include "smsppara.h"
-#include "SmsuBackup.h"
-#include <es_prot_internal.h>
-
-using namespace CommsDat;
-
-//
-// Class implementations
-//
-
-// application port range according to 3GPP TS 23.040 v4.4.0
-// chapters 9.2.3.24.3 and 9.2.3.24.4
-
-const TInt KMin8BitPortNumber = 240;
-const TInt KMax8BitPortNumber = 255;
-
-const TInt KMin16BitPortNumber = 16000;
-const TInt KMax16BitPortNumber = 16999;
-
-
-/**
- * 2 phase constructor
- *
- */
-CSmsProtocolFamily * CSmsProtocolFamily::NewL()
- {
- LOGSMSPROT4("CSmsProtocolFamily::NewL [version %d.%d.%d]",
- KSmsPrtMajorVersionNumber,
- KSmsPrtMinorVersionNumber,
- KSmsPrtBuildVersionNumber
- );
- return new (ELeave)CSmsProtocolFamily;
- } // CSmsProtocolFamily::NewL
-
-
-/**
- * Implementation of the pure virtual CProtocolFamilyBase::Install().
- * Called by the socket server after creation of this object.
- * Does nothing.
- *
- */
-TInt CSmsProtocolFamily::Install()
- {
- LOGSMSPROT1("CSmsProtocolFamily::Install");
- return KErrNone;
- } // CProtocolFamilyBase::Install
-
-
-/**
- * Implementation of the pure virtual CProtocolFamilyBase::Remove().
- * Called by the socket server before unloading the library for the SMS
- * protocol family.
- * Does nothing.
- *
- */
-TInt CSmsProtocolFamily::Remove()
- {
- LOGSMSPROT1("CSmsProtocolFamily::Remove");
- return KErrNone;
- } // CProtocolFamilyBase::Remove
-
-
-/**
- * Implementation of the pure virtual CProtocolFamilyBase::NewProtocolL().
- * Called by the socket server to create the CSmsProtocol object.
- *
- * @param aSockType not used, assumes datagram.
- * @param aProtocol not used, assumes KSmsDatagram, the only protocol provided.
- * @return a new instance of the CSmsProtocol class.
- *
- */
-CProtocolBase * CSmsProtocolFamily::NewProtocolL(TUint /*aSockType*/,TUint /*aProtocol*/)
- {
- LOGSMSPROT1("CSmsProtocolFamily::NewProtocolL");
- return CSmsProtocol::NewL();
- } // CProtocolFamilyBase::NewProtocolL
-
-
-/**
- * Implementation of the pure virtual CProtocolFamilyBase::ProtocolList().
- * Called by the socket server during initialisation to retrieve a list
- * of the protocols we support.
- * Only KSmsDatagram is supported.
- *
- * @return aProtocolList a pointer to an array of protocol description objects
- * that this function creates and fills in.
- * @return the number of protocols supported (1).
- *
- */
-TUint CSmsProtocolFamily::ProtocolList(TServerProtocolDesc *& aProtocolList)
- {
- LOGSMSPROT1("CSmsProtocolFamily::ProtocolList");
-
- TRAPD(ret, (aProtocolList=new(ELeave) TServerProtocolDesc[1]));
- if(ret!=KErrNone)
- {
- LOGSMSPROT2("WARNING! new TServerProtocolDesc left with %d", ret);
- return 0;
- }
-
- // Datagram protocol
- aProtocolList[0].iName=KSmsDatagram;
- aProtocolList[0].iAddrFamily=KSMSAddrFamily;
- aProtocolList[0].iSockType=KSockDatagram;
- aProtocolList[0].iProtocol=KSMSDatagramProtocol;
- aProtocolList[0].iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
- aProtocolList[0].iByteOrder=ELittleEndian;
- aProtocolList[0].iServiceInfo=KSMSDatagramServiceInfo;
- aProtocolList[0].iNamingServices=0;
- aProtocolList[0].iSecurity=KSocketNoSecurity;
- aProtocolList[0].iMessageSize=KSMSMaxDatagramSize;
- aProtocolList[0].iServiceTypeInfo=ESocketSupport;
- aProtocolList[0].iNumSockets=KSMSNumberSockets;
-
- return 1;
- } // CProtocolFamilyBase::ProtocolList
-
-
-/**
- * Constructor (empty)
- */
-CSmsProtocolFamily::CSmsProtocolFamily()
- {
- } // CSmsProtocolFamily::CSmsProtocolFamily
-
-
-/**
- * The single exported function, called by the socket server to create
- * an instance of our CProtocolFamilyBase derived class.
- *
- */
-EXPORT_C CProtocolFamilyBase* InstallSMS()
- {
- LOGSMSPROT1("CSmsProtocolFamily::CSmsProtocolFamily()");
-
- CSmsProtocolFamily* smsProtocolFamily(NULL);
-
- TRAP_IGNORE(smsProtocolFamily = CSmsProtocolFamily::NewL());
-
- return smsProtocolFamily;
- } // CSmsProtocolFamily::CSmsProtocolFamily
-
-
-//
-// implementation of CSmsProtocol
-//
-
-
-/**
- * 2 phase constructor.
- *
- */
-CSmsProtocol* CSmsProtocol::NewL()
- {
- LOGSMSPROT1("CSmsProtocol::NewL()");
-
- return new (ELeave) CSmsProtocol();
- } // CSmsProtocol::NewL
-
-
-/**
- * Destructor, ensures all outstanding queues are empty,
- * all resource handles are closed, and all allocated memory freed.
- *
- */
-CSmsProtocol::~CSmsProtocol()
- {
- delete iSmsPhoneInitialization;
- delete iSmsModemNotification;
-
- delete iSendQueue;
- delete iSetBearer; // referenced by iSendQueue
-
- delete iSmsPDURead;
- delete iReceiveMode; // referenced by iSmsPDURead
- delete iSmsPhoneEnumeration;
- delete iWriteQueue;
- delete iDeleteQueue;
-
-
- delete iSmsReadParams;
- delete iSmsWriteParams;
- delete iSmsMonitorDiskSpace;
-
- delete iReassemblyStore;
-
- if(iSegmentationStore)
- {
- iSegmentationStore->Close();
- delete iSegmentationStore;
- }
- iFs.Close();
-
- iSmsMessaging.Close();
- iGsmPhone.Close();
- iEnumerationPhone.Close();
- iWritePhone.Close();
- iTelServer.Close();
- delete iBackupRestoreSession;
- delete iBootTimer;
- } // CSmsProtocol::~CSmsProtocol
-
-
-
-/**
- * Override of CProtocolBase::NewSAPL().
- * Called by the server to create a new SMS service access point object.
- *
- * @param aSocketType the socket type
- * @leave Leaves if aSocketType is not KSockDatagram.
- * @leave Leaves if not enough memory is available.
- * @return a new CSmsProvider object.
- *
- */
-CServProviderBase *CSmsProtocol::NewSAPL(TUint aSocketType)
- {
- LOGSMSPROT2("*CSmsProtocol::NewSAPL [sockettype=%d]", aSocketType);
- if (aSocketType!=KSockDatagram)
- User::Leave(KErrNotSupported);
- return CSmsProvider::NewL(*this);
- } // CProtocolBase::NewSAPL
-
-
-/**
- * Override of CProtocolBase::InitL().
- * Called by the socket server to allow any resource initialisation
- * by the protocol.
- *
- * The following tasks are performed:
- * - All member objects constructed (deferred from ConstructL() for efficiency reasons; see comment there)
- * - TSY Name read from Comms Database
- * - Event notification state machines started
- * - Modem checked to see if it is already connected, and if so, a number of
- * state machines started (otherwise wait until we receive notification of connection).
- *
- */
-void CSmsProtocol::InitL(TDesC& /*aTag*/)
- {
- LOGSMSPROT1("CSmsProtocol::InitL");
-
- User::LeaveIfError(iFs.Connect());
-
- iReassemblyStore=CFacadeSmsReassemblyStore::NewL(iFs, *this);
- iReassemblyStore->InitL();
-
- LOGSMSPROT1("CSmsProtocol::InitL Constructing members");
-
- ReadConfigurableSettingsL();
-
- iBootTimer = CSmsProtocolBootTimer::NewL(*this);
- iBootTimer->Start(iSmsSettings.BootTimerTimeout().Int());
-
- iSegmentationStore=CSmsSegmentationStore::NewL(iFs);
-
- iSetBearer=CSmspSetBearer::NewL(iSmsSettings, iSmsMessaging, KSmsSessionPriority);
-
- iReceiveMode = CSmspReceiveMode::NewL(iSmsSettings, iSmsMessaging, iMobileSmsCaps, KSmsSessionPriority);
-
- iSmsModemNotification=CSmsModemNotification::NewL(*this);
-
- iSendQueue = CSmspSendQueue::NewL(*this, *iSegmentationStore, iSmsSettings, iMobileSmsCaps, iSmsMessaging, KSmsSessionPriority, *iSetBearer);
-
- iSmsMonitorDiskSpace=CSmsMonitorDiskSpace::NewL(*this, iSmsMessaging,iFs);
-
- iSmsPDURead=CSmsPDURead::NewL(*this, iSmsSettings, iSmsMessaging,*iReassemblyStore,*iSegmentationStore, iMobileSmsCaps, KSmsSessionPriority, *iReceiveMode, *iSmsMonitorDiskSpace);
-
- iSmsPhoneInitialization = new (ELeave) CSmsPhoneInitialization(iSmsMessaging, iGsmPhone, *iSmsPDURead, iMobileSmsCaps, KSmsSessionPriority, iSetBearer);
-
- iBackupRestoreSession = CBackupAndRestore::NewL(*this);
-
-/* THIS CODE SHOULD NEVER BE NECESSARY - who could have called CProtocolBase::InitL() if not ESOCK, which means
- * a running C32 already. However, if this is a wrong analysis then reinstate the code but with an explanatory comment
-#if defined (__WINS__)
- // Make sure C32 is started under WINS
- TInt ret=StartC32();
- if (ret!=KErrAlreadyExists)
- User::LeaveIfError(ret);
-#endif
-*/
- LOGSMSPROT1("CSmsProtocol::InitL Querying CommDb");
-
- // Read the global modem ID setting from Cooms Database
- TUint32 modemId = 0;
-
-
-#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
- CMDBSession* sess = CMDBSession::NewL(KCDVersion1_2);
-#else
- CMDBSession* sess = CMDBSession::NewL(KCDVersion1_1);
-#endif
- CleanupStack::PushL(sess);
-
- CMDBField<TUint32>* globalSettingField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
- CleanupStack::PushL(globalSettingField);
- globalSettingField->SetRecordId(1);
- globalSettingField->LoadL(*sess);
- modemId = *globalSettingField;
- CleanupStack::PopAndDestroy(globalSettingField);
-
- CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
- CleanupStack::PushL(tsyField);
- tsyField->SetRecordId(modemId);
- tsyField->LoadL(*sess);
- iGsmTsyName = *tsyField;
- CleanupStack::PopAndDestroy(tsyField);
-
- CleanupStack::PopAndDestroy(sess);
-
-#ifdef _SMS_LOGGING_ENABLED
- TBuf8<KCommsDbSvrMaxFieldLength> buf8;
- buf8.Copy(iGsmTsyName);
- LOGSMSPROT3("CSmsProtocol::InitL [modemId=%d tsy=%S]",
- modemId, &buf8);
-#endif
-
- // Start event notification state machines
- iSmsModemNotification->Start();
-
- // Intialise the SmsStack to the state that the phone has been found in
- iModemDetection=iSmsModemNotification->ModemState();
-
- if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
- {
- DoPowerUpL(); //Call the leaving version because powering up must work here
- }
- else
- {
- PowerDown();
- }
-
- //
- // Define the Disk Space Monitor P&S variable...
- //
- TInt ret;
-
- TSecurityPolicy readPolicy(ECapabilityReadDeviceData);
- TSecurityPolicy writePolicy(ECapabilityWriteDeviceData);
-
- ret = RProperty::Define(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey,
- KUidPSSMSStackDiskSpaceMonitorKeyType, readPolicy, writePolicy);
- if (ret != KErrNone && ret != KErrAlreadyExists)
- {
- User::Leave(ret);
- }
-
- User::LeaveIfError(RProperty::Set(KUidPSSMSStackCategory,
- KUidPSSMSStackDiskSpaceMonitorKey, ESmsDiskSpaceAvailable));
- } // CProtocolBase::InitL
-
-
-/**
- * Override of CProtocolBase::StartL().
- * Called by the socket server to indicate all bindings are complete
- * and that datagram processing can begin.
- *
- * Binding is not supported so this indication is not important to us.
- *
- */
-void CSmsProtocol::StartL(void)
- {
- LOGSMSPROT1("CSmsProtocol::StartL");
- } // CSmsProtocol::StartL
-
-
-/**
- * Override of CProtocolBase::Identify().
- * Called by the socket server to obtain a description of the SMS protocol.
- *
- */
-void CSmsProtocol::Identify(TServerProtocolDesc *aDesc)const
- {
- LOGSMSPROT1("CSmsProtocol::Identify");
-
- aDesc->iName=KSmsDatagram;
- aDesc->iAddrFamily=KSMSAddrFamily;
- aDesc->iSockType=KSockDatagram;
- aDesc->iProtocol=KSMSDatagramProtocol;
- aDesc->iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
- aDesc->iByteOrder=ELittleEndian;
- aDesc->iServiceInfo=KSMSDatagramServiceInfo;
- aDesc->iNamingServices=0;
- aDesc->iSecurity=KSocketNoSecurity;
- aDesc->iMessageSize=KSMSMaxDatagramSize;
- aDesc->iServiceTypeInfo=0;
- aDesc->iNumSockets=KSMSNumberSockets;
- } // CProtocolBase::Identify
-
-
-/**
- * Override of CProtocolBase::NewHostResolverL().
- * Called by socket server to create a host resolver.
- * No host resolver service is provided by this SMS protocol.
- *
- * @leave Panics if called.
- *
- */
-CHostResolvProvdBase *CSmsProtocol::NewHostResolverL()
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::NewHostResolverL");
- SmspPanic(ESmspCantCreateHostResolver);
- return NULL;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::NewServiceResolverL().
- * Called by socket server to create a new service resolver.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-CServiceResolvProvdBase *CSmsProtocol::NewServiceResolverL()
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("*CSmsProtocol::NewServiceResolverL");
- SmspPanic(ESmspCantCreateServiceResolver);
- return NULL;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::NewNetDatabaseL().
- * Called by socket server to create a new network database.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-CNetDBProvdBase* CSmsProtocol::NewNetDatabaseL()
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::NewNetDatabaseL");
- SmspPanic(ESmspCantCreateNetDatabase);
- return NULL;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::BindL().
- * Called by next protocol above wishing to bind to the SMS protocol.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-void CSmsProtocol::BindL(CProtocolBase* /*aProtocol*/,TUint /*aId*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::BindL");
- SmspPanic(ESmspCantBind);
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::BindToL().
- * Called by socket server when a lower protocol must bind to the
- * SMS protocol.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-void CSmsProtocol::BindToL(CProtocolBase* /*aProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::BindToL");
- SmspPanic(ESmspCantBindTo);
- BULLSEYE_RESTORE
- }
-
-/**
- * Reads timeout value for send operation from configuration file
- *
- * @leave Leaves if configuration file cannot be read
- * @leave Leaves if value not greater than zero
- */
-void CSmsProtocol::ReadConfigurableSettingsL()
- {
- CESockIniData* ini = NULL;
- TRAPD(ret, ini=CESockIniData::NewL(_L("smswap.sms.esk")));
- if(ret!=KErrNone)
- {
- LOGSMSPROT2("esk read failed, error code = [%d]", ret);
- User::Leave(ret);
- }
-
- CleanupStack::PushL(ini);
-
- TInt var(0);
- if(ini->FindVar(_L("customTimeoutSettings"),_L("sendTryTimeout"),var))
- {
- if (var > 0)
- {
- LOGSMSPROT2("sendTryTimeout [%d]", var);
- iSmsSettings.SetSendTryTimeout(var);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- }
-
- if(ini->FindVar(_L("customTimeoutSettings"),_L("bootTimerTimeout"),var))
- {
- if (var > 0)
- {
- LOGSMSPROT2("bootTimerTimeout [%d]", var);
- iSmsSettings.SetBootTimerTimeout(var);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- }
-
- CleanupStack::PopAndDestroy(ini);
- } // CSmsProtocol::ReadConfigurableSettingsL
-
-
-/**
- * Override of CProtocolBase::Send().
- * A down call from a protocol bound above to send a datagram.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-TInt CSmsProtocol::Send(TDes8& /*aDes*/,TSockAddr* /*aTo*/,TSockAddr* /*aFrom*/,CProtocolBase* /*aSourceProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::Send");
- SmspPanic(ESmspCantSend);
- return KErrNotSupported;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::Process().
- * An up call from a protocol bound below to process a datagram.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-void CSmsProtocol::Process(TDes8& /*aDes*/,TSockAddr* /*aFrom*/,TSockAddr* /*aTo*/,CProtocolBase* /*aSourceProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::Process");
- SmspPanic(ESmspCantProcess);
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::GetOption().
- * A down call from a protocol bound above to get a protocol option.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-TInt CSmsProtocol::GetOption(TUint /*aLevel*/,TUint /*aName*/,TDes8 & /*aOption*/,CProtocolBase* /*aSourceProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::GetOption");
- // SmspPanic(ESmspCantGetOption);
- return KErrNotSupported;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::SetOption().
- * A down call from a protocol bound above to set a protocol option.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-TInt CSmsProtocol::SetOption(TUint /*aLevel*/,TUint /*aName*/,const TDesC8& /*option*/,CProtocolBase* /*aSourceProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::SetOption");
- //SmspPanic(ESmspCantSetOption);
- return KErrNotSupported;
- BULLSEYE_RESTORE
- }
-
-/**
- * Override of CProtocolBase::Error().
- * An up call from a protocol bound below to indicate an error.
- * Not supported by this protocol.
- *
- * @leave Panics if called.
- *
- */
-void CSmsProtocol::Error(TInt /*aError*/,CProtocolBase* /*aSourceProtocol*/)
- {
- // Ignore in code coverage - not intended to be used
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::Error");
- SmspPanic(ESmspCantError);
- BULLSEYE_RESTORE
- }
-
-/**
- * Adds an observer to the protocol's observer list.
- * Used by CSmsProvider and CWapSmsProtocol.
- *
- * @leave Leaves if not enough memory is available.
- *
- */
-void CSmsProtocol::AddSmsMessageObserverL(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT2("CSmsProtocol::AddSmsMessageObserverL [aObserver=0x%08x]", &aObserver);
- iSmsMessageObserverList.AppendL(&aObserver);
- SetClosingDown(EFalse);
- }
-
-/**
- * Binds an SMS observer to the protocol.
- * The protocol ensures there are no providers with duplicate addresses.
- * Used by CSmsProvider::SetLocalName(), and SMS WAP protocol.
- *
- * @param aObserver the observer.
- * @param aSmsAddr the local address of the observer.
- * @return KErrNone on success, or KErrAlreadyExists if a duplicate exists.
- *
- */
-TInt CSmsProtocol::BindSmsMessageObserver(MSmsMessageObserver& aObserver,const TSmsAddr& aSmsAddr)
- {
- LOGSMSPROT2("CSmsProtocol::BindSmsMessageObserver 0x%08x", &aObserver);
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
- TInt ret=KErrNone;
-
- if (!SmsAddrIsAlreadyUsed(&aObserver,aSmsAddr))
- {
- aObserver.SetLocalAddress(aSmsAddr);
- OrderSmsMessageObserver(aObserver);
-
- // If not in the powered-up state then the SAR store is closed. When the phone does power-up
- // then anything waiting in the store will get processed
- if(CheckPoweredUp() == KErrNone)
- {
- //
- // check the SAR store for any complete messages.
- // if there are any, send them to the observer
- //
- TRAP(ret, ProcessCompleteSmsMessagesL());
- if(ret != KErrNone)
- {
- LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
- }
- }
- }
- else
- {
- ret=KErrAlreadyExists;
- }
- return ret;
- } // CSmsProvider::SetLocalName
-
-
-/**
- * Removes an observer from the observer list.
- * Observers should at least call this method in their destructors.
- *
- */
-void CSmsProtocol::RemoveSmsMessageObserver(const MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT2("CSmsProtocol::RemoveSmsMessageObserver 0x%08x", &aObserver);
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
- TInt index=ObserverIndex(aObserver);
- iSmsMessageObserverList.Delete(index);
- }
-
-/**
- * Handles a request from a SAP to send a SMS message.
- * Ensures there is a current connection to the modem and queues the message.
- * Completes with an error immediately if CheckPoweredUp() returns an error code
- */
-void CSmsProtocol::SendSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver,TUint aOptions)
- {
- LOGSMSPROT2("CSmsProtocol::SendSmsMessage [aObserver=0x%X]", &aObserver);
- __ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
-
- // Ensure the modem is connected and initialized
- const TInt err = CheckPoweredUp();
-
- if (err != KErrNone)
- {
- // Nope, complete immediately
- aObserver.MessageSendCompleted(err);
- delete aSmsMessage;
- }
- else
- {
- iSendQueue->Queue(aSmsMessage, aObserver, aOptions);
- }
- }
-
-TInt CSmsProtocol::CheckPoweredUp() const
- {
- TInt err = KErrNone;
-
- if( iModemDetection == RPhone::EDetectedNotPresent || iState == EPoweredDown )
- {
- err = KErrDisconnected;
- }
- else if( iBackupRestoreSession->IsBackupOrRestoreInProgress() )
- {
- err = KErrAccessDenied;
- }
- else
- {
- err = iSmsPhoneInitialization->Initialized();
- }
- if( err != KErrNone )
- {
- LOGSMSPROT4("CSmsProtocol::CheckPoweredUp [err=%d, iModemDetection=%d, IsBackupOrRestoreInProgress=%d]", err, iModemDetection, iBackupRestoreSession->IsBackupOrRestoreInProgress());
- }
- return err;
- }
-
-/**
- * Cancels a previous request to send an SMS message.
- * Searches the send queue for the message. If it is found at the
- * head of the queue the sending state machine is cancelled, which
- * in turn will callback to the protocol and delete the message.
- * If the message is elsewhere in the queue, it is simply removed
- * from the queue and the observer notified.
- *
- * @leave Panics in DEBUG if the message is not found in the queue.
- *
- */
-void CSmsProtocol::CancelSendSmsMessage(MSmsMessageObserver& aObserver,TBool)
- {
- LOGSMSPROT2("CSmsProtocol::CancelSendSmsMessage 0x%08x", &aObserver);
-
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- iSendQueue->CancelObserver(aObserver);
- } // CSmsProtocol::CancelSendSmsMessage
-
-
-/**
- * Handles a request from a SAP to enumerate the SMS messages stored on the phone.
- */
-void CSmsProtocol::EnumeratePhone(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::EnumeratePhone");
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- // Ensure the modem is connected and initialized
- const TInt err = CheckPoweredUp();
-
- if (err != KErrNone)
- aObserver.EnumeratePhoneCompleted(err);
- else
- {
- if (iPhoneEnumerationObserver!=NULL)
- {
- aObserver.EnumeratePhoneCompleted(KErrInUse);
- }
- else
- {
- iPhoneEnumerationObserver=&aObserver;
- iSmsPhoneEnumeration->Start();
- }
- }
- } // CSmsProtocol::EnumeratePhone
-
-
-/**
- * Cancels a previous request to enumerate the message on the phone memory.
- *
- * @leave Panics in DEBUG if the SAP is invalid.
- *
- */
-void CSmsProtocol::CancelEnumeratePhone(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::CancelEnumeratePhone");
-
- __ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
- __ASSERT_DEBUG(iPhoneEnumerationObserver==NULL || &aObserver==iPhoneEnumerationObserver, SmspPanic(ESmspMessageWrongObserver));
-
- if (iSmsPhoneEnumeration != NULL)
- {
- iSmsPhoneEnumeration->Cancel();
- }
-
- iReassemblyStore->DeleteEnumeratedSIMEntries();
-
- (void) aObserver;
- } // CSmsProtocol::CancelEnumeratePhone
-
-
-TInt CSmsProtocol::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
- {
- return iReassemblyStore->ExternalizeEnumeratedMessagesL(aProvider, aCount);
- } // CSmsProtocol::ExternalizeEnumeratedMessagesL
-
-
-/**
- * Handles a request to write an SMS message to the phone's memory.
- * Completes with an error immediately if CheckPoweredUp() returns an error code
- * Otherwise the message is added to the tail of the write queue.
- */
-void CSmsProtocol::WriteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::WriteSmsMessage");
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- const TInt err = CheckPoweredUp();
-
- if (err != KErrNone)
- {
- aObserver.MessageWriteCompleted(err);
- delete aSmsMessage;
- }
- else
- {
- iWriteQueue->Queue(aSmsMessage, aObserver, NULL);
- }
- } // CSmsProtocol::WriteSmsMessage
-
-
-void CSmsProtocol::CancelWriteSmsMessage(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::CancelWriteSmsMessage()");
-
- if (iWriteQueue != NULL)
- iWriteQueue->CancelObserver(aObserver);
- } // CSmsProtocol::CancelWriteSmsMessage
-
-
-/**
- * Handles a request from a SAP to delete a message from the phone memory.
- * Completes with an error immediately if CheckPoweredUp() returns an error code
- * If the cached image of the phone's memory is not yet initialised, complete the
- * request with KErrNotReady.
- * Otherwise match the message in the phone image and queue the message for deletion.
- *
- * @note aSmsMessage is destroyed from memory on completion.
- *
- */
-void CSmsProtocol::DeleteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::DeleteSmsMessage");
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- // Ensure the modem is connected and initialized
- const TInt err = CheckPoweredUp();
-
- if (err != KErrNone)
- {
- // Not connected or backup running
- aObserver.MessageDeleteCompleted(err);
- }
- else if (aSmsMessage->iSlotArray.Count()==0)
- aObserver.MessageDeleteCompleted(KErrArgument);
- else
- DeletePDUs(aSmsMessage->iSlotArray,&aObserver);
-
- delete aSmsMessage;
- } // CSmsProtocol::DeleteSmsMessage
-
-
-/**
- * Cancels a previous request to delete a message from the phone memory.
- *
- * @leave Panics in DEBUG if the SAP is invalid.
- *
- */
-void CSmsProtocol::CancelDeleteSmsMessage(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::CancelDeleteSmsMessage");
-
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- iDeleteQueue->CancelObserver(aObserver);
- } // CSmsProtocol::CancelDeleteSmsMessage
-
-
-/**
- * Handles a request from a SAP to read the SMS parameters stored on the phone.
- * Completes with an error immediately if CheckPoweredUp() returns an error code
- * If TSY doesn't support retrieving of parameters, the request is completed
- * immediately with KErrNotSupported.
- * The request is completed with KErrNoMemory if creation of CSmsReadParams
- * object fails.
- * The request is completed with KErrInUse if another SAP is reading.
- * Otherwise, the reading process is started.
- *
- */
-void CSmsProtocol::ReadSmsParameters(MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::ReadSmsParameters");
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
- TInt ret = CheckPoweredUp();
-
- if (ret == KErrNone)
- {
- if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList)
- {
- if (iSmsReadParams==NULL)
- {
- TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
- }
- else if (iSmsReadParams->IsActive())
- {
- ret = KErrInUse;
- }
- }
- else
- ret = KErrNotSupported;
- }
-
- if(ret != KErrNone)
- aObserver.ReadSmsParamsCompleted(ret, NULL);
- else
- iSmsReadParams->Start(aObserver);
- } // CSmsProtocol::ReadSmsParameters
-
-
-/**
- * Cancels a previous request to read SMS parameters.
- *
- */
-void CSmsProtocol::CancelReadSmsParams()
- {
- LOGSMSPROT1("CSmsProtocol::CancelReadSmsParams");
-
- if(iSmsReadParams != NULL)
- iSmsReadParams->Cancel();
- } // CSmsProtocol::CancelReadSmsParams
-
-
-/**
- * Handles a request to write an SMS parameters to the phone's memory.
- * Completes with an error immediately if CheckPoweredUp() returns an error code
- * If TSY doesn't support retrieving and writing of parameters, the request is completed
- * immediately with KErrNotSupported.
- * The request is completed with KErrInUse if another SAP is reading or writing.
- * The request is completed with KErrNoMemory if creation of CSmsReadParams or
- * CSmsWriteParams object fails.
- * Otherwise, the writing process is started.
- *
- */
-void CSmsProtocol::WriteSmsParameters(CMobilePhoneSmspList* aMobilePhoneSmspList,MSmsMessageObserver& aObserver)
- {
- LOGSMSPROT1("CSmsProtocol::WriteSmsParameters");
- __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
-
- TInt ret = CheckPoweredUp();
-
- if (ret == KErrNone)
- {
- if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList && iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsSetSmspList)
- {
- if (iSmsReadParams==NULL)
- {
- TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
- }
- else if (iSmsReadParams->IsActive())
- ret=KErrInUse;
- }
- else
- ret=KErrNotSupported;
- }
-
- if (ret==KErrNone)
- {
- if (iSmsWriteParams==NULL)
- {
- TRAP(ret,(iSmsWriteParams=CSmsWriteParams::NewL(*this,iSmsSettings,iSmsMessaging,*iSmsReadParams)));
- }
- else if (iSmsWriteParams->IsActive())
- ret=KErrInUse;
- }
-
- if (ret==KErrNone)
- iSmsWriteParams->Start(aObserver,aMobilePhoneSmspList);
- else
- {
- aObserver.WriteSmsParamsCompleted(ret);
- delete aMobilePhoneSmspList;
- }
- } // CSmsProtocol::WriteSmsParameters
-
-
-/**
- * Cancels a previous request to write SMS parameters.
- *
- */
-void CSmsProtocol::CancelWriteSmsParams()
- {
- LOGSMSPROT1("CSmsProtocol::CancelWriteSmsParams");
-
- if(iSmsWriteParams != NULL)
- iSmsWriteParams->Cancel();
- } // CSmsProtocol::CancelWriteSmsParams
-
-
-/**
- * Processes a received SMS message by matching it to an observer and
- * notifying the observer of the new message.
- *
- * If the message has been matched to a message previously sent by the protocol
- * (i.e. a status report from a previous submit), then the original message and address
- * are supplied. Matching priority in this case is given to the original sender.
- *
- * If the message remains in phone or SIM memory, the message is sent to the "receive any"
- * observer, otherwise the match based on the message and address of the observer.
- *
- * @param aSmsMessage the received message
- * @param aOriginalSmsAddr pointer to the address of the sender of a previously sent
- * message matched to the received one (e.g. status report). Null if not matched.
- * @param aOriginalSmsMessage pointer to a message previously sent matched to the
- * received one (e.g. status report). Null if not matched.
- * @param aDes user data for the deliver report acknowledging this message to the SC.
- * Filled in by the observer.
- * @return KErrNone if the observer handled the message successfully, otherwise an error.
- *
- */
-TInt CSmsProtocol::ProcessMessageL(const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,
- const CSmsMessage* /*aOriginalSmsMessage*/,TDes& aDes)
- {
- LOGSMSPROT1("CSmsProtocol::ProcessMessage");
-
- MSmsMessageObserver* observer=NULL;
- if (aOriginalSmsAddr!=NULL)
- {
- // Status report and original message matched - send to original sender as priority
- observer=MatchSmsAddressToObserver(*aOriginalSmsAddr);
- if (observer==NULL)
- {
- // Sender no longer present or is read only - match on received message as usual
- observer=MatchSmsMessageToObserver(aSmsMessage);
- }
- }
- else if (iPhoneEnumerationObserver==NULL || IsAppPortSMS(aSmsMessage ))
- {
- // Only match if not currently enumerating or if it is meant for an app port.
- observer = MatchSmsMessageToObserver(aSmsMessage);
- }
-
- LOGSMSPROT2("CSmsProtocol::ProcessMessage [observer=0x%08x]",observer);
- TInt ret=KErrNone;
-
- if (observer!=NULL)
- {
- TBool isAppPortSms = IsAppPortSMS(aSmsMessage );
-
- if(isAppPortSms && iBootTimer !=NULL && iBootTimer->IsActive() && observer->GetLocalAddress().SmsAddrFamily() == ESmsAddrRecvAny)
- {
- ret = KErrNotReady;
- }
- else
- {
- ret=observer->MessageReceived(aSmsMessage,aDes);
- }
-
- if(ret == KErrNone && (observer->ClientConfirmsMessage() == EFalse) && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
- {
- iReassemblyStore->DeleteMessageL(aSmsMessage, EFalse);
- ret=KErrInUse;
- // used to signal to client that there is nothing to be done on reassembly store
- // and code different from KErrNone will do - won't be propagated
- }
- else if(ret == KErrNotFound && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
- {
- if ( iBootTimer && !iBootTimer->IsActive() && (aOriginalSmsAddr==NULL || aOriginalSmsAddr->SmsAddrFamily() != ESmsAddrRecvAny))
- {
- TSmsAddr addr;
- addr.SetSmsAddrFamily(ESmsAddrRecvAny);
- ret = ProcessMessageL(aSmsMessage, &addr, NULL, aDes);
- }
- }
- }
- else
- {
- ret=KErrNotReady; // Observers are not ready
- }
- return ret;
- } // CSmsProtocol::ProcessMessageL
-
-
-/**
- * Deletes one or more PDUs from phone or SIM memory.
- * The PDUs are added to the deletion queue. If this queue is empty, the deletion
- * state machine is started.
- *
- * @param aSlotArray
- */
-void CSmsProtocol::DeletePDUs(const CArrayFix<TGsmSmsSlotEntry>& aSlotArray, MSmsMessageObserver* aObserver)
- {
- LOGSMSPROT3("CSmsProtocol::DeletePDUs [count=%d aObserver=0x%08X", aSlotArray.Count(), aObserver);
- __ASSERT_DEBUG(aSlotArray.Count() != 0, SmspPanic(KSmspSlotArrayEmpty));
-
- for(TInt i=0; i< aSlotArray.Count() ;i++)
- {
- LOGSMSPROT3("CSmsProtocol::DeletePDUs index: %d store %S", aSlotArray[i].iIndex, &aSlotArray[i].iStore);
- }
-
- if (iDeleteQueue != NULL && aSlotArray.Count() != 0)
- {
- iDeleteQueue->Queue(aSlotArray, aObserver);
- }
- } // CSmsProtocol::DeletePDUs
-
-/**
- * Called when the modem detection state has changed.
- * If a modem has connection has just been made, a number of event monitoring
- * state machines are restarted, and as is the bearer setting state machine.
- * If the the modem connection was lost, outstanding operations are cancelled.
- *
- */
-void CSmsProtocol::ModemNotificationCompleted(TInt aStatus,
- RPhone::TModemDetection aNewState)
- {
- LOGSMSPROT3("CSmsProtocol::ModemNotificationCompleted(): aStatus=%d, aNewState=%d",
- aStatus, aNewState);
-
- TBool stateChanged = EFalse;
-
- if (aStatus==KErrNone)
- {
- switch (iModemDetection)
- {
- //
- // it goes from OFF to ON
- //
- case RPhone::EDetectedNotPresent:
- case RPhone::EDetectedUnknown:
- {
- LOGSMSPROT1("RPhone::EDetectedNotPresent: [OFF -> ON]");
- if (aNewState==RPhone::EDetectedPresent)
- {
- // There is a new modem connection
- iModemDetection=aNewState;
- stateChanged = ETrue;
- }
- break;
- }
- //
- // it goes from ON to OFF
- //
- case RPhone::EDetectedPresent:
- {
- LOGSMSPROT1("RPhone::EDetectedPresent: [ON -> OFF]");
- if (aNewState!=RPhone::EDetectedPresent)
- {
- // Ah, lost our modem - cancel outstanding operations
- iModemDetection=aNewState;
- stateChanged = ETrue;
- }
- break;
- }
- default:
- {
- __ASSERT_DEBUG(EFalse,SmspPanic(KSmspPanicUnknownModemDetection));
- }
- }
-
- if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
- {
- if (stateChanged || iState == EPoweredDown)
- {
- PowerUp();
- }
- }
- else if (stateChanged || iState != EPoweredDown)
- {
- PowerDown();
- }
- }
- } // CSmsProtocol::ModemNotificationCompleted
-
-
-void CSmsProtocol::DiskSpaceMonitorStateChange(TSmsDiskSpaceMonitorStatus aStatus)
-/**
- * Called when the Disk Space Monitor state has changed.
- */
- {
- LOGSMSPROT2("CSmsProtocol::DiskSpaceMonitorStateChange(): aStatus=%d", aStatus);
-
- RProperty::Set(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey, aStatus);
- } // CSmsProtocol::DiskSpaceMonitorStateChange
-
-
-/**
- * Called when all message send requests have completed.
- * Increments the number of segmentation store accesses and purges the store
- * if it exceeds CSmsProtocol::KNumSARStoreAccessesBeforePurging.
- */
-void CSmsProtocol::MessageSendCompleted(TInt aStatus)
- {
- LOGSMSPROT3("*** CSmsProtocol::MessageSendCompleted [aStatus=%d iNumSegmentationStoreAccesses=%d]", aStatus, iNumSegmentationStoreAccesses);
- (void) aStatus;
- iNumSegmentationStoreAccesses++;
- if (iNumSegmentationStoreAccesses>=KNumSARStoreAccessesBeforePurging)
- {
- LOGSMSPROT1("iSegmentationStore->PurgeL Start");
- TRAPD(ret, iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse));
- if(ret!=KErrNone)
- {
- // we need to close the file because the function
- // left with the file opened
- // iSegmentationStore->CloseFile();
- LOGSMSPROT2("WARNING! iSegmentationStore->PurgeL left with %d", ret);
- }
- iNumSegmentationStoreAccesses=0;
- LOGSMSPROT2("iSegmentationStore->PurgeL End [ret=%d]", ret);
- }
- } // CSmsProtocol::KNumSARStoreAccessesBeforePurging
-
-
-/**
- * Called when the state machine for enumerating messages on the
- * phone has completed. Notifies the SAP that made the request.
- *
- */
-void CSmsProtocol::PhoneEnumerationCompleted(TInt aStatus)
- {
- LOGSMSPROT1("CSmsProtocol::PhoneEnumerationCompleted");
- iPhoneEnumerationObserver->EnumeratePhoneCompleted(aStatus);
- } // CSmsProtocol::PhoneEnumerationCompleted
-
-
-/**
- * Called by CProtocolBase::Close() to handle any delayed shutdown.
- * If there are messages in the deletion queue then the shut down flag
- * is set, otherwise CProtocolBase::CanClose() is called to finish closing.
- *
- */
-void CSmsProtocol::CloseNow()
- {
- LOGSMSPROT1("CSmsProtocol::CloseNow");
- if (iDeleteQueue != NULL && iDeleteQueue->IsActive())
- SetClosingDown(ETrue);
- else
- CanClose();
- } // CSmsProtocol::CloseNow
-
-
-/**
- * Private constructor.
- *
- */
-CSmsProtocol::CSmsProtocol()
- :iSmsMessageObserverList(8)
- ,iModemDetection(RPhone::EDetectedUnknown)
- {
- iSmsSettings.SetDeletePDUsFromSIM(EFalse);
- iSmsSettings.SetDeletePDUsFromPhoneStores(EFalse);
- iSmsSettings.SetDeletePDUsFromCombinedStores(EFalse);
- iNext8BitPort=KMin8BitPortNumber;
- iNext16BitPort=KMin16BitPortNumber;
- } // CSmsProtocol::CSmsProtocol
-
-
-/**
- * Returns the index of an observer in the observer list.
- *
- */
-TInt CSmsProtocol::ObserverIndex(const MSmsMessageObserver& aObserver) const
- {
- LOGSMSPROT1("CSmsProtocol::ObserverIndex()");
-
- TInt count=iSmsMessageObserverList.Count();
- TInt index=0;
- for (; index<count; index++)
- if (iSmsMessageObserverList[index]==&aObserver)
- break;
- return index;
- } // CSmsProtocol::ObserverIndex
-
-
-/**
- * Checks if an SMS address type is a duplicate of an existing SAP / observer.
- *
- */
-TBool CSmsProtocol::SmsAddrIsAlreadyUsed(const MSmsMessageObserver* aObserver,const TSmsAddr& aSmsAddr)const
- {
- LOGSMSPROT1("CSmsProtocol::SmsAddrIsAlreadyUsed()");
-
- TBool isduplicate=EFalse;
- TInt count=iSmsMessageObserverList.Count();
- for (TInt i=0; (i<count) && (!isduplicate); i++)
- isduplicate=(iSmsMessageObserverList[i]->SmsAddrIsDuplicate(aObserver,aSmsAddr));
- return isduplicate;
- } // CSmsProtocol::SmsAddrIsAlreadyUsed
-
-
-/**
- * A utility class for prioritizing the SMS protocol observers based
- * on their SMS address type.
- * A higher priority observer will be given the opportunity to
- * accept a received messages before one of a lower priority.
- */
-class TKeySmsObserver : public TKeyArrayFix
- {
-public:
- TKeySmsObserver();
- virtual TInt Compare(TInt aLeft,TInt aRight) const;
- static TInt SmsAddressPriority(const TSmsAddr& aAddr);
- };
-
-
-/**
- * Constructor
- *
- */
-TKeySmsObserver::TKeySmsObserver()
- :TKeyArrayFix(0,ECmpTInt)
- {
- iKeyOffset = 0;
- } // TKeySmsObserver::TKeySmsObserver
-
-
-/**
- * Static method that returns the priority of a given SMS address.
- *
- * @leave Panics on an unknown address type.
- *
- */
-TInt TKeySmsObserver::SmsAddressPriority(const TSmsAddr& aAddr)
- {
- TSmsAddrFamily fam = aAddr.SmsAddrFamily();
-
- switch (fam)
- {
- case ESmsAddrEmail:
- return 11;
- case ESmsAddrApplication8BitPort:
- return 10;
- case ESmsAddrApplication16BitPort:
- return 9;
- case ESmsAddrMessageIndication:
- return 8;
- case ESmsAddrStatusReport:
- return 7;
- case ESmsAddrMatchIEI:
- return 6;
- case ESmsAddrMatchText:
- return 5;
- case ESmsAddrRecvAny:
- return 4;
- case ESmsAddrSendOnly:
- return 3;
- case ESmsAddrLocalOperation:
- return 2;
- case ESmsAddrUnbound:
- return 1;
- default:
- SmspPanic(ESmspUnknownSmsAddressFamily);
- };
- return KErrNotFound;
- } // TKeySmsObserver::SmsAddressPriority
-
-
-/**
- * Compares two observers.
- * Override of TKeyArrayFix::Compare() called on to help sort
- * the observer list based on their address types.
- *
- */
-TInt TKeySmsObserver::Compare(TInt aLeft, TInt aRight) const
- {
- LOGSMSPROT3("TKeySmsObserver::Compare [left=%d, right=%d]", aLeft, aRight);
-
- const TInt lhptr = -1; // Left higher priority than right
- const TInt rhptl = 1; // Right higher priority than left
-
- MSmsMessageObserver* left = *(MSmsMessageObserver**)At(aLeft);
- MSmsMessageObserver* right = *(MSmsMessageObserver**)At(aRight);
-
- const TSmsAddr& leftAddr = left->GetLocalAddress();
- const TSmsAddr& rightAddr = right->GetLocalAddress();
-
- TSmsAddrFamily leftFamily = leftAddr.SmsAddrFamily();
-
-
- TInt leftPriority = SmsAddressPriority(leftAddr);
- TInt rightPriority = SmsAddressPriority(rightAddr);
-
- if (leftPriority > rightPriority)
- return lhptr;
- if (rightPriority > leftPriority)
- return rhptl;
-
- if (leftFamily == ESmsAddrMatchText)
- {
- // Longer strings are higher priority than shorter ones
- TInt rightLen = rightAddr.TextMatch().Length();
- TInt leftLen = leftAddr.TextMatch().Length();
- if (leftLen > rightLen)
- return lhptr;
- if (rightLen > leftLen)
- return rhptl;
- }
-
- return 0;
- } // TKeyArrayFix::Compare
-
-
-/**
- * Re-orders the observer list using TKeySmsObserver to determine priorities.
- *
- */
-void CSmsProtocol::OrderSmsMessageObserver(const MSmsMessageObserver& /*aObserver*/)
- {
- LOGSMSPROT1("CSmsProtocol::OrderSmsMessageObserver()");
-
- TKeySmsObserver smsObsKey;
-#ifdef _DEBUG
- TInt ret=iSmsMessageObserverList.Sort(smsObsKey);
- __ASSERT_DEBUG(ret==KErrNone,SmspPanic(ESmspCorruptObserverList));
-#else
- iSmsMessageObserverList.Sort(smsObsKey);
-#endif
- } // CSmsProtocol::OrderSmsMessageObserver
-
-
-/**
- * Attempts to match an incoming message to a SAP / observer. Starts with the
- * highest priority observer.
- *
- */
-MSmsMessageObserver* CSmsProtocol::MatchSmsMessageToObserver(const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CSmsProtocol::MatchSmsMessageToObserver()");
-
- TInt count=iSmsMessageObserverList.Count();
- for (TInt i=0;i<count;i++)
- {
- MSmsMessageObserver* obs = iSmsMessageObserverList[i];
- if (IsMatch(obs->GetLocalAddress(),aSmsMessage))
- return obs;
- }
- return NULL;
- } // CSmsProtocol::MatchSmsMessageToObserver
-
-
-/**
- * Tries to match an SMS address to a SAP / observer. Starts with the highest
- * priority observer.
- *
- */
-MSmsMessageObserver* CSmsProtocol::MatchSmsAddressToObserver(const TSmsAddr& aAddr)
- {
- LOGSMSPROT1("CSmsProtocol::MatchSmsAddressToObserver()");
-
- TInt count=iSmsMessageObserverList.Count();
- for (TInt i=0;i<count;i++)
- {
- MSmsMessageObserver* obs = iSmsMessageObserverList[i];
- if (obs->GetLocalAddress()==aAddr)
- return obs;
- }
- return NULL;
- } // CSmsProtocol::MatchSmsAddressToObserver
-
-
-/**
- * Static function checks if a message is matched to a given SMS address type. Used by
- * MatchSmsMessageToObserver() to find a matching observer for the message.
- *
- */
-TBool CSmsProtocol::IsMatch(const TSmsAddr& aSmsAddr, const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CSmsProtocol::IsMatch()");
-
- TSmsAddrFamily family = aSmsAddr.SmsAddrFamily();
-
- switch(family)
- {
- case (ESmsAddrUnbound):
- case (ESmsAddrSendOnly):
- case(ESmsAddrLocalOperation):
- return EFalse;
-
- case(ESmsAddrApplication8BitPort ):
- {
- return (MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),EFalse));
- }
-
- case (ESmsAddrApplication16BitPort ):
- {
- return(MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),ETrue));
- }
-
- case (ESmsAddrMessageIndication):
- {
- if (MatchInformationElement(aSmsMessage,CSmsInformationElement::ESmsIEISpecialSMSMessageIndication))
- return ETrue;
- if (aSmsMessage.SmsPDU().DataCodingSchemePresent())
- {
- TSmsDataCodingScheme::TSmsDCSBits7To4 bits7to4 = aSmsMessage.SmsPDU().Bits7To4();
- switch (bits7to4)
- {
- case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:
- case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
- case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
- return ETrue;
- default:
- break;
- }
- }
- // CPHS Implementation of message waiting indicator (CPHS Phase 2)
- TGsmSmsTelNumber address;
- aSmsMessage.ParsedToFromAddress(address);
-
- //as far as I can see you can't get the npi from the address. (==0?)
- //might want to compare the content of the tel number with the spec to make sure
- //that we are dealing with a cphs message !
-
- if((address.iTypeOfAddress.TON() == EGsmSmsTONAlphaNumeric) &&
- (address.iTelNumber.Length() == 4) &&
- ((address.iTelNumber[2] & 0x7E) == 0x10) &&// x001 000x constant value
- ((address.iTelNumber[3] & 0x7E) == 0x00) )// x000 000x constant value
- return ETrue; // This means that the SMS received is a Message Waiting indication
- return EFalse;
- }
-
- case (ESmsAddrStatusReport):
- {
- LOGSMSPROT1("TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:");
- if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
- return ETrue;
- }
- break;
- case (ESmsAddrMatchIEI):
- {
- return (MatchInformationElement(aSmsMessage,CSmsInformationElement::TSmsInformationElementIdentifier(aSmsAddr.IdentifierMatch())));
- }
- case (ESmsAddrMatchText):
- {
- TBuf<TSmsAddr::EMaxTextMatchLength> textMatch;
- textMatch.Copy(aSmsAddr.TextMatch());
- TBuf<TSmsAddr::EMaxTextMatchLength> smsMsgBuf;
- TInt bufferLen = aSmsMessage.Buffer().Length();
- bufferLen = Min(bufferLen,textMatch.Length());
- aSmsMessage.Buffer().Extract(smsMsgBuf,0,bufferLen);
- if (textMatch.CompareF(smsMsgBuf)==KErrNone)
- return ETrue;
- return EFalse;
- }
- case (ESmsAddrEmail):
- {
- if(aSmsMessage.IsEmailHeader())
- return ETrue;
- break;
- }
- case (ESmsAddrRecvAny):
- return ETrue;
- default:
- return EFalse;
-
- }
- return EFalse;
- } // CSmsProtocol::IsMatch
-
-/**
- * Static function checks if a message contains a given port. Used by IsMatch()
- * to determine if an SMS address type matches an application port.
- *
- */
-TBool CSmsProtocol::MatchApplicationPort(const CSmsMessage& aSmsMessage,TUint aPort,TBool a16Bit)
- {
- LOGSMSPROT1("CSmsProtocol::MatchApplicationPort");
-
- if (!aSmsMessage.SmsPDU().UserDataPresent())
- return EFalse;
-
- const CSmsPDU& Pdu = aSmsMessage.SmsPDU();
- TInt ToPort = 0;
- TInt FromPort = 0;
- TBool Is16BitPorts = 0;
-
- Pdu.ApplicationPortAddressing(ToPort,FromPort,&Is16BitPorts);
- if((TInt)aPort == ToPort && Is16BitPorts == a16Bit) return ETrue;
-
- return EFalse;
- } // CSmsProtocol::MatchApplicationPort
-
-
-/**
- * Static function checks if a message contains a given information element. Used by IsMatch()
- * to determine if an SMS address type matches a message.
- *
- */
-TBool CSmsProtocol::MatchInformationElement(const CSmsMessage& aSmsMessage, CSmsInformationElement::TSmsInformationElementIdentifier aIeVal)
- {
- LOGSMSPROT1("CSmsProtocol::MatchInformationElement");
-
- if (!aSmsMessage.SmsPDU().UserDataPresent())
- return EFalse;
-
- TInt count=aSmsMessage.SmsPDU().UserData().NumInformationElements();
- for (TInt i=0; i<count; i++)
- {
- TInt identifier=aSmsMessage.SmsPDU().UserData().InformationElement(i).Identifier();
- if (identifier==aIeVal)
- return ETrue;
- }
- return EFalse;
- } // CSmsProtocol::MatchInformationElement
-
-
-/**
- * Searches the reassembly store for complete messages and tries to match
- * them to an observer. If a match is found the message is passed to
- * the observer and deleted from the store, otherwise it's left in store.
- * Called when a new observer is added or a PDU has been received and
- * successfully processed.
- *
- */
-void CSmsProtocol::ProcessCompleteSmsMessagesL()
- {
- LOGSMSPROT1("CSmsProtocol::ProcessCompleteSmsMessagesL");
-
- if(iPhoneEnumerationObserver) return;
-
- iReassemblyStore->ProcessCompleteSmsMessagesL(*this, iSmsPDURead->CurrentMessage());
- } // CSmsProtocol::ProcessCompleteSmsMessagesL
-
-
-/**
- * Called when the state machine for processing a received PDU has completed.
- * The reassembly store access count is incremented and purged if it exceeds
- * CSmsProtocol::KNumSARStoreAccessesBeforePurging.
- * The completed entry is removed from the processing queue and if the queue is
- * not empty, and the processing state machinery is started for the next entry.
- *
- */
-void CSmsProtocol::MessageReadedSuccessfully()
- {
- LOGSMSPROT1("CSmsProtocol::MessageReadedSuccessfully");
- TRAPD(ret,ProcessCompleteSmsMessagesL());
- if(ret!=KErrNone)
- {
- LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
- }
-
- iNumReassemblyStoreAccesses++;
- if(iNumReassemblyStoreAccesses>=KNumSARStoreAccessesBeforePurging)
- {
- TRAP(ret, iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(),EFalse));
-
- if(ret!=KErrNone)
- {
- LOGSMSPROT2("WARNING! iReassemblyStore->PurgeL left with %d", ret);
- }
-
- iNumReassemblyStoreAccesses=0;
- }
- if(CheckPoweredUp() == KErrNone )
- iSmsPDURead->ResumeSmsReception();
- } // CSmsProtocol::MessageReadedSuccessfully
-
-
-/**
- * method to delete sms from the reastore
- */
-void CSmsProtocol::DeleteSMSFromReaStoreL(const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL entry");
- if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
- {
- LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL it's SR");
- return;
- }
-
- TSmsDataCodingScheme::TSmsClass msgClass;
-
- if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Class(msgClass))
- {
- if (msgClass == TSmsDataCodingScheme::ESmsClass0)
- {
- if (!aSmsMessage.IsComplete())
- {
- CIncompleteClass0MessageInfo& incompleteClass0MsgInfo = (CIncompleteClass0MessageInfo &) aSmsMessage.GetOperationsForNonIEL(ESmsIncompleteClass0MessageParameter);
- // Retrieve incomplete class 0 message information & process
- TInt startPos, endPos;
- TBool isLastMessage;
- incompleteClass0MsgInfo.GetIncompleteMessageInfoL(startPos, endPos, isLastMessage);
- if (!isLastMessage)
- {
- /*
- Only in this condition set incomplete message as forwarded
- which internally will remove the PDUs from pre-allocated file.
- */
- LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL Incomplete Message Not last segment");
- iReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
- return;
- }
- }
- }
- }
- iReassemblyStore->DeleteMessageL(aSmsMessage, ETrue);
-
- LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL exit");
- } // CSmsProtocol::DeleteSMSFromReaStoreL
-
-
-/**
- * Used to notify observer of the change in state of the modem connection.
- * Send only observers are not notified (why?).
- */
-void CSmsProtocol::NotifyMessageObservers(TInt aStatus)
- {
- LOGSMSPROT1("CSmsProtocol::NotifyMessageObservers");
-
- TInt count=iSmsMessageObserverList.Count();
- LOGSMSPROT3("CSmsProtocol::NotifyMessageObservers [count=%d, aStatus=%d]",count, aStatus);
- for (TInt index=0; index<count; index++)
- {
- MSmsMessageObserver* observer=iSmsMessageObserverList[index];
- TSmsAddrFamily fam = observer->GetLocalAddress().SmsAddrFamily();
- LOGSMSPROT2("CSmsProtocol::NotifyMessageObservers [family=%d]", fam);
- switch (fam)
- {
- case ESmsAddrMessageIndication:
- case ESmsAddrStatusReport:
- case ESmsAddrMatchIEI:
- case ESmsAddrMatchText:
- case ESmsAddrEmail:
- case ESmsAddrRecvAny:
- case ESmsAddrLocalOperation:
- case ESmsAddrApplication8BitPort:
- case ESmsAddrApplication16BitPort:
- {
- observer->ModemNotificationCompleted(aStatus);
- break;
- }
- case ESmsAddrSendOnly:
- case ESmsAddrUnbound:
- break;
- default:
- SmspPanic(ESmspPanicAddrFamilyNotAllowed);
- }
- }
- } // CSmsProtocol::NotifyMessageObservers
-
-
-void CSmsProtocol::PowerUp()
- {
- LOGSMSPROT2("CSmsProtocol::PowerUp [iState=%d]", iState);
- __ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
-
- if (iState == EPoweredDown)
- {
- TRAPD(err, DoPowerUpL());
-
- if (err != KErrNone)
- {
- LOGSMSPROT3("WARNING: CSmsProtocol::DoPowerUpL left [err=%d iState=%d]", err, iState);
- __ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
- PowerDown();
- }
- }
- } // CSmsProtocol::PowerUp
-
-
-/**
- * Handles the event of the modem powering on (when it had been powered off).
- * Does the following...
- * - The TSY loaded
- * - ETEL resource handles initialised
- * - ETEL parameters set and retrieved
- * - A number of state machines started
- *
- */
-void CSmsProtocol::DoPowerUpL()
- {
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL");
- __ASSERT_DEBUG(iModemDetection==RPhone::EDetectedPresent,SmspPanic(KSmspPhoneHasNotTurnedOn));
-
- //Open the segmentation and reassembly stores
-
- iReassemblyStore->OpenStoreL();
- iSegmentationStore->OpenStoreL();
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
- iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(), ETrue);
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
- iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse);
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
-
- // Connect to ETEL and load the TSY
- User::LeaveIfError(iTelServer.Connect());
- User::LeaveIfError(iTelServer.LoadPhoneModule(iGsmTsyName));
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL Connected to Etel");
-
- // Find the phone corresponding to this TSY and open a number of handles on it
- TInt numPhones;
- User::LeaveIfError(iTelServer.EnumeratePhones(numPhones));
- TInt i=0;
- for (; i<numPhones; i++)
- {
- RTelServer::TPhoneInfo info;
- User::LeaveIfError(iTelServer.GetPhoneInfo(i,info));
- TName tsyName;
- User::LeaveIfError(iTelServer.GetTsyName(i,tsyName));
- if (tsyName.CompareF(iGsmTsyName)==KErrNone)
- {
- User::LeaveIfError(iGsmPhone.Open(iTelServer,info.iName));
- User::LeaveIfError(iEnumerationPhone.Open(iTelServer,info.iName));
- User::LeaveIfError(iWritePhone.Open(iTelServer,info.iName));
- break;
- }
- }
- __ASSERT_DEBUG(i<numPhones,SmspPanic(ESmspPhoneNotFound));
- if (iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended)!=KErrNone)
- User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorBasic));
- User::LeaveIfError(iSmsMessaging.Open(iGsmPhone));
-
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL Opened TSY handles");
-
- if (iSmsPhoneEnumeration == NULL)
- iSmsPhoneEnumeration=CSmsPhoneEnumeration::NewL(*this, iSmsSettings, *iReassemblyStore, *iSegmentationStore, iEnumerationPhone, KSmsSessionPriority, *iSmsMonitorDiskSpace);
-
- if (iWriteQueue == NULL)
- iWriteQueue = CSmspWriteQueue::NewL(*this, iSmsSettings, iWritePhone,*iSegmentationStore, KSmsSessionPriority);
-
- if (iDeleteQueue == NULL)
- iDeleteQueue = CSmspDeleteQueue::NewL(*this,iSmsSettings,iSmsMessaging, KSmsSessionPriority);
-
- // Start state machines
- iSmsPhoneInitialization->Start();
-
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL Started state machines");
-
- NotifyMessageObservers(KIoctlSelectModemPresent);
- LOGSMSPROT1("CSmsProtocol::DoPowerUpL Notified message observers");
-
-
- // Process any waiting messages
- ProcessCompleteSmsMessagesL();
-
- iState = EPoweredUp;
- } // CSmsProtocol::DoPowerUpL
-
-
-/**
- * Handles the event of the modem powering off (when it had been powered on).
- * Does the following...
- * - State mechines cancelled
- * - Close TSY handles
- * - Disconnect from Etel
- *
- * This function will also be called if PowerUpL() leaves
- */
-void CSmsProtocol::PowerDown()
- {
- LOGSMSPROT1("CSmsProtocol::PowerDown");
-
- iSetBearer->Cancel();
- iReceiveMode->Cancel();
-
- iSendQueue->Cancel();
-
- iSmsPDURead->Cancel();
-
- iSmsMonitorDiskSpace->Cancel();
-
- delete iSmsPhoneEnumeration; //must be deleted because uses iSmsMessaging which is soon closed
- iSmsPhoneEnumeration = NULL;
-
- iSmsPhoneInitialization->Cancel();
-
- if( iSmsReadParams != NULL )
- {
- iSmsReadParams->Cancel();
- }
- if( iSmsWriteParams != NULL )
- {
- iSmsWriteParams->Cancel();
- }
-
- delete iWriteQueue; //must be deleted because uses iSmsMessaging which is soon closed
- iWriteQueue = NULL;
-
- delete iDeleteQueue; //must be deleted because uses iSmsMessaging which is soon closed
- iDeleteQueue = NULL;
-
- LOGSMSPROT1("CSmsProtocol::PowerDown Cancelled state machines");
-
- NotifyMessageObservers(KIoctlSelectModemNotPresent);
- LOGSMSPROT1("CSmsProtocol::PowerDown Notified message observers");
-
- // Close TSY handles
- iSmsMessaging.Close();
- iGsmPhone.Close();
- iEnumerationPhone.Close();
- iWritePhone.Close();
- LOGSMSPROT1("CSmsProtocol::PowerDown Closed TSY handles");
-
- // Disconnect from Etel
- iTelServer.Close();
- LOGSMSPROT1("CSmsProtocol::PowerDown Disconnected from Etel");
-
- iReassemblyStore->Close();
- iSegmentationStore->Close();
-
- iState = EPoweredDown;
- }
-
-void CSmsProtocol::CloseNowWrap()
- {
- // Ignore in code coverage - called when PDU delete queue is not
- // empty and SMS stack is closing down - can only get this situation
- // when the PDU delete has been initiated by the SMS stack itself
- // (rather than the client) and the PDUs are still being deleted
- // when last client disconnects.
- BULLSEYE_OFF
- LOGSMSPROT1("CSmsProtocol::CloseNowWrap()");
-
- if( iDeleteQueue == NULL || !iDeleteQueue->IsActive() )
- {
- CloseNow();
- }
- BULLSEYE_RESTORE
- }
-
-void CSmsProtocol::HandleBackupOrRestoreStartingL()
- {
- LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreStartingL [ModemState=%d]", iSmsModemNotification->ModemState());
- PowerDown();
- }
-
-void CSmsProtocol::HandleBackupOrRestoreCompleteL()
- {
- LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreCompleteL [ModemState=%d]", iSmsModemNotification->ModemState());
-
- if (iModemDetection == RPhone::EDetectedPresent)
- {
- PowerUp();
- }
- }
-
-/**
- * Set the sap port number
- */
-TBool CSmsProtocol::AllocateLocalAddress(TSmsAddr& aAddr)
- {
- LOGSMSPROT1("CSmsProtocol::AllocateLocalAddressL");
-
- TBool found=EFalse;
- TUint count=0,attempts=0;
- TSmsAddr locAddr=aAddr;
-
- if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
- {
- count =KMax8BitPortNumber-KMin8BitPortNumber+1;
- }
- else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
- {
- count =KMax16BitPortNumber-KMin16BitPortNumber+1;
- }
-
- for(;!found && attempts < count; ++attempts)
- {
- if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
- {
- locAddr.SetPort(iNext8BitPort++);
- if(iNext8BitPort > KMax8BitPortNumber)iNext8BitPort=KMin8BitPortNumber;
- }
- else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
- {
- locAddr.SetPort(iNext16BitPort++);
- if(iNext16BitPort > KMax16BitPortNumber)iNext8BitPort=KMin16BitPortNumber;
- }
- if(!SmsAddrIsAlreadyUsed(NULL,locAddr))found=ETrue;
- }
-
- if(found)
- {
- aAddr=locAddr;
- }
- return found;
- } // CSmsProtocol::AllocateLocalAddress
-
-/**
- * Static method that returns the boolean value indicating whether the given
- * CSmsMessage is for application port.
- * This function is an utility function which determines the passed sms message
- * is for application port or not. This function is also used in CFacadeSmsReassemblyStore class.
- *
- * @param aSmsMessage reference to CSmsMessage object.
- *
- */
-TBool CSmsProtocol::IsAppPortSMS(const CSmsMessage& aSmsMessage)
- {
- LOGSMSPROT1("CSmsProtocol::IsAppPortSMS()");
-
- TSmsAddr addr;
- addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
- addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit);
- if (IsMatch(addr,aSmsMessage))
- {
- return ETrue;
- }
-
- addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
- addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit);
- if (IsMatch(addr,aSmsMessage))
- {
- return ETrue;
- }
-
- addr.SetSmsAddrFamily(ESmsAddrMatchText);
- addr.SetTextMatch(_L8("//SCK"));
- if (IsMatch(addr,aSmsMessage))
- {
- return ETrue;
- }
-
- return EFalse;
- } // CSmsProtocol::IsAppPortSMS
-
-
-const RMobilePhone::TMobilePhoneNetworkInfoV1& CSmsProtocol::NetworkInfo() const
- {
- LOGSMSPROT1("CSmsProtocol::NetworkInfo()");
-
- return iSmsPhoneInitialization->NetworkInfo();
- } // CSmsProtocol::NetworkInfo
-
-
-TBool CSmsProtocol::NetworkInfoAvailable() const
- {
- LOGSMSPROT1("CSmsProtocol::NetworkInfoAvailable()");
-
- return iSmsPhoneInitialization->NetworkInfoAvailable();
- } // CSmsProtocol::NetworkInfoAvailable
-
-
-// implementation of CSmsProtocolBootTimer
-//
-
-/**
- * 2 phase contructor
- *
- * @param aActive Reference to an CSmsProtocol object
- */
-CSmsProtocolBootTimer* CSmsProtocolBootTimer::NewL(CSmsProtocol& aSmsProtocol)
- {
- LOGSMSPROT1("CSmsProtocolBootTimer::NewL");
-
- CSmsProtocolBootTimer* self = new(ELeave) CSmsProtocolBootTimer(aSmsProtocol);
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop(self);
- return self;
- }
-
-/**
- * D'tor
- */
-CSmsProtocolBootTimer::~CSmsProtocolBootTimer()
- {
- Cancel();
- }
-
-/**
- * Start a timeout specified in aTimeIntervalMicroSeconds32
- */
-void CSmsProtocolBootTimer::Start(const TTimeIntervalMicroSeconds32& aTimeIntervalMicroSeconds32)
- {
- LOGSMSPROT1("CSmsProtocolBootTimer::Start");
- After(aTimeIntervalMicroSeconds32);
- }
-
-/**
- * C'tor
- */
-CSmsProtocolBootTimer::CSmsProtocolBootTimer(CSmsProtocol& aSmsProtocol)
-: CTimer(KSmsSessionPriority), iSmsProtocol(aSmsProtocol)
- {
- CActiveScheduler::Add(this);
- }
-
-/**
- * Timer completed - cancel the observer
- */
-void CSmsProtocolBootTimer::RunL()
- {
- LOGSMSPROT2("CSmsProtocolBootTimer::RunL [iStatus=%d]", iStatus.Int() );
- iSmsProtocol.MessageReadedSuccessfully();
- }
+// 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:
+// Implements the CSmsProtocol and its helper classes.
+//
+//
+
+/**
+ @file
+*/
+
+#include <commsdattypesv1_1.h>
+#include <logwrap.h>
+#include "Gsmumsg.h"
+#include "gsmubuf.h"
+#include "Gsmuelem.h"
+#include "gsmunonieoperations.h"
+
+#include "smsprot.h"
+#include "smspfacadestor.h"
+#include "smspmodm.h"
+#include "smspenum.h"
+#include "smspread.h"
+#include "smspdel.h"
+#include "smspproc.h"
+#include "smspmondsk.h"
+#include "smspmain.h"
+#include "smspver.h"
+#include "smsppara.h"
+#include "SmsuBackup.h"
+#include <es_prot_internal.h>
+
+using namespace CommsDat;
+
+//
+// Class implementations
+//
+
+// application port range according to 3GPP TS 23.040 v4.4.0
+// chapters 9.2.3.24.3 and 9.2.3.24.4
+
+const TInt KMin8BitPortNumber = 240;
+const TInt KMax8BitPortNumber = 255;
+
+const TInt KMin16BitPortNumber = 16000;
+const TInt KMax16BitPortNumber = 16999;
+
+
+/**
+ * 2 phase constructor
+ *
+ */
+CSmsProtocolFamily * CSmsProtocolFamily::NewL()
+ {
+ LOGSMSPROT4("CSmsProtocolFamily::NewL [version %d.%d.%d]",
+ KSmsPrtMajorVersionNumber,
+ KSmsPrtMinorVersionNumber,
+ KSmsPrtBuildVersionNumber
+ );
+ return new (ELeave)CSmsProtocolFamily;
+ } // CSmsProtocolFamily::NewL
+
+
+/**
+ * Implementation of the pure virtual CProtocolFamilyBase::Install().
+ * Called by the socket server after creation of this object.
+ * Does nothing.
+ *
+ */
+TInt CSmsProtocolFamily::Install()
+ {
+ LOGSMSPROT1("CSmsProtocolFamily::Install");
+ return KErrNone;
+ } // CProtocolFamilyBase::Install
+
+
+/**
+ * Implementation of the pure virtual CProtocolFamilyBase::Remove().
+ * Called by the socket server before unloading the library for the SMS
+ * protocol family.
+ * Does nothing.
+ *
+ */
+TInt CSmsProtocolFamily::Remove()
+ {
+ LOGSMSPROT1("CSmsProtocolFamily::Remove");
+ return KErrNone;
+ } // CProtocolFamilyBase::Remove
+
+
+/**
+ * Implementation of the pure virtual CProtocolFamilyBase::NewProtocolL().
+ * Called by the socket server to create the CSmsProtocol object.
+ *
+ * @param aSockType not used, assumes datagram.
+ * @param aProtocol not used, assumes KSmsDatagram, the only protocol provided.
+ * @return a new instance of the CSmsProtocol class.
+ *
+ */
+CProtocolBase * CSmsProtocolFamily::NewProtocolL(TUint /*aSockType*/,TUint /*aProtocol*/)
+ {
+ LOGSMSPROT1("CSmsProtocolFamily::NewProtocolL");
+ return CSmsProtocol::NewL();
+ } // CProtocolFamilyBase::NewProtocolL
+
+
+/**
+ * Implementation of the pure virtual CProtocolFamilyBase::ProtocolList().
+ * Called by the socket server during initialisation to retrieve a list
+ * of the protocols we support.
+ * Only KSmsDatagram is supported.
+ *
+ * @return aProtocolList a pointer to an array of protocol description objects
+ * that this function creates and fills in.
+ * @return the number of protocols supported (1).
+ *
+ */
+TUint CSmsProtocolFamily::ProtocolList(TServerProtocolDesc *& aProtocolList)
+ {
+ LOGSMSPROT1("CSmsProtocolFamily::ProtocolList");
+
+ TRAPD(ret, (aProtocolList=new(ELeave) TServerProtocolDesc[1]));
+ if(ret!=KErrNone)
+ {
+ LOGSMSPROT2("WARNING! new TServerProtocolDesc left with %d", ret);
+ return 0;
+ }
+
+ // Datagram protocol
+ aProtocolList[0].iName=KSmsDatagram;
+ aProtocolList[0].iAddrFamily=KSMSAddrFamily;
+ aProtocolList[0].iSockType=KSockDatagram;
+ aProtocolList[0].iProtocol=KSMSDatagramProtocol;
+ aProtocolList[0].iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
+ aProtocolList[0].iByteOrder=ELittleEndian;
+ aProtocolList[0].iServiceInfo=KSMSDatagramServiceInfo;
+ aProtocolList[0].iNamingServices=0;
+ aProtocolList[0].iSecurity=KSocketNoSecurity;
+ aProtocolList[0].iMessageSize=KSMSMaxDatagramSize;
+ aProtocolList[0].iServiceTypeInfo=ESocketSupport;
+ aProtocolList[0].iNumSockets=KSMSNumberSockets;
+
+ return 1;
+ } // CProtocolFamilyBase::ProtocolList
+
+
+/**
+ * Constructor (empty)
+ */
+CSmsProtocolFamily::CSmsProtocolFamily()
+ {
+ } // CSmsProtocolFamily::CSmsProtocolFamily
+
+
+/**
+ * The single exported function, called by the socket server to create
+ * an instance of our CProtocolFamilyBase derived class.
+ *
+ */
+EXPORT_C CProtocolFamilyBase* InstallSMS()
+ {
+ LOGSMSPROT1("CSmsProtocolFamily::CSmsProtocolFamily()");
+
+ CSmsProtocolFamily* smsProtocolFamily(NULL);
+
+ TRAP_IGNORE(smsProtocolFamily = CSmsProtocolFamily::NewL());
+
+ return smsProtocolFamily;
+ } // CSmsProtocolFamily::CSmsProtocolFamily
+
+
+//
+// implementation of CSmsProtocol
+//
+
+
+/**
+ * 2 phase constructor.
+ *
+ */
+CSmsProtocol* CSmsProtocol::NewL()
+ {
+ LOGSMSPROT1("CSmsProtocol::NewL()");
+
+ return new (ELeave) CSmsProtocol();
+ } // CSmsProtocol::NewL
+
+
+/**
+ * Destructor, ensures all outstanding queues are empty,
+ * all resource handles are closed, and all allocated memory freed.
+ *
+ */
+CSmsProtocol::~CSmsProtocol()
+ {
+ delete iSmsPhoneInitialization;
+ delete iSmsModemNotification;
+
+ delete iSendQueue;
+ delete iSetBearer; // referenced by iSendQueue
+
+ delete iSmsPDURead;
+ delete iReceiveMode; // referenced by iSmsPDURead
+ delete iSmsPhoneEnumeration;
+ delete iWriteQueue;
+ delete iDeleteQueue;
+
+
+ delete iSmsReadParams;
+ delete iSmsWriteParams;
+ delete iSmsMonitorDiskSpace;
+
+ delete iReassemblyStore;
+
+ if(iSegmentationStore)
+ {
+ iSegmentationStore->Close();
+ delete iSegmentationStore;
+ }
+ iFs.Close();
+
+ iSmsMessaging.Close();
+ iGsmPhone.Close();
+ iEnumerationPhone.Close();
+ iWritePhone.Close();
+ iTelServer.Close();
+ delete iBackupRestoreSession;
+ delete iBootTimer;
+ } // CSmsProtocol::~CSmsProtocol
+
+
+
+/**
+ * Override of CProtocolBase::NewSAPL().
+ * Called by the server to create a new SMS service access point object.
+ *
+ * @param aSocketType the socket type
+ * @leave Leaves if aSocketType is not KSockDatagram.
+ * @leave Leaves if not enough memory is available.
+ * @return a new CSmsProvider object.
+ *
+ */
+CServProviderBase *CSmsProtocol::NewSAPL(TUint aSocketType)
+ {
+ LOGSMSPROT2("*CSmsProtocol::NewSAPL [sockettype=%d]", aSocketType);
+ if (aSocketType!=KSockDatagram)
+ User::Leave(KErrNotSupported);
+ return CSmsProvider::NewL(*this);
+ } // CProtocolBase::NewSAPL
+
+
+/**
+ * Override of CProtocolBase::InitL().
+ * Called by the socket server to allow any resource initialisation
+ * by the protocol.
+ *
+ * The following tasks are performed:
+ * - All member objects constructed (deferred from ConstructL() for efficiency reasons; see comment there)
+ * - TSY Name read from Comms Database
+ * - Event notification state machines started
+ * - Modem checked to see if it is already connected, and if so, a number of
+ * state machines started (otherwise wait until we receive notification of connection).
+ *
+ */
+void CSmsProtocol::InitL(TDesC& /*aTag*/)
+ {
+ LOGSMSPROT1("CSmsProtocol::InitL");
+
+ User::LeaveIfError(iFs.Connect());
+
+ iReassemblyStore=CFacadeSmsReassemblyStore::NewL(iFs, *this);
+ iReassemblyStore->InitL();
+
+ LOGSMSPROT1("CSmsProtocol::InitL Constructing members");
+
+ ReadConfigurableSettingsL();
+
+ iBootTimer = CSmsProtocolBootTimer::NewL(*this);
+ iBootTimer->Start(iSmsSettings.BootTimerTimeout().Int());
+
+ iSegmentationStore=CSmsSegmentationStore::NewL(iFs);
+
+ iSetBearer=CSmspSetBearer::NewL(iSmsSettings, iSmsMessaging, KSmsSessionPriority);
+
+ iReceiveMode = CSmspReceiveMode::NewL(iSmsSettings, iSmsMessaging, iMobileSmsCaps, KSmsSessionPriority);
+
+ iSmsModemNotification=CSmsModemNotification::NewL(*this);
+
+ iSendQueue = CSmspSendQueue::NewL(*this, *iSegmentationStore, iSmsSettings, iMobileSmsCaps, iSmsMessaging, KSmsSessionPriority, *iSetBearer);
+
+ iSmsMonitorDiskSpace=CSmsMonitorDiskSpace::NewL(*this, iSmsMessaging,iFs);
+
+ iSmsPDURead=CSmsPDURead::NewL(*this, iSmsSettings, iSmsMessaging,*iReassemblyStore,*iSegmentationStore, iMobileSmsCaps, KSmsSessionPriority, *iReceiveMode, *iSmsMonitorDiskSpace);
+
+ iSmsPhoneInitialization = new (ELeave) CSmsPhoneInitialization(iSmsMessaging, iGsmPhone, *iSmsPDURead, iMobileSmsCaps, KSmsSessionPriority, iSetBearer);
+
+ iBackupRestoreSession = CBackupAndRestore::NewL(*this);
+
+/* THIS CODE SHOULD NEVER BE NECESSARY - who could have called CProtocolBase::InitL() if not ESOCK, which means
+ * a running C32 already. However, if this is a wrong analysis then reinstate the code but with an explanatory comment
+#if defined (__WINS__)
+ // Make sure C32 is started under WINS
+ TInt ret=StartC32();
+ if (ret!=KErrAlreadyExists)
+ User::LeaveIfError(ret);
+#endif
+*/
+ LOGSMSPROT1("CSmsProtocol::InitL Querying CommDb");
+
+ // Read the global modem ID setting from Cooms Database
+ TUint32 modemId = 0;
+
+
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ CMDBSession* sess = CMDBSession::NewL(KCDVersion1_2);
+#else
+ CMDBSession* sess = CMDBSession::NewL(KCDVersion1_1);
+#endif
+ CleanupStack::PushL(sess);
+
+ CMDBField<TUint32>* globalSettingField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
+ CleanupStack::PushL(globalSettingField);
+ globalSettingField->SetRecordId(1);
+ globalSettingField->LoadL(*sess);
+ modemId = *globalSettingField;
+ CleanupStack::PopAndDestroy(globalSettingField);
+
+ CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
+ CleanupStack::PushL(tsyField);
+ tsyField->SetRecordId(modemId);
+ tsyField->LoadL(*sess);
+ iGsmTsyName = *tsyField;
+ CleanupStack::PopAndDestroy(tsyField);
+
+ CleanupStack::PopAndDestroy(sess);
+
+#ifdef _SMS_LOGGING_ENABLED
+ TBuf8<KCommsDbSvrMaxFieldLength> buf8;
+ buf8.Copy(iGsmTsyName);
+ LOGSMSPROT3("CSmsProtocol::InitL [modemId=%d tsy=%S]",
+ modemId, &buf8);
+#endif
+
+ // Start event notification state machines
+ iSmsModemNotification->Start();
+
+ // Intialise the SmsStack to the state that the phone has been found in
+ iModemDetection=iSmsModemNotification->ModemState();
+
+ if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
+ {
+ DoPowerUpL(); //Call the leaving version because powering up must work here
+ }
+ else
+ {
+ PowerDown();
+ }
+
+ //
+ // Define the Disk Space Monitor P&S variable...
+ //
+ TInt ret;
+
+ TSecurityPolicy readPolicy(ECapabilityReadDeviceData);
+ TSecurityPolicy writePolicy(ECapabilityWriteDeviceData);
+
+ ret = RProperty::Define(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey,
+ KUidPSSMSStackDiskSpaceMonitorKeyType, readPolicy, writePolicy);
+ if (ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ User::Leave(ret);
+ }
+
+ User::LeaveIfError(RProperty::Set(KUidPSSMSStackCategory,
+ KUidPSSMSStackDiskSpaceMonitorKey, ESmsDiskSpaceAvailable));
+ } // CProtocolBase::InitL
+
+
+/**
+ * Override of CProtocolBase::StartL().
+ * Called by the socket server to indicate all bindings are complete
+ * and that datagram processing can begin.
+ *
+ * Binding is not supported so this indication is not important to us.
+ *
+ */
+void CSmsProtocol::StartL(void)
+ {
+ LOGSMSPROT1("CSmsProtocol::StartL");
+ } // CSmsProtocol::StartL
+
+
+/**
+ * Override of CProtocolBase::Identify().
+ * Called by the socket server to obtain a description of the SMS protocol.
+ *
+ */
+void CSmsProtocol::Identify(TServerProtocolDesc *aDesc)const
+ {
+ LOGSMSPROT1("CSmsProtocol::Identify");
+
+ aDesc->iName=KSmsDatagram;
+ aDesc->iAddrFamily=KSMSAddrFamily;
+ aDesc->iSockType=KSockDatagram;
+ aDesc->iProtocol=KSMSDatagramProtocol;
+ aDesc->iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
+ aDesc->iByteOrder=ELittleEndian;
+ aDesc->iServiceInfo=KSMSDatagramServiceInfo;
+ aDesc->iNamingServices=0;
+ aDesc->iSecurity=KSocketNoSecurity;
+ aDesc->iMessageSize=KSMSMaxDatagramSize;
+ aDesc->iServiceTypeInfo=0;
+ aDesc->iNumSockets=KSMSNumberSockets;
+ } // CProtocolBase::Identify
+
+
+/**
+ * Override of CProtocolBase::NewHostResolverL().
+ * Called by socket server to create a host resolver.
+ * No host resolver service is provided by this SMS protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+CHostResolvProvdBase *CSmsProtocol::NewHostResolverL()
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::NewHostResolverL");
+ SmspPanic(ESmspCantCreateHostResolver);
+ return NULL;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::NewServiceResolverL().
+ * Called by socket server to create a new service resolver.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+CServiceResolvProvdBase *CSmsProtocol::NewServiceResolverL()
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("*CSmsProtocol::NewServiceResolverL");
+ SmspPanic(ESmspCantCreateServiceResolver);
+ return NULL;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::NewNetDatabaseL().
+ * Called by socket server to create a new network database.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+CNetDBProvdBase* CSmsProtocol::NewNetDatabaseL()
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::NewNetDatabaseL");
+ SmspPanic(ESmspCantCreateNetDatabase);
+ return NULL;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::BindL().
+ * Called by next protocol above wishing to bind to the SMS protocol.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+void CSmsProtocol::BindL(CProtocolBase* /*aProtocol*/,TUint /*aId*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::BindL");
+ SmspPanic(ESmspCantBind);
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::BindToL().
+ * Called by socket server when a lower protocol must bind to the
+ * SMS protocol.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+void CSmsProtocol::BindToL(CProtocolBase* /*aProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::BindToL");
+ SmspPanic(ESmspCantBindTo);
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Reads timeout value for send operation from configuration file
+ *
+ * @leave Leaves if configuration file cannot be read
+ * @leave Leaves if value not greater than zero
+ */
+void CSmsProtocol::ReadConfigurableSettingsL()
+ {
+ CESockIniData* ini = NULL;
+ TRAPD(ret, ini=CESockIniData::NewL(_L("smswap.sms.esk")));
+ if(ret!=KErrNone)
+ {
+ LOGSMSPROT2("esk read failed, error code = [%d]", ret);
+ User::Leave(ret);
+ }
+
+ CleanupStack::PushL(ini);
+
+ TInt var(0);
+ if(ini->FindVar(_L("customTimeoutSettings"),_L("sendTryTimeout"),var))
+ {
+ if (var > 0)
+ {
+ LOGSMSPROT2("sendTryTimeout [%d]", var);
+ iSmsSettings.SetSendTryTimeout(var);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+ if(ini->FindVar(_L("customTimeoutSettings"),_L("bootTimerTimeout"),var))
+ {
+ if (var > 0)
+ {
+ LOGSMSPROT2("bootTimerTimeout [%d]", var);
+ iSmsSettings.SetBootTimerTimeout(var);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(ini);
+ } // CSmsProtocol::ReadConfigurableSettingsL
+
+
+/**
+ * Override of CProtocolBase::Send().
+ * A down call from a protocol bound above to send a datagram.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+TInt CSmsProtocol::Send(TDes8& /*aDes*/,TSockAddr* /*aTo*/,TSockAddr* /*aFrom*/,CProtocolBase* /*aSourceProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::Send");
+ SmspPanic(ESmspCantSend);
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::Process().
+ * An up call from a protocol bound below to process a datagram.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+void CSmsProtocol::Process(TDes8& /*aDes*/,TSockAddr* /*aFrom*/,TSockAddr* /*aTo*/,CProtocolBase* /*aSourceProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::Process");
+ SmspPanic(ESmspCantProcess);
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::GetOption().
+ * A down call from a protocol bound above to get a protocol option.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+TInt CSmsProtocol::GetOption(TUint /*aLevel*/,TUint /*aName*/,TDes8 & /*aOption*/,CProtocolBase* /*aSourceProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::GetOption");
+ // SmspPanic(ESmspCantGetOption);
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::SetOption().
+ * A down call from a protocol bound above to set a protocol option.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+TInt CSmsProtocol::SetOption(TUint /*aLevel*/,TUint /*aName*/,const TDesC8& /*option*/,CProtocolBase* /*aSourceProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::SetOption");
+ //SmspPanic(ESmspCantSetOption);
+ return KErrNotSupported;
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Override of CProtocolBase::Error().
+ * An up call from a protocol bound below to indicate an error.
+ * Not supported by this protocol.
+ *
+ * @leave Panics if called.
+ *
+ */
+void CSmsProtocol::Error(TInt /*aError*/,CProtocolBase* /*aSourceProtocol*/)
+ {
+ // Ignore in code coverage - not intended to be used
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::Error");
+ SmspPanic(ESmspCantError);
+ BULLSEYE_RESTORE
+ }
+
+/**
+ * Adds an observer to the protocol's observer list.
+ * Used by CSmsProvider and CWapSmsProtocol.
+ *
+ * @leave Leaves if not enough memory is available.
+ *
+ */
+void CSmsProtocol::AddSmsMessageObserverL(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT2("CSmsProtocol::AddSmsMessageObserverL [aObserver=0x%08x]", &aObserver);
+ iSmsMessageObserverList.AppendL(&aObserver);
+ SetClosingDown(EFalse);
+ }
+
+/**
+ * Binds an SMS observer to the protocol.
+ * The protocol ensures there are no providers with duplicate addresses.
+ * Used by CSmsProvider::SetLocalName(), and SMS WAP protocol.
+ *
+ * @param aObserver the observer.
+ * @param aSmsAddr the local address of the observer.
+ * @return KErrNone on success, or KErrAlreadyExists if a duplicate exists.
+ *
+ */
+TInt CSmsProtocol::BindSmsMessageObserver(MSmsMessageObserver& aObserver,const TSmsAddr& aSmsAddr)
+ {
+ LOGSMSPROT2("CSmsProtocol::BindSmsMessageObserver 0x%08x", &aObserver);
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+ TInt ret=KErrNone;
+
+ if (!SmsAddrIsAlreadyUsed(&aObserver,aSmsAddr))
+ {
+ aObserver.SetLocalAddress(aSmsAddr);
+ OrderSmsMessageObserver(aObserver);
+
+ // If not in the powered-up state then the SAR store is closed. When the phone does power-up
+ // then anything waiting in the store will get processed
+ if(CheckPoweredUp() == KErrNone)
+ {
+ //
+ // check the SAR store for any complete messages.
+ // if there are any, send them to the observer
+ //
+ TRAP(ret, ProcessCompleteSmsMessagesL());
+ if(ret != KErrNone)
+ {
+ LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
+ }
+ }
+ }
+ else
+ {
+ ret=KErrAlreadyExists;
+ }
+ return ret;
+ } // CSmsProvider::SetLocalName
+
+
+/**
+ * Removes an observer from the observer list.
+ * Observers should at least call this method in their destructors.
+ *
+ */
+void CSmsProtocol::RemoveSmsMessageObserver(const MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT2("CSmsProtocol::RemoveSmsMessageObserver 0x%08x", &aObserver);
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+ TInt index=ObserverIndex(aObserver);
+ iSmsMessageObserverList.Delete(index);
+ }
+
+/**
+ * Handles a request from a SAP to send a SMS message.
+ * Ensures there is a current connection to the modem and queues the message.
+ * Completes with an error immediately if CheckPoweredUp() returns an error code
+ */
+void CSmsProtocol::SendSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver,TUint aOptions)
+ {
+ LOGSMSPROT2("CSmsProtocol::SendSmsMessage [aObserver=0x%X]", &aObserver);
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
+
+ // Ensure the modem is connected and initialized
+ const TInt err = CheckPoweredUp();
+
+ if (err != KErrNone)
+ {
+ // Nope, complete immediately
+ aObserver.MessageSendCompleted(err);
+ delete aSmsMessage;
+ }
+ else
+ {
+ iSendQueue->Queue(aSmsMessage, aObserver, aOptions);
+ }
+ }
+
+TInt CSmsProtocol::CheckPoweredUp() const
+ {
+ TInt err = KErrNone;
+
+ if( iModemDetection == RPhone::EDetectedNotPresent || iState == EPoweredDown )
+ {
+ err = KErrDisconnected;
+ }
+ else if( iBackupRestoreSession->IsBackupOrRestoreInProgress() )
+ {
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ err = iSmsPhoneInitialization->Initialized();
+ }
+ if( err != KErrNone )
+ {
+ LOGSMSPROT4("CSmsProtocol::CheckPoweredUp [err=%d, iModemDetection=%d, IsBackupOrRestoreInProgress=%d]", err, iModemDetection, iBackupRestoreSession->IsBackupOrRestoreInProgress());
+ }
+ return err;
+ }
+
+/**
+ * Cancels a previous request to send an SMS message.
+ * Searches the send queue for the message. If it is found at the
+ * head of the queue the sending state machine is cancelled, which
+ * in turn will callback to the protocol and delete the message.
+ * If the message is elsewhere in the queue, it is simply removed
+ * from the queue and the observer notified.
+ *
+ * @leave Panics in DEBUG if the message is not found in the queue.
+ *
+ */
+void CSmsProtocol::CancelSendSmsMessage(MSmsMessageObserver& aObserver,TBool)
+ {
+ LOGSMSPROT2("CSmsProtocol::CancelSendSmsMessage 0x%08x", &aObserver);
+
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ iSendQueue->CancelObserver(aObserver);
+ } // CSmsProtocol::CancelSendSmsMessage
+
+
+/**
+ * Handles a request from a SAP to enumerate the SMS messages stored on the phone.
+ */
+void CSmsProtocol::EnumeratePhone(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::EnumeratePhone");
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ // Ensure the modem is connected and initialized
+ const TInt err = CheckPoweredUp();
+
+ if (err != KErrNone)
+ aObserver.EnumeratePhoneCompleted(err);
+ else
+ {
+ if (iPhoneEnumerationObserver!=NULL)
+ {
+ aObserver.EnumeratePhoneCompleted(KErrInUse);
+ }
+ else
+ {
+ iPhoneEnumerationObserver=&aObserver;
+ iSmsPhoneEnumeration->Start();
+ }
+ }
+ } // CSmsProtocol::EnumeratePhone
+
+
+/**
+ * Cancels a previous request to enumerate the message on the phone memory.
+ *
+ * @leave Panics in DEBUG if the SAP is invalid.
+ *
+ */
+void CSmsProtocol::CancelEnumeratePhone(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::CancelEnumeratePhone");
+
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
+ __ASSERT_DEBUG(iPhoneEnumerationObserver==NULL || &aObserver==iPhoneEnumerationObserver, SmspPanic(ESmspMessageWrongObserver));
+
+ if (iSmsPhoneEnumeration != NULL)
+ {
+ iSmsPhoneEnumeration->Cancel();
+ }
+
+ iReassemblyStore->DeleteEnumeratedSIMEntries();
+
+ (void) aObserver;
+ } // CSmsProtocol::CancelEnumeratePhone
+
+
+TInt CSmsProtocol::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
+ {
+ return iReassemblyStore->ExternalizeEnumeratedMessagesL(aProvider, aCount);
+ } // CSmsProtocol::ExternalizeEnumeratedMessagesL
+
+
+/**
+ * Handles a request to write an SMS message to the phone's memory.
+ * Completes with an error immediately if CheckPoweredUp() returns an error code
+ * Otherwise the message is added to the tail of the write queue.
+ */
+void CSmsProtocol::WriteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::WriteSmsMessage");
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ const TInt err = CheckPoweredUp();
+
+ if (err != KErrNone)
+ {
+ aObserver.MessageWriteCompleted(err);
+ delete aSmsMessage;
+ }
+ else
+ {
+ iWriteQueue->Queue(aSmsMessage, aObserver, NULL);
+ }
+ } // CSmsProtocol::WriteSmsMessage
+
+
+void CSmsProtocol::CancelWriteSmsMessage(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::CancelWriteSmsMessage()");
+
+ if (iWriteQueue != NULL)
+ iWriteQueue->CancelObserver(aObserver);
+ } // CSmsProtocol::CancelWriteSmsMessage
+
+
+/**
+ * Handles a request from a SAP to delete a message from the phone memory.
+ * Completes with an error immediately if CheckPoweredUp() returns an error code
+ * If the cached image of the phone's memory is not yet initialised, complete the
+ * request with KErrNotReady.
+ * Otherwise match the message in the phone image and queue the message for deletion.
+ *
+ * @note aSmsMessage is destroyed from memory on completion.
+ *
+ */
+void CSmsProtocol::DeleteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::DeleteSmsMessage");
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ // Ensure the modem is connected and initialized
+ const TInt err = CheckPoweredUp();
+
+ if (err != KErrNone)
+ {
+ // Not connected or backup running
+ aObserver.MessageDeleteCompleted(err);
+ }
+ else if (aSmsMessage->iSlotArray.Count()==0)
+ aObserver.MessageDeleteCompleted(KErrArgument);
+ else
+ DeletePDUs(aSmsMessage->iSlotArray,&aObserver);
+
+ delete aSmsMessage;
+ } // CSmsProtocol::DeleteSmsMessage
+
+
+/**
+ * Cancels a previous request to delete a message from the phone memory.
+ *
+ * @leave Panics in DEBUG if the SAP is invalid.
+ *
+ */
+void CSmsProtocol::CancelDeleteSmsMessage(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::CancelDeleteSmsMessage");
+
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ iDeleteQueue->CancelObserver(aObserver);
+ } // CSmsProtocol::CancelDeleteSmsMessage
+
+
+/**
+ * Handles a request from a SAP to read the SMS parameters stored on the phone.
+ * Completes with an error immediately if CheckPoweredUp() returns an error code
+ * If TSY doesn't support retrieving of parameters, the request is completed
+ * immediately with KErrNotSupported.
+ * The request is completed with KErrNoMemory if creation of CSmsReadParams
+ * object fails.
+ * The request is completed with KErrInUse if another SAP is reading.
+ * Otherwise, the reading process is started.
+ *
+ */
+void CSmsProtocol::ReadSmsParameters(MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::ReadSmsParameters");
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+ TInt ret = CheckPoweredUp();
+
+ if (ret == KErrNone)
+ {
+ if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList)
+ {
+ if (iSmsReadParams==NULL)
+ {
+ TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
+ }
+ else if (iSmsReadParams->IsActive())
+ {
+ ret = KErrInUse;
+ }
+ }
+ else
+ ret = KErrNotSupported;
+ }
+
+ if(ret != KErrNone)
+ aObserver.ReadSmsParamsCompleted(ret, NULL);
+ else
+ iSmsReadParams->Start(aObserver);
+ } // CSmsProtocol::ReadSmsParameters
+
+
+/**
+ * Cancels a previous request to read SMS parameters.
+ *
+ */
+void CSmsProtocol::CancelReadSmsParams()
+ {
+ LOGSMSPROT1("CSmsProtocol::CancelReadSmsParams");
+
+ if(iSmsReadParams != NULL)
+ iSmsReadParams->Cancel();
+ } // CSmsProtocol::CancelReadSmsParams
+
+
+/**
+ * Handles a request to write an SMS parameters to the phone's memory.
+ * Completes with an error immediately if CheckPoweredUp() returns an error code
+ * If TSY doesn't support retrieving and writing of parameters, the request is completed
+ * immediately with KErrNotSupported.
+ * The request is completed with KErrInUse if another SAP is reading or writing.
+ * The request is completed with KErrNoMemory if creation of CSmsReadParams or
+ * CSmsWriteParams object fails.
+ * Otherwise, the writing process is started.
+ *
+ */
+void CSmsProtocol::WriteSmsParameters(CMobilePhoneSmspList* aMobilePhoneSmspList,MSmsMessageObserver& aObserver)
+ {
+ LOGSMSPROT1("CSmsProtocol::WriteSmsParameters");
+ __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
+
+ TInt ret = CheckPoweredUp();
+
+ if (ret == KErrNone)
+ {
+ if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList && iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsSetSmspList)
+ {
+ if (iSmsReadParams==NULL)
+ {
+ TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
+ }
+ else if (iSmsReadParams->IsActive())
+ ret=KErrInUse;
+ }
+ else
+ ret=KErrNotSupported;
+ }
+
+ if (ret==KErrNone)
+ {
+ if (iSmsWriteParams==NULL)
+ {
+ TRAP(ret,(iSmsWriteParams=CSmsWriteParams::NewL(*this,iSmsSettings,iSmsMessaging,*iSmsReadParams)));
+ }
+ else if (iSmsWriteParams->IsActive())
+ ret=KErrInUse;
+ }
+
+ if (ret==KErrNone)
+ iSmsWriteParams->Start(aObserver,aMobilePhoneSmspList);
+ else
+ {
+ aObserver.WriteSmsParamsCompleted(ret);
+ delete aMobilePhoneSmspList;
+ }
+ } // CSmsProtocol::WriteSmsParameters
+
+
+/**
+ * Cancels a previous request to write SMS parameters.
+ *
+ */
+void CSmsProtocol::CancelWriteSmsParams()
+ {
+ LOGSMSPROT1("CSmsProtocol::CancelWriteSmsParams");
+
+ if(iSmsWriteParams != NULL)
+ iSmsWriteParams->Cancel();
+ } // CSmsProtocol::CancelWriteSmsParams
+
+
+/**
+ * Processes a received SMS message by matching it to an observer and
+ * notifying the observer of the new message.
+ *
+ * If the message has been matched to a message previously sent by the protocol
+ * (i.e. a status report from a previous submit), then the original message and address
+ * are supplied. Matching priority in this case is given to the original sender.
+ *
+ * If the message remains in phone or SIM memory, the message is sent to the "receive any"
+ * observer, otherwise the match based on the message and address of the observer.
+ *
+ * @param aSmsMessage the received message
+ * @param aOriginalSmsAddr pointer to the address of the sender of a previously sent
+ * message matched to the received one (e.g. status report). Null if not matched.
+ * @param aOriginalSmsMessage pointer to a message previously sent matched to the
+ * received one (e.g. status report). Null if not matched.
+ * @param aDes user data for the deliver report acknowledging this message to the SC.
+ * Filled in by the observer.
+ * @return KErrNone if the observer handled the message successfully, otherwise an error.
+ *
+ */
+TInt CSmsProtocol::ProcessMessageL(const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,
+ const CSmsMessage* /*aOriginalSmsMessage*/,TDes& aDes)
+ {
+ LOGSMSPROT1("CSmsProtocol::ProcessMessage");
+
+ MSmsMessageObserver* observer=NULL;
+ if (aOriginalSmsAddr!=NULL)
+ {
+ // Status report and original message matched - send to original sender as priority
+ observer=MatchSmsAddressToObserver(*aOriginalSmsAddr);
+ if (observer==NULL)
+ {
+ // Sender no longer present or is read only - match on received message as usual
+ observer=MatchSmsMessageToObserver(aSmsMessage);
+ }
+ }
+ else if (iPhoneEnumerationObserver==NULL || IsAppPortSMS(aSmsMessage ))
+ {
+ // Only match if not currently enumerating or if it is meant for an app port.
+ observer = MatchSmsMessageToObserver(aSmsMessage);
+ }
+
+ LOGSMSPROT2("CSmsProtocol::ProcessMessage [observer=0x%08x]",observer);
+ TInt ret=KErrNone;
+
+ if (observer!=NULL)
+ {
+ TBool isAppPortSms = IsAppPortSMS(aSmsMessage );
+
+ if(isAppPortSms && iBootTimer !=NULL && iBootTimer->IsActive() && observer->GetLocalAddress().SmsAddrFamily() == ESmsAddrRecvAny)
+ {
+ ret = KErrNotReady;
+ }
+ else
+ {
+ ret=observer->MessageReceived(aSmsMessage,aDes);
+ }
+
+ if(ret == KErrNone && (observer->ClientConfirmsMessage() == EFalse) && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
+ {
+ iReassemblyStore->DeleteMessageL(aSmsMessage, EFalse);
+ ret=KErrInUse;
+ // used to signal to client that there is nothing to be done on reassembly store
+ // and code different from KErrNone will do - won't be propagated
+ }
+ else if(ret == KErrNotFound && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
+ {
+ if ( iBootTimer && !iBootTimer->IsActive() && (aOriginalSmsAddr==NULL || aOriginalSmsAddr->SmsAddrFamily() != ESmsAddrRecvAny))
+ {
+ TSmsAddr addr;
+ addr.SetSmsAddrFamily(ESmsAddrRecvAny);
+ ret = ProcessMessageL(aSmsMessage, &addr, NULL, aDes);
+ }
+ }
+ }
+ else
+ {
+ ret=KErrNotReady; // Observers are not ready
+ }
+ return ret;
+ } // CSmsProtocol::ProcessMessageL
+
+
+/**
+ * Deletes one or more PDUs from phone or SIM memory.
+ * The PDUs are added to the deletion queue. If this queue is empty, the deletion
+ * state machine is started.
+ *
+ * @param aSlotArray
+ */
+void CSmsProtocol::DeletePDUs(const CArrayFix<TGsmSmsSlotEntry>& aSlotArray, MSmsMessageObserver* aObserver)
+ {
+ LOGSMSPROT3("CSmsProtocol::DeletePDUs [count=%d aObserver=0x%08X", aSlotArray.Count(), aObserver);
+ __ASSERT_DEBUG(aSlotArray.Count() != 0, SmspPanic(KSmspSlotArrayEmpty));
+
+ for(TInt i=0; i< aSlotArray.Count() ;i++)
+ {
+ LOGSMSPROT3("CSmsProtocol::DeletePDUs index: %d store %S", aSlotArray[i].iIndex, &aSlotArray[i].iStore);
+ }
+
+ if (iDeleteQueue != NULL && aSlotArray.Count() != 0)
+ {
+ iDeleteQueue->Queue(aSlotArray, aObserver);
+ }
+ } // CSmsProtocol::DeletePDUs
+
+/**
+ * Called when the modem detection state has changed.
+ * If a modem has connection has just been made, a number of event monitoring
+ * state machines are restarted, and as is the bearer setting state machine.
+ * If the the modem connection was lost, outstanding operations are cancelled.
+ *
+ */
+void CSmsProtocol::ModemNotificationCompleted(TInt aStatus,
+ RPhone::TModemDetection aNewState)
+ {
+ LOGSMSPROT3("CSmsProtocol::ModemNotificationCompleted(): aStatus=%d, aNewState=%d",
+ aStatus, aNewState);
+
+ TBool stateChanged = EFalse;
+
+ if (aStatus==KErrNone)
+ {
+ switch (iModemDetection)
+ {
+ //
+ // it goes from OFF to ON
+ //
+ case RPhone::EDetectedNotPresent:
+ case RPhone::EDetectedUnknown:
+ {
+ LOGSMSPROT1("RPhone::EDetectedNotPresent: [OFF -> ON]");
+ if (aNewState==RPhone::EDetectedPresent)
+ {
+ // There is a new modem connection
+ iModemDetection=aNewState;
+ stateChanged = ETrue;
+ }
+ break;
+ }
+ //
+ // it goes from ON to OFF
+ //
+ case RPhone::EDetectedPresent:
+ {
+ LOGSMSPROT1("RPhone::EDetectedPresent: [ON -> OFF]");
+ if (aNewState!=RPhone::EDetectedPresent)
+ {
+ // Ah, lost our modem - cancel outstanding operations
+ iModemDetection=aNewState;
+ stateChanged = ETrue;
+ }
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG(EFalse,SmspPanic(KSmspPanicUnknownModemDetection));
+ }
+ }
+
+ if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
+ {
+ if (stateChanged || iState == EPoweredDown)
+ {
+ PowerUp();
+ }
+ }
+ else if (stateChanged || iState != EPoweredDown)
+ {
+ PowerDown();
+ }
+ }
+ } // CSmsProtocol::ModemNotificationCompleted
+
+
+void CSmsProtocol::DiskSpaceMonitorStateChange(TSmsDiskSpaceMonitorStatus aStatus)
+/**
+ * Called when the Disk Space Monitor state has changed.
+ */
+ {
+ LOGSMSPROT2("CSmsProtocol::DiskSpaceMonitorStateChange(): aStatus=%d", aStatus);
+
+ RProperty::Set(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey, aStatus);
+ } // CSmsProtocol::DiskSpaceMonitorStateChange
+
+
+/**
+ * Called when all message send requests have completed.
+ * Increments the number of segmentation store accesses and purges the store
+ * if it exceeds CSmsProtocol::KNumSARStoreAccessesBeforePurging.
+ */
+void CSmsProtocol::MessageSendCompleted(TInt aStatus)
+ {
+ LOGSMSPROT3("*** CSmsProtocol::MessageSendCompleted [aStatus=%d iNumSegmentationStoreAccesses=%d]", aStatus, iNumSegmentationStoreAccesses);
+ (void) aStatus;
+ iNumSegmentationStoreAccesses++;
+ if (iNumSegmentationStoreAccesses>=KNumSARStoreAccessesBeforePurging)
+ {
+ LOGSMSPROT1("iSegmentationStore->PurgeL Start");
+ TRAPD(ret, iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse));
+ if(ret!=KErrNone)
+ {
+ // we need to close the file because the function
+ // left with the file opened
+ // iSegmentationStore->CloseFile();
+ LOGSMSPROT2("WARNING! iSegmentationStore->PurgeL left with %d", ret);
+ }
+ iNumSegmentationStoreAccesses=0;
+ LOGSMSPROT2("iSegmentationStore->PurgeL End [ret=%d]", ret);
+ }
+ } // CSmsProtocol::KNumSARStoreAccessesBeforePurging
+
+
+/**
+ * Called when the state machine for enumerating messages on the
+ * phone has completed. Notifies the SAP that made the request.
+ *
+ */
+void CSmsProtocol::PhoneEnumerationCompleted(TInt aStatus)
+ {
+ LOGSMSPROT1("CSmsProtocol::PhoneEnumerationCompleted");
+ iPhoneEnumerationObserver->EnumeratePhoneCompleted(aStatus);
+ } // CSmsProtocol::PhoneEnumerationCompleted
+
+
+/**
+ * Called by CProtocolBase::Close() to handle any delayed shutdown.
+ * If there are messages in the deletion queue then the shut down flag
+ * is set, otherwise CProtocolBase::CanClose() is called to finish closing.
+ *
+ */
+void CSmsProtocol::CloseNow()
+ {
+ LOGSMSPROT1("CSmsProtocol::CloseNow");
+ if (iDeleteQueue != NULL && iDeleteQueue->IsActive())
+ SetClosingDown(ETrue);
+ else
+ CanClose();
+ } // CSmsProtocol::CloseNow
+
+
+/**
+ * Private constructor.
+ *
+ */
+CSmsProtocol::CSmsProtocol()
+ :iSmsMessageObserverList(8)
+ ,iModemDetection(RPhone::EDetectedUnknown)
+ {
+ iSmsSettings.SetDeletePDUsFromSIM(EFalse);
+ iSmsSettings.SetDeletePDUsFromPhoneStores(EFalse);
+ iSmsSettings.SetDeletePDUsFromCombinedStores(EFalse);
+ iNext8BitPort=KMin8BitPortNumber;
+ iNext16BitPort=KMin16BitPortNumber;
+ } // CSmsProtocol::CSmsProtocol
+
+
+/**
+ * Returns the index of an observer in the observer list.
+ *
+ */
+TInt CSmsProtocol::ObserverIndex(const MSmsMessageObserver& aObserver) const
+ {
+ LOGSMSPROT1("CSmsProtocol::ObserverIndex()");
+
+ TInt count=iSmsMessageObserverList.Count();
+ TInt index=0;
+ for (; index<count; index++)
+ if (iSmsMessageObserverList[index]==&aObserver)
+ break;
+ return index;
+ } // CSmsProtocol::ObserverIndex
+
+
+/**
+ * Checks if an SMS address type is a duplicate of an existing SAP / observer.
+ *
+ */
+TBool CSmsProtocol::SmsAddrIsAlreadyUsed(const MSmsMessageObserver* aObserver,const TSmsAddr& aSmsAddr)const
+ {
+ LOGSMSPROT1("CSmsProtocol::SmsAddrIsAlreadyUsed()");
+
+ TBool isduplicate=EFalse;
+ TInt count=iSmsMessageObserverList.Count();
+ for (TInt i=0; (i<count) && (!isduplicate); i++)
+ isduplicate=(iSmsMessageObserverList[i]->SmsAddrIsDuplicate(aObserver,aSmsAddr));
+ return isduplicate;
+ } // CSmsProtocol::SmsAddrIsAlreadyUsed
+
+
+/**
+ * A utility class for prioritizing the SMS protocol observers based
+ * on their SMS address type.
+ * A higher priority observer will be given the opportunity to
+ * accept a received messages before one of a lower priority.
+ */
+class TKeySmsObserver : public TKeyArrayFix
+ {
+public:
+ TKeySmsObserver();
+ virtual TInt Compare(TInt aLeft,TInt aRight) const;
+ static TInt SmsAddressPriority(const TSmsAddr& aAddr);
+ };
+
+
+/**
+ * Constructor
+ *
+ */
+TKeySmsObserver::TKeySmsObserver()
+ :TKeyArrayFix(0,ECmpTInt)
+ {
+ iKeyOffset = 0;
+ } // TKeySmsObserver::TKeySmsObserver
+
+
+/**
+ * Static method that returns the priority of a given SMS address.
+ *
+ * @leave Panics on an unknown address type.
+ *
+ */
+TInt TKeySmsObserver::SmsAddressPriority(const TSmsAddr& aAddr)
+ {
+ TSmsAddrFamily fam = aAddr.SmsAddrFamily();
+
+ switch (fam)
+ {
+ case ESmsAddrEmail:
+ return 11;
+ case ESmsAddrApplication8BitPort:
+ return 10;
+ case ESmsAddrApplication16BitPort:
+ return 9;
+ case ESmsAddrMessageIndication:
+ return 8;
+ case ESmsAddrStatusReport:
+ return 7;
+ case ESmsAddrMatchIEI:
+ return 6;
+ case ESmsAddrMatchText:
+ return 5;
+ case ESmsAddrRecvAny:
+ return 4;
+ case ESmsAddrSendOnly:
+ return 3;
+ case ESmsAddrLocalOperation:
+ return 2;
+ case ESmsAddrUnbound:
+ return 1;
+ default:
+ SmspPanic(ESmspUnknownSmsAddressFamily);
+ };
+ return KErrNotFound;
+ } // TKeySmsObserver::SmsAddressPriority
+
+
+/**
+ * Compares two observers.
+ * Override of TKeyArrayFix::Compare() called on to help sort
+ * the observer list based on their address types.
+ *
+ */
+TInt TKeySmsObserver::Compare(TInt aLeft, TInt aRight) const
+ {
+ LOGSMSPROT3("TKeySmsObserver::Compare [left=%d, right=%d]", aLeft, aRight);
+
+ const TInt lhptr = -1; // Left higher priority than right
+ const TInt rhptl = 1; // Right higher priority than left
+
+ MSmsMessageObserver* left = *(MSmsMessageObserver**)At(aLeft);
+ MSmsMessageObserver* right = *(MSmsMessageObserver**)At(aRight);
+
+ const TSmsAddr& leftAddr = left->GetLocalAddress();
+ const TSmsAddr& rightAddr = right->GetLocalAddress();
+
+ TSmsAddrFamily leftFamily = leftAddr.SmsAddrFamily();
+
+
+ TInt leftPriority = SmsAddressPriority(leftAddr);
+ TInt rightPriority = SmsAddressPriority(rightAddr);
+
+ if (leftPriority > rightPriority)
+ return lhptr;
+ if (rightPriority > leftPriority)
+ return rhptl;
+
+ if (leftFamily == ESmsAddrMatchText)
+ {
+ // Longer strings are higher priority than shorter ones
+ TInt rightLen = rightAddr.TextMatch().Length();
+ TInt leftLen = leftAddr.TextMatch().Length();
+ if (leftLen > rightLen)
+ return lhptr;
+ if (rightLen > leftLen)
+ return rhptl;
+ }
+
+ return 0;
+ } // TKeyArrayFix::Compare
+
+
+/**
+ * Re-orders the observer list using TKeySmsObserver to determine priorities.
+ *
+ */
+void CSmsProtocol::OrderSmsMessageObserver(const MSmsMessageObserver& /*aObserver*/)
+ {
+ LOGSMSPROT1("CSmsProtocol::OrderSmsMessageObserver()");
+
+ TKeySmsObserver smsObsKey;
+#ifdef _DEBUG
+ TInt ret=iSmsMessageObserverList.Sort(smsObsKey);
+ __ASSERT_DEBUG(ret==KErrNone,SmspPanic(ESmspCorruptObserverList));
+#else
+ iSmsMessageObserverList.Sort(smsObsKey);
+#endif
+ } // CSmsProtocol::OrderSmsMessageObserver
+
+
+/**
+ * Attempts to match an incoming message to a SAP / observer. Starts with the
+ * highest priority observer.
+ *
+ */
+MSmsMessageObserver* CSmsProtocol::MatchSmsMessageToObserver(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CSmsProtocol::MatchSmsMessageToObserver()");
+
+ TInt count=iSmsMessageObserverList.Count();
+ for (TInt i=0;i<count;i++)
+ {
+ MSmsMessageObserver* obs = iSmsMessageObserverList[i];
+ if (IsMatch(obs->GetLocalAddress(),aSmsMessage))
+ return obs;
+ }
+ return NULL;
+ } // CSmsProtocol::MatchSmsMessageToObserver
+
+
+/**
+ * Tries to match an SMS address to a SAP / observer. Starts with the highest
+ * priority observer.
+ *
+ */
+MSmsMessageObserver* CSmsProtocol::MatchSmsAddressToObserver(const TSmsAddr& aAddr)
+ {
+ LOGSMSPROT1("CSmsProtocol::MatchSmsAddressToObserver()");
+
+ TInt count=iSmsMessageObserverList.Count();
+ for (TInt i=0;i<count;i++)
+ {
+ MSmsMessageObserver* obs = iSmsMessageObserverList[i];
+ if (obs->GetLocalAddress()==aAddr)
+ return obs;
+ }
+ return NULL;
+ } // CSmsProtocol::MatchSmsAddressToObserver
+
+
+/**
+ * Static function checks if a message is matched to a given SMS address type. Used by
+ * MatchSmsMessageToObserver() to find a matching observer for the message.
+ *
+ */
+TBool CSmsProtocol::IsMatch(const TSmsAddr& aSmsAddr, const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CSmsProtocol::IsMatch()");
+
+ TSmsAddrFamily family = aSmsAddr.SmsAddrFamily();
+
+ switch(family)
+ {
+ case (ESmsAddrUnbound):
+ case (ESmsAddrSendOnly):
+ case(ESmsAddrLocalOperation):
+ return EFalse;
+
+ case(ESmsAddrApplication8BitPort ):
+ {
+ return (MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),EFalse));
+ }
+
+ case (ESmsAddrApplication16BitPort ):
+ {
+ return(MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),ETrue));
+ }
+
+ case (ESmsAddrMessageIndication):
+ {
+ if (MatchInformationElement(aSmsMessage,CSmsInformationElement::ESmsIEISpecialSMSMessageIndication))
+ return ETrue;
+ if (aSmsMessage.SmsPDU().DataCodingSchemePresent())
+ {
+ TSmsDataCodingScheme::TSmsDCSBits7To4 bits7to4 = aSmsMessage.SmsPDU().Bits7To4();
+ switch (bits7to4)
+ {
+ case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:
+ case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
+ case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
+ return ETrue;
+ default:
+ break;
+ }
+ }
+ // CPHS Implementation of message waiting indicator (CPHS Phase 2)
+ TGsmSmsTelNumber address;
+ aSmsMessage.ParsedToFromAddress(address);
+
+ //as far as I can see you can't get the npi from the address. (==0?)
+ //might want to compare the content of the tel number with the spec to make sure
+ //that we are dealing with a cphs message !
+
+ if((address.iTypeOfAddress.TON() == EGsmSmsTONAlphaNumeric) &&
+ (address.iTelNumber.Length() == 4) &&
+ ((address.iTelNumber[2] & 0x7E) == 0x10) &&// x001 000x constant value
+ ((address.iTelNumber[3] & 0x7E) == 0x00) )// x000 000x constant value
+ return ETrue; // This means that the SMS received is a Message Waiting indication
+ return EFalse;
+ }
+
+ case (ESmsAddrStatusReport):
+ {
+ LOGSMSPROT1("TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:");
+ if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
+ return ETrue;
+ }
+ break;
+ case (ESmsAddrMatchIEI):
+ {
+ return (MatchInformationElement(aSmsMessage,CSmsInformationElement::TSmsInformationElementIdentifier(aSmsAddr.IdentifierMatch())));
+ }
+ case (ESmsAddrMatchText):
+ {
+ TBuf<TSmsAddr::EMaxTextMatchLength> textMatch;
+ textMatch.Copy(aSmsAddr.TextMatch());
+ TBuf<TSmsAddr::EMaxTextMatchLength> smsMsgBuf;
+ TInt bufferLen = aSmsMessage.Buffer().Length();
+ bufferLen = Min(bufferLen,textMatch.Length());
+ aSmsMessage.Buffer().Extract(smsMsgBuf,0,bufferLen);
+ if (textMatch.CompareF(smsMsgBuf)==KErrNone)
+ return ETrue;
+ return EFalse;
+ }
+ case (ESmsAddrEmail):
+ {
+ if(aSmsMessage.IsEmailHeader())
+ return ETrue;
+ break;
+ }
+ case (ESmsAddrRecvAny):
+ return ETrue;
+ default:
+ return EFalse;
+
+ }
+ return EFalse;
+ } // CSmsProtocol::IsMatch
+
+/**
+ * Static function checks if a message contains a given port. Used by IsMatch()
+ * to determine if an SMS address type matches an application port.
+ *
+ */
+TBool CSmsProtocol::MatchApplicationPort(const CSmsMessage& aSmsMessage,TUint aPort,TBool a16Bit)
+ {
+ LOGSMSPROT1("CSmsProtocol::MatchApplicationPort");
+
+ if (!aSmsMessage.SmsPDU().UserDataPresent())
+ return EFalse;
+
+ const CSmsPDU& Pdu = aSmsMessage.SmsPDU();
+ TInt ToPort = 0;
+ TInt FromPort = 0;
+ TBool Is16BitPorts = 0;
+
+ Pdu.ApplicationPortAddressing(ToPort,FromPort,&Is16BitPorts);
+ if((TInt)aPort == ToPort && Is16BitPorts == a16Bit) return ETrue;
+
+ return EFalse;
+ } // CSmsProtocol::MatchApplicationPort
+
+
+/**
+ * Static function checks if a message contains a given information element. Used by IsMatch()
+ * to determine if an SMS address type matches a message.
+ *
+ */
+TBool CSmsProtocol::MatchInformationElement(const CSmsMessage& aSmsMessage, CSmsInformationElement::TSmsInformationElementIdentifier aIeVal)
+ {
+ LOGSMSPROT1("CSmsProtocol::MatchInformationElement");
+
+ if (!aSmsMessage.SmsPDU().UserDataPresent())
+ return EFalse;
+
+ TInt count=aSmsMessage.SmsPDU().UserData().NumInformationElements();
+ for (TInt i=0; i<count; i++)
+ {
+ TInt identifier=aSmsMessage.SmsPDU().UserData().InformationElement(i).Identifier();
+ if (identifier==aIeVal)
+ return ETrue;
+ }
+ return EFalse;
+ } // CSmsProtocol::MatchInformationElement
+
+
+/**
+ * Searches the reassembly store for complete messages and tries to match
+ * them to an observer. If a match is found the message is passed to
+ * the observer and deleted from the store, otherwise it's left in store.
+ * Called when a new observer is added or a PDU has been received and
+ * successfully processed.
+ *
+ */
+void CSmsProtocol::ProcessCompleteSmsMessagesL()
+ {
+ LOGSMSPROT1("CSmsProtocol::ProcessCompleteSmsMessagesL");
+
+ if(iPhoneEnumerationObserver) return;
+
+ iReassemblyStore->ProcessCompleteSmsMessagesL(*this, iSmsPDURead->CurrentMessage());
+ } // CSmsProtocol::ProcessCompleteSmsMessagesL
+
+
+/**
+ * Called when the state machine for processing a received PDU has completed.
+ * The reassembly store access count is incremented and purged if it exceeds
+ * CSmsProtocol::KNumSARStoreAccessesBeforePurging.
+ * The completed entry is removed from the processing queue and if the queue is
+ * not empty, and the processing state machinery is started for the next entry.
+ *
+ */
+void CSmsProtocol::MessageReadedSuccessfully()
+ {
+ LOGSMSPROT1("CSmsProtocol::MessageReadedSuccessfully");
+ TRAPD(ret,ProcessCompleteSmsMessagesL());
+ if(ret!=KErrNone)
+ {
+ LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
+ }
+
+ iNumReassemblyStoreAccesses++;
+ if(iNumReassemblyStoreAccesses>=KNumSARStoreAccessesBeforePurging)
+ {
+ TRAP(ret, iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(),EFalse));
+
+ if(ret!=KErrNone)
+ {
+ LOGSMSPROT2("WARNING! iReassemblyStore->PurgeL left with %d", ret);
+ }
+
+ iNumReassemblyStoreAccesses=0;
+ }
+ if(CheckPoweredUp() == KErrNone )
+ iSmsPDURead->ResumeSmsReception();
+ } // CSmsProtocol::MessageReadedSuccessfully
+
+
+/**
+ * method to delete sms from the reastore
+ */
+void CSmsProtocol::DeleteSMSFromReaStoreL(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL entry");
+ if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
+ {
+ LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL it's SR");
+ return;
+ }
+
+ TSmsDataCodingScheme::TSmsClass msgClass;
+
+ if (aSmsMessage.SmsPDU().DataCodingSchemePresent() && aSmsMessage.SmsPDU().Class(msgClass))
+ {
+ if (msgClass == TSmsDataCodingScheme::ESmsClass0)
+ {
+ if (!aSmsMessage.IsComplete())
+ {
+ CIncompleteClass0MessageInfo& incompleteClass0MsgInfo = (CIncompleteClass0MessageInfo &) aSmsMessage.GetOperationsForNonIEL(ESmsIncompleteClass0MessageParameter);
+ // Retrieve incomplete class 0 message information & process
+ TInt startPos, endPos;
+ TBool isLastMessage;
+ incompleteClass0MsgInfo.GetIncompleteMessageInfoL(startPos, endPos, isLastMessage);
+ if (!isLastMessage)
+ {
+ /*
+ Only in this condition set incomplete message as forwarded
+ which internally will remove the PDUs from pre-allocated file.
+ */
+ LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL Incomplete Message Not last segment");
+ iReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
+ return;
+ }
+ }
+ }
+ }
+ iReassemblyStore->DeleteMessageL(aSmsMessage, ETrue);
+
+ LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL exit");
+ } // CSmsProtocol::DeleteSMSFromReaStoreL
+
+
+/**
+ * Used to notify observer of the change in state of the modem connection.
+ * Send only observers are not notified (why?).
+ */
+void CSmsProtocol::NotifyMessageObservers(TInt aStatus)
+ {
+ LOGSMSPROT1("CSmsProtocol::NotifyMessageObservers");
+
+ TInt count=iSmsMessageObserverList.Count();
+ LOGSMSPROT3("CSmsProtocol::NotifyMessageObservers [count=%d, aStatus=%d]",count, aStatus);
+ for (TInt index=0; index<count; index++)
+ {
+ MSmsMessageObserver* observer=iSmsMessageObserverList[index];
+ TSmsAddrFamily fam = observer->GetLocalAddress().SmsAddrFamily();
+ LOGSMSPROT2("CSmsProtocol::NotifyMessageObservers [family=%d]", fam);
+ switch (fam)
+ {
+ case ESmsAddrMessageIndication:
+ case ESmsAddrStatusReport:
+ case ESmsAddrMatchIEI:
+ case ESmsAddrMatchText:
+ case ESmsAddrEmail:
+ case ESmsAddrRecvAny:
+ case ESmsAddrLocalOperation:
+ case ESmsAddrApplication8BitPort:
+ case ESmsAddrApplication16BitPort:
+ {
+ observer->ModemNotificationCompleted(aStatus);
+ break;
+ }
+ case ESmsAddrSendOnly:
+ case ESmsAddrUnbound:
+ break;
+ default:
+ SmspPanic(ESmspPanicAddrFamilyNotAllowed);
+ }
+ }
+ } // CSmsProtocol::NotifyMessageObservers
+
+
+void CSmsProtocol::PowerUp()
+ {
+ LOGSMSPROT2("CSmsProtocol::PowerUp [iState=%d]", iState);
+ __ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
+
+ if (iState == EPoweredDown)
+ {
+ TRAPD(err, DoPowerUpL());
+
+ if (err != KErrNone)
+ {
+ LOGSMSPROT3("WARNING: CSmsProtocol::DoPowerUpL left [err=%d iState=%d]", err, iState);
+ __ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
+ PowerDown();
+ }
+ }
+ } // CSmsProtocol::PowerUp
+
+
+/**
+ * Handles the event of the modem powering on (when it had been powered off).
+ * Does the following...
+ * - The TSY loaded
+ * - ETEL resource handles initialised
+ * - ETEL parameters set and retrieved
+ * - A number of state machines started
+ *
+ */
+void CSmsProtocol::DoPowerUpL()
+ {
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL");
+ __ASSERT_DEBUG(iModemDetection==RPhone::EDetectedPresent,SmspPanic(KSmspPhoneHasNotTurnedOn));
+
+ //Open the segmentation and reassembly stores
+
+ iReassemblyStore->OpenStoreL();
+ iSegmentationStore->OpenStoreL();
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
+ iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(), ETrue);
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
+ iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse);
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
+
+ // Connect to ETEL and load the TSY
+ User::LeaveIfError(iTelServer.Connect());
+ User::LeaveIfError(iTelServer.LoadPhoneModule(iGsmTsyName));
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL Connected to Etel");
+
+ // Find the phone corresponding to this TSY and open a number of handles on it
+ TInt numPhones;
+ User::LeaveIfError(iTelServer.EnumeratePhones(numPhones));
+ TInt i=0;
+ for (; i<numPhones; i++)
+ {
+ RTelServer::TPhoneInfo info;
+ User::LeaveIfError(iTelServer.GetPhoneInfo(i,info));
+ TName tsyName;
+ User::LeaveIfError(iTelServer.GetTsyName(i,tsyName));
+ if (tsyName.CompareF(iGsmTsyName)==KErrNone)
+ {
+ User::LeaveIfError(iGsmPhone.Open(iTelServer,info.iName));
+ User::LeaveIfError(iEnumerationPhone.Open(iTelServer,info.iName));
+ User::LeaveIfError(iWritePhone.Open(iTelServer,info.iName));
+ break;
+ }
+ }
+ __ASSERT_DEBUG(i<numPhones,SmspPanic(ESmspPhoneNotFound));
+ if (iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended)!=KErrNone)
+ User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorBasic));
+ User::LeaveIfError(iSmsMessaging.Open(iGsmPhone));
+
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL Opened TSY handles");
+
+ if (iSmsPhoneEnumeration == NULL)
+ iSmsPhoneEnumeration=CSmsPhoneEnumeration::NewL(*this, iSmsSettings, *iReassemblyStore, *iSegmentationStore, iEnumerationPhone, KSmsSessionPriority, *iSmsMonitorDiskSpace);
+
+ if (iWriteQueue == NULL)
+ iWriteQueue = CSmspWriteQueue::NewL(*this, iSmsSettings, iWritePhone,*iSegmentationStore, KSmsSessionPriority);
+
+ if (iDeleteQueue == NULL)
+ iDeleteQueue = CSmspDeleteQueue::NewL(*this,iSmsSettings,iSmsMessaging, KSmsSessionPriority);
+
+ // Start state machines
+ iSmsPhoneInitialization->Start();
+
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL Started state machines");
+
+ NotifyMessageObservers(KIoctlSelectModemPresent);
+ LOGSMSPROT1("CSmsProtocol::DoPowerUpL Notified message observers");
+
+
+ // Process any waiting messages
+ ProcessCompleteSmsMessagesL();
+
+ iState = EPoweredUp;
+ } // CSmsProtocol::DoPowerUpL
+
+
+/**
+ * Handles the event of the modem powering off (when it had been powered on).
+ * Does the following...
+ * - State mechines cancelled
+ * - Close TSY handles
+ * - Disconnect from Etel
+ *
+ * This function will also be called if PowerUpL() leaves
+ */
+void CSmsProtocol::PowerDown()
+ {
+ LOGSMSPROT1("CSmsProtocol::PowerDown");
+
+ iSetBearer->Cancel();
+ iReceiveMode->Cancel();
+
+ iSendQueue->Cancel();
+
+ iSmsPDURead->Cancel();
+
+ iSmsMonitorDiskSpace->Cancel();
+
+ delete iSmsPhoneEnumeration; //must be deleted because uses iSmsMessaging which is soon closed
+ iSmsPhoneEnumeration = NULL;
+
+ iSmsPhoneInitialization->Cancel();
+
+ if( iSmsReadParams != NULL )
+ {
+ iSmsReadParams->Cancel();
+ }
+ if( iSmsWriteParams != NULL )
+ {
+ iSmsWriteParams->Cancel();
+ }
+
+ delete iWriteQueue; //must be deleted because uses iSmsMessaging which is soon closed
+ iWriteQueue = NULL;
+
+ delete iDeleteQueue; //must be deleted because uses iSmsMessaging which is soon closed
+ iDeleteQueue = NULL;
+
+ LOGSMSPROT1("CSmsProtocol::PowerDown Cancelled state machines");
+
+ NotifyMessageObservers(KIoctlSelectModemNotPresent);
+ LOGSMSPROT1("CSmsProtocol::PowerDown Notified message observers");
+
+ // Close TSY handles
+ iSmsMessaging.Close();
+ iGsmPhone.Close();
+ iEnumerationPhone.Close();
+ iWritePhone.Close();
+ LOGSMSPROT1("CSmsProtocol::PowerDown Closed TSY handles");
+
+ // Disconnect from Etel
+ iTelServer.Close();
+ LOGSMSPROT1("CSmsProtocol::PowerDown Disconnected from Etel");
+
+ iReassemblyStore->Close();
+ iSegmentationStore->Close();
+
+ iState = EPoweredDown;
+ }
+
+void CSmsProtocol::CloseNowWrap()
+ {
+ // Ignore in code coverage - called when PDU delete queue is not
+ // empty and SMS stack is closing down - can only get this situation
+ // when the PDU delete has been initiated by the SMS stack itself
+ // (rather than the client) and the PDUs are still being deleted
+ // when last client disconnects.
+ BULLSEYE_OFF
+ LOGSMSPROT1("CSmsProtocol::CloseNowWrap()");
+
+ if( iDeleteQueue == NULL || !iDeleteQueue->IsActive() )
+ {
+ CloseNow();
+ }
+ BULLSEYE_RESTORE
+ }
+
+void CSmsProtocol::HandleBackupOrRestoreStartingL()
+ {
+ LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreStartingL [ModemState=%d]", iSmsModemNotification->ModemState());
+ PowerDown();
+ }
+
+void CSmsProtocol::HandleBackupOrRestoreCompleteL()
+ {
+ LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreCompleteL [ModemState=%d]", iSmsModemNotification->ModemState());
+
+ if (iModemDetection == RPhone::EDetectedPresent)
+ {
+ PowerUp();
+ }
+ }
+
+/**
+ * Set the sap port number
+ */
+TBool CSmsProtocol::AllocateLocalAddress(TSmsAddr& aAddr)
+ {
+ LOGSMSPROT1("CSmsProtocol::AllocateLocalAddressL");
+
+ TBool found=EFalse;
+ TUint count=0,attempts=0;
+ TSmsAddr locAddr=aAddr;
+
+ if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
+ {
+ count =KMax8BitPortNumber-KMin8BitPortNumber+1;
+ }
+ else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
+ {
+ count =KMax16BitPortNumber-KMin16BitPortNumber+1;
+ }
+
+ for(;!found && attempts < count; ++attempts)
+ {
+ if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
+ {
+ locAddr.SetPort(iNext8BitPort++);
+ if(iNext8BitPort > KMax8BitPortNumber)iNext8BitPort=KMin8BitPortNumber;
+ }
+ else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
+ {
+ locAddr.SetPort(iNext16BitPort++);
+ if(iNext16BitPort > KMax16BitPortNumber)iNext8BitPort=KMin16BitPortNumber;
+ }
+ if(!SmsAddrIsAlreadyUsed(NULL,locAddr))found=ETrue;
+ }
+
+ if(found)
+ {
+ aAddr=locAddr;
+ }
+ return found;
+ } // CSmsProtocol::AllocateLocalAddress
+
+/**
+ * Static method that returns the boolean value indicating whether the given
+ * CSmsMessage is for application port.
+ * This function is an utility function which determines the passed sms message
+ * is for application port or not. This function is also used in CFacadeSmsReassemblyStore class.
+ *
+ * @param aSmsMessage reference to CSmsMessage object.
+ *
+ */
+TBool CSmsProtocol::IsAppPortSMS(const CSmsMessage& aSmsMessage)
+ {
+ LOGSMSPROT1("CSmsProtocol::IsAppPortSMS()");
+
+ TSmsAddr addr;
+ addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
+ addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit);
+ if (IsMatch(addr,aSmsMessage))
+ {
+ return ETrue;
+ }
+
+ addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
+ addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit);
+ if (IsMatch(addr,aSmsMessage))
+ {
+ return ETrue;
+ }
+
+ addr.SetSmsAddrFamily(ESmsAddrMatchText);
+ addr.SetTextMatch(_L8("//SCK"));
+ if (IsMatch(addr,aSmsMessage))
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ } // CSmsProtocol::IsAppPortSMS
+
+
+const RMobilePhone::TMobilePhoneNetworkInfoV1& CSmsProtocol::NetworkInfo() const
+ {
+ LOGSMSPROT1("CSmsProtocol::NetworkInfo()");
+
+ return iSmsPhoneInitialization->NetworkInfo();
+ } // CSmsProtocol::NetworkInfo
+
+
+TBool CSmsProtocol::NetworkInfoAvailable() const
+ {
+ LOGSMSPROT1("CSmsProtocol::NetworkInfoAvailable()");
+
+ return iSmsPhoneInitialization->NetworkInfoAvailable();
+ } // CSmsProtocol::NetworkInfoAvailable
+
+
+// implementation of CSmsProtocolBootTimer
+//
+
+/**
+ * 2 phase contructor
+ *
+ * @param aActive Reference to an CSmsProtocol object
+ */
+CSmsProtocolBootTimer* CSmsProtocolBootTimer::NewL(CSmsProtocol& aSmsProtocol)
+ {
+ LOGSMSPROT1("CSmsProtocolBootTimer::NewL");
+
+ CSmsProtocolBootTimer* self = new(ELeave) CSmsProtocolBootTimer(aSmsProtocol);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+ * D'tor
+ */
+CSmsProtocolBootTimer::~CSmsProtocolBootTimer()
+ {
+ Cancel();
+ }
+
+/**
+ * Start a timeout specified in aTimeIntervalMicroSeconds32
+ */
+void CSmsProtocolBootTimer::Start(const TTimeIntervalMicroSeconds32& aTimeIntervalMicroSeconds32)
+ {
+ LOGSMSPROT1("CSmsProtocolBootTimer::Start");
+ After(aTimeIntervalMicroSeconds32);
+ }
+
+/**
+ * C'tor
+ */
+CSmsProtocolBootTimer::CSmsProtocolBootTimer(CSmsProtocol& aSmsProtocol)
+: CTimer(KSmsSessionPriority), iSmsProtocol(aSmsProtocol)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+/**
+ * Timer completed - cancel the observer
+ */
+void CSmsProtocolBootTimer::RunL()
+ {
+ LOGSMSPROT2("CSmsProtocolBootTimer::RunL [iStatus=%d]", iStatus.Int() );
+ iSmsProtocol.MessageReadedSuccessfully();
+ }