smsprotocols/smsstack/smsprot/Src/smspenum.cpp
changeset 0 3553901f7fa8
child 14 7ef16719d8cb
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 1999-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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18 */
       
    19 
       
    20 #include "smspenum.h"
       
    21 #include "smspproc.h"
       
    22 #include "smsuset.h"
       
    23 #include "smspmain.h"
       
    24 #include "smspstor.h"
       
    25 #include "Gsmumsg.h"
       
    26 #include "SmsuTimer.h"
       
    27 #include "exterror.h"
       
    28 
       
    29 // constant used to handle inconsistency between slots used and total slots
       
    30 const TInt KSmsDefaultTotalMessageStoreSlots = 50;
       
    31 
       
    32 
       
    33 /**
       
    34  *  Creates new CSmsStoreRead instance
       
    35  *  
       
    36  *  @param aSmsComm Used to set CSmsPDUProcess object
       
    37  *  @param aSmsSettings Used to start CSmsTimeout object
       
    38  *  @param aSmsMessaging Used to get message store info and open store
       
    39  *  @param aReassemblyStore Used to set CSmsPDUProcess object
       
    40  *  @param aSegmentationStore Used to set CSmsPDUProcess object
       
    41  *  @param aPriority Used to set CSmsPDUProcess object
       
    42  *  @param aSmsMonitorDiskSpace Used to set CSmsPDUProcess object
       
    43  *  
       
    44  *  @leave Leaves if ContructL() leaves, or not enough memory is available.
       
    45  *  @return a new CSmsStoreRead object.
       
    46  */
       
    47 CSmsStoreRead* CSmsStoreRead::NewL(MSmsComm& aSmsComm,
       
    48 								   const TSmsSettings& aSmsSettings,
       
    49 								   RMobileSmsMessaging& aSmsMessaging,
       
    50 								   CFacadeSmsReassemblyStore& aReassemblyStore,
       
    51 								   CSmsSegmentationStore& aSegmentationStore,
       
    52 								   TInt aPriority,
       
    53 								   CSmsMonitorDiskSpace& aSmsMonitorDiskSpace)
       
    54 	{
       
    55 	LOGSMSPROT1("CSmsStoreRead::NewL()");
       
    56 
       
    57 	CSmsStoreRead* smsStoreRead = new ( ELeave ) CSmsStoreRead(aSmsComm,
       
    58 															   aSmsSettings,
       
    59 															   aSmsMessaging,
       
    60 															   aReassemblyStore,
       
    61 															   aSegmentationStore,
       
    62 															   aPriority,
       
    63 															   aSmsMonitorDiskSpace);
       
    64 	CleanupStack::PushL(smsStoreRead);
       
    65 	smsStoreRead->ConstructL();
       
    66 	CleanupStack::Pop(smsStoreRead);
       
    67 	return smsStoreRead;
       
    68 	} // CSmsStoreRead::NewL
       
    69 
       
    70 
       
    71 /**
       
    72  *  Constructor
       
    73  *  
       
    74  *  @param aSmsComm Used to set CSmsPDUProcess object
       
    75  *  @param aSmsSettings Used to start CSmsTimeout object
       
    76  *  @param aSmsMessaging Used to get message store info and open store
       
    77  *  @param aReassemblyStore Used to  set CSmsPDUProcess object
       
    78  *  @param aSegmentationStore Used to  set CSmsPDUProcess object
       
    79  *  @param aPriority Used to  set CSmsPDUProcess object
       
    80  *  @param aSmsMonitorDiskSpace Used to set CSmsPDUProcess object
       
    81  */
       
    82 CSmsStoreRead::CSmsStoreRead(MSmsComm& aSmsComm,
       
    83 							 const TSmsSettings& aSmsSettings,
       
    84 							 RMobileSmsMessaging& aSmsMessaging,
       
    85 							 CFacadeSmsReassemblyStore& aReassemblyStore,
       
    86 							 CSmsSegmentationStore& aSegmentationStore,
       
    87 							 TInt aPriority,
       
    88 							 CSmsMonitorDiskSpace& aSmsMonitorDiskSpace)
       
    89   : CSmsuActiveBase(aPriority),
       
    90 	iState(ESmsStoreReadIdle),
       
    91 	iSmsComm(aSmsComm),
       
    92 	iSmsSettings(aSmsSettings),
       
    93 	iSmsMessaging(aSmsMessaging),
       
    94 	iReassemblyStore(aReassemblyStore),
       
    95 	iSegmentationStore(aSegmentationStore),
       
    96 	iSmsMonitorDiskSpace(aSmsMonitorDiskSpace),
       
    97 	iStoreInfoPckg(iStoreInfo),
       
    98 	iEntryV1Pckg(iSmsEntry)
       
    99 	{
       
   100 	} // CSmsStoreRead::CSmsStoreRead
       
   101 
       
   102 
       
   103 /**
       
   104  *  Calls ConstructTimeoutL from the class CSmsuActiveBase
       
   105  */
       
   106 void CSmsStoreRead::ConstructL()
       
   107 	{
       
   108 	LOGSMSPROT1("CSmsStoreRead::ConstructL()");
       
   109 
       
   110 	ConstructTimeoutL();
       
   111 	ReadConfigurableSmsSettingsL();
       
   112 	} // CSmsStoreRead::ConstructL
       
   113 
       
   114 
       
   115 /**
       
   116  *  
       
   117  *  Synopsis:
       
   118  *  
       
   119  *  Certain pieces of Release 6 functionality cause breaks to existing functionality.
       
   120  *  These are disabled by default, but can be configured as follows.
       
   121  *  
       
   122  *  (1) Class 2 messages on the SIM will be deleted when the DCS
       
   123  *  byte specifies that "the message is specified for automatic deletion"
       
   124  *  See 23.038 Section 4, "SMS Data Coding Scheme" and when the following
       
   125  *  text segment is included in the smswap.sms.ESK file:
       
   126  *  
       
   127  *  [Release6Configurability]
       
   128  *  AutomaticDeletionOfClass2= 1
       
   129  *  
       
   130  *  (2) Class 2 messages on the SIM will be deleted and will not be
       
   131  *  forwarded to the client when the PID  byte specifies that the
       
   132  *  message is type 0 as per 23.40 v6.5.0  9.2.3.9 and when the
       
   133  *  following text segment is included in the  smswap.sms.ESK file:
       
   134  *  
       
   135  *  [Release6Configurability]
       
   136  *  DiscardType0_Class2Message= 1
       
   137  *  
       
   138  *  
       
   139  *  (3) Class 0 messages will not be forwarded to the SMS Stack client
       
   140  *  when the PID byte specifies that the message is type 0 as per
       
   141  *  23.40 v6.5.0 9.2.3.9 and when the following text segment is included
       
   142  *  in the smswap.sms.esk file:
       
   143  *  [Release6Configurability]
       
   144  *  DiscardType0_Class0Message= 1
       
   145  *  
       
   146  *  Note: The Release 6 Configuration Option tag [Release6Configurability]
       
   147  *  must only be specified once in the configuration file, even if
       
   148  *  more than one Release 6 configuration option is specified. For example:
       
   149  *  [Release6Configurability]
       
   150  *  AutomaticDeletionOfClass2=  1
       
   151  *  DiscardType0_Class2Message= 1
       
   152  *  DiscardType0_Class0Message= 1
       
   153  *  
       
   154  */
       
   155 void CSmsStoreRead::ReadConfigurableSmsSettingsL()
       
   156     {
       
   157     LOGSMSPROT1("CSmsStoreRead::ReadConfigurableSmsSettingsL()");
       
   158 
       
   159     CESockIniData*  ini = NULL;
       
   160     TRAPD(ret, ini=CESockIniData::NewL(_L("smswap.sms.esk")));
       
   161     if(ret!=KErrNone)
       
   162         {
       
   163         LOGSMSPROT2("CSmsStoreRead::ReadConfigurableSmsSettingsL(): ret=%d", ret);
       
   164         User::Leave(ret);
       
   165         }
       
   166 
       
   167     CleanupStack::PushL(ini);
       
   168     
       
   169     //
       
   170     // Save Release 6 options...
       
   171     //
       
   172     TBool status(EFalse);
       
   173 
       
   174     if (ini->FindVar(_L("Release6Configurability"),
       
   175     				 _L("AutomaticDeletionOfClass2"), status))
       
   176     	{
       
   177         iConfigAutomaticDeletionForClass2 = status;
       
   178         }
       
   179 
       
   180 	LOGSMSPROT2("CSmsStoreRead::ReadConfigurableSmsSettingsL(): iConfigAutomaticDeletionForClass2=%d",
       
   181 				iConfigAutomaticDeletionForClass2);
       
   182 
       
   183     if (ini->FindVar(_L("Release6Configurability"),
       
   184     				 _L("DiscardType0_Class2Message"), status))
       
   185     	{
       
   186         iConfigDiscardingType0Class2 = status;
       
   187         }
       
   188 
       
   189 	LOGSMSPROT2("CSmsStoreRead::ReadConfigurableSmsSettingsL(): iConfigDiscardingType0Class2=%d",
       
   190 				iConfigDiscardingType0Class2);
       
   191 
       
   192     if (ini->FindVar(_L("Release6Configurability"),
       
   193     				 _L("DiscardType0_Class0Message"), status))
       
   194     	{
       
   195         iConfigDiscardingType0Class0 = status;
       
   196         }
       
   197 
       
   198 	LOGSMSPROT2("CSmsStoreRead::ReadConfigurableSmsSettingsL(): iConfigDiscardingType0Class0=%d",
       
   199 				iConfigDiscardingType0Class0);
       
   200 
       
   201     CleanupStack::PopAndDestroy(ini);
       
   202     } // CSmsStoreRead::ReadConfigurableSmsSettingsL
       
   203 
       
   204 
       
   205 /**
       
   206  *  Starts CSmsStoreRead active object
       
   207  *  Calls GetMessageStoreInfo method from the MM API
       
   208  *  
       
   209  *  @param aStatus Reguest status
       
   210  *  @param aStoreIndex Index to the store to be read
       
   211  */
       
   212 void CSmsStoreRead::Start( TRequestStatus& aStatus, TInt aStoreIndex )
       
   213 	{
       
   214 	LOGSMSPROT1("CSmsStoreRead::Start()");
       
   215 
       
   216 	iState = ESmsStoreReadGettingStoreInfo;
       
   217 	// Initialises current slot index
       
   218 	iCurrentSlotIndex = 0;
       
   219 
       
   220 	// Gets current store info
       
   221 	iSmsMessaging.GetMessageStoreInfo( iStatus, aStoreIndex, iStoreInfoPckg );
       
   222 
       
   223 	Queue(aStatus);
       
   224 	TimedSetActive(iSmsSettings.Timeout());
       
   225 	} // CSmsStoreRead::Start
       
   226 
       
   227 
       
   228 /**
       
   229  *  Called by CSmsuActive object to run this object
       
   230  *  Cancels timeout timer
       
   231  *  State ESmsStoreReadGettingStoreInfo:
       
   232  *  Change state to ESmsStoreReadReadingList or ESmsStoreReadReadingSlot
       
   233  *  Sets value of the total entries if inconsistency between slots used and total slots
       
   234  *  If store can be read opens store, otherwise leaves with KErrNotSupported
       
   235  *  If store can be read att once, starts two-phased reading of the message list,
       
   236  *  Otherwise start reading store slot by slot
       
   237  *  State ESmsStoreReadReadingList:
       
   238  *  Gets readed store list
       
   239  *  Starts process Pdus
       
   240  *  State ESmsStoreReadReadingSlot:
       
   241  *  Adds readed store entry to the entry list
       
   242  *  Starts reading of the next slot
       
   243  *  Starts process Pdus when all entries are read and
       
   244  *  State ESmsStoreReadIdle is unexpected state
       
   245  *  
       
   246  *  @leave Leaves if there was an error
       
   247  *  @leave Leaves if open store leaves
       
   248  *  @leave Leaves with KErrNotSupported if store has no read access
       
   249  *  @leave Panic if complete is called while state is ESmsStoreReadIdle
       
   250  */
       
   251 void CSmsStoreRead::DoRunL()
       
   252 	{
       
   253 	LOGSMSPROT2("CSmsStoreRead::DoRunL [iStatus=%d]", iStatus.Int() );
       
   254 
       
   255 	TInt status = iStatus.Int();
       
   256 
       
   257 	//status is KErrNotFound or KErrGsmSMSInvalidMemoryIndex if last read entry was empty
       
   258 	//status is KErrCorrupt if the TSY declares a PDU to be corrupt
       
   259  	if (status != KErrNone  &&  status != KErrNotFound  &&
       
   260  	    status != KErrCorrupt  &&  status != KErrGsmSMSInvalidMemoryIndex)
       
   261  	    {
       
   262 		User::Leave(status); //< Trapped in CSmsuActiveBase::RunError() which calls Complete().
       
   263 		}
       
   264 
       
   265     switch ( iState )
       
   266 		{
       
   267 		case ESmsStoreReadGettingStoreInfo:
       
   268 			{
       
   269 			if ( ( iStoreInfo.iTotalEntries == 0 ) && ( iStoreInfo.iUsedEntries > 0 ) )
       
   270 				{
       
   271 				// Handle inconsistency between slots used & total slots (7110!)
       
   272 				iStoreInfo.iTotalEntries = KSmsDefaultTotalMessageStoreSlots;
       
   273 				}
       
   274 			// Checks reading capabilities of the current store
       
   275 			if ( iStoreInfo.iCaps & RMobilePhoneStore::KCapsReadAccess )
       
   276 				{
       
   277 				// Opens current store
       
   278 				User::LeaveIfError( iSmsStorage.Open( iSmsMessaging, iStoreInfo.iName ) );
       
   279 				}
       
   280 			else
       
   281 				{
       
   282 				User::Leave( KErrNotSupported );
       
   283 				}
       
   284 			if ( iStoreInfo.iCaps & static_cast<TUint32>(RMobilePhoneStore::KCapsWholeStore) )
       
   285 				{
       
   286 				iState = ESmsStoreReadReadingList;
       
   287 				delete iRetrieveMobilePhoneSmsList;
       
   288 				iRetrieveMobilePhoneSmsList = NULL;
       
   289 				// Create CRetrieveMobilePhoneSmsList object
       
   290 				iRetrieveMobilePhoneSmsList = CRetrieveMobilePhoneSmsList::NewL(
       
   291 					iSmsStorage, RMobileSmsStore::KETelMobileGsmSmsEntryV1 );
       
   292 				// Starts two-phased reading of the message list
       
   293 				iRetrieveMobilePhoneSmsList->Start(iStatus);
       
   294 				TimedSetActive(KDefaultEnumerateTimeoutSeconds);
       
   295 				}
       
   296 			else if ( iStoreInfo.iCaps & RMobilePhoneStore::KCapsIndividualEntry )
       
   297 				{
       
   298 				iState = ESmsStoreReadReadingSlot;
       
   299 				// Reads next single message from the store
       
   300 				delete iMobilePhoneGsmSmsList;
       
   301 				iMobilePhoneGsmSmsList = NULL;
       
   302 				iMobilePhoneGsmSmsList = CMobilePhoneGsmSmsList::NewL();
       
   303 				ReadNextSlotL();
       
   304 				}
       
   305 			else
       
   306 				{
       
   307 				User::Leave( KErrNotSupported );
       
   308 				}
       
   309 			}
       
   310 			break;
       
   311 
       
   312 		case ESmsStoreReadReadingSlot:
       
   313 			{
       
   314 			if ( iStatus == KErrNone )
       
   315 				{
       
   316 				// Add current message to the list
       
   317 				iMobilePhoneGsmSmsList->AddEntryL( iSmsEntry );
       
   318 				LOGSMSIFSMSENTRY(_L8("SMSENTRY: "), iSmsEntry);
       
   319 				iStoreInfo.iUsedEntries--;
       
   320 				}
       
   321 			// Reads next single message from the store
       
   322 			ReadNextSlotL();
       
   323 			}
       
   324 			break;
       
   325 
       
   326 		case ESmsStoreReadReadingList:
       
   327 			{
       
   328 			// Gets whole message list
       
   329 			if (iStatus != KErrNotFound  &&
       
   330 			    iStatus != KErrGsmSMSInvalidMemoryIndex  &&
       
   331 			    iStatus != KErrCorrupt)	//ReadList has completed if iStatus is KErrNotFound => empty list
       
   332 				{
       
   333 				CMobilePhoneGsmSmsList* tempList = iRetrieveMobilePhoneSmsList->RetrieveGsmListL();
       
   334 				delete iMobilePhoneGsmSmsList;
       
   335 				iMobilePhoneGsmSmsList = tempList;
       
   336 				ProcessPduL();
       
   337 				}
       
   338 			else
       
   339 				{
       
   340 				iStatus = KErrNone;	//iStatus is used as completion object for this AO call, so set to status to KErrNone as we do not want to propogate KErrNotFound back to phone enumeration AO as it is not actually an error.
       
   341 				}
       
   342 			}
       
   343 			break;
       
   344 
       
   345 		default:
       
   346 			{
       
   347 			SmspPanic(KSmspPanicUnexpectedState);
       
   348 			}
       
   349 			break;
       
   350 		}
       
   351 
       
   352 	//
       
   353 	// DoRunL() will now return to CSmsuActiveBase which if the object
       
   354 	// is not active, will call Complete().
       
   355 	//
       
   356 	} // CSmsStoreRead::DoRunL
       
   357 
       
   358 
       
   359 /**
       
   360  *  private method for reading one slot from the store
       
   361  */
       
   362 void CSmsStoreRead::ReadNextSlotL()
       
   363 	{
       
   364 	LOGSMSPROT1("CSmsStoreRead::ReadNextSlotL()");
       
   365 
       
   366 	//Increments current slot index
       
   367 	iCurrentSlotIndex++;
       
   368 	// Sets message entry index
       
   369 	iSmsEntry.iIndex = iCurrentSlotIndex;
       
   370 
       
   371 	if (iStoreInfo.iUsedEntries > 0  &&
       
   372 		iCurrentSlotIndex <= iStoreInfo.iTotalEntries)
       
   373 		{
       
   374 		// Reads message from the store
       
   375 		iSmsStorage.Read( iStatus, iEntryV1Pckg );
       
   376 		SetActive();
       
   377 		}
       
   378 	else
       
   379 		{
       
   380 		ProcessPduL();
       
   381 		}
       
   382 	} // CSmsStoreRead::ReadNextSlotL
       
   383 
       
   384 
       
   385 /**
       
   386  *  private method for process one slot from the entry list
       
   387  */
       
   388 void CSmsStoreRead::ProcessPduL()
       
   389 	{
       
   390 	LOGSMSPROT1("CSmsStoreRead::ProcessPduL()");
       
   391 
       
   392 	// Increments slot index
       
   393 	for ( iCurrentSlotIndex = 0; iCurrentSlotIndex < iMobilePhoneGsmSmsList->Enumerate(); iCurrentSlotIndex++ )
       
   394 		{
       
   395 		CSmsPDUProcessor*  pduProcessor = CSmsPDUProcessor::NewL(iSmsComm, iSmsSettings, iReassemblyStore,
       
   396 											 iSegmentationStore, iSmsMonitorDiskSpace);
       
   397 		CleanupStack::PushL(pduProcessor);
       
   398 
       
   399 		pduProcessor->SetApplyAutoDeletionToClass2(iConfigAutomaticDeletionForClass2);
       
   400 		pduProcessor->SetDiscardType0Class0(iConfigDiscardingType0Class0);
       
   401 		pduProcessor->SetDiscardType0Class2(iConfigDiscardingType0Class2);
       
   402 
       
   403 		// Gets message from the list
       
   404 		iSlot = iMobilePhoneGsmSmsList->GetEntryL( iCurrentSlotIndex );
       
   405 
       
   406 		// Sets store name to the slot
       
   407 		iSlot.iStore = iStoreInfo.iName;
       
   408 
       
   409 		//User::LeaveIfError( Decode( iSlot ) );
       
   410         // ALR-56UJLB - Enumerating messages on SIM may fail
       
   411         // if there is a corrupt message on SIM
       
   412         // the enumeration of a submit pdu with a 9210
       
   413         // return KErrcorrupt, because the submit pdu
       
   414         // is stored as a deliver pdu in the SIM store
       
   415         // that is a defect in the modem software of the 9210
       
   416         // but in this case none of the messages have been passed
       
   417         // to the client, this has been fixed here
       
   418 		TRAPD(ret, pduProcessor->DecodeAndProcessPDUL(iSlot, ETrue));
       
   419 		LOGSMSPROT2("CSmsStoreRead::ProcessPduL(): DecodeAndProcessPDUL() returned %d", ret);
       
   420 
       
   421 		if (ret == KErrNone)
       
   422 			{
       
   423 			if (pduProcessor->IsForwardMessageToClient())
       
   424 				{
       
   425 				//
       
   426 				// Note, at this point we have not placed the message in
       
   427 				// the reassembly store.
       
   428 				//
       
   429 				pduProcessor->ProcessMessageIfCompleteL();
       
   430 				}
       
   431 			}
       
   432 		 else if (ret == KErrCorrupt)
       
   433 			{
       
   434       		pduProcessor->DeletePDUL();
       
   435 			}
       
   436 		else if (ret ==  KErrDiskFull  ||  ret ==  KErrNoMemory)
       
   437 			{
       
   438 		 	//
       
   439 		 	// Permanant error, can't continue message enumeration,
       
   440 		 	// so just leave...
       
   441 		 	//
       
   442 		 	User::Leave(ret);
       
   443 			}
       
   444 			
       
   445 		CleanupStack::PopAndDestroy(pduProcessor);
       
   446 		}
       
   447 	} // CSmsStoreRead::ProcessPduL
       
   448 
       
   449 
       
   450 /**
       
   451  *  Called by CSmsuActive object to cancel this object
       
   452  *  Cancels timeout timer
       
   453  *  State ESmsStoreReadGettingStoreInfo:
       
   454  *  Cancels reading of the message store info
       
   455  *  State ESmsStoreReadReadingList:
       
   456  *  Cancels reading of the message store list
       
   457  *  State ESmsStoreReadReadingSlot:
       
   458  *  Cancels reading of the single slot
       
   459  *  State ESmsStoreReadIdle is unexpected state
       
   460  *  
       
   461  *  @leave Panic if complete is called while state is ESmsStoreReadIdle
       
   462  */
       
   463 void CSmsStoreRead::DoCancel()
       
   464 	{
       
   465 	LOGSMSPROT1("CSmsStoreRead::DoCancel()");
       
   466 
       
   467 	TimedSetActiveCancel();
       
   468 
       
   469 	switch (iState)
       
   470 		{
       
   471 		case ESmsStoreReadGettingStoreInfo:
       
   472 			{
       
   473 			// Cancels message store info reading
       
   474 			iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingGetMessageStoreInfo);
       
   475 			}
       
   476 			break;
       
   477 
       
   478 		case ESmsStoreReadReadingList:
       
   479 			{
       
   480 			// Cancels message list reading
       
   481 			iRetrieveMobilePhoneSmsList->Cancel();
       
   482 			}
       
   483 			break;
       
   484 
       
   485 		case ESmsStoreReadReadingSlot:
       
   486 			{
       
   487 			// Cancels slot reading
       
   488  			iSmsStorage.CancelAsyncRequest( EMobilePhoneStoreRead );
       
   489  			iState = ESmsStoreReadReadingSlotCancel;
       
   490 			}
       
   491 			break;
       
   492 
       
   493 		default:
       
   494 			{
       
   495 			SmspPanic(KSmspPanicUnexpectedState);
       
   496 			}
       
   497 			break;
       
   498 		}
       
   499 
       
   500 	//
       
   501 	// Handle completion of this Active Object. Note that the object
       
   502 	// may well still be active at this point...
       
   503 	//
       
   504 	if (TimedOut())
       
   505 		{
       
   506 		Complete(KErrTimedOut);
       
   507 		}
       
   508 	else
       
   509 		{
       
   510 		Complete(KErrCancel);
       
   511 		}
       
   512 	} // CSmsStoreRead::DoCancel
       
   513 
       
   514 
       
   515 /**
       
   516  *  Completes store read request
       
   517  *  
       
   518  *  Closes phone side store if necessary.
       
   519  *  
       
   520  *  @param aStatus a status value
       
   521  *  @leave Panic if complete is called while state is ESmsStoreReadIdle
       
   522  */
       
   523 void CSmsStoreRead::Complete(TInt aStatus)
       
   524 	{
       
   525 	LOGSMSPROT1("CSmsStoreRead::Complete()");
       
   526 
       
   527 	__ASSERT_DEBUG(iState != ESmsStoreReadIdle, SmspPanic(KSmspPanicUnexpectedState));
       
   528 
       
   529 	//
       
   530 	// Close the store if needed...
       
   531 	//
       
   532 	if (iState != ESmsStoreReadReadingSlotCancel)
       
   533 		{
       
   534 		CloseStore();
       
   535 		}
       
   536 
       
   537 	//
       
   538 	// Call the base function to perform the actual complete...
       
   539 	//
       
   540 	CSmsuActiveBase::Complete(aStatus);
       
   541 
       
   542 	iState = ESmsStoreReadIdle;
       
   543 	} // CSmsStoreRead::Complete
       
   544 
       
   545 
       
   546 /**
       
   547  *  Closes the store
       
   548  */
       
   549 void CSmsStoreRead::CloseStore()
       
   550  	{
       
   551  	iSmsStorage.Close();
       
   552  	} // CSmsStoreRead::CloseStore
       
   553 
       
   554 
       
   555 /**
       
   556  *  Destructor
       
   557  */
       
   558 CSmsStoreRead::~CSmsStoreRead()
       
   559 	{
       
   560 	Cancel();
       
   561 
       
   562 	// Deletes created instances
       
   563 	delete iRetrieveMobilePhoneSmsList;
       
   564 	delete iMobilePhoneGsmSmsList;
       
   565 	} // CSmsStoreRead::~CSmsStoreRead
       
   566 
       
   567 
       
   568 /**
       
   569  *  Creates new CSmsPhoneEnumeration instance
       
   570  *  
       
   571  *  @param aSmsComm Used to complete enumeration
       
   572  *  @param aSmsSettings Used to create CSmsStoreRead object and start timer
       
   573  *  @param aReassemblyStore Used to create CSmsStoreRead object
       
   574  *  @param aSegmentationStore Used to create CSmsStoreRead object
       
   575  *  @param aGsmPhone Used to Initialise phone and open RMobileSmsMessaging for enumerate message
       
   576  *  @param aPriority Used to set CSmsuActiveBase object
       
   577  */
       
   578 CSmsPhoneEnumeration* CSmsPhoneEnumeration::NewL( MSmsComm& aSmsComm,
       
   579 												  const TSmsSettings& aSmsSettings,
       
   580 												  CFacadeSmsReassemblyStore& aReassemblyStore,
       
   581 												  CSmsSegmentationStore& aSegmentationStore,
       
   582 												  RMobilePhone& aGsmPhone,
       
   583 												  TInt aPriority,
       
   584 												  CSmsMonitorDiskSpace& aSmsMonitorDiskSpace )
       
   585 	{
       
   586 	LOGSMSPROT1("CSmsPhoneEnumeration::NewL()");
       
   587 
       
   588 	CSmsPhoneEnumeration* smsPhoneEnumeration =
       
   589 		new ( ELeave ) CSmsPhoneEnumeration( aSmsComm,
       
   590 											 aSmsSettings,
       
   591 											 aGsmPhone,
       
   592 											 aPriority );
       
   593 	CleanupStack::PushL( smsPhoneEnumeration );
       
   594 	smsPhoneEnumeration->ConstructL( aReassemblyStore, aSegmentationStore, aSmsMonitorDiskSpace );
       
   595 	CleanupStack::Pop( smsPhoneEnumeration );
       
   596 	return smsPhoneEnumeration;
       
   597 	} // CSmsPhoneEnumeration::NewL
       
   598 
       
   599 
       
   600 /**
       
   601  *  Constructor
       
   602  *  
       
   603  *  @param aSmsComm Used to complete enumeration
       
   604  *  @param aSmsSettings Used to create CSmsStoreRead object and start timer
       
   605  *  @param aReassemblyStore Used to create CSmsStoreRead object
       
   606  *  @param aSegmentationStore Used to create CSmsStoreRead object
       
   607  *  @param aGsmPhone Used to Initialise phone and open RMobileSmsMessaging for enumerate message
       
   608  *  @param aPriority Used to set CSmsuActiveBase object
       
   609  */
       
   610 CSmsPhoneEnumeration::CSmsPhoneEnumeration( MSmsComm& aSmsComm,
       
   611 											const TSmsSettings& aSmsSettings,
       
   612 											RMobilePhone& aGsmPhone,
       
   613 											TInt aPriority )
       
   614 	:CSmsuActiveBase( aPriority )
       
   615 	,iState( ESmsPhoneEnumerationIdle )
       
   616 	,iSmsComm( aSmsComm )
       
   617 	,iSmsSettings( aSmsSettings )
       
   618 	,iGsmPhone( aGsmPhone )
       
   619 	{
       
   620 	} // CSmsPhoneEnumeration::CSmsPhoneEnumeration
       
   621 
       
   622 
       
   623 /**
       
   624  *  Destructor
       
   625  */
       
   626 CSmsPhoneEnumeration::~CSmsPhoneEnumeration()
       
   627 	{
       
   628 	Cancel();
       
   629 	//deletes created instances
       
   630 	delete iSmsStoreRead;
       
   631 	} // CSmsPhoneEnumeration::~CSmsPhoneEnumeration
       
   632 
       
   633 
       
   634 /**
       
   635  *  Starts CSmsPhoneEnumeration active object
       
   636  *  Calls Initialise method from RMobilePhone object
       
   637  *  Sets timed active
       
   638  */
       
   639 void CSmsPhoneEnumeration::Start()
       
   640 	{
       
   641 	LOGSMSPROT1("CSmsPhoneEnumeration::Start()");
       
   642 
       
   643 	iState = ESmsPhoneEnumerationInitializing;
       
   644 	iCurrentStore = 0;
       
   645 	iGsmPhone.Initialise( iStatus );
       
   646 	TimedSetActive( iSmsSettings.Timeout() );
       
   647 	} // CSmsPhoneEnumeration::Start
       
   648 
       
   649 
       
   650 /**
       
   651  *  Called by CSmsuActive object to run this object
       
   652  *  Cancels timeout timer
       
   653  *  State ESmsPhoneEnumerationInitializing:
       
   654  *  Change State to ESmsPhoneEnumerationReadingStores
       
   655  *  Calls Open method from class RMobileSmsMessaging
       
   656  *  If opening returns KErrNone
       
   657  *  Gets number of enumerate message stores
       
   658  *  Marks initialization begin in phone image
       
   659  *  Starts CSmsStoreRead active object to read first store
       
   660  *  State ESmsPhoneEnumerationReadingStores:
       
   661  *  Reads all existing stores
       
   662  *  State Completes when all stores are readed
       
   663  *  State ESmsPhoneEnumerationIdle is unexpected state
       
   664  *  Completes if object is not active
       
   665  *  
       
   666  *  @leave Leaves if there was an error
       
   667  *  @leave Panic if called while state is ESmsPhoneEnumerationIdle
       
   668  */
       
   669 void CSmsPhoneEnumeration::DoRunL()
       
   670 	{
       
   671 	LOGSMSPROT3("CSmsPhoneEnumeration::RunL [iStatus=%d], [iState=%d]", iStatus.Int(), iState );
       
   672 
       
   673     switch (iState)
       
   674 		{
       
   675 		case ESmsPhoneEnumerationInitializing:
       
   676 			{
       
   677 		    if (iStatus.Int() == KErrNone)
       
   678     			{
       
   679 				iState = ESmsPhoneEnumerationReadingStores;
       
   680 				User::LeaveIfError(iSmsMessaging.Open(iGsmPhone));
       
   681 				User::LeaveIfError(iSmsMessaging.EnumerateMessageStores(iNumStores));
       
   682 
       
   683 				iSmsStoreRead->Start(iStatus, iCurrentStore);
       
   684 				SetActive();
       
   685 				}
       
   686 			}
       
   687 			break;
       
   688 
       
   689 		case ESmsPhoneEnumerationReadingStores:
       
   690 			{
       
   691 		    if (iStatus.Int() == KErrNone)
       
   692     			{
       
   693 				iCurrentStore++;
       
   694 				if (iCurrentStore < iNumStores)
       
   695 					{
       
   696 					iSmsStoreRead->Start( iStatus, iCurrentStore );
       
   697 					SetActive();
       
   698 					}
       
   699 				}
       
   700 			}
       
   701 			break;
       
   702 
       
   703 		default:
       
   704 			{
       
   705 			SmspPanic(KSmspPanicUnexpectedState);
       
   706 			}
       
   707 			break;
       
   708 		}
       
   709 
       
   710 	//
       
   711 	// DoRunL() will now return to CSmsuActiveBase which if the object
       
   712 	// is not active, will call Complete().
       
   713 	//
       
   714 	} // CSmsPhoneEnumeration::DoRunL
       
   715 
       
   716 
       
   717 void CSmsPhoneEnumeration::DoCancel()
       
   718 	{
       
   719 	LOGSMSPROT1("CSmsPhoneEnumeration::DoCancel()");
       
   720 
       
   721 	TimedSetActiveCancel();
       
   722 
       
   723 	switch (iState)
       
   724 		{
       
   725 		case ESmsPhoneEnumerationInitializing:
       
   726 			{
       
   727 			iGsmPhone.InitialiseCancel();
       
   728 			}
       
   729 			break;
       
   730 
       
   731 		case ESmsPhoneEnumerationReadingStores:
       
   732 			{
       
   733 			iSmsStoreRead->Cancel();
       
   734 			iSmsStoreRead->CloseStore();
       
   735 			}
       
   736 			break;
       
   737 
       
   738 		default:
       
   739 			{
       
   740 			SmspPanic(KSmspPanicUnexpectedState);
       
   741 			}
       
   742 			break;
       
   743 		}
       
   744 
       
   745 	//
       
   746 	// Handle completion of this Active Object. Note that the object
       
   747 	// may well still be active at this point...
       
   748 	//
       
   749 	if (TimedOut())
       
   750 		{
       
   751 		Complete(KErrTimedOut);
       
   752 		}
       
   753 	else
       
   754 		{
       
   755 		Complete(KErrCancel);
       
   756 		}
       
   757 	} // CSmsPhoneEnumeration::DoCancel
       
   758 
       
   759 
       
   760 /**
       
   761  *  Creates instances to the classes CSmsTimeout and CSmsStoreRead
       
   762  */
       
   763 void CSmsPhoneEnumeration::ConstructL(CFacadeSmsReassemblyStore& aReassemblyStore,CSmsSegmentationStore& aSegmentationStore,CSmsMonitorDiskSpace& aSmsMonitorDiskSpace)
       
   764 	{
       
   765 	LOGSMSPROT1("CSmsPhoneEnumeration::ConstructL()");
       
   766 
       
   767 	iSmsStoreRead = CSmsStoreRead::NewL(iSmsComm, iSmsSettings, iSmsMessaging, aReassemblyStore, aSegmentationStore, Priority(), aSmsMonitorDiskSpace);
       
   768 	ConstructTimeoutL();
       
   769 	} // CSmsPhoneEnumeration::ConstructL
       
   770 
       
   771 
       
   772 void CSmsPhoneEnumeration::Complete(TInt aStatus)
       
   773 	{
       
   774 	LOGSMSPROT2("CSmsPhoneEnumeration::Complete [aStatus=%d]", aStatus);
       
   775 
       
   776 	//
       
   777 	// Call the base function to perform the actual complete...
       
   778 	//
       
   779 	CSmsuActiveBase::Complete(aStatus);
       
   780 
       
   781 	//
       
   782 	// Finish up...
       
   783 	//
       
   784 	iState = ESmsPhoneEnumerationIdle;
       
   785 	iSmsMessaging.Close();
       
   786 	
       
   787 	//
       
   788 	// Send an event to say that the enumeration is complete...
       
   789 	//
       
   790 	iSmsComm.PhoneEnumerationCompleted(aStatus);
       
   791 	} // CSmsPhoneEnumeration::Complete
       
   792 
       
   793 
       
   794 /**
       
   795  *  Creates new CSmsMessageWrite instance
       
   796  *  
       
   797  *  @param aSmsSettings Used to start CSmsTimeout object
       
   798  *  @param aGsmPhone Used to Initialise phone
       
   799  *  @param aSegmentationStore Used to get next 8 or 16bit reference
       
   800  */
       
   801 CSmsMessageWrite* CSmsMessageWrite::NewL( MSmsComm& aSmsComm, const TSmsSettings& aSmsSettings,
       
   802 										  RMobilePhone& aGsmPhone,
       
   803 										  CSmsSegmentationStore& aSegmentationStore
       
   804 										  )
       
   805 	{
       
   806 	LOGSMSPROT1("CSmsMessageWrite::NewL()");
       
   807 
       
   808 	CSmsMessageWrite* smsMessageWrite = new (ELeave) CSmsMessageWrite(aSmsComm, aSmsSettings,
       
   809 																	  aGsmPhone,
       
   810 																	  aSegmentationStore);
       
   811 	CleanupStack::PushL(smsMessageWrite);
       
   812 	smsMessageWrite->ConstructL();
       
   813 	CleanupStack::Pop(smsMessageWrite);
       
   814 	return smsMessageWrite;
       
   815 	} // CSmsMessageWrite::NewL
       
   816 
       
   817 
       
   818 /**
       
   819  *  Destructor
       
   820  */
       
   821 CSmsMessageWrite::~CSmsMessageWrite()
       
   822 	{
       
   823 	LOGSMSPROT1("CSmsMessageWrite::~CSmsMessageWrite()");
       
   824 
       
   825 	Cancel();
       
   826 	iSmsStorage.Close();
       
   827 	iSmsMessaging.Close();
       
   828 	} // CSmsMessageWrite::~CSmsMessageWrite
       
   829 
       
   830 
       
   831 void CSmsMessageWrite::Start( CSmsMessage* aSmsMessage, TRequestStatus& aStatus )
       
   832 	{
       
   833 	Queue(aStatus);
       
   834 
       
   835 	iSmsStorage.Close();
       
   836 	iSmsMessaging.Close();
       
   837 
       
   838 	iState = ESmsMessageWriteInitializing;
       
   839 
       
   840 
       
   841 	iSmsMessage = aSmsMessage;
       
   842     LOGSMSPROT3("CSmsMessageWrite::Start  Storage=[%d]   Type=[%d]", iSmsMessage->Storage(), iSmsMessage->Type());
       
   843 	iCurrentStore = 0;
       
   844 	iStoreInfo.iName = KNullDesC;
       
   845 
       
   846 	switch (iSmsMessage->Storage())
       
   847 		{
       
   848 		case CSmsMessage::ESmsSIMStorage:
       
   849 			{
       
   850  			iSlot.iStore = KETelIccSmsStore;
       
   851 			}
       
   852 			break;
       
   853 
       
   854 		case CSmsMessage::ESmsPhoneStorage:
       
   855 			{
       
   856  			iSlot.iStore = KETelMeSmsStore;
       
   857 			}
       
   858 			break;
       
   859 
       
   860 		case CSmsMessage::ESmsCombinedStorage:
       
   861 			{
       
   862  			iSlot.iStore = KETelCombinedSmsStore;
       
   863 			}
       
   864 			break;
       
   865 
       
   866 		default:
       
   867 			{
       
   868 			Complete(KErrArgument);
       
   869 			return;
       
   870 			}
       
   871 		}
       
   872 
       
   873 	switch (iSmsMessage->Type())
       
   874 		{
       
   875 		case CSmsPDU::ESmsSubmit:
       
   876 		case CSmsPDU::ESmsCommand:
       
   877 			{
       
   878 			iSlot.iMsgStatus = RMobileSmsStore::EStoredMessageUnsent;
       
   879 			}
       
   880 			break;
       
   881 
       
   882 		case CSmsPDU::ESmsDeliver:
       
   883 		case CSmsPDU::ESmsStatusReport:
       
   884 			{
       
   885 			// Check read status in iSmsMessage
       
   886 			if (iSmsMessage->Status() == NMobileSmsStore::EStoredMessageRead)
       
   887 		 		{
       
   888 	 			iSlot.iMsgStatus = RMobileSmsStore::EStoredMessageRead;
       
   889 	 			}
       
   890 	 		else
       
   891 	 			{
       
   892 				iSlot.iMsgStatus = RMobileSmsStore::EStoredMessageUnread;
       
   893 	 			}
       
   894 			break;
       
   895 			}
       
   896 		default:
       
   897 			{
       
   898 			SmspPanic(ESmspUnexpectedSmsPDUType);
       
   899 			}
       
   900 			break;
       
   901 		}
       
   902 
       
   903 	//
       
   904 	// Begin initialising...
       
   905 	//
       
   906 	iGsmPhone.Initialise(iStatus);
       
   907 	TimedSetActive(iSmsSettings.Timeout());
       
   908 	} // CSmsMessageWrite::Start
       
   909 
       
   910 
       
   911 void CSmsMessageWrite::DoRunL()
       
   912 	{
       
   913 	LOGSMSPROT3("CSmsMessageWrite::DoRunL [iStatus=%d iState=%d]", iStatus.Int() , iState);
       
   914 
       
   915 	switch (iState)
       
   916 		{
       
   917 		case ESmsMessageWriteInitializing:
       
   918 			{
       
   919 			if (iStatus.Int() == KErrNone)
       
   920 				{
       
   921 				iState = ESmsMessageWriteGettingStoreInfo;
       
   922 				iSmsMessaging.Close();
       
   923 				User::LeaveIfError(iSmsMessaging.Open(iGsmPhone));
       
   924 				User::LeaveIfError(iSmsMessaging.EnumerateMessageStores(iNumStores));
       
   925 	 			iSmsMessaging.GetMessageStoreInfo(iStatus, iCurrentStore, iStoreInfoPckg);
       
   926 
       
   927 				TimedSetActive(iSmsSettings.Timeout());
       
   928 				}
       
   929 			}
       
   930 			break;
       
   931 
       
   932 		case ESmsMessageWriteGettingStoreInfo:
       
   933 			{
       
   934 			if (iStatus.Int() == KErrNone)
       
   935 				{
       
   936 				if (iStoreInfo.iName == iSlot.iStore)
       
   937 					{
       
   938 					if ((iStoreInfo.iCaps & RMobilePhoneStore::KCapsWriteAccess) == 0)
       
   939 						{
       
   940 						User::Leave(KErrNotSupported);
       
   941 						}
       
   942 
       
   943 					iState = ESmsMessageWriteWritingPDUs;
       
   944 					SegmentMessageL();
       
   945 					WriteNextSlot();
       
   946 					}
       
   947 				else
       
   948 					{
       
   949 					iCurrentStore++;
       
   950 					if (iCurrentStore < iNumStores)
       
   951 						{
       
   952 	 					iSmsMessaging.GetMessageStoreInfo(iStatus, iCurrentStore, iStoreInfoPckg);
       
   953 						TimedSetActive(iSmsSettings.Timeout());
       
   954 						}
       
   955 					else
       
   956 						{
       
   957 						User::Leave(KErrNotFound); //< TODO Is this correct?
       
   958 						}
       
   959 					}
       
   960 				}
       
   961 			}
       
   962 			break;
       
   963 
       
   964 		case ESmsMessageWriteWritingPDUs:
       
   965 			{
       
   966 			if (iStatus.Int() == KErrNone)
       
   967 				{
       
   968 				iSmsArray.Delete( 0 );
       
   969 				iSlot.iIndex = iEntryToWrite.iIndex;
       
   970 
       
   971 				//
       
   972 				// Initialise slot entry for transfer to array
       
   973 				//
       
   974 				TGsmSmsSlotEntry smsSlotEntry;
       
   975 
       
   976 				smsSlotEntry.iIndex = iSlot.iIndex;
       
   977 				smsSlotEntry.iStore = iSlot.iStore;
       
   978 				iSmsMessage->AddSlotL(smsSlotEntry);
       
   979 				WriteNextSlot();
       
   980 				}
       
   981 			}
       
   982 			break;
       
   983 
       
   984 		default:
       
   985 			{
       
   986 			SmspPanic(KSmspPanicUnexpectedState);
       
   987 			}
       
   988 			break;
       
   989 		}
       
   990 
       
   991 	//
       
   992 	// DoRunL() will now return to CSmsuActiveBase which if the object
       
   993 	// is not active, will call Complete().
       
   994 	//
       
   995 	} // CSmsMessageWrite::DoRunL
       
   996 
       
   997 
       
   998 void CSmsMessageWrite::DoCancel()
       
   999 	{
       
  1000 	LOGSMSPROT1("CSmsMessageWrite::DoCancel()");
       
  1001 
       
  1002 	TimedSetActiveCancel();
       
  1003 
       
  1004 	switch (iState)
       
  1005 		{
       
  1006 		case ESmsMessageWriteInitializing:
       
  1007 			{
       
  1008 			iGsmPhone.InitialiseCancel();
       
  1009 			}
       
  1010 			break;
       
  1011 
       
  1012 		case ESmsMessageWriteGettingStoreInfo:
       
  1013 			{
       
  1014 			iSmsMessaging.CancelAsyncRequest(EMobileSmsMessagingGetMessageStoreInfo);
       
  1015 			}
       
  1016 			break;
       
  1017 
       
  1018 		case ESmsMessageWriteWritingPDUs:
       
  1019 			{
       
  1020 			iSmsStorage.CancelAsyncRequest(EMobilePhoneStoreWrite);
       
  1021 			}
       
  1022 			break;
       
  1023 
       
  1024 		default:
       
  1025 			{
       
  1026 			SmspPanic(KSmspPanicUnexpectedState);
       
  1027 			}
       
  1028 			break;
       
  1029 		}
       
  1030 
       
  1031 	//
       
  1032 	// Handle completion of this Active Object. Note that the object
       
  1033 	// may well still be active at this point...
       
  1034 	//
       
  1035 	if (TimedOut())
       
  1036 		{
       
  1037 		Complete(KErrTimedOut);
       
  1038 		}
       
  1039 	else
       
  1040 		{
       
  1041 		Complete(KErrCancel);
       
  1042 		}
       
  1043 	} // CSmsMessageWrite::DoCancel
       
  1044 
       
  1045 
       
  1046 CSmsMessageWrite::CSmsMessageWrite(MSmsComm& aSmsComm, const TSmsSettings& aSmsSettings,
       
  1047 								   RMobilePhone& aGsmPhone,
       
  1048 								   CSmsSegmentationStore& aSegmentationStore)
       
  1049   : CSmsuActiveBase(KSmsSessionPriority),
       
  1050 	iSmsComm(aSmsComm),
       
  1051 	iState(ESmsMessageWriteIdle),
       
  1052 	iSmsSettings(aSmsSettings),
       
  1053 	iGsmPhone(aGsmPhone),
       
  1054 	iStoreInfoPckg (iStoreInfo),
       
  1055 	iWriteEntryV1Pckg(iEntryToWrite),
       
  1056 	iSegmentationStore(aSegmentationStore),
       
  1057 	iSmsArray(8)
       
  1058 	{
       
  1059 	LOGSMSPROT1("CSmsMessageWrite::CSmsMessageWrite()");
       
  1060 
       
  1061 	} // CSmsMessageWrite::CSmsMessageWrite
       
  1062 
       
  1063 
       
  1064 void CSmsMessageWrite::ConstructL()
       
  1065 	{
       
  1066 	LOGSMSPROT1("CSmsMessageWrite::ConstructL()");
       
  1067 
       
  1068 	ConstructTimeoutL();
       
  1069 	} // CSmsMessageWrite::ConstructL
       
  1070 
       
  1071 
       
  1072 void CSmsMessageWrite::SegmentMessageL()
       
  1073 	{
       
  1074 	LOGSMSPROT1("CSmsMessageWrite::SegmentMessageL()");
       
  1075 
       
  1076 	if (iStoreInfo.iTotalEntries == iStoreInfo.iUsedEntries)
       
  1077 		{
       
  1078 		User::Leave(KErrNoMemory);
       
  1079 		}
       
  1080 
       
  1081 	TInt reference = 0;
       
  1082 
       
  1083 	TBool is16bit = EFalse;
       
  1084 	TBool concatenationIEPresent = EFalse;
       
  1085 
       
  1086 	//
       
  1087 	// Ensure text present before testing concatenation requirement
       
  1088 	//
       
  1089 	if (iSmsMessage->TextPresent())
       
  1090 		{
       
  1091 		concatenationIEPresent= iSmsMessage->SmsPDU().TextConcatenated( &is16bit );
       
  1092 		iSmsMessage->SmsPDU().SetTextConcatenatedL(EFalse,EFalse);
       
  1093 		}
       
  1094 
       
  1095 	if (!iSmsMessage->EncodeIntoSinglePDUL(iSmsArray))
       
  1096 		{
       
  1097 		if (concatenationIEPresent && is16bit)
       
  1098 			{
       
  1099 			iSmsMessage->Set16BitConcatenation(ETrue);
       
  1100 			}
       
  1101 
       
  1102 		reference=is16bit? iSegmentationStore.Next16BitReferenceL(): iSegmentationStore.Next8BitReferenceL();
       
  1103 		iSmsMessage->EncodeMessagePDUsL(iSmsArray, reference);
       
  1104 		}
       
  1105 
       
  1106 	TInt spare=iStoreInfo.iTotalEntries-iStoreInfo.iUsedEntries;
       
  1107 	if (spare<iSmsArray.Count())
       
  1108 		{
       
  1109 		User::Leave(KErrNoMemory);
       
  1110 		}
       
  1111 
       
  1112 	User::LeaveIfError(iSmsStorage.Open(iSmsMessaging,iSlot.iStore));
       
  1113 	} // CSmsMessageWrite::SegmentMessageL
       
  1114 
       
  1115 
       
  1116 void CSmsMessageWrite::WriteNextSlot()
       
  1117 	{
       
  1118 	LOGSMSPROT1("CSmsMessageWrite::WriteNextSlot()");
       
  1119 
       
  1120 	if (iSmsArray.Count()>0)
       
  1121 		{
       
  1122 		iState=ESmsMessageWriteWritingPDUs;
       
  1123 		//Set PDU to the slot
       
  1124 		iSlot.iMsgData=iSmsArray[0].Pdu();
       
  1125 		//Sets Service Centre Address to the slot
       
  1126 
       
  1127 		iSlot.iServiceCentre.iTelNumber = iSmsArray[0].Sca().iTelNumber;
       
  1128 		NMobilePhone::TMobileTON ton = static_cast<NMobilePhone::TMobileTON>(static_cast<TInt>(iSlot.iServiceCentre.iTypeOfNumber));
       
  1129 		NMobilePhone::TMobileNPI npi = static_cast<NMobilePhone::TMobileNPI>(static_cast<TInt>(iSlot.iServiceCentre.iNumberPlan));
       
  1130 		iSmsArray[0].Sca().iTypeOfAddress.ConvertToETelMM( ton, npi );
       
  1131 
       
  1132 		iEntryToWrite = iSlot;
       
  1133 		iEntryToWrite.iIndex = -1;
       
  1134  		iSmsStorage.Write( iStatus, iWriteEntryV1Pckg );
       
  1135 		TimedSetActive( iSmsSettings.Timeout() );
       
  1136 		}
       
  1137 	} // CSmsMessageWrite::WriteNextSlot
       
  1138 
       
  1139 
       
  1140 void CSmsMessageWrite::Complete(TInt aStatus)
       
  1141 	{
       
  1142 	LOGSMSPROT2("CSmsMessageWrite::Complete [aStatus=%d]", aStatus);
       
  1143 
       
  1144 	__ASSERT_DEBUG(iState != ESmsMessageWriteIdle, SmspPanic(KSmspPanicUnexpectedState));
       
  1145 
       
  1146 	//
       
  1147 	// Finish up...
       
  1148 	//
       
  1149 	iSmsArray.Reset();
       
  1150 
       
  1151 	if (aStatus != KErrNone   &&
       
  1152 		iSmsMessage != NULL   &&  iSmsMessage->iSlotArray.Count() >0)
       
  1153 		{
       
  1154 		iSmsComm.DeletePDUs(iSmsMessage->iSlotArray, NULL);
       
  1155 		}
       
  1156 
       
  1157 	iSmsMessage = NULL;
       
  1158 	iState      = ESmsMessageWriteIdle;
       
  1159 
       
  1160 	//
       
  1161 	// Call the base function to perform the actual complete...
       
  1162 	//
       
  1163 	CSmsuActiveBase::Complete(aStatus);
       
  1164 	} // CSmsMessageWrite::Complete
       
  1165