smsprotocols/smsstack/smsprot/Src/smsprot.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the CSmsProtocol and its helper classes.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <commsdattypesv1_1.h>
       
    23 #include <logwrap.h>
       
    24 #include "Gsmumsg.h"
       
    25 #include "gsmubuf.h"
       
    26 #include "Gsmuelem.h"
       
    27 #include "gsmunonieoperations.h"
       
    28 
       
    29 #include "smsprot.h"
       
    30 #include "smspfacadestor.h"
       
    31 #include "smspmodm.h"
       
    32 #include "smspenum.h"
       
    33 #include "smspread.h"
       
    34 #include "smspdel.h"
       
    35 #include "smspproc.h"
       
    36 #include "smspmondsk.h"
       
    37 #include "smspmain.h"
       
    38 #include "smspver.h"
       
    39 #include "smsppara.h"
       
    40 #include "SmsuBackup.h"
       
    41 #include <es_prot_internal.h>
       
    42 
       
    43 using namespace CommsDat;
       
    44 
       
    45 //
       
    46 // Class implementations
       
    47 //
       
    48 
       
    49 // application port range according to 3GPP TS 23.040 v4.4.0
       
    50 // chapters 9.2.3.24.3 and 9.2.3.24.4
       
    51 
       
    52 const TInt KMin8BitPortNumber = 240;
       
    53 const TInt KMax8BitPortNumber = 255;
       
    54 
       
    55 const TInt KMin16BitPortNumber = 16000;
       
    56 const TInt KMax16BitPortNumber = 16999;
       
    57 
       
    58 
       
    59 /**
       
    60  *  2 phase constructor
       
    61  *  
       
    62  */
       
    63 CSmsProtocolFamily * CSmsProtocolFamily::NewL()
       
    64 	{
       
    65 	LOGSMSPROT4("CSmsProtocolFamily::NewL [version %d.%d.%d]",
       
    66 			 KSmsPrtMajorVersionNumber,
       
    67 			 KSmsPrtMinorVersionNumber,
       
    68 			 KSmsPrtBuildVersionNumber
       
    69 			 );
       
    70 	return new (ELeave)CSmsProtocolFamily;
       
    71 	} // CSmsProtocolFamily::NewL
       
    72 
       
    73 
       
    74 /**
       
    75  *  Implementation of the pure virtual CProtocolFamilyBase::Install().
       
    76  *  Called by the socket server after creation of this object.
       
    77  *  Does nothing.
       
    78  *  
       
    79  */
       
    80 TInt CSmsProtocolFamily::Install()
       
    81 	{
       
    82 	LOGSMSPROT1("CSmsProtocolFamily::Install");
       
    83 	return KErrNone;
       
    84 	} // CProtocolFamilyBase::Install
       
    85 
       
    86 
       
    87 /**
       
    88  *  Implementation of the pure virtual CProtocolFamilyBase::Remove().
       
    89  *  Called by the socket server before unloading the library for the SMS
       
    90  *  protocol family.
       
    91  *  Does nothing.
       
    92  *  
       
    93  */
       
    94 TInt CSmsProtocolFamily::Remove()
       
    95 	{
       
    96 	LOGSMSPROT1("CSmsProtocolFamily::Remove");
       
    97 	return KErrNone;
       
    98 	} // CProtocolFamilyBase::Remove
       
    99 
       
   100 
       
   101 /**
       
   102  *  Implementation of the pure virtual CProtocolFamilyBase::NewProtocolL().
       
   103  *  Called by the socket server to create the CSmsProtocol object.
       
   104  *  
       
   105  *  @param aSockType not used, assumes datagram.
       
   106  *  @param aProtocol not used, assumes KSmsDatagram, the only protocol provided.
       
   107  *  @return a new instance of the CSmsProtocol class.
       
   108  *  
       
   109  */
       
   110 CProtocolBase * CSmsProtocolFamily::NewProtocolL(TUint /*aSockType*/,TUint /*aProtocol*/)
       
   111 	{
       
   112 	LOGSMSPROT1("CSmsProtocolFamily::NewProtocolL");
       
   113 	return CSmsProtocol::NewL();
       
   114 	} // CProtocolFamilyBase::NewProtocolL
       
   115 
       
   116 
       
   117 /**
       
   118  *  Implementation of the pure virtual CProtocolFamilyBase::ProtocolList().
       
   119  *  Called by the socket server during initialisation to retrieve a list
       
   120  *  of the protocols we support.
       
   121  *  Only KSmsDatagram is supported.
       
   122  *  
       
   123  *  @return aProtocolList a pointer to an array of protocol description objects
       
   124  *  that this function creates and fills in.
       
   125  *  @return the number of protocols supported (1).
       
   126  *  
       
   127  */
       
   128 TUint CSmsProtocolFamily::ProtocolList(TServerProtocolDesc *& aProtocolList)
       
   129 	{
       
   130 	LOGSMSPROT1("CSmsProtocolFamily::ProtocolList");
       
   131 
       
   132 	TRAPD(ret, (aProtocolList=new(ELeave) TServerProtocolDesc[1]));
       
   133 	if(ret!=KErrNone)
       
   134 		{
       
   135 		LOGSMSPROT2("WARNING! new TServerProtocolDesc left with %d", ret);
       
   136 		return 0;
       
   137 		}
       
   138 
       
   139 	// Datagram protocol
       
   140 	aProtocolList[0].iName=KSmsDatagram;
       
   141 	aProtocolList[0].iAddrFamily=KSMSAddrFamily;
       
   142 	aProtocolList[0].iSockType=KSockDatagram;
       
   143 	aProtocolList[0].iProtocol=KSMSDatagramProtocol;
       
   144 	aProtocolList[0].iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
       
   145 	aProtocolList[0].iByteOrder=ELittleEndian;
       
   146 	aProtocolList[0].iServiceInfo=KSMSDatagramServiceInfo;
       
   147 	aProtocolList[0].iNamingServices=0;
       
   148 	aProtocolList[0].iSecurity=KSocketNoSecurity;
       
   149 	aProtocolList[0].iMessageSize=KSMSMaxDatagramSize;
       
   150 	aProtocolList[0].iServiceTypeInfo=ESocketSupport;
       
   151 	aProtocolList[0].iNumSockets=KSMSNumberSockets;
       
   152 
       
   153 	return 1;
       
   154 	} // CProtocolFamilyBase::ProtocolList
       
   155 
       
   156 
       
   157 /**
       
   158  *  Constructor (empty)
       
   159  */
       
   160 CSmsProtocolFamily::CSmsProtocolFamily()
       
   161 	{
       
   162 	} // CSmsProtocolFamily::CSmsProtocolFamily
       
   163 
       
   164 
       
   165 /**
       
   166  *  The single exported function, called by the socket server to create
       
   167  *  an instance of our CProtocolFamilyBase derived class.
       
   168  *  
       
   169  */
       
   170 EXPORT_C CProtocolFamilyBase* InstallSMS()
       
   171 	{
       
   172 	LOGSMSPROT1("CSmsProtocolFamily::CSmsProtocolFamily()");
       
   173 
       
   174 	CSmsProtocolFamily*  smsProtocolFamily(NULL);
       
   175 	
       
   176 	TRAP_IGNORE(smsProtocolFamily = CSmsProtocolFamily::NewL());
       
   177 
       
   178 	return smsProtocolFamily;
       
   179 	} // CSmsProtocolFamily::CSmsProtocolFamily
       
   180 
       
   181 
       
   182 //
       
   183 // implementation of CSmsProtocol
       
   184 //
       
   185 
       
   186 
       
   187 /**
       
   188  *  2 phase constructor.
       
   189  *  
       
   190  */
       
   191 CSmsProtocol* CSmsProtocol::NewL()
       
   192 	{
       
   193 	LOGSMSPROT1("CSmsProtocol::NewL()");
       
   194 
       
   195 	return new (ELeave) CSmsProtocol();
       
   196 	} // CSmsProtocol::NewL
       
   197 
       
   198 
       
   199 /**
       
   200  *  Destructor, ensures all outstanding queues are empty,
       
   201  *  all resource handles are closed, and all allocated memory freed.
       
   202  *  
       
   203  */
       
   204 CSmsProtocol::~CSmsProtocol()
       
   205     {
       
   206     delete iSmsPhoneInitialization;
       
   207     delete iSmsModemNotification;
       
   208 
       
   209     delete iSendQueue;
       
   210 	delete iSetBearer;	// referenced by iSendQueue
       
   211 
       
   212     delete iSmsPDURead;
       
   213 	delete iReceiveMode;	// referenced by iSmsPDURead
       
   214     delete iSmsPhoneEnumeration;
       
   215     delete iWriteQueue;
       
   216     delete iDeleteQueue;
       
   217 
       
   218 
       
   219     delete iSmsReadParams;
       
   220     delete iSmsWriteParams;
       
   221     delete iSmsMonitorDiskSpace;
       
   222 
       
   223     delete iReassemblyStore;
       
   224 
       
   225     if(iSegmentationStore)
       
   226         {
       
   227         iSegmentationStore->Close();
       
   228         delete iSegmentationStore;
       
   229         }
       
   230     iFs.Close();
       
   231 
       
   232     iSmsMessaging.Close();
       
   233     iGsmPhone.Close();
       
   234     iEnumerationPhone.Close();
       
   235     iWritePhone.Close();
       
   236     iTelServer.Close();
       
   237 	delete iBackupRestoreSession;
       
   238 	delete iBootTimer;
       
   239     } // CSmsProtocol::~CSmsProtocol
       
   240 
       
   241 
       
   242 
       
   243 /**
       
   244  *  Override of CProtocolBase::NewSAPL().
       
   245  *  Called by the server to create a new SMS service access point object.
       
   246  *  
       
   247  *  @param aSocketType the socket type
       
   248  *  @leave Leaves if aSocketType is not KSockDatagram.
       
   249  *  @leave Leaves if not enough memory is available.
       
   250  *  @return a new CSmsProvider object.
       
   251  *  
       
   252  */
       
   253 CServProviderBase *CSmsProtocol::NewSAPL(TUint aSocketType)
       
   254 	{
       
   255 	LOGSMSPROT2("*CSmsProtocol::NewSAPL [sockettype=%d]", aSocketType);
       
   256 	if (aSocketType!=KSockDatagram)
       
   257 		User::Leave(KErrNotSupported);
       
   258 	return CSmsProvider::NewL(*this);
       
   259 	} // CProtocolBase::NewSAPL
       
   260 
       
   261 
       
   262 /**
       
   263  *  Override of CProtocolBase::InitL().
       
   264  *  Called by the socket server to allow any resource initialisation
       
   265  *  by the protocol.
       
   266  *  
       
   267  *  The following tasks are performed:
       
   268  *  - All member objects constructed (deferred from ConstructL() for efficiency reasons; see comment there)
       
   269  *  - TSY Name read from Comms Database
       
   270  *  - Event notification state machines started
       
   271  *  - Modem checked to see if it is already connected, and if so, a number of
       
   272  *  state machines started (otherwise wait until we receive notification of connection).
       
   273  *  
       
   274  */
       
   275 void CSmsProtocol::InitL(TDesC& /*aTag*/)
       
   276 	{
       
   277 	LOGSMSPROT1("CSmsProtocol::InitL");
       
   278 
       
   279 	User::LeaveIfError(iFs.Connect());
       
   280 
       
   281 	iReassemblyStore=CFacadeSmsReassemblyStore::NewL(iFs, *this);
       
   282 	iReassemblyStore->InitL();
       
   283 
       
   284 	LOGSMSPROT1("CSmsProtocol::InitL Constructing members");
       
   285 
       
   286 	ReadConfigurableSettingsL();
       
   287 
       
   288 	iBootTimer = CSmsProtocolBootTimer::NewL(*this);
       
   289 	iBootTimer->Start(iSmsSettings.BootTimerTimeout().Int());
       
   290 
       
   291 	iSegmentationStore=CSmsSegmentationStore::NewL(iFs);
       
   292 
       
   293 	iSetBearer=CSmspSetBearer::NewL(iSmsSettings, iSmsMessaging, KSmsSessionPriority);
       
   294 
       
   295 	iReceiveMode = CSmspReceiveMode::NewL(iSmsSettings, iSmsMessaging, iMobileSmsCaps, KSmsSessionPriority);
       
   296 
       
   297 	iSmsModemNotification=CSmsModemNotification::NewL(*this);
       
   298 
       
   299 	iSendQueue = CSmspSendQueue::NewL(*this, *iSegmentationStore, iSmsSettings, iMobileSmsCaps, iSmsMessaging, KSmsSessionPriority, *iSetBearer);
       
   300 
       
   301 	iSmsMonitorDiskSpace=CSmsMonitorDiskSpace::NewL(*this, iSmsMessaging,iFs);
       
   302 
       
   303 	iSmsPDURead=CSmsPDURead::NewL(*this, iSmsSettings, iSmsMessaging,*iReassemblyStore,*iSegmentationStore, iMobileSmsCaps, KSmsSessionPriority, *iReceiveMode, *iSmsMonitorDiskSpace);
       
   304 
       
   305 	iSmsPhoneInitialization = new (ELeave) CSmsPhoneInitialization(iSmsMessaging, iGsmPhone, *iSmsPDURead, iMobileSmsCaps, KSmsSessionPriority, iSetBearer);
       
   306 
       
   307 	iBackupRestoreSession = CBackupAndRestore::NewL(*this);
       
   308 
       
   309 /* THIS CODE SHOULD NEVER BE NECESSARY - who could have called CProtocolBase::InitL() if not ESOCK, which means
       
   310  * a running C32 already. However, if this is a wrong analysis then reinstate the code but with an explanatory comment
       
   311 #if defined (__WINS__)
       
   312 	// Make sure C32 is started under WINS
       
   313 	TInt ret=StartC32();
       
   314 	if (ret!=KErrAlreadyExists)
       
   315 		User::LeaveIfError(ret);
       
   316 #endif
       
   317 */
       
   318 	LOGSMSPROT1("CSmsProtocol::InitL Querying CommDb");
       
   319 
       
   320 	// Read the global modem ID setting from  Cooms Database
       
   321 	TUint32 modemId = 0;
       
   322 
       
   323 	
       
   324 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   325 	CMDBSession* sess = CMDBSession::NewL(KCDVersion1_2);
       
   326 #else
       
   327 	CMDBSession* sess = CMDBSession::NewL(KCDVersion1_1);
       
   328 #endif
       
   329 	CleanupStack::PushL(sess);
       
   330 
       
   331 	CMDBField<TUint32>* globalSettingField = new(ELeave) CMDBField<TUint32>(KCDTIdModemPhoneServicesSMS);
       
   332 	CleanupStack::PushL(globalSettingField);
       
   333 	globalSettingField->SetRecordId(1);
       
   334 	globalSettingField->LoadL(*sess);
       
   335 	modemId = *globalSettingField;
       
   336 	CleanupStack::PopAndDestroy(globalSettingField);
       
   337 
       
   338 	CMDBField<TDesC>* tsyField = new(ELeave) CMDBField<TDesC>(KCDTIdTsyName);
       
   339 	CleanupStack::PushL(tsyField);
       
   340 	tsyField->SetRecordId(modemId);
       
   341 	tsyField->LoadL(*sess);
       
   342 	iGsmTsyName = *tsyField;
       
   343 	CleanupStack::PopAndDestroy(tsyField);
       
   344 
       
   345 	CleanupStack::PopAndDestroy(sess);
       
   346 
       
   347 #ifdef _SMS_LOGGING_ENABLED
       
   348 	TBuf8<KCommsDbSvrMaxFieldLength> buf8;
       
   349 	buf8.Copy(iGsmTsyName);
       
   350 	LOGSMSPROT3("CSmsProtocol::InitL [modemId=%d tsy=%S]",
       
   351 				modemId, &buf8);
       
   352 #endif
       
   353 
       
   354 	// Start event notification state machines
       
   355 	iSmsModemNotification->Start();
       
   356 
       
   357 	// Intialise the SmsStack to the state that the phone has been found in
       
   358 	iModemDetection=iSmsModemNotification->ModemState();
       
   359 
       
   360 	if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
       
   361 		{
       
   362 		DoPowerUpL(); //Call the leaving version because powering up must work here
       
   363 		}
       
   364 	else
       
   365 		{
       
   366 		PowerDown();
       
   367 		}
       
   368 
       
   369 	//
       
   370 	// Define the Disk Space Monitor P&S variable...
       
   371 	//
       
   372 	TInt  ret;
       
   373 
       
   374 	TSecurityPolicy  readPolicy(ECapabilityReadDeviceData);
       
   375 	TSecurityPolicy  writePolicy(ECapabilityWriteDeviceData);
       
   376 	
       
   377 	ret = RProperty::Define(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey,
       
   378 							KUidPSSMSStackDiskSpaceMonitorKeyType, readPolicy, writePolicy);
       
   379 	if (ret != KErrNone  &&  ret != KErrAlreadyExists)
       
   380 		{
       
   381 		User::Leave(ret);
       
   382 		}
       
   383 
       
   384 	User::LeaveIfError(RProperty::Set(KUidPSSMSStackCategory,
       
   385 									  KUidPSSMSStackDiskSpaceMonitorKey, ESmsDiskSpaceAvailable));
       
   386 	} // CProtocolBase::InitL
       
   387 
       
   388 
       
   389 /**
       
   390  *  Override of CProtocolBase::StartL().
       
   391  *  Called by the socket server to indicate all bindings are complete
       
   392  *  and that datagram processing can begin.
       
   393  *  
       
   394  *  Binding is not supported so this indication is not important to us.
       
   395  *  
       
   396  */
       
   397 void CSmsProtocol::StartL(void)
       
   398 	{
       
   399 	LOGSMSPROT1("CSmsProtocol::StartL");
       
   400 	} // CSmsProtocol::StartL
       
   401 
       
   402 
       
   403 /**
       
   404  *  Override of CProtocolBase::Identify().
       
   405  *  Called by the socket server to obtain a description of the SMS protocol.
       
   406  *  
       
   407  */
       
   408 void CSmsProtocol::Identify(TServerProtocolDesc *aDesc)const
       
   409 	{
       
   410 	LOGSMSPROT1("CSmsProtocol::Identify");
       
   411 
       
   412 	aDesc->iName=KSmsDatagram;
       
   413 	aDesc->iAddrFamily=KSMSAddrFamily;
       
   414 	aDesc->iSockType=KSockDatagram;
       
   415 	aDesc->iProtocol=KSMSDatagramProtocol;
       
   416 	aDesc->iVersion=TVersion(KSmsPrtMajorVersionNumber,KSmsPrtMinorVersionNumber,KSmsPrtBuildVersionNumber);
       
   417 	aDesc->iByteOrder=ELittleEndian;
       
   418 	aDesc->iServiceInfo=KSMSDatagramServiceInfo;
       
   419 	aDesc->iNamingServices=0;
       
   420 	aDesc->iSecurity=KSocketNoSecurity;
       
   421 	aDesc->iMessageSize=KSMSMaxDatagramSize;
       
   422 	aDesc->iServiceTypeInfo=0;
       
   423 	aDesc->iNumSockets=KSMSNumberSockets;
       
   424 	} // CProtocolBase::Identify
       
   425 
       
   426 
       
   427 /**
       
   428  *  Override of CProtocolBase::NewHostResolverL().
       
   429  *  Called by socket server to create a host resolver.
       
   430  *  No host resolver service is provided by this SMS protocol.
       
   431  *  
       
   432  *  @leave Panics if called.
       
   433  *  
       
   434  */
       
   435 CHostResolvProvdBase *CSmsProtocol::NewHostResolverL()
       
   436     {
       
   437     // Ignore in code coverage - not intended to be used
       
   438     BULLSEYE_OFF    
       
   439     LOGSMSPROT1("CSmsProtocol::NewHostResolverL");
       
   440     SmspPanic(ESmspCantCreateHostResolver);
       
   441     return NULL;
       
   442     BULLSEYE_RESTORE
       
   443     }
       
   444 
       
   445 /**
       
   446  *  Override of CProtocolBase::NewServiceResolverL().
       
   447  *  Called by socket server to create a new service resolver.
       
   448  *  Not supported by this protocol.
       
   449  *  
       
   450  *  @leave Panics if called.
       
   451  *  
       
   452  */
       
   453 CServiceResolvProvdBase *CSmsProtocol::NewServiceResolverL()
       
   454     {
       
   455     // Ignore in code coverage - not intended to be used
       
   456     BULLSEYE_OFF    
       
   457     LOGSMSPROT1("*CSmsProtocol::NewServiceResolverL");
       
   458     SmspPanic(ESmspCantCreateServiceResolver);
       
   459     return NULL;
       
   460     BULLSEYE_RESTORE
       
   461     }
       
   462 
       
   463 /**
       
   464  *  Override of CProtocolBase::NewNetDatabaseL().
       
   465  *  Called by socket server to create a new network database.
       
   466  *  Not supported by this protocol.
       
   467  *  
       
   468  *  @leave Panics if called.
       
   469  *  
       
   470  */
       
   471 CNetDBProvdBase* CSmsProtocol::NewNetDatabaseL()
       
   472     {
       
   473     // Ignore in code coverage - not intended to be used
       
   474     BULLSEYE_OFF    
       
   475     LOGSMSPROT1("CSmsProtocol::NewNetDatabaseL");
       
   476     SmspPanic(ESmspCantCreateNetDatabase);
       
   477     return NULL;
       
   478     BULLSEYE_RESTORE
       
   479     }
       
   480 
       
   481 /**
       
   482  *  Override of CProtocolBase::BindL().
       
   483  *  Called by next protocol above wishing to bind to the SMS protocol.
       
   484  *  Not supported by this protocol.
       
   485  *  
       
   486  *  @leave Panics if called.
       
   487  *  
       
   488  */
       
   489 void CSmsProtocol::BindL(CProtocolBase* /*aProtocol*/,TUint /*aId*/)
       
   490     {
       
   491     // Ignore in code coverage - not intended to be used
       
   492     BULLSEYE_OFF    
       
   493     LOGSMSPROT1("CSmsProtocol::BindL");
       
   494     SmspPanic(ESmspCantBind);
       
   495     BULLSEYE_RESTORE
       
   496     }
       
   497 
       
   498 /**
       
   499  *  Override of CProtocolBase::BindToL().
       
   500  *  Called by socket server when a lower protocol must bind to the
       
   501  *  SMS protocol.
       
   502  *  Not supported by this protocol.
       
   503  *  
       
   504  *  @leave Panics if called.
       
   505  *  
       
   506  */
       
   507 void CSmsProtocol::BindToL(CProtocolBase* /*aProtocol*/)
       
   508     {
       
   509     // Ignore in code coverage - not intended to be used
       
   510     BULLSEYE_OFF    
       
   511     LOGSMSPROT1("CSmsProtocol::BindToL");
       
   512     SmspPanic(ESmspCantBindTo);
       
   513     BULLSEYE_RESTORE
       
   514     }
       
   515 
       
   516 /**
       
   517  *  Reads timeout value for send operation from configuration file
       
   518  *  
       
   519  *  @leave Leaves if configuration file cannot be read
       
   520  *  @leave Leaves if value not greater than zero
       
   521  */
       
   522 void CSmsProtocol::ReadConfigurableSettingsL()
       
   523 	{
       
   524 	CESockIniData* ini = NULL;
       
   525 	TRAPD(ret, ini=CESockIniData::NewL(_L("smswap.sms.esk")));
       
   526 	if(ret!=KErrNone)
       
   527 		{
       
   528 		LOGSMSPROT2("esk read failed, error code = [%d]", ret);
       
   529 		User::Leave(ret);
       
   530 		}
       
   531 
       
   532 	CleanupStack::PushL(ini);
       
   533 
       
   534 	TInt var(0);
       
   535 	if(ini->FindVar(_L("customTimeoutSettings"),_L("sendTryTimeout"),var))
       
   536 		{
       
   537 		if (var > 0)
       
   538 			{
       
   539 			LOGSMSPROT2("sendTryTimeout [%d]", var);
       
   540 			iSmsSettings.SetSendTryTimeout(var);
       
   541 			}
       
   542 		else
       
   543 			{
       
   544 			User::Leave(KErrArgument);
       
   545 			}
       
   546 		}
       
   547 
       
   548 	if(ini->FindVar(_L("customTimeoutSettings"),_L("bootTimerTimeout"),var))
       
   549 		{
       
   550 		if (var > 0)
       
   551 			{
       
   552 			LOGSMSPROT2("bootTimerTimeout [%d]", var);
       
   553 			iSmsSettings.SetBootTimerTimeout(var);
       
   554 			}
       
   555 		else
       
   556 			{
       
   557 			User::Leave(KErrArgument);
       
   558 			}
       
   559 		}
       
   560 
       
   561 	CleanupStack::PopAndDestroy(ini);
       
   562 	} // CSmsProtocol::ReadConfigurableSettingsL
       
   563 
       
   564 
       
   565 /**
       
   566  *  Override of CProtocolBase::Send().
       
   567  *  A down call from a protocol bound above to send a datagram.
       
   568  *  Not supported by this protocol.
       
   569  *  
       
   570  *  @leave Panics if called.
       
   571  *  
       
   572  */
       
   573 TInt CSmsProtocol::Send(TDes8& /*aDes*/,TSockAddr* /*aTo*/,TSockAddr* /*aFrom*/,CProtocolBase* /*aSourceProtocol*/)
       
   574     {
       
   575     // Ignore in code coverage - not intended to be used
       
   576     BULLSEYE_OFF    
       
   577     LOGSMSPROT1("CSmsProtocol::Send");
       
   578     SmspPanic(ESmspCantSend);
       
   579     return KErrNotSupported;
       
   580     BULLSEYE_RESTORE
       
   581     }
       
   582 
       
   583 /**
       
   584  *  Override of CProtocolBase::Process().
       
   585  *  An up call from a protocol bound below to process a datagram.
       
   586  *  Not supported by this protocol.
       
   587  *  
       
   588  *  @leave Panics if called.
       
   589  *  
       
   590  */
       
   591 void CSmsProtocol::Process(TDes8& /*aDes*/,TSockAddr* /*aFrom*/,TSockAddr* /*aTo*/,CProtocolBase* /*aSourceProtocol*/)
       
   592     {
       
   593     // Ignore in code coverage - not intended to be used
       
   594     BULLSEYE_OFF    
       
   595     LOGSMSPROT1("CSmsProtocol::Process");
       
   596     SmspPanic(ESmspCantProcess);
       
   597     BULLSEYE_RESTORE
       
   598     }
       
   599 
       
   600 /**
       
   601  *  Override of CProtocolBase::GetOption().
       
   602  *  A down call from a protocol bound above to get a protocol option.
       
   603  *  Not supported by this protocol.
       
   604  *  
       
   605  *  @leave Panics if called.
       
   606  *  
       
   607  */
       
   608 TInt CSmsProtocol::GetOption(TUint /*aLevel*/,TUint /*aName*/,TDes8 & /*aOption*/,CProtocolBase* /*aSourceProtocol*/)
       
   609     {
       
   610     // Ignore in code coverage - not intended to be used
       
   611     BULLSEYE_OFF    
       
   612     LOGSMSPROT1("CSmsProtocol::GetOption");
       
   613     // SmspPanic(ESmspCantGetOption);
       
   614     return KErrNotSupported;
       
   615     BULLSEYE_RESTORE
       
   616     }
       
   617 
       
   618 /**
       
   619  *  Override of CProtocolBase::SetOption().
       
   620  *  A down call from a protocol bound above to set a protocol option.
       
   621  *  Not supported by this protocol.
       
   622  *  
       
   623  *  @leave Panics if called.
       
   624  *  
       
   625  */
       
   626 TInt CSmsProtocol::SetOption(TUint /*aLevel*/,TUint /*aName*/,const TDesC8& /*option*/,CProtocolBase* /*aSourceProtocol*/)
       
   627     {
       
   628     // Ignore in code coverage - not intended to be used
       
   629     BULLSEYE_OFF    
       
   630     LOGSMSPROT1("CSmsProtocol::SetOption");
       
   631     //SmspPanic(ESmspCantSetOption);
       
   632     return KErrNotSupported;
       
   633     BULLSEYE_RESTORE
       
   634     }
       
   635 
       
   636 /**
       
   637  *  Override of CProtocolBase::Error().
       
   638  *  An up call from a protocol bound below to indicate an error.
       
   639  *  Not supported by this protocol.
       
   640  *  
       
   641  *  @leave Panics if called.
       
   642  *  
       
   643  */
       
   644 void CSmsProtocol::Error(TInt /*aError*/,CProtocolBase* /*aSourceProtocol*/)
       
   645     {
       
   646     // Ignore in code coverage - not intended to be used
       
   647     BULLSEYE_OFF    
       
   648     LOGSMSPROT1("CSmsProtocol::Error");
       
   649     SmspPanic(ESmspCantError);
       
   650     BULLSEYE_RESTORE
       
   651     }
       
   652 
       
   653 /**
       
   654  *  Adds an observer to the protocol's observer list.
       
   655  *  Used by CSmsProvider and CWapSmsProtocol.
       
   656  *  
       
   657  *  @leave Leaves if not enough memory is available.
       
   658  *  
       
   659  */
       
   660 void CSmsProtocol::AddSmsMessageObserverL(MSmsMessageObserver& aObserver)
       
   661     {
       
   662     LOGSMSPROT2("CSmsProtocol::AddSmsMessageObserverL [aObserver=0x%08x]", &aObserver);
       
   663     iSmsMessageObserverList.AppendL(&aObserver);
       
   664     SetClosingDown(EFalse);
       
   665     }
       
   666 
       
   667 /**
       
   668  *  Binds an SMS observer to the protocol.
       
   669  *  The protocol ensures there are no providers with duplicate addresses.
       
   670  *  Used by CSmsProvider::SetLocalName(), and SMS WAP protocol.
       
   671  *  
       
   672  *  @param aObserver the observer.
       
   673  *  @param aSmsAddr the local address of the observer.
       
   674  *  @return KErrNone on success, or KErrAlreadyExists if a duplicate exists.
       
   675  *  
       
   676  */
       
   677 TInt CSmsProtocol::BindSmsMessageObserver(MSmsMessageObserver& aObserver,const TSmsAddr& aSmsAddr)
       
   678 	{
       
   679 	LOGSMSPROT2("CSmsProtocol::BindSmsMessageObserver 0x%08x", &aObserver);
       
   680 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   681 	TInt ret=KErrNone;
       
   682 
       
   683 	if (!SmsAddrIsAlreadyUsed(&aObserver,aSmsAddr))
       
   684 		{
       
   685 		aObserver.SetLocalAddress(aSmsAddr);
       
   686 		OrderSmsMessageObserver(aObserver);
       
   687 
       
   688 		// If not in the powered-up state then the SAR store is closed. When the phone does power-up
       
   689 		// then anything waiting in the store will get processed
       
   690 		if(CheckPoweredUp() == KErrNone)
       
   691 			{
       
   692 			//
       
   693 			// check the SAR store for any complete messages.
       
   694 			// if there are any, send them to the observer
       
   695 			//
       
   696 			TRAP(ret, ProcessCompleteSmsMessagesL());
       
   697 			if(ret != KErrNone)
       
   698 				{
       
   699 				LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
       
   700 				}
       
   701 			}
       
   702 		}
       
   703 	else
       
   704 		{
       
   705 		ret=KErrAlreadyExists;
       
   706 		}
       
   707 	return ret;
       
   708 	} // CSmsProvider::SetLocalName
       
   709 
       
   710 
       
   711 /**
       
   712  *  Removes an observer from the observer list.
       
   713  *  Observers should at least call this method in their destructors.
       
   714  *  
       
   715  */
       
   716 void CSmsProtocol::RemoveSmsMessageObserver(const MSmsMessageObserver& aObserver)
       
   717     {
       
   718     LOGSMSPROT2("CSmsProtocol::RemoveSmsMessageObserver 0x%08x", &aObserver);
       
   719     __ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   720     TInt index=ObserverIndex(aObserver);
       
   721     iSmsMessageObserverList.Delete(index);
       
   722     }
       
   723 
       
   724 /**
       
   725  *  Handles a request from a SAP to send a SMS message.
       
   726  *  Ensures there is a current connection to the modem and queues the message.
       
   727  *  Completes with an error immediately if CheckPoweredUp() returns an error code
       
   728  */
       
   729 void CSmsProtocol::SendSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver,TUint aOptions)
       
   730 	{
       
   731 	LOGSMSPROT2("CSmsProtocol::SendSmsMessage [aObserver=0x%X]", &aObserver);
       
   732 	__ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
       
   733 
       
   734 	// Ensure the modem is connected and initialized
       
   735 	const TInt err = CheckPoweredUp();
       
   736 
       
   737 	if (err != KErrNone)
       
   738 		{
       
   739 		// Nope, complete immediately
       
   740 		aObserver.MessageSendCompleted(err);
       
   741 		delete aSmsMessage;
       
   742 		}
       
   743 	else
       
   744 		{
       
   745 		iSendQueue->Queue(aSmsMessage, aObserver, aOptions);
       
   746 		}
       
   747 	}
       
   748 
       
   749 TInt CSmsProtocol::CheckPoweredUp() const
       
   750     {
       
   751     TInt err = KErrNone;
       
   752     
       
   753     if( iModemDetection == RPhone::EDetectedNotPresent || iState == EPoweredDown )
       
   754         {
       
   755         err = KErrDisconnected;
       
   756         }
       
   757     else if( iBackupRestoreSession->IsBackupOrRestoreInProgress() )
       
   758         {
       
   759         err = KErrAccessDenied;
       
   760         }
       
   761     else
       
   762         {
       
   763         err = iSmsPhoneInitialization->Initialized();
       
   764         }
       
   765     if( err != KErrNone )
       
   766         {
       
   767         LOGSMSPROT4("CSmsProtocol::CheckPoweredUp [err=%d, iModemDetection=%d, IsBackupOrRestoreInProgress=%d]", err, iModemDetection, iBackupRestoreSession->IsBackupOrRestoreInProgress());
       
   768         }    
       
   769     return err;
       
   770     }
       
   771 
       
   772 /**
       
   773  *  Cancels a previous request to send an SMS message.
       
   774  *  Searches the send queue for the message.  If it is found at the
       
   775  *  head of the queue the sending state machine is cancelled, which
       
   776  *  in turn will callback to the protocol and delete the message.
       
   777  *  If the message is elsewhere in the queue, it is simply removed
       
   778  *  from the queue and the observer notified.
       
   779  *  
       
   780  *  @leave Panics in DEBUG if the message is not found in the queue.
       
   781  *  
       
   782  */
       
   783 void CSmsProtocol::CancelSendSmsMessage(MSmsMessageObserver& aObserver,TBool)
       
   784 	{
       
   785 	LOGSMSPROT2("CSmsProtocol::CancelSendSmsMessage 0x%08x", &aObserver);
       
   786 
       
   787 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   788 
       
   789 	iSendQueue->CancelObserver(aObserver);
       
   790 	} // CSmsProtocol::CancelSendSmsMessage
       
   791 
       
   792 
       
   793 /**
       
   794  *  Handles a request from a SAP to enumerate the SMS messages stored on the phone.
       
   795  */
       
   796 void CSmsProtocol::EnumeratePhone(MSmsMessageObserver& aObserver)
       
   797 	{
       
   798 	LOGSMSPROT1("CSmsProtocol::EnumeratePhone");
       
   799 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   800 
       
   801 	// Ensure the modem is connected and initialized
       
   802 	const TInt err = CheckPoweredUp();
       
   803 
       
   804 	if (err != KErrNone)
       
   805 		aObserver.EnumeratePhoneCompleted(err);
       
   806 	else
       
   807 		{
       
   808 		if (iPhoneEnumerationObserver!=NULL)
       
   809 			{
       
   810 			aObserver.EnumeratePhoneCompleted(KErrInUse);
       
   811 			}
       
   812 		else
       
   813 			{
       
   814 			iPhoneEnumerationObserver=&aObserver;
       
   815 			iSmsPhoneEnumeration->Start();
       
   816 			}
       
   817 		}
       
   818 	} // CSmsProtocol::EnumeratePhone
       
   819 
       
   820 
       
   821 /**
       
   822  *  Cancels a previous request to enumerate the message on the phone memory.
       
   823  *  
       
   824  *  @leave Panics in DEBUG if the SAP is invalid.
       
   825  *  
       
   826  */
       
   827 void CSmsProtocol::CancelEnumeratePhone(MSmsMessageObserver& aObserver)
       
   828 	{
       
   829 	LOGSMSPROT1("CSmsProtocol::CancelEnumeratePhone");
       
   830 
       
   831 	__ASSERT_DEBUG(ObserverIsPresent(aObserver), SmspPanic(ESmspMessageObserverNotFound));
       
   832 	__ASSERT_DEBUG(iPhoneEnumerationObserver==NULL || &aObserver==iPhoneEnumerationObserver, SmspPanic(ESmspMessageWrongObserver));
       
   833 
       
   834 	if (iSmsPhoneEnumeration != NULL)
       
   835 		{
       
   836 		iSmsPhoneEnumeration->Cancel();
       
   837 		}
       
   838 
       
   839 	iReassemblyStore->DeleteEnumeratedSIMEntries();
       
   840 
       
   841     (void) aObserver;
       
   842 	} // CSmsProtocol::CancelEnumeratePhone
       
   843 
       
   844 
       
   845 TInt CSmsProtocol::ExternalizeEnumeratedMessagesL(CSmsProvider& aProvider,TInt& aCount)
       
   846 	{
       
   847 	return iReassemblyStore->ExternalizeEnumeratedMessagesL(aProvider, aCount);
       
   848 	} // CSmsProtocol::ExternalizeEnumeratedMessagesL
       
   849 
       
   850 
       
   851 /**
       
   852  *  Handles a request to write an SMS message to the phone's memory.
       
   853  *  Completes with an error immediately if CheckPoweredUp() returns an error code
       
   854  *  Otherwise the message is added to the tail of the write queue.
       
   855  */
       
   856 void CSmsProtocol::WriteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
       
   857 	{
       
   858 	LOGSMSPROT1("CSmsProtocol::WriteSmsMessage");
       
   859 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   860 
       
   861 	const TInt err = CheckPoweredUp();
       
   862 
       
   863 	if (err != KErrNone)
       
   864 		{
       
   865 		aObserver.MessageWriteCompleted(err);
       
   866 		delete aSmsMessage;
       
   867 		}
       
   868 	else
       
   869 		{
       
   870 		iWriteQueue->Queue(aSmsMessage, aObserver, NULL);
       
   871 		}
       
   872 	} // CSmsProtocol::WriteSmsMessage
       
   873 
       
   874 
       
   875 void CSmsProtocol::CancelWriteSmsMessage(MSmsMessageObserver& aObserver)
       
   876 	{
       
   877 	LOGSMSPROT1("CSmsProtocol::CancelWriteSmsMessage()");
       
   878 
       
   879 	if (iWriteQueue != NULL)
       
   880 		iWriteQueue->CancelObserver(aObserver);
       
   881 	} // CSmsProtocol::CancelWriteSmsMessage
       
   882 
       
   883 
       
   884 /**
       
   885  *  Handles a request from a SAP to delete a message from the phone memory.
       
   886  *  Completes with an error immediately if CheckPoweredUp() returns an error code
       
   887  *  If the cached image of the phone's memory is not yet initialised, complete the
       
   888  *  request with KErrNotReady.
       
   889  *  Otherwise match the message in the phone image and queue the message for deletion.
       
   890  *  
       
   891  *  @note aSmsMessage is destroyed from memory on completion.
       
   892  *  
       
   893  */
       
   894 void CSmsProtocol::DeleteSmsMessage(CSmsMessage* aSmsMessage,MSmsMessageObserver& aObserver)
       
   895 	{
       
   896 	LOGSMSPROT1("CSmsProtocol::DeleteSmsMessage");
       
   897 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   898 
       
   899 	// Ensure the modem is connected and initialized
       
   900 	const TInt err = CheckPoweredUp();
       
   901 
       
   902 	if (err != KErrNone)
       
   903 		{
       
   904 		// Not connected or backup running
       
   905 		aObserver.MessageDeleteCompleted(err);
       
   906 		}
       
   907 	else if (aSmsMessage->iSlotArray.Count()==0)
       
   908 		aObserver.MessageDeleteCompleted(KErrArgument);
       
   909 	else
       
   910 		DeletePDUs(aSmsMessage->iSlotArray,&aObserver);
       
   911 
       
   912 	delete aSmsMessage;
       
   913 	} // CSmsProtocol::DeleteSmsMessage
       
   914 
       
   915 
       
   916 /**
       
   917  *  Cancels a previous request to delete a message from the phone memory.
       
   918  *  
       
   919  *  @leave Panics in DEBUG if the SAP is invalid.
       
   920  *  
       
   921  */
       
   922 void CSmsProtocol::CancelDeleteSmsMessage(MSmsMessageObserver& aObserver)
       
   923 	{
       
   924 	LOGSMSPROT1("CSmsProtocol::CancelDeleteSmsMessage");
       
   925 
       
   926 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   927 
       
   928 	iDeleteQueue->CancelObserver(aObserver);
       
   929 	} // CSmsProtocol::CancelDeleteSmsMessage
       
   930 
       
   931 
       
   932 /**
       
   933  *  Handles a request from a SAP to read the SMS parameters stored on the phone.
       
   934  *  Completes with an error immediately if CheckPoweredUp() returns an error code
       
   935  *  If TSY doesn't support retrieving of parameters, the request is completed
       
   936  *  immediately with KErrNotSupported.
       
   937  *  The request is completed with KErrNoMemory if creation of CSmsReadParams
       
   938  *  object fails.
       
   939  *  The request is completed with KErrInUse if another SAP is reading.
       
   940  *  Otherwise, the reading process is started.
       
   941  *  
       
   942  */
       
   943 void CSmsProtocol::ReadSmsParameters(MSmsMessageObserver& aObserver)
       
   944 	{
       
   945 	LOGSMSPROT1("CSmsProtocol::ReadSmsParameters");
       
   946 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
   947 	TInt ret = CheckPoweredUp();
       
   948 
       
   949 	if (ret == KErrNone)
       
   950 		{
       
   951 		if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList)
       
   952 			{
       
   953 			if (iSmsReadParams==NULL)
       
   954 				{
       
   955 				TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
       
   956 				}
       
   957 			else if (iSmsReadParams->IsActive())
       
   958 				{
       
   959 				ret = KErrInUse;
       
   960 				}
       
   961 			}
       
   962 		else
       
   963 			ret = KErrNotSupported;
       
   964 		}
       
   965 
       
   966 	if(ret != KErrNone)
       
   967 		aObserver.ReadSmsParamsCompleted(ret, NULL);
       
   968 	else
       
   969 		iSmsReadParams->Start(aObserver);
       
   970 	} // CSmsProtocol::ReadSmsParameters
       
   971 
       
   972 
       
   973 /**
       
   974  *  Cancels a previous request to read SMS parameters.
       
   975  *  
       
   976  */
       
   977 void CSmsProtocol::CancelReadSmsParams()
       
   978 	{
       
   979 	LOGSMSPROT1("CSmsProtocol::CancelReadSmsParams");
       
   980 
       
   981 	if(iSmsReadParams != NULL)
       
   982 		iSmsReadParams->Cancel();
       
   983 	} // CSmsProtocol::CancelReadSmsParams
       
   984 
       
   985 
       
   986 /**
       
   987  *  Handles a request to write an SMS parameters to the phone's memory.
       
   988  *  Completes with an error immediately if CheckPoweredUp() returns an error code
       
   989  *  If TSY doesn't support retrieving and writing of parameters, the request is completed
       
   990  *  immediately with KErrNotSupported.
       
   991  *  The request is completed with KErrInUse if another SAP is reading or writing.
       
   992  *  The request is completed with KErrNoMemory if creation of CSmsReadParams or
       
   993  *  CSmsWriteParams object fails.
       
   994  *  Otherwise, the writing process is started.
       
   995  *  
       
   996  */
       
   997 void CSmsProtocol::WriteSmsParameters(CMobilePhoneSmspList* aMobilePhoneSmspList,MSmsMessageObserver& aObserver)
       
   998 	{
       
   999 	LOGSMSPROT1("CSmsProtocol::WriteSmsParameters");
       
  1000 	__ASSERT_DEBUG(ObserverIsPresent(aObserver),SmspPanic(ESmspMessageObserverNotFound));
       
  1001 
       
  1002 	TInt ret = CheckPoweredUp();
       
  1003 
       
  1004 	if (ret == KErrNone)
       
  1005 		{
       
  1006 		if(iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsGetSmspList && iMobileSmsCaps.iSmsControl & RMobileSmsMessaging::KCapsSetSmspList)
       
  1007 			{
       
  1008 			if (iSmsReadParams==NULL)
       
  1009 				{
       
  1010 				TRAP(ret,(iSmsReadParams=CSmsReadParams::NewL(*this,iSmsSettings,iSmsMessaging)));
       
  1011 				}
       
  1012 			else if (iSmsReadParams->IsActive())
       
  1013 				ret=KErrInUse;
       
  1014 			}
       
  1015 		else
       
  1016 			ret=KErrNotSupported;
       
  1017 		}
       
  1018 
       
  1019 	if (ret==KErrNone)
       
  1020 		{
       
  1021 		if (iSmsWriteParams==NULL)
       
  1022 			{
       
  1023 			TRAP(ret,(iSmsWriteParams=CSmsWriteParams::NewL(*this,iSmsSettings,iSmsMessaging,*iSmsReadParams)));
       
  1024 			}
       
  1025 		else if (iSmsWriteParams->IsActive())
       
  1026 			ret=KErrInUse;
       
  1027 		}
       
  1028 
       
  1029 	if (ret==KErrNone)
       
  1030 		iSmsWriteParams->Start(aObserver,aMobilePhoneSmspList);
       
  1031 	else
       
  1032 		{
       
  1033 		aObserver.WriteSmsParamsCompleted(ret);
       
  1034 		delete aMobilePhoneSmspList;
       
  1035 		}
       
  1036 	} // CSmsProtocol::WriteSmsParameters
       
  1037 
       
  1038 
       
  1039 /**
       
  1040  *  Cancels a previous request to write SMS parameters.
       
  1041  *  
       
  1042  */
       
  1043 void CSmsProtocol::CancelWriteSmsParams()
       
  1044 	{
       
  1045 	LOGSMSPROT1("CSmsProtocol::CancelWriteSmsParams");
       
  1046 
       
  1047 	if(iSmsWriteParams != NULL)
       
  1048 		iSmsWriteParams->Cancel();
       
  1049 	} // CSmsProtocol::CancelWriteSmsParams
       
  1050 
       
  1051 
       
  1052 /**
       
  1053  *  Processes a received SMS message by matching it to an observer and
       
  1054  *  notifying the observer of the new message.
       
  1055  *  
       
  1056  *  If the message has been matched to a message previously sent by the protocol
       
  1057  *  (i.e. a status report from a previous submit), then the original message and address
       
  1058  *  are supplied.  Matching priority in this case is given to the original sender.
       
  1059  *  
       
  1060  *  If the message remains in phone or SIM memory, the message is sent to the "receive any"
       
  1061  *  observer, otherwise the match based on the message and address of the observer.
       
  1062  *  
       
  1063  *  @param aSmsMessage the received message
       
  1064  *  @param aOriginalSmsAddr pointer to the address of the sender of a previously sent
       
  1065  *  message matched to the received one (e.g. status report). Null if not matched.
       
  1066  *  @param aOriginalSmsMessage pointer to a message previously sent matched to the
       
  1067  *  received one (e.g. status report).	Null if not matched.
       
  1068  *  @param aDes user data for the deliver report acknowledging this message to the SC.
       
  1069  *  Filled in by the observer.
       
  1070  *  @return KErrNone if the observer handled the message successfully, otherwise an error.
       
  1071  *  
       
  1072  */
       
  1073 TInt CSmsProtocol::ProcessMessageL(const CSmsMessage& aSmsMessage,const TSmsAddr* aOriginalSmsAddr,
       
  1074 		const CSmsMessage* /*aOriginalSmsMessage*/,TDes& aDes)
       
  1075 	{
       
  1076 	LOGSMSPROT1("CSmsProtocol::ProcessMessage");
       
  1077 
       
  1078 	MSmsMessageObserver* observer=NULL;
       
  1079 	if (aOriginalSmsAddr!=NULL)
       
  1080 		{
       
  1081 		// Status report and original message matched - send to original sender as priority
       
  1082 		observer=MatchSmsAddressToObserver(*aOriginalSmsAddr);
       
  1083 		if (observer==NULL)
       
  1084 			{
       
  1085 			// Sender no longer present or is read only - match on received message as usual
       
  1086 			observer=MatchSmsMessageToObserver(aSmsMessage);
       
  1087 			}
       
  1088 		}
       
  1089 	else if (iPhoneEnumerationObserver==NULL  ||  IsAppPortSMS(aSmsMessage ))
       
  1090 		{
       
  1091 		// Only match if not currently enumerating or if it is meant for an app port.
       
  1092 		observer = MatchSmsMessageToObserver(aSmsMessage);
       
  1093 		}
       
  1094 
       
  1095 	LOGSMSPROT2("CSmsProtocol::ProcessMessage [observer=0x%08x]",observer);
       
  1096 	TInt ret=KErrNone;
       
  1097 
       
  1098 	if (observer!=NULL)
       
  1099 		{
       
  1100 		TBool isAppPortSms = IsAppPortSMS(aSmsMessage );
       
  1101 
       
  1102 		if(isAppPortSms && iBootTimer !=NULL && iBootTimer->IsActive() && observer->GetLocalAddress().SmsAddrFamily() == ESmsAddrRecvAny)
       
  1103 			{
       
  1104 			ret = KErrNotReady;
       
  1105 			}
       
  1106 		else
       
  1107 			{
       
  1108 			ret=observer->MessageReceived(aSmsMessage,aDes);
       
  1109 			}
       
  1110 
       
  1111 		if(ret == KErrNone && (observer->ClientConfirmsMessage() == EFalse)  && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
       
  1112 		{
       
  1113 			iReassemblyStore->DeleteMessageL(aSmsMessage, EFalse);
       
  1114 			ret=KErrInUse;                
       
  1115 			// used to signal to client that there is nothing to be done on reassembly store
       
  1116 			// and code different from KErrNone will do - won't be propagated
       
  1117 		}
       
  1118 		else if(ret == KErrNotFound && observer->GetLocalAddress().SmsAddrFamily() != ESmsAddrRecvAny)
       
  1119 			{
       
  1120 			if ( iBootTimer && !iBootTimer->IsActive() && (aOriginalSmsAddr==NULL || aOriginalSmsAddr->SmsAddrFamily() != ESmsAddrRecvAny))
       
  1121  				{
       
  1122 				TSmsAddr addr;
       
  1123 				addr.SetSmsAddrFamily(ESmsAddrRecvAny);
       
  1124 				ret = ProcessMessageL(aSmsMessage, &addr, NULL, aDes);
       
  1125 				}
       
  1126 			}
       
  1127 		}
       
  1128 	else
       
  1129 		{
       
  1130         ret=KErrNotReady; // Observers are not ready
       
  1131 		}
       
  1132 	return ret;
       
  1133 	} // CSmsProtocol::ProcessMessageL
       
  1134 
       
  1135 
       
  1136 /**
       
  1137  *  Deletes one or more PDUs from phone or SIM memory.
       
  1138  *  The PDUs are added to the deletion queue.  If this queue is empty, the deletion
       
  1139  *  state machine is started.
       
  1140  *  
       
  1141  *  @param aSlotArray
       
  1142  */
       
  1143 void CSmsProtocol::DeletePDUs(const CArrayFix<TGsmSmsSlotEntry>& aSlotArray, MSmsMessageObserver* aObserver)
       
  1144 	{
       
  1145 	LOGSMSPROT3("CSmsProtocol::DeletePDUs [count=%d aObserver=0x%08X", aSlotArray.Count(), aObserver);
       
  1146 	__ASSERT_DEBUG(aSlotArray.Count() != 0, SmspPanic(KSmspSlotArrayEmpty));
       
  1147 
       
  1148 	for(TInt i=0; i< aSlotArray.Count() ;i++)
       
  1149 		{
       
  1150 		LOGSMSPROT3("CSmsProtocol::DeletePDUs index: %d store %S", aSlotArray[i].iIndex, &aSlotArray[i].iStore);
       
  1151 		}
       
  1152 
       
  1153 	if (iDeleteQueue != NULL && aSlotArray.Count() != 0)
       
  1154 		{
       
  1155 		iDeleteQueue->Queue(aSlotArray, aObserver);
       
  1156 		}
       
  1157 	} // CSmsProtocol::DeletePDUs
       
  1158 
       
  1159 /**
       
  1160  *  Called when the modem detection state has changed.
       
  1161  *  If a modem has connection has just been made, a number of event monitoring
       
  1162  *  state machines are restarted, and as is the bearer setting state machine.
       
  1163  *  If the the modem connection was lost, outstanding operations are cancelled.
       
  1164  *  
       
  1165  */
       
  1166 void CSmsProtocol::ModemNotificationCompleted(TInt aStatus,
       
  1167 											  RPhone::TModemDetection aNewState)
       
  1168 	{
       
  1169 	LOGSMSPROT3("CSmsProtocol::ModemNotificationCompleted(): aStatus=%d, aNewState=%d",
       
  1170 				aStatus, aNewState);
       
  1171 
       
  1172 	TBool stateChanged = EFalse;
       
  1173 
       
  1174 	if (aStatus==KErrNone)
       
  1175 		{
       
  1176 		switch (iModemDetection)
       
  1177 			{
       
  1178 			//
       
  1179 			// it goes from OFF to ON
       
  1180 			//
       
  1181 			case RPhone::EDetectedNotPresent:
       
  1182 			case RPhone::EDetectedUnknown:
       
  1183 				{
       
  1184 				LOGSMSPROT1("RPhone::EDetectedNotPresent: [OFF -> ON]");
       
  1185 				if (aNewState==RPhone::EDetectedPresent)
       
  1186 					{
       
  1187 					// There is a new modem connection
       
  1188 					iModemDetection=aNewState;
       
  1189 					stateChanged = ETrue;
       
  1190 					}
       
  1191 				break;
       
  1192 				}
       
  1193 			//
       
  1194 			// it goes from ON to OFF
       
  1195 			//
       
  1196 			case RPhone::EDetectedPresent:
       
  1197 				{
       
  1198 				LOGSMSPROT1("RPhone::EDetectedPresent: [ON -> OFF]");
       
  1199 				if (aNewState!=RPhone::EDetectedPresent)
       
  1200 					{
       
  1201 					// Ah, lost our modem - cancel outstanding operations
       
  1202 					iModemDetection=aNewState;
       
  1203 					stateChanged = ETrue;
       
  1204 					}
       
  1205 				break;
       
  1206 				}
       
  1207 			default:
       
  1208 				{
       
  1209 				__ASSERT_DEBUG(EFalse,SmspPanic(KSmspPanicUnknownModemDetection));
       
  1210 				}
       
  1211 			}
       
  1212 
       
  1213 		if (iModemDetection == RPhone::EDetectedPresent && !iBackupRestoreSession->IsBackupOrRestoreInProgress())
       
  1214 			{
       
  1215 			if (stateChanged || iState == EPoweredDown)
       
  1216 				{
       
  1217 				PowerUp();
       
  1218 				}
       
  1219 			}
       
  1220 		else if (stateChanged || iState != EPoweredDown)
       
  1221 			{
       
  1222 			PowerDown();
       
  1223 			}
       
  1224 		}
       
  1225 	} // CSmsProtocol::ModemNotificationCompleted
       
  1226 
       
  1227 
       
  1228 void CSmsProtocol::DiskSpaceMonitorStateChange(TSmsDiskSpaceMonitorStatus aStatus)
       
  1229 /**
       
  1230  * Called when the Disk Space Monitor state has changed.
       
  1231  */
       
  1232 	{
       
  1233 	LOGSMSPROT2("CSmsProtocol::DiskSpaceMonitorStateChange(): aStatus=%d", aStatus);
       
  1234 
       
  1235 	RProperty::Set(KUidPSSMSStackCategory, KUidPSSMSStackDiskSpaceMonitorKey, aStatus);
       
  1236 	} // CSmsProtocol::DiskSpaceMonitorStateChange
       
  1237 
       
  1238 
       
  1239 /**
       
  1240  *  Called when all message send requests have completed.
       
  1241  *  Increments the number of segmentation store accesses and purges the store
       
  1242  *  if it exceeds CSmsProtocol::KNumSARStoreAccessesBeforePurging.
       
  1243  */
       
  1244 void CSmsProtocol::MessageSendCompleted(TInt aStatus)
       
  1245 	{
       
  1246 	LOGSMSPROT3("*** CSmsProtocol::MessageSendCompleted [aStatus=%d iNumSegmentationStoreAccesses=%d]", aStatus, iNumSegmentationStoreAccesses);
       
  1247     (void) aStatus;
       
  1248 	iNumSegmentationStoreAccesses++;
       
  1249 	if (iNumSegmentationStoreAccesses>=KNumSARStoreAccessesBeforePurging)
       
  1250 		{
       
  1251 		LOGSMSPROT1("iSegmentationStore->PurgeL Start");
       
  1252 		TRAPD(ret, iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse));
       
  1253 		if(ret!=KErrNone)
       
  1254 			{
       
  1255 			// we need to close the file because the function
       
  1256 			// left with the file opened
       
  1257 			// iSegmentationStore->CloseFile();
       
  1258 			LOGSMSPROT2("WARNING! iSegmentationStore->PurgeL left with %d", ret);
       
  1259 			}
       
  1260 		iNumSegmentationStoreAccesses=0;
       
  1261 		LOGSMSPROT2("iSegmentationStore->PurgeL End [ret=%d]", ret);
       
  1262 		}
       
  1263 	} // CSmsProtocol::KNumSARStoreAccessesBeforePurging
       
  1264 
       
  1265 
       
  1266 /**
       
  1267  *  Called when the state machine for enumerating messages on the
       
  1268  *  phone has completed.  Notifies the SAP that made the request.
       
  1269  *  
       
  1270  */
       
  1271 void CSmsProtocol::PhoneEnumerationCompleted(TInt aStatus)
       
  1272 	{
       
  1273 	LOGSMSPROT1("CSmsProtocol::PhoneEnumerationCompleted");
       
  1274 	iPhoneEnumerationObserver->EnumeratePhoneCompleted(aStatus);
       
  1275 	} // CSmsProtocol::PhoneEnumerationCompleted
       
  1276 
       
  1277 
       
  1278 /**
       
  1279  *  Called by CProtocolBase::Close() to handle any delayed shutdown.
       
  1280  *  If there are messages in the deletion queue then the shut down flag
       
  1281  *  is set, otherwise CProtocolBase::CanClose() is called to finish closing.
       
  1282  *  
       
  1283  */
       
  1284 void CSmsProtocol::CloseNow()
       
  1285 	{
       
  1286 	LOGSMSPROT1("CSmsProtocol::CloseNow");
       
  1287 	if (iDeleteQueue != NULL && iDeleteQueue->IsActive())
       
  1288 		SetClosingDown(ETrue);
       
  1289 	else
       
  1290 		CanClose();
       
  1291 	} // CSmsProtocol::CloseNow
       
  1292 
       
  1293 
       
  1294 /**
       
  1295  *  Private constructor.
       
  1296  *  
       
  1297  */
       
  1298 CSmsProtocol::CSmsProtocol()
       
  1299 	:iSmsMessageObserverList(8)
       
  1300 	,iModemDetection(RPhone::EDetectedUnknown)
       
  1301 	{
       
  1302 	iSmsSettings.SetDeletePDUsFromSIM(EFalse);
       
  1303 	iSmsSettings.SetDeletePDUsFromPhoneStores(EFalse);
       
  1304 	iSmsSettings.SetDeletePDUsFromCombinedStores(EFalse);
       
  1305 	iNext8BitPort=KMin8BitPortNumber;
       
  1306 	iNext16BitPort=KMin16BitPortNumber;
       
  1307 	} // CSmsProtocol::CSmsProtocol
       
  1308 
       
  1309 
       
  1310 /**
       
  1311  *  Returns the index of an observer in the observer list.
       
  1312  *  
       
  1313  */
       
  1314 TInt CSmsProtocol::ObserverIndex(const MSmsMessageObserver& aObserver) const
       
  1315 	{
       
  1316 	LOGSMSPROT1("CSmsProtocol::ObserverIndex()");
       
  1317 
       
  1318 	TInt count=iSmsMessageObserverList.Count();
       
  1319 	TInt index=0;
       
  1320 	for (; index<count; index++)
       
  1321 		if (iSmsMessageObserverList[index]==&aObserver)
       
  1322 			break;
       
  1323 	return index;
       
  1324 	} // CSmsProtocol::ObserverIndex
       
  1325 
       
  1326 
       
  1327 /**
       
  1328  *  Checks if an SMS address type is a duplicate of an existing SAP / observer.
       
  1329  *  
       
  1330  */
       
  1331 TBool CSmsProtocol::SmsAddrIsAlreadyUsed(const MSmsMessageObserver* aObserver,const TSmsAddr& aSmsAddr)const
       
  1332 	{
       
  1333 	LOGSMSPROT1("CSmsProtocol::SmsAddrIsAlreadyUsed()");
       
  1334 
       
  1335 	TBool isduplicate=EFalse;
       
  1336 	TInt count=iSmsMessageObserverList.Count();
       
  1337 	for (TInt i=0; (i<count) && (!isduplicate); i++)
       
  1338 		isduplicate=(iSmsMessageObserverList[i]->SmsAddrIsDuplicate(aObserver,aSmsAddr));
       
  1339 	return isduplicate;
       
  1340 	} // CSmsProtocol::SmsAddrIsAlreadyUsed
       
  1341 
       
  1342 
       
  1343 /**
       
  1344  *  A utility class for prioritizing the SMS protocol observers based
       
  1345  *  on their SMS address type.
       
  1346  *  A higher priority observer will be given the opportunity to
       
  1347  *  accept a received messages before one of a lower priority.
       
  1348  */
       
  1349 class TKeySmsObserver : public TKeyArrayFix
       
  1350 	{
       
  1351 public:
       
  1352 	TKeySmsObserver();
       
  1353 	virtual TInt Compare(TInt aLeft,TInt aRight) const;
       
  1354 	static TInt SmsAddressPriority(const TSmsAddr& aAddr);
       
  1355 	};
       
  1356 
       
  1357 
       
  1358 /**
       
  1359  *  Constructor
       
  1360  *  
       
  1361  */
       
  1362 TKeySmsObserver::TKeySmsObserver()
       
  1363 	:TKeyArrayFix(0,ECmpTInt)
       
  1364 	{
       
  1365 	iKeyOffset = 0;
       
  1366 	} // TKeySmsObserver::TKeySmsObserver
       
  1367 
       
  1368 
       
  1369 /**
       
  1370  *  Static method that returns the priority of a given SMS address.
       
  1371  *  
       
  1372  *  @leave Panics on an unknown address type.
       
  1373  *  
       
  1374  */
       
  1375 TInt TKeySmsObserver::SmsAddressPriority(const TSmsAddr& aAddr)
       
  1376 	{
       
  1377 	TSmsAddrFamily fam = aAddr.SmsAddrFamily();
       
  1378 
       
  1379 	switch (fam)
       
  1380 		{
       
  1381 		case ESmsAddrEmail:
       
  1382 			return 11;
       
  1383 		case ESmsAddrApplication8BitPort:
       
  1384 			return 10;
       
  1385 		case ESmsAddrApplication16BitPort:
       
  1386 			return 9;
       
  1387 		case ESmsAddrMessageIndication:
       
  1388 			return 8;
       
  1389 		case ESmsAddrStatusReport:
       
  1390 			return 7;
       
  1391 		case ESmsAddrMatchIEI:
       
  1392 			return 6;
       
  1393 		case ESmsAddrMatchText:
       
  1394 			return 5;
       
  1395 		case ESmsAddrRecvAny:
       
  1396 			return 4;
       
  1397 		case ESmsAddrSendOnly:
       
  1398 			return 3;
       
  1399 		case ESmsAddrLocalOperation:
       
  1400 			return 2;
       
  1401 		case ESmsAddrUnbound:
       
  1402 			return 1;
       
  1403 		default:
       
  1404 			SmspPanic(ESmspUnknownSmsAddressFamily);
       
  1405 		};
       
  1406 	return KErrNotFound;
       
  1407 	} // TKeySmsObserver::SmsAddressPriority
       
  1408 
       
  1409 
       
  1410 /**
       
  1411  *  Compares two observers.
       
  1412  *  Override of TKeyArrayFix::Compare() called on to help sort
       
  1413  *  the observer list based on their address types.
       
  1414  *  
       
  1415  */
       
  1416 TInt TKeySmsObserver::Compare(TInt aLeft, TInt aRight) const
       
  1417 	{
       
  1418 	LOGSMSPROT3("TKeySmsObserver::Compare [left=%d, right=%d]", aLeft, aRight);
       
  1419 
       
  1420 	const TInt lhptr = -1; // Left higher priority than right
       
  1421 	const TInt rhptl = 1; // Right higher priority than left
       
  1422 
       
  1423 	MSmsMessageObserver* left = *(MSmsMessageObserver**)At(aLeft);
       
  1424 	MSmsMessageObserver* right = *(MSmsMessageObserver**)At(aRight);
       
  1425 
       
  1426 	const TSmsAddr& leftAddr = left->GetLocalAddress();
       
  1427 	const TSmsAddr& rightAddr = right->GetLocalAddress();
       
  1428 
       
  1429 	TSmsAddrFamily leftFamily = leftAddr.SmsAddrFamily();
       
  1430 
       
  1431 
       
  1432 	TInt leftPriority = SmsAddressPriority(leftAddr);
       
  1433 	TInt rightPriority = SmsAddressPriority(rightAddr);
       
  1434 
       
  1435 	if (leftPriority > rightPriority)
       
  1436 		return lhptr;
       
  1437 	if (rightPriority > leftPriority)
       
  1438 		return rhptl;
       
  1439 
       
  1440 	if (leftFamily == ESmsAddrMatchText)
       
  1441 		{
       
  1442 		// Longer strings are higher priority than shorter ones
       
  1443 		TInt rightLen = rightAddr.TextMatch().Length();
       
  1444 		TInt leftLen = leftAddr.TextMatch().Length();
       
  1445 		if (leftLen > rightLen)
       
  1446 			return lhptr;
       
  1447 		if (rightLen > leftLen)
       
  1448 			return rhptl;
       
  1449 		}
       
  1450 
       
  1451 	return 0;
       
  1452 	} // TKeyArrayFix::Compare
       
  1453 
       
  1454 
       
  1455 /**
       
  1456  *  Re-orders the observer list using TKeySmsObserver to determine priorities.
       
  1457  *  
       
  1458  */
       
  1459 void CSmsProtocol::OrderSmsMessageObserver(const MSmsMessageObserver& /*aObserver*/)
       
  1460 	{
       
  1461 	LOGSMSPROT1("CSmsProtocol::OrderSmsMessageObserver()");
       
  1462 
       
  1463 	TKeySmsObserver smsObsKey;
       
  1464 #ifdef _DEBUG
       
  1465 	TInt ret=iSmsMessageObserverList.Sort(smsObsKey);
       
  1466 	__ASSERT_DEBUG(ret==KErrNone,SmspPanic(ESmspCorruptObserverList));
       
  1467 #else
       
  1468     iSmsMessageObserverList.Sort(smsObsKey);
       
  1469 #endif
       
  1470 	} // CSmsProtocol::OrderSmsMessageObserver
       
  1471 
       
  1472 
       
  1473 /**
       
  1474  *  Attempts to match an incoming message to a SAP / observer.  Starts with the
       
  1475  *  highest priority observer.
       
  1476  *  
       
  1477  */
       
  1478 MSmsMessageObserver* CSmsProtocol::MatchSmsMessageToObserver(const CSmsMessage& aSmsMessage)
       
  1479 	{
       
  1480 	LOGSMSPROT1("CSmsProtocol::MatchSmsMessageToObserver()");
       
  1481 
       
  1482 	TInt count=iSmsMessageObserverList.Count();
       
  1483 	for (TInt i=0;i<count;i++)
       
  1484 		{
       
  1485 		MSmsMessageObserver* obs = iSmsMessageObserverList[i];
       
  1486 		if (IsMatch(obs->GetLocalAddress(),aSmsMessage))
       
  1487 			return obs;
       
  1488 		}
       
  1489 	return NULL;
       
  1490 	} // CSmsProtocol::MatchSmsMessageToObserver
       
  1491 
       
  1492 
       
  1493 /**
       
  1494  *  Tries to match an SMS address to a SAP / observer.  Starts with the highest
       
  1495  *  priority observer.
       
  1496  *  
       
  1497  */
       
  1498 MSmsMessageObserver* CSmsProtocol::MatchSmsAddressToObserver(const TSmsAddr& aAddr)
       
  1499 	{
       
  1500 	LOGSMSPROT1("CSmsProtocol::MatchSmsAddressToObserver()");
       
  1501 
       
  1502 	TInt count=iSmsMessageObserverList.Count();
       
  1503 	for (TInt i=0;i<count;i++)
       
  1504 		{
       
  1505 		MSmsMessageObserver* obs = iSmsMessageObserverList[i];
       
  1506 		if (obs->GetLocalAddress()==aAddr)
       
  1507 			return obs;
       
  1508 		}
       
  1509 	return NULL;
       
  1510 	} // CSmsProtocol::MatchSmsAddressToObserver
       
  1511 
       
  1512 
       
  1513 /**
       
  1514  *  Static function checks if a message is matched to a given SMS address type.	Used by
       
  1515  *  MatchSmsMessageToObserver() to find a matching observer for the message.
       
  1516  *  
       
  1517  */
       
  1518 TBool CSmsProtocol::IsMatch(const TSmsAddr& aSmsAddr, const CSmsMessage& aSmsMessage)
       
  1519 	{
       
  1520 	LOGSMSPROT1("CSmsProtocol::IsMatch()");
       
  1521 
       
  1522 	TSmsAddrFamily family = aSmsAddr.SmsAddrFamily();
       
  1523 
       
  1524 	switch(family)
       
  1525 	{
       
  1526 		case (ESmsAddrUnbound):
       
  1527 		case (ESmsAddrSendOnly):
       
  1528 		case(ESmsAddrLocalOperation):
       
  1529 			return EFalse;
       
  1530 
       
  1531 		case(ESmsAddrApplication8BitPort ):
       
  1532 			{
       
  1533 			return (MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),EFalse));
       
  1534 			}
       
  1535 
       
  1536 		case (ESmsAddrApplication16BitPort ):
       
  1537 			{
       
  1538 			return(MatchApplicationPort(aSmsMessage,aSmsAddr.Port(),ETrue));
       
  1539 			}
       
  1540 
       
  1541 		case (ESmsAddrMessageIndication):
       
  1542 			{
       
  1543 			if (MatchInformationElement(aSmsMessage,CSmsInformationElement::ESmsIEISpecialSMSMessageIndication))
       
  1544 				return ETrue;
       
  1545 			if (aSmsMessage.SmsPDU().DataCodingSchemePresent())
       
  1546 				{
       
  1547 				TSmsDataCodingScheme::TSmsDCSBits7To4 bits7to4 = aSmsMessage.SmsPDU().Bits7To4();
       
  1548 				switch (bits7to4)
       
  1549 					{
       
  1550 					case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:
       
  1551 					case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
       
  1552 					case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
       
  1553 						return ETrue;
       
  1554 					default:
       
  1555 						break;
       
  1556 					}
       
  1557 				}
       
  1558 			// CPHS Implementation of message waiting indicator (CPHS Phase 2)
       
  1559 			TGsmSmsTelNumber address;
       
  1560 			aSmsMessage.ParsedToFromAddress(address);
       
  1561 
       
  1562 			//as far as I can see you can't get the npi from the address. (==0?)
       
  1563 			//might want to compare the content of the tel number with the spec to make sure
       
  1564 			//that we are dealing with a cphs message !
       
  1565 
       
  1566 			if((address.iTypeOfAddress.TON() == EGsmSmsTONAlphaNumeric)  &&
       
  1567 				(address.iTelNumber.Length() == 4) &&
       
  1568 					((address.iTelNumber[2] & 0x7E) == 0x10)  &&// x001 000x constant value
       
  1569 						((address.iTelNumber[3] & 0x7E) == 0x00) )// x000 000x constant value
       
  1570 						return ETrue; // This means that the SMS received is a Message Waiting indication
       
  1571 			return EFalse;
       
  1572 			}
       
  1573 
       
  1574 		case (ESmsAddrStatusReport):
       
  1575 			{
       
  1576 			LOGSMSPROT1("TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationDiscardMessage:");
       
  1577 			if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
       
  1578 				return ETrue;
       
  1579 			}
       
  1580 			break;
       
  1581 		case (ESmsAddrMatchIEI):
       
  1582 			{
       
  1583 			return (MatchInformationElement(aSmsMessage,CSmsInformationElement::TSmsInformationElementIdentifier(aSmsAddr.IdentifierMatch())));
       
  1584 			}
       
  1585 		case (ESmsAddrMatchText):
       
  1586 			{
       
  1587 			TBuf<TSmsAddr::EMaxTextMatchLength> textMatch;
       
  1588 			textMatch.Copy(aSmsAddr.TextMatch());
       
  1589 			TBuf<TSmsAddr::EMaxTextMatchLength> smsMsgBuf;
       
  1590 			TInt bufferLen = aSmsMessage.Buffer().Length();
       
  1591 			bufferLen = Min(bufferLen,textMatch.Length());
       
  1592 			aSmsMessage.Buffer().Extract(smsMsgBuf,0,bufferLen);
       
  1593 			if (textMatch.CompareF(smsMsgBuf)==KErrNone)
       
  1594 				return ETrue;
       
  1595 			return EFalse;
       
  1596 			}
       
  1597 		case (ESmsAddrEmail):
       
  1598 			{
       
  1599 			if(aSmsMessage.IsEmailHeader())
       
  1600 	 			return ETrue;
       
  1601 			break;
       
  1602 			}
       
  1603 		case (ESmsAddrRecvAny):
       
  1604 			return ETrue;
       
  1605 		default:
       
  1606 			return EFalse;
       
  1607 
       
  1608 		}
       
  1609 	return EFalse;
       
  1610 	} // CSmsProtocol::IsMatch
       
  1611 
       
  1612 /**
       
  1613  *  Static function checks if a message contains a given port.  Used by IsMatch()
       
  1614  *  to determine if an SMS address type matches an application port.
       
  1615  *  
       
  1616  */
       
  1617 TBool CSmsProtocol::MatchApplicationPort(const CSmsMessage& aSmsMessage,TUint aPort,TBool a16Bit)
       
  1618 	{
       
  1619 	LOGSMSPROT1("CSmsProtocol::MatchApplicationPort");
       
  1620 
       
  1621 	if (!aSmsMessage.SmsPDU().UserDataPresent())
       
  1622 		return EFalse;
       
  1623 
       
  1624 	const CSmsPDU& Pdu = aSmsMessage.SmsPDU();
       
  1625 	TInt ToPort = 0;
       
  1626 	TInt FromPort = 0;
       
  1627 	TBool Is16BitPorts = 0;
       
  1628 
       
  1629     Pdu.ApplicationPortAddressing(ToPort,FromPort,&Is16BitPorts);
       
  1630 	if((TInt)aPort == ToPort && Is16BitPorts == a16Bit) return ETrue;
       
  1631 
       
  1632 	return EFalse;
       
  1633 	} // CSmsProtocol::MatchApplicationPort
       
  1634 
       
  1635 
       
  1636 /**
       
  1637  *  Static function checks if a message contains a given information element.  Used by IsMatch()
       
  1638  *  to determine if an SMS address type matches a message.
       
  1639  *  
       
  1640  */
       
  1641 TBool CSmsProtocol::MatchInformationElement(const CSmsMessage& aSmsMessage, CSmsInformationElement::TSmsInformationElementIdentifier aIeVal)
       
  1642 	{
       
  1643 	LOGSMSPROT1("CSmsProtocol::MatchInformationElement");
       
  1644 
       
  1645 	if (!aSmsMessage.SmsPDU().UserDataPresent())
       
  1646 		return EFalse;
       
  1647 
       
  1648 	TInt count=aSmsMessage.SmsPDU().UserData().NumInformationElements();
       
  1649 	for (TInt i=0; i<count; i++)
       
  1650 		{
       
  1651 		TInt identifier=aSmsMessage.SmsPDU().UserData().InformationElement(i).Identifier();
       
  1652 		if (identifier==aIeVal)
       
  1653 			return ETrue;
       
  1654 		}
       
  1655 	return EFalse;
       
  1656 	} // CSmsProtocol::MatchInformationElement
       
  1657 
       
  1658 
       
  1659 /**
       
  1660  *  Searches the reassembly store for complete messages and tries to match
       
  1661  *  them to an observer.  If a match is found the message is passed to
       
  1662  *  the observer and deleted from the store, otherwise it's left in store.
       
  1663  *  Called when a new observer is added or a PDU has been received and
       
  1664  *  successfully processed.
       
  1665  *  
       
  1666  */
       
  1667 void CSmsProtocol::ProcessCompleteSmsMessagesL()
       
  1668 	{
       
  1669 	LOGSMSPROT1("CSmsProtocol::ProcessCompleteSmsMessagesL");
       
  1670 
       
  1671 	if(iPhoneEnumerationObserver) return;
       
  1672 
       
  1673 	iReassemblyStore->ProcessCompleteSmsMessagesL(*this, iSmsPDURead->CurrentMessage());
       
  1674 	} // CSmsProtocol::ProcessCompleteSmsMessagesL
       
  1675 
       
  1676 
       
  1677 /**
       
  1678  *  Called when the state machine for processing a received PDU has completed.
       
  1679  *  The reassembly store access count is incremented and purged if it exceeds
       
  1680  *  CSmsProtocol::KNumSARStoreAccessesBeforePurging.
       
  1681  *  The completed entry is removed from the processing queue and if the queue is
       
  1682  *  not empty, and the processing state machinery is started for the next entry.
       
  1683  *  
       
  1684  */
       
  1685 void CSmsProtocol::MessageReadedSuccessfully()
       
  1686 	{
       
  1687 	LOGSMSPROT1("CSmsProtocol::MessageReadedSuccessfully");
       
  1688 	TRAPD(ret,ProcessCompleteSmsMessagesL());
       
  1689 	if(ret!=KErrNone)
       
  1690 		{
       
  1691 		LOGSMSPROT2("WARNING! CSmsProtocol::ProcessCompleteSmsMessagesL left with %d", ret);
       
  1692 		}
       
  1693 
       
  1694 	iNumReassemblyStoreAccesses++;
       
  1695 	if(iNumReassemblyStoreAccesses>=KNumSARStoreAccessesBeforePurging)
       
  1696 		{
       
  1697 		TRAP(ret, iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(),EFalse));
       
  1698 
       
  1699 		if(ret!=KErrNone)
       
  1700 			{
       
  1701 			LOGSMSPROT2("WARNING! iReassemblyStore->PurgeL left with %d", ret);
       
  1702 			}
       
  1703 
       
  1704 		iNumReassemblyStoreAccesses=0;
       
  1705 		}
       
  1706 	if(CheckPoweredUp() == KErrNone )
       
  1707 		iSmsPDURead->ResumeSmsReception();
       
  1708 	} // CSmsProtocol::MessageReadedSuccessfully
       
  1709 
       
  1710 
       
  1711 /**
       
  1712  *  method to delete sms from the reastore
       
  1713  */
       
  1714 void CSmsProtocol::DeleteSMSFromReaStoreL(const CSmsMessage& aSmsMessage)
       
  1715 	{
       
  1716 	LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL entry");
       
  1717 	if (aSmsMessage.Type() == CSmsPDU::ESmsStatusReport)
       
  1718 	{
       
  1719 		LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL it's SR");
       
  1720 		return;
       
  1721 	}
       
  1722 
       
  1723 	TSmsDataCodingScheme::TSmsClass  msgClass;
       
  1724 
       
  1725 	if (aSmsMessage.SmsPDU().DataCodingSchemePresent()	&&	aSmsMessage.SmsPDU().Class(msgClass))
       
  1726 		{
       
  1727 		if (msgClass == TSmsDataCodingScheme::ESmsClass0)
       
  1728 			{
       
  1729 			if (!aSmsMessage.IsComplete())
       
  1730 				{
       
  1731 				CIncompleteClass0MessageInfo& incompleteClass0MsgInfo = (CIncompleteClass0MessageInfo &) aSmsMessage.GetOperationsForNonIEL(ESmsIncompleteClass0MessageParameter);
       
  1732 				// Retrieve incomplete class 0 message information & process
       
  1733 				TInt startPos, endPos;
       
  1734 				TBool isLastMessage;
       
  1735 				incompleteClass0MsgInfo.GetIncompleteMessageInfoL(startPos, endPos, isLastMessage);
       
  1736 				if (!isLastMessage)
       
  1737 					{
       
  1738 					/*
       
  1739 					Only in this condition set incomplete message as forwarded
       
  1740 					which internally will remove the PDUs from pre-allocated file.
       
  1741 					*/
       
  1742 					LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL Incomplete Message Not last segment");
       
  1743 					iReassemblyStore->SetIncompleteMessageForwardedToClientL(aSmsMessage);
       
  1744 					return;
       
  1745 					}
       
  1746 				}
       
  1747 			}
       
  1748 		}
       
  1749 	iReassemblyStore->DeleteMessageL(aSmsMessage, ETrue);
       
  1750 
       
  1751 	LOGSMSPROT1("CSmsProtocol::DeleteSMSFromReaStoreL exit");
       
  1752 	} // CSmsProtocol::DeleteSMSFromReaStoreL
       
  1753 
       
  1754 
       
  1755 /**
       
  1756  *  Used to notify observer of the change in state of the modem connection.
       
  1757  *  Send only observers are not notified (why?).
       
  1758  */
       
  1759 void CSmsProtocol::NotifyMessageObservers(TInt aStatus)
       
  1760 	{
       
  1761 	LOGSMSPROT1("CSmsProtocol::NotifyMessageObservers");
       
  1762 
       
  1763 	TInt count=iSmsMessageObserverList.Count();
       
  1764 	LOGSMSPROT3("CSmsProtocol::NotifyMessageObservers [count=%d, aStatus=%d]",count, aStatus);
       
  1765 	for (TInt index=0; index<count; index++)
       
  1766 		{
       
  1767 		MSmsMessageObserver* observer=iSmsMessageObserverList[index];
       
  1768 		TSmsAddrFamily fam = observer->GetLocalAddress().SmsAddrFamily();
       
  1769 	    LOGSMSPROT2("CSmsProtocol::NotifyMessageObservers [family=%d]", fam);
       
  1770 		switch (fam)
       
  1771 			{
       
  1772 			case ESmsAddrMessageIndication:
       
  1773 			case ESmsAddrStatusReport:
       
  1774 			case ESmsAddrMatchIEI:
       
  1775 			case ESmsAddrMatchText:
       
  1776 			case ESmsAddrEmail:
       
  1777 			case ESmsAddrRecvAny:
       
  1778 			case ESmsAddrLocalOperation:
       
  1779 			case ESmsAddrApplication8BitPort:
       
  1780 	        case ESmsAddrApplication16BitPort:
       
  1781 				{
       
  1782 				observer->ModemNotificationCompleted(aStatus);
       
  1783 				break;
       
  1784 				}
       
  1785 			case ESmsAddrSendOnly:
       
  1786 			case ESmsAddrUnbound:
       
  1787 				break;
       
  1788 			default:
       
  1789 				SmspPanic(ESmspPanicAddrFamilyNotAllowed);
       
  1790 			}
       
  1791 		}
       
  1792 	} // CSmsProtocol::NotifyMessageObservers
       
  1793 
       
  1794 
       
  1795 void CSmsProtocol::PowerUp()
       
  1796 	{
       
  1797 	LOGSMSPROT2("CSmsProtocol::PowerUp [iState=%d]", iState);
       
  1798 	__ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
       
  1799 
       
  1800 	if (iState == EPoweredDown)
       
  1801 		{
       
  1802 		TRAPD(err, DoPowerUpL());
       
  1803 
       
  1804 		if (err != KErrNone)
       
  1805 			{
       
  1806 			LOGSMSPROT3("WARNING: CSmsProtocol::DoPowerUpL left [err=%d iState=%d]", err, iState);
       
  1807 			__ASSERT_DEBUG(iState == EPoweredDown, SmspPanic(KSmspPanicUnexpectedState));
       
  1808 			PowerDown();
       
  1809 			}
       
  1810 		}
       
  1811 	} // CSmsProtocol::PowerUp
       
  1812 
       
  1813 
       
  1814 /**
       
  1815  *  Handles the event of the modem powering on (when it had been powered off).
       
  1816  *  Does the following...
       
  1817  *  - The TSY loaded
       
  1818  *  - ETEL resource handles initialised
       
  1819  *  - ETEL parameters set and retrieved
       
  1820  *  - A number of state machines started
       
  1821  *  
       
  1822  */
       
  1823 void CSmsProtocol::DoPowerUpL()
       
  1824 	{
       
  1825 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL");
       
  1826 	__ASSERT_DEBUG(iModemDetection==RPhone::EDetectedPresent,SmspPanic(KSmspPhoneHasNotTurnedOn));
       
  1827 
       
  1828 	//Open the segmentation and reassembly stores
       
  1829 
       
  1830 	iReassemblyStore->OpenStoreL();
       
  1831 	iSegmentationStore->OpenStoreL();
       
  1832 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
       
  1833 	iReassemblyStore->PurgeL(iSmsSettings.ReassemblyLifetime(), ETrue);
       
  1834 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
       
  1835 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL Start");
       
  1836 	iSegmentationStore->PurgeL(iSmsSettings.KSegmentationLifetimeMultiplier(),EFalse);
       
  1837 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL->PurgeL End");
       
  1838 
       
  1839 	// Connect to ETEL and load the TSY
       
  1840 	User::LeaveIfError(iTelServer.Connect());
       
  1841 	User::LeaveIfError(iTelServer.LoadPhoneModule(iGsmTsyName));
       
  1842 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL  Connected to Etel");
       
  1843 
       
  1844 	// Find the phone corresponding to this TSY and open a number of handles on it
       
  1845 	TInt numPhones;
       
  1846 	User::LeaveIfError(iTelServer.EnumeratePhones(numPhones));
       
  1847 	TInt i=0;
       
  1848 	for (; i<numPhones; i++)
       
  1849 		{
       
  1850 		RTelServer::TPhoneInfo info;
       
  1851 		User::LeaveIfError(iTelServer.GetPhoneInfo(i,info));
       
  1852 		TName tsyName;
       
  1853 		User::LeaveIfError(iTelServer.GetTsyName(i,tsyName));
       
  1854 		if (tsyName.CompareF(iGsmTsyName)==KErrNone)
       
  1855 			{
       
  1856 			User::LeaveIfError(iGsmPhone.Open(iTelServer,info.iName));
       
  1857 			User::LeaveIfError(iEnumerationPhone.Open(iTelServer,info.iName));
       
  1858 			User::LeaveIfError(iWritePhone.Open(iTelServer,info.iName));
       
  1859 			break;
       
  1860 			}
       
  1861 		}
       
  1862 	__ASSERT_DEBUG(i<numPhones,SmspPanic(ESmspPhoneNotFound));
       
  1863 	if (iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended)!=KErrNone)
       
  1864 		User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorBasic));
       
  1865 	User::LeaveIfError(iSmsMessaging.Open(iGsmPhone));
       
  1866 
       
  1867 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL  Opened TSY handles");
       
  1868 
       
  1869 	if (iSmsPhoneEnumeration == NULL)
       
  1870 		iSmsPhoneEnumeration=CSmsPhoneEnumeration::NewL(*this, iSmsSettings, *iReassemblyStore, *iSegmentationStore, iEnumerationPhone, KSmsSessionPriority, *iSmsMonitorDiskSpace);
       
  1871 
       
  1872 	if (iWriteQueue == NULL)
       
  1873 		iWriteQueue = CSmspWriteQueue::NewL(*this, iSmsSettings, iWritePhone,*iSegmentationStore, KSmsSessionPriority);
       
  1874 
       
  1875 	if (iDeleteQueue == NULL)
       
  1876 		iDeleteQueue = CSmspDeleteQueue::NewL(*this,iSmsSettings,iSmsMessaging, KSmsSessionPriority);
       
  1877 
       
  1878 	// Start state machines
       
  1879 	iSmsPhoneInitialization->Start();
       
  1880 
       
  1881 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL  Started state machines");
       
  1882 
       
  1883 	NotifyMessageObservers(KIoctlSelectModemPresent);
       
  1884 	LOGSMSPROT1("CSmsProtocol::DoPowerUpL  Notified message observers");
       
  1885 
       
  1886 
       
  1887 	// Process any waiting messages
       
  1888 	ProcessCompleteSmsMessagesL();
       
  1889 
       
  1890 	iState = EPoweredUp;
       
  1891 	} // CSmsProtocol::DoPowerUpL
       
  1892 
       
  1893 
       
  1894 /**
       
  1895  *  Handles the event of the modem powering off (when it had been powered on).
       
  1896  *  Does the following...
       
  1897  *  - State mechines cancelled
       
  1898  *  - Close TSY handles
       
  1899  *  - Disconnect from Etel
       
  1900  *  
       
  1901  *  This function will also be called if PowerUpL() leaves
       
  1902  */
       
  1903 void CSmsProtocol::PowerDown()
       
  1904     {
       
  1905     LOGSMSPROT1("CSmsProtocol::PowerDown");
       
  1906     
       
  1907     iSetBearer->Cancel();
       
  1908     iReceiveMode->Cancel();
       
  1909     
       
  1910     iSendQueue->Cancel();
       
  1911     
       
  1912     iSmsPDURead->Cancel();
       
  1913     
       
  1914     iSmsMonitorDiskSpace->Cancel();
       
  1915     
       
  1916     delete iSmsPhoneEnumeration; //must be deleted because uses iSmsMessaging which is soon closed
       
  1917     iSmsPhoneEnumeration = NULL;
       
  1918     
       
  1919     iSmsPhoneInitialization->Cancel();
       
  1920     
       
  1921     if( iSmsReadParams != NULL )
       
  1922         {
       
  1923         iSmsReadParams->Cancel();
       
  1924         }
       
  1925     if( iSmsWriteParams != NULL )
       
  1926         {
       
  1927         iSmsWriteParams->Cancel();
       
  1928         }
       
  1929     
       
  1930     delete iWriteQueue; //must be deleted because uses iSmsMessaging which is soon closed
       
  1931     iWriteQueue = NULL;
       
  1932     
       
  1933     delete iDeleteQueue; //must be deleted because uses iSmsMessaging which is soon closed
       
  1934     iDeleteQueue = NULL;
       
  1935     
       
  1936     LOGSMSPROT1("CSmsProtocol::PowerDown  Cancelled state machines");
       
  1937     
       
  1938     NotifyMessageObservers(KIoctlSelectModemNotPresent);
       
  1939     LOGSMSPROT1("CSmsProtocol::PowerDown  Notified message observers");
       
  1940     
       
  1941     // Close TSY handles
       
  1942     iSmsMessaging.Close();
       
  1943     iGsmPhone.Close();
       
  1944     iEnumerationPhone.Close();
       
  1945     iWritePhone.Close();
       
  1946     LOGSMSPROT1("CSmsProtocol::PowerDown  Closed TSY handles");
       
  1947     
       
  1948     // Disconnect from Etel
       
  1949     iTelServer.Close();
       
  1950     LOGSMSPROT1("CSmsProtocol::PowerDown  Disconnected from Etel");
       
  1951     
       
  1952     iReassemblyStore->Close();
       
  1953     iSegmentationStore->Close();
       
  1954     
       
  1955     iState = EPoweredDown;
       
  1956     }
       
  1957 
       
  1958 void CSmsProtocol::CloseNowWrap()
       
  1959     {
       
  1960     // Ignore in code coverage - called when PDU delete queue is not 
       
  1961     // empty and SMS stack is closing down - can only get this situation
       
  1962     // when the PDU delete has been initiated by the SMS stack itself 
       
  1963     // (rather than the client) and the PDUs are still being deleted 
       
  1964     // when last client disconnects.
       
  1965     BULLSEYE_OFF
       
  1966     LOGSMSPROT1("CSmsProtocol::CloseNowWrap()");
       
  1967     
       
  1968     if( iDeleteQueue == NULL || !iDeleteQueue->IsActive() )
       
  1969         {
       
  1970         CloseNow();
       
  1971         }
       
  1972     BULLSEYE_RESTORE
       
  1973     }
       
  1974 
       
  1975 void CSmsProtocol::HandleBackupOrRestoreStartingL()
       
  1976     {
       
  1977     LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreStartingL [ModemState=%d]",  iSmsModemNotification->ModemState());
       
  1978     PowerDown();
       
  1979     }
       
  1980 
       
  1981 void CSmsProtocol::HandleBackupOrRestoreCompleteL()
       
  1982     {
       
  1983     LOGSMSPROT2("CSmsProtocol::HandleBackupOrRestoreCompleteL [ModemState=%d]", iSmsModemNotification->ModemState());
       
  1984     
       
  1985     if (iModemDetection == RPhone::EDetectedPresent)
       
  1986         {
       
  1987         PowerUp();
       
  1988         }
       
  1989     }
       
  1990 
       
  1991 /**
       
  1992  *  Set the sap port number
       
  1993  */
       
  1994 TBool CSmsProtocol::AllocateLocalAddress(TSmsAddr& aAddr)
       
  1995 	{
       
  1996     LOGSMSPROT1("CSmsProtocol::AllocateLocalAddressL");
       
  1997 
       
  1998 	TBool found=EFalse;
       
  1999 	TUint count=0,attempts=0;
       
  2000 	TSmsAddr locAddr=aAddr;
       
  2001 
       
  2002 	if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
       
  2003 		{
       
  2004 		count =KMax8BitPortNumber-KMin8BitPortNumber+1;
       
  2005 		}
       
  2006 	else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
       
  2007 		{
       
  2008 		count =KMax16BitPortNumber-KMin16BitPortNumber+1;
       
  2009 		}
       
  2010 
       
  2011 	for(;!found && attempts < count; ++attempts)
       
  2012 		{
       
  2013 		if(locAddr.SmsAddrFamily() == ESmsAddrApplication8BitPort )
       
  2014 			{
       
  2015 			locAddr.SetPort(iNext8BitPort++);
       
  2016 			if(iNext8BitPort > KMax8BitPortNumber)iNext8BitPort=KMin8BitPortNumber;
       
  2017 			}
       
  2018 		else if(locAddr.SmsAddrFamily() == ESmsAddrApplication16BitPort )
       
  2019 			{
       
  2020 			locAddr.SetPort(iNext16BitPort++);
       
  2021 			if(iNext16BitPort > KMax16BitPortNumber)iNext8BitPort=KMin16BitPortNumber;
       
  2022 			}
       
  2023 		if(!SmsAddrIsAlreadyUsed(NULL,locAddr))found=ETrue;
       
  2024 		}
       
  2025 
       
  2026 	if(found)
       
  2027 		{
       
  2028 		aAddr=locAddr;
       
  2029 		}
       
  2030 	return found;
       
  2031 	} // CSmsProtocol::AllocateLocalAddress
       
  2032 
       
  2033 /**
       
  2034  *  Static method that returns the boolean value indicating whether the given
       
  2035  *  CSmsMessage is for application port.
       
  2036  *  This function is an utility function which determines the passed sms message
       
  2037  *  is for application port or not. This function is also used in CFacadeSmsReassemblyStore class.
       
  2038  *
       
  2039  *  @param aSmsMessage reference to CSmsMessage object.
       
  2040  *  
       
  2041  */
       
  2042 TBool CSmsProtocol::IsAppPortSMS(const CSmsMessage& aSmsMessage)
       
  2043 	{
       
  2044 	LOGSMSPROT1("CSmsProtocol::IsAppPortSMS()");
       
  2045 
       
  2046 	TSmsAddr addr;
       
  2047 	addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
       
  2048 	addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit);
       
  2049 	if (IsMatch(addr,aSmsMessage))
       
  2050 		{
       
  2051 		return ETrue;
       
  2052 		}
       
  2053 
       
  2054 	addr.SetSmsAddrFamily(ESmsAddrMatchIEI);
       
  2055 	addr.SetIdentifierMatch(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit);
       
  2056 	if (IsMatch(addr,aSmsMessage))
       
  2057 		{
       
  2058 		return ETrue;
       
  2059 		}
       
  2060 
       
  2061 	addr.SetSmsAddrFamily(ESmsAddrMatchText);
       
  2062 	addr.SetTextMatch(_L8("//SCK"));
       
  2063 	if (IsMatch(addr,aSmsMessage))
       
  2064 		{
       
  2065 		return ETrue;
       
  2066 		}
       
  2067 
       
  2068 	return EFalse;
       
  2069 	} // CSmsProtocol::IsAppPortSMS
       
  2070 
       
  2071 
       
  2072 const RMobilePhone::TMobilePhoneNetworkInfoV1& CSmsProtocol::NetworkInfo() const
       
  2073 	{
       
  2074 	LOGSMSPROT1("CSmsProtocol::NetworkInfo()");
       
  2075 
       
  2076 	return iSmsPhoneInitialization->NetworkInfo();
       
  2077 	} // CSmsProtocol::NetworkInfo
       
  2078 
       
  2079 
       
  2080 TBool CSmsProtocol::NetworkInfoAvailable() const
       
  2081 	{
       
  2082 	LOGSMSPROT1("CSmsProtocol::NetworkInfoAvailable()");
       
  2083 
       
  2084 	return iSmsPhoneInitialization->NetworkInfoAvailable();
       
  2085 	} // CSmsProtocol::NetworkInfoAvailable
       
  2086 
       
  2087 
       
  2088 // implementation of CSmsProtocolBootTimer
       
  2089 //
       
  2090 
       
  2091 /**
       
  2092  *  2 phase contructor
       
  2093  *  
       
  2094  *  @param aActive Reference to an CSmsProtocol object
       
  2095  */
       
  2096 CSmsProtocolBootTimer* CSmsProtocolBootTimer::NewL(CSmsProtocol& aSmsProtocol)
       
  2097     {
       
  2098     LOGSMSPROT1("CSmsProtocolBootTimer::NewL");
       
  2099     
       
  2100     CSmsProtocolBootTimer* self = new(ELeave) CSmsProtocolBootTimer(aSmsProtocol);
       
  2101     CleanupStack::PushL(self);
       
  2102     self->ConstructL();
       
  2103     CleanupStack::Pop(self);
       
  2104     return self;
       
  2105     }
       
  2106 
       
  2107 /**
       
  2108  *  D'tor
       
  2109  */
       
  2110 CSmsProtocolBootTimer::~CSmsProtocolBootTimer()
       
  2111     {
       
  2112     Cancel();
       
  2113     }
       
  2114 
       
  2115 /**
       
  2116  *  Start a timeout specified in aTimeIntervalMicroSeconds32
       
  2117  */
       
  2118 void CSmsProtocolBootTimer::Start(const TTimeIntervalMicroSeconds32& aTimeIntervalMicroSeconds32)
       
  2119 	{
       
  2120 	LOGSMSPROT1("CSmsProtocolBootTimer::Start");
       
  2121 	After(aTimeIntervalMicroSeconds32);
       
  2122 	}
       
  2123 
       
  2124 /**
       
  2125  *  C'tor
       
  2126  */
       
  2127 CSmsProtocolBootTimer::CSmsProtocolBootTimer(CSmsProtocol& aSmsProtocol)
       
  2128 : CTimer(KSmsSessionPriority), iSmsProtocol(aSmsProtocol)
       
  2129     {
       
  2130     CActiveScheduler::Add(this);
       
  2131     }
       
  2132 
       
  2133 /**
       
  2134  *  Timer completed - cancel the observer
       
  2135  */
       
  2136 void CSmsProtocolBootTimer::RunL()
       
  2137     {
       
  2138     LOGSMSPROT2("CSmsProtocolBootTimer::RunL [iStatus=%d]", iStatus.Int() );
       
  2139     iSmsProtocol.MessageReadedSuccessfully();
       
  2140     }