messagingappbase/smsmtm/test/src/t_smcmrecvmanual.cpp
changeset 25 84d9eb65b26f
parent 23 238255e8b033
child 27 e4592d119491
child 37 518b245aa84c
child 79 2981cb3aa489
equal deleted inserted replaced
23:238255e8b033 25:84d9eb65b26f
     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 #include "t_smcmrecvmanual.h"
       
    17 #include <msvuids.h>
       
    18 #include <smuthdr.h>
       
    19 #include <smscmds.h>
       
    20 #include <msgtestscripts.h>
       
    21 #include <txtrich.h>
       
    22 
       
    23 _LIT(KSmcmRecvOnlyTestName, "Receive SMS Messages");
       
    24 _LIT(KHelpText, "\n[1] Start Watchers\n[2] Stop Watchers\n[3] Send myself message\n[D] Display Unmatched Messages\ne[X]it\n");
       
    25 _LIT(KMessageText, "\n[1] Short Message\n[2] Long Message\n[3] Message Indication\n[4] Replace Type\n[5] From sendrecv.script\n[D] Display Unmatched Messages\ne[X]it\n");
       
    26 _LIT(KSmsScript, "sendrecv.script");
       
    27 _LIT(KDefaultScript, "defaults.script");
       
    28 _LIT(KRecipients, "Recipients");
       
    29 _LIT(KServiceCenter, "SC");
       
    30 const TInt KWaitAfterRecv = 100000; //< 0.1 second
       
    31 
       
    32 RTest test(_L("T_SmcmRecvManual: Receive SMS Messages"));
       
    33 CTrapCleanup* theCleanup;
       
    34 
       
    35 LOCAL_C void doMainL()
       
    36 	{
       
    37 	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
       
    38 	CleanupStack::PushL(scheduler);
       
    39 	CActiveScheduler::Install( scheduler );
       
    40 
       
    41 	CSmsTestUtils* smsTest = CSmsTestUtils::NewL(test);
       
    42 	CleanupStack::PushL(smsTest);
       
    43 	TInt nextTest = 0;
       
    44 	
       
    45 	smsTest->NotifySaPhoneOnL();
       
    46 
       
    47 	CSmcmRecvOnly* scTest = CSmcmRecvOnly::NewLC(*smsTest, KSmsScript, nextTest);
       
    48 
       
    49 	scTest->StartL();
       
    50 
       
    51 	CActiveScheduler::Start();
       
    52 
       
    53 	CleanupStack::PopAndDestroy(3); //SmsTest, scheduler
       
    54 	}
       
    55 
       
    56 GLDEF_C TInt E32Main()
       
    57 	{	
       
    58 	__UHEAP_MARK;
       
    59 	test.Start(_L("Setup"));
       
    60 	theCleanup = CTrapCleanup::New();
       
    61 	TRAPD(ret,doMainL());		
       
    62 	test(ret==KErrNone);
       
    63 	delete theCleanup;	
       
    64 	test.Console()->SetPos(0, 13);
       
    65 	test.End();
       
    66 	test.Close();
       
    67 	__UHEAP_MARKEND;
       
    68 	return(KErrNone);
       
    69 	}
       
    70 
       
    71 CSmcmRecvOnly::~CSmcmRecvOnly()
       
    72 /**
       
    73  * CSmcmRecvOnly destructor
       
    74  */
       
    75 	{
       
    76 	Cancel();
       
    77 	delete iRecvActive;
       
    78 	delete iWatchers;
       
    79 	delete iOperation;
       
    80 	iOperation = NULL;
       
    81 
       
    82 	delete iRecipient;
       
    83 	delete iServiceCenter;
       
    84 
       
    85 	delete iSelection;
       
    86 	iSelection = NULL;
       
    87 	}
       
    88 
       
    89 CSmcmRecvOnly* CSmcmRecvOnly::NewLC(CSmsTestUtils& aSmsTest, const TDesC& aScriptFile, TInt& aNextTest)
       
    90 /**
       
    91  * CSmcmRecvOnly factory function
       
    92  */
       
    93 	{
       
    94 	CSmcmRecvOnly* self = new (ELeave) CSmcmRecvOnly(aSmsTest, aScriptFile, aNextTest);
       
    95 	CleanupStack::PushL(self);
       
    96 
       
    97 	self->ConstructL();
       
    98 	return self;
       
    99 	}
       
   100 
       
   101 CSmcmRecvOnly::CSmcmRecvOnly(CSmsTestUtils& aSmsTest, const TDesC& aScriptFile, TInt& aNextTest)
       
   102 : CSmsTestBase(aSmsTest, aScriptFile, aNextTest)
       
   103 /**
       
   104  * CSmcmRecvOnly constructor
       
   105  */
       
   106 	{
       
   107 	CActiveScheduler::Add(this);
       
   108 	}
       
   109 
       
   110 void CSmcmRecvOnly::DisplayAndRead(const TDesC& aText)
       
   111 /**
       
   112  * Displays aText then issues a read on the console
       
   113  */
       
   114 	{
       
   115 	iSmsTest.Printf(aText);
       
   116 	Read();
       
   117 	}
       
   118 
       
   119 void CSmcmRecvOnly::RunAutoL()
       
   120 	{
       
   121 	DisplayAndRead(KHelpText);
       
   122 	}
       
   123 
       
   124 void CSmcmRecvOnly::ConstructL()
       
   125 	{
       
   126 	iSmsTest.NotifySaPhoneOnL();
       
   127 	SetTestNameL(KSmcmRecvOnlyTestName);
       
   128 	iSmsTest.InstantiateClientMtmsL();
       
   129 
       
   130 	iSmsTest.SetLogToFile();
       
   131 	iRecvActive = CSmcmRecvActive::NewL(iSmsTest, Priority()-1);
       
   132 	iSelection = new (ELeave) CMsvEntrySelection;
       
   133 
       
   134 	User::After(1000000);
       
   135 
       
   136 	CScriptFile* script = CScriptFile::NewLC(iSmsTest, KSmsComponent);
       
   137 	script->ReadScriptL(KDefaultScript);
       
   138 
       
   139 	iRecipient = script->ItemValue(KDefaults, KRecipients, KNullDesC).AllocL();
       
   140 	iServiceCenter = script->ItemValue(KDefaults, KServiceCenter, KNullDesC).AllocL();
       
   141 
       
   142 	CleanupStack::PopAndDestroy(script);
       
   143 
       
   144 	User::After(1000000);
       
   145 
       
   146 	iSmsTest.Printf(_L("Deleting SMS messages in outbox..."));
       
   147 	iSmsTest.DeleteSmsMessagesL(KMsvGlobalOutBoxIndexEntryId);
       
   148 
       
   149 	User::After(1000000);
       
   150 	
       
   151 	iSmsTest.Printf(_L("Done\nDeleting SMS messages in sent..."));
       
   152 	iSmsTest.DeleteSmsMessagesL(KMsvSentEntryId);
       
   153 
       
   154 	User::After(1000000);
       
   155 	
       
   156 	iSmsTest.Printf(_L("Done\nDeleting SMS messages in inbox..."));
       
   157 	iSmsTest.DeleteSmsMessagesL(KMsvGlobalInBoxIndexEntryId);
       
   158 
       
   159 	iSmsTest.Printf(_L("Done\n"));
       
   160 	}
       
   161 
       
   162 void CSmcmRecvOnly::ShowMenuL()
       
   163 	{
       
   164 	RunAutoL();
       
   165 	}
       
   166 
       
   167 void CSmcmRecvOnly::DoRunMainMenuL(TKeyCode aCode)
       
   168 /**
       
   169  * Called by RunL when iState == EMainMenu, when there is a key press event.
       
   170  * Acts on the user's request.
       
   171  */
       
   172 	{
       
   173 	const TChar ch = TChar(aCode);
       
   174 	const TDesC* text = &KHelpText();
       
   175 
       
   176 	switch (ch)
       
   177 		{
       
   178 		case '1':
       
   179 
       
   180 			iSmsTest.Printf(_L("\nStarting Watchers\n"));
       
   181 
       
   182 			if (iWatchers == NULL)
       
   183 				iWatchers = CTestUtilsWatcherStarter::NewL(Priority());
       
   184 			else
       
   185 				iSmsTest.Printf(_L("OOPS: Watchers already started!!\n"));
       
   186 
       
   187 			break;
       
   188 
       
   189 		case '2':
       
   190 
       
   191 			iSmsTest.Printf(_L("\nStopping Watchers\n"));
       
   192 
       
   193 			if (iWatchers == NULL)
       
   194 				iSmsTest.Printf(_L("OOPS: Watchers not started yet!!\n"));
       
   195 			else
       
   196 				{
       
   197 				delete iWatchers;
       
   198 				iWatchers = NULL;
       
   199 				}
       
   200 			break;
       
   201 
       
   202 		case '3':
       
   203 
       
   204 			text = &KMessageText();
       
   205 			iState = ESendingMenu;
       
   206 			break;
       
   207 
       
   208 		case 'D':
       
   209 		case 'd':
       
   210 
       
   211 			iRecvActive->DisplayUnmatched();
       
   212 			break;
       
   213 
       
   214 		case 'x':
       
   215 		case 'X':
       
   216 		case EKeyEscape:
       
   217 
       
   218 			text = NULL;
       
   219 			Complete(KErrNone);
       
   220 			break;
       
   221 
       
   222 		case EKeySpace:
       
   223 
       
   224 			ReshowMenu();
       
   225 			break;
       
   226 
       
   227 		default:
       
   228 
       
   229 			Read();
       
   230 			break;
       
   231 		}
       
   232 
       
   233 	if (!IsActive() && text != NULL)
       
   234 		DisplayAndRead(*text);
       
   235 	}
       
   236 
       
   237 void CSmcmRecvOnly::Read()
       
   238 /**
       
   239  * Issues an asynchronous read on the console
       
   240  */
       
   241 	{
       
   242 	Cancel();
       
   243 	iSmsTest.Test().Console()->Read(iStatus);
       
   244 	SetActive();
       
   245 	}
       
   246 
       
   247 void CSmcmRecvOnly::SendReplaceTypeL()
       
   248 	{
       
   249 	iSmsTest.Printf(_L("\nSendReplaceTypeL\n"));
       
   250 	_LIT(KShortMessage, "Replace Type %d");
       
   251 	TBuf<64> buf;
       
   252 	buf.AppendFormat(KShortMessage, iReplaceTypeCount++);
       
   253 
       
   254 	const TMsvId id = CreateMessageLC(buf);
       
   255 
       
   256 	CSmsHeader* header = iSmsTest.GetHeaderLC(id);
       
   257 
       
   258 	CSmsSubmit& submit = header->Submit();
       
   259 	submit.SetPIDType(TSmsProtocolIdentifier::ESmsPIDShortMessageType);
       
   260 	submit.SetShortMessageType(TSmsProtocolIdentifier::ESmsReplaceShortMessageType1);
       
   261 	StoreMessageL(id, *header);
       
   262 	CleanupStack::PopAndDestroy(header);
       
   263 
       
   264 	iSelection->Reset();
       
   265 	iSelection->AppendL(id);
       
   266 	ScheduleSendL();
       
   267 	iSmsTest.iMsvSession->CleanupEntryPop(); //id
       
   268 	}
       
   269 
       
   270 void CSmcmRecvOnly::DoRunSendingMenuL(TKeyCode aCode)
       
   271 /**
       
   272  * Called by RunL when iState == ESendingMenu, when there is a key press event.
       
   273  * Acts on the user's sending request.
       
   274  */
       
   275 	{
       
   276 	const TChar ch = TChar(aCode);
       
   277 
       
   278 	switch (ch)
       
   279 		{
       
   280 		case '1':
       
   281 			SendShortMessageL();
       
   282 			break;
       
   283 		case '2':
       
   284 			SendLongMessageL();
       
   285 			break;
       
   286 		case '3':
       
   287 			SendMessageIndicationL();
       
   288 			break;
       
   289 
       
   290 		case '4':
       
   291 			SendReplaceTypeL();
       
   292 			break;
       
   293 
       
   294 		case '5':
       
   295 			SendFromScriptL();
       
   296 			break;
       
   297 
       
   298 		case 'D':
       
   299 		case 'd':
       
   300 
       
   301 			iRecvActive->DisplayUnmatched();
       
   302 			ReshowMenu();
       
   303 			break;
       
   304 
       
   305 		case 'x':
       
   306 		case 'X':
       
   307 		case EKeyEscape:
       
   308 
       
   309 			DisplayAndRead(KHelpText);
       
   310 			iState = EMainMenu;
       
   311 			break;
       
   312 
       
   313 		case EKeySpace:
       
   314 			
       
   315 			ReshowMenu();
       
   316 			break;
       
   317 
       
   318 		default:
       
   319 
       
   320 			Read();
       
   321 			break;
       
   322 		}
       
   323 	}
       
   324 
       
   325 void CSmcmRecvOnly::ReshowMenu()
       
   326 /**
       
   327  * Redisplays the current menu
       
   328  */
       
   329 	{
       
   330 	const TDesC* menu = NULL;
       
   331 
       
   332 	switch (iState)
       
   333 		{
       
   334 		case EMainMenu:
       
   335 			menu = &KHelpText();
       
   336 			break;
       
   337 		case ESendingMenu:
       
   338 			menu = &KMessageText();
       
   339 			break;
       
   340 
       
   341 		default:
       
   342 			break;
       
   343 		}
       
   344 
       
   345 	if (menu != NULL)
       
   346 		{
       
   347 		DisplayAndRead(*menu);
       
   348 		}
       
   349 	}
       
   350 
       
   351 void CSmcmRecvOnly::SendFromScriptL()
       
   352 /**
       
   353  * Sends SMS messages from sendrecv.script
       
   354  */
       
   355 	{
       
   356 	iSmsTest.Printf(_L("\nSendFromScriptL\n"));
       
   357 	iSelection->Reset();
       
   358 	TTime now;
       
   359 	now.HomeTime();
       
   360 	iSmsTest.ReadScriptL(iScriptFile, KMsvGlobalOutBoxIndexEntryId, *iSelection, now);
       
   361 	ScheduleSendL();
       
   362 	}
       
   363 
       
   364 void CSmcmRecvOnly::SendLongMessageL()
       
   365 /**
       
   366  * Sends a 2-part concatenated SMS message
       
   367  */
       
   368 	{
       
   369 	iSmsTest.Printf(_L("\nSendLongMessageL\n"));
       
   370 
       
   371 	_LIT(KLongMessage, "LungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungo");
       
   372 	const TMsvId id = CreateMessageLC(KLongMessage);
       
   373 	iSelection->Reset();
       
   374 	iSelection->AppendL(id);
       
   375 	ScheduleSendL();
       
   376 	iSmsTest.iMsvSession->CleanupEntryPop(); //id
       
   377 	}
       
   378 
       
   379 TMsvId CSmcmRecvOnly::CreateMessageLC(const TDesC& aBody)
       
   380 /**
       
   381  * Creates a message in the outbox with body text aBody
       
   382  *
       
   383  * @param aBody Body text of the new message
       
   384  * @return ID of the new message
       
   385  */
       
   386 	{
       
   387 	const TMsvId id = iSmsTest.CreateDummyMessageToSendL();
       
   388 	iSmsTest.iMsvSession->CleanupEntryPushL(id);
       
   389 
       
   390 	CSmsHeader* header = iSmsTest.GetHeaderLC(id);
       
   391 
       
   392 	header->Recipients().ResetAndDestroy();
       
   393 	CSmsNumber* number = CSmsNumber::NewL();
       
   394 	CleanupStack::PushL(number);
       
   395 	number->SetAddressL(*iRecipient);
       
   396 	number->SetNameL(*iRecipient);
       
   397 	header->Recipients().AppendL(number);
       
   398 	CleanupStack::Pop(number);
       
   399 
       
   400 	header->Submit().SetServiceCenterAddressL(*iServiceCenter);
       
   401 
       
   402 	TMsvEntry entry(iSmsTest.Entry());
       
   403 	entry.iDate.HomeTime();
       
   404 	iSmsTest.ChangeEntryL(entry);
       
   405 
       
   406 
       
   407 	_LIT(KDateFormat, " %-B%:0%J%:1%T%:2%S%.%*C4%:3%+B %D%M%Y%/0%1%/1%2%/2%3%/3");
       
   408 	TBuf<64> dateString;
       
   409 	entry.iDate.FormatL(dateString, KDateFormat);
       
   410 	iSmsTest.iRichText->Reset();
       
   411 	iSmsTest.iRichText->InsertL(0, dateString);
       
   412 	iSmsTest.iRichText->InsertL(0, aBody);
       
   413 
       
   414 	StoreMessageL(id, *header);
       
   415 
       
   416 	CleanupStack::PopAndDestroy(header);
       
   417 
       
   418 	return id;
       
   419 	}
       
   420 
       
   421 void CSmcmRecvOnly::SendShortMessageL()
       
   422 /**
       
   423  * Sends a single-part SMS message
       
   424  */
       
   425 	{
       
   426 	iSmsTest.Printf(_L("\nSendShortMessageL\n"));
       
   427 	_LIT(KShortMessage, "ridere");
       
   428 	const TMsvId id = CreateMessageLC(KShortMessage);
       
   429 	iSelection->Reset();
       
   430 	iSelection->AppendL(id);
       
   431 	ScheduleSendL();
       
   432 	iSmsTest.iMsvSession->CleanupEntryPop(); //id
       
   433 	}
       
   434 
       
   435 void CSmcmRecvOnly::StoreMessageL(TMsvId aId, const CSmsHeader& aHeader)
       
   436 /**
       
   437  * Stores the header against a message
       
   438  *
       
   439  * @param aId ID of the message
       
   440  * @param aHeader The CSmsHeader to store against the message
       
   441  */
       
   442 	{
       
   443 	iSmsTest.SetEntryL(aId);
       
   444 	CMsvStore* store = iSmsTest.EditStoreL();
       
   445 	CleanupStack::PushL(store);
       
   446 	aHeader.StoreL(*store);
       
   447 	store->StoreBodyTextL(*iSmsTest.iRichText);
       
   448 	store->CommitL();
       
   449 	CleanupStack::PopAndDestroy(store);
       
   450 	}
       
   451 
       
   452 void CSmcmRecvOnly::ScheduleSendL()
       
   453 /**
       
   454  * Sends all messages in iSelection
       
   455  * @note Messages are actually scheduled. Actual ending occurs a few seconds later.
       
   456  */
       
   457 	{
       
   458 	iState = ESending;
       
   459 	delete iOperation;
       
   460 	iOperation = NULL;
       
   461 	iOperation = iSmsTest.iMsvSession->TransferCommandL(*iSelection, ESmsMtmCommandScheduleCopy, KNullDesC8, iStatus);
       
   462 	SetActive();
       
   463 	}
       
   464 
       
   465 void CSmcmRecvOnly::SendMessageIndicationL(TUint8 aMessageType, TUint8 aMessageCount)
       
   466 /**
       
   467  * Sends an SMS message with Special SMS Message Indication set in the user data header.
       
   468  *
       
   469  * @param aMessageType The type of the Special SMS Message Indication
       
   470  * @param aMessageCount The number of "messages" waiting
       
   471  */
       
   472 	{
       
   473 	iSmsTest.Printf(_L("\nSendMessageIndicationL\n"));
       
   474 	_LIT(KShortMessage, "SMI");
       
   475 	const TMsvId id = CreateMessageLC(KShortMessage);
       
   476 
       
   477 	CSmsHeader* header = iSmsTest.GetHeaderLC(id);
       
   478 
       
   479 	TBuf8<2> data;
       
   480 	data.SetLength(2);
       
   481 	data[0] = aMessageType;
       
   482 	data[1] = aMessageCount;
       
   483 
       
   484 	header->Submit().UserData().AddInformationElementL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication, data);
       
   485 	StoreMessageL(id, *header);
       
   486 	CleanupStack::PopAndDestroy(header);
       
   487 
       
   488 	iSelection->Reset();
       
   489 	iSelection->AppendL(id);
       
   490 	ScheduleSendL();
       
   491 	iSmsTest.iMsvSession->CleanupEntryPop(); //id
       
   492 	}
       
   493 
       
   494 void CSmcmRecvOnly::DoRunSendingL()
       
   495 /**
       
   496  * Called by CSmcmRecvOnly::RunL() when sending has completed.
       
   497  * Displays the current state of all sent messages (in iSelection) and determines whether there was and error.
       
   498  */
       
   499 	{
       
   500 	iSmsTest.SetProgressL(*iOperation);
       
   501 	delete iOperation;
       
   502 	iOperation = NULL;
       
   503 
       
   504 	iSmsTest.Printf(_L("\nDoRunSendingL [iStatus=%d Progress.iError=%d]\n"), iStatus.Int(), iSmsTest.iProgress.iError);
       
   505 
       
   506 	iSmsTest.DisplaySendingStatesL(*iSelection);
       
   507 
       
   508 	TInt error = KErrNone;
       
   509 	const TBool sendingComplete = iSmsTest.SendingCompleteL(*iSelection, error);
       
   510 
       
   511 	iSmsTest.Printf(_L("[sendingCompete=%d error=%d]\n"), sendingComplete, error);
       
   512 
       
   513 	if (iStatus.Int() == KErrNone && iSmsTest.iProgress.iError == KErrNone && error == KErrNone)
       
   514 		iRecvActive->SentL(*iSelection);
       
   515 
       
   516 	iState = ESendingMenu;
       
   517 	DisplayAndRead(KMessageText);
       
   518 	}
       
   519 
       
   520 void CSmcmRecvOnly::RunL()
       
   521 	{
       
   522 	User::LeaveIfError(iStatus.Int());
       
   523 
       
   524 	const TKeyCode keyCode = iSmsTest.Test().Console()->KeyCode();
       
   525 
       
   526 	switch (iState)
       
   527 		{
       
   528 		case EMainMenu:
       
   529 			DoRunMainMenuL(keyCode);
       
   530 			break;
       
   531 		case ESendingMenu:
       
   532 			DoRunSendingMenuL(keyCode);
       
   533 			break;
       
   534 		case ESending:
       
   535 			DoRunSendingL();
       
   536 			break;
       
   537 		}
       
   538 	}
       
   539 
       
   540 TInt CSmcmRecvOnly::RunError(TInt aError)
       
   541 	{
       
   542 	Complete(aError);
       
   543 	return KErrNone;
       
   544 	}
       
   545 
       
   546 void CSmcmRecvOnly::Complete(TInt aStatus)
       
   547 	{
       
   548 	iSmsTest.Printf(_L("CSmcmRecvOnly Completed with %d\n"), aStatus);
       
   549 	CActiveScheduler::Stop();
       
   550 	}
       
   551 
       
   552 void CSmcmRecvOnly::DoCancel()
       
   553 	{
       
   554 	iSmsTest.Test().Console()->ReadCancel();
       
   555 	if (iOperation != NULL)
       
   556 		iOperation->Cancel();
       
   557 	}
       
   558 
       
   559 //
       
   560 
       
   561 CSmcmRecvActive* CSmcmRecvActive::NewL(CSmsTestUtils& aSmsTest, TInt aPriority)
       
   562 /**
       
   563  * CSmcmRecvActive factory function
       
   564  */
       
   565 	{
       
   566 	CSmcmRecvActive* self = new (ELeave) CSmcmRecvActive(aSmsTest, aPriority);
       
   567 	CleanupStack::PushL(self);
       
   568 	self->ConstructL();
       
   569 	CleanupStack::Pop(self);
       
   570 	return self;
       
   571 	}
       
   572 
       
   573 CSmcmRecvActive::CSmcmRecvActive(CSmsTestUtils& aSmsTest, TInt aPriority)
       
   574 : CActive(aPriority), iSmsTest(aSmsTest)
       
   575 /**
       
   576  * CSmcmRecvActive constructor
       
   577  */
       
   578 	{
       
   579 	CActiveScheduler::Add(this);
       
   580 	}
       
   581 
       
   582 CSmcmRecvActive::~CSmcmRecvActive()
       
   583 /**
       
   584  * CSmcmRecvActive destructor
       
   585  */
       
   586 	{
       
   587 	Cancel();
       
   588 	iTimer.Close();
       
   589 	iSmsTest.iMsvSession->RemoveObserver(*this);
       
   590 	delete iSelection;
       
   591 	delete iReceived;
       
   592 	delete iSent;
       
   593 	delete iMatched;
       
   594 	}
       
   595 
       
   596 void CSmcmRecvActive::ConstructL()
       
   597 	{
       
   598 	User::LeaveIfError(iTimer.CreateLocal());
       
   599 	iSelection = new (ELeave) CMsvEntrySelection;
       
   600 	iSent = new (ELeave) CMsvEntrySelection;
       
   601 	iReceived = new (ELeave) CMsvEntrySelection;
       
   602 	iMatched = new (ELeave) CMsvEntrySelection;
       
   603 	iSmsTest.iMsvSession->AddObserverL(*this);
       
   604 	}
       
   605 
       
   606 void CSmcmRecvActive::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* , TAny* )
       
   607 /**
       
   608  * Called by CMsvSession when a messaging event has occurred. It is used here to find out if any new messages have been created.
       
   609  */
       
   610 	{
       
   611 	CMsvEntrySelection* entries = NULL;
       
   612 
       
   613 	switch (aEvent)
       
   614 		{
       
   615 		case EMsvEntriesCreated:
       
   616 			entries = STATIC_CAST(CMsvEntrySelection*, aArg1);
       
   617 			break;
       
   618 		default:
       
   619 			break;
       
   620 		}
       
   621 
       
   622 	if (entries != NULL)
       
   623 		{
       
   624 		TInt count = entries->Count();
       
   625 
       
   626 		while (count--)
       
   627 			{
       
   628 			const TMsvId id = (*entries)[count];
       
   629 			iSmsTest.SetEntryL(id);
       
   630 
       
   631 			const TMsvEntry& entry = iSmsTest.Entry();
       
   632 
       
   633 			if ((entry.iMtm == KUidMsgTypeSMS || entry.iBioType != 0) && entry.iType == KUidMsvMessageEntry)
       
   634 				iSelection->AppendL(id);
       
   635 			}
       
   636 
       
   637 		if (iSelection->Count() != 0)
       
   638 			{
       
   639 			Cancel();
       
   640 			iTimer.After(iStatus, KWaitAfterRecv);
       
   641 			SetActive();
       
   642 			}
       
   643 		}
       
   644 	}
       
   645 
       
   646 void CSmcmRecvActive::RunL()
       
   647 /**
       
   648  * Called after the timer completes, which was started when a new message arrived (in CSmcmRecvActive::HandleSessionEventL()).
       
   649  * Displays all new messages then determines whether they match sent messages.
       
   650  */
       
   651 	{
       
   652 	const TInt recvCount = iReceived->Count();
       
   653 	TInt count = iSelection->Count();
       
   654 
       
   655 	while (count--)
       
   656 		{
       
   657 		const TMsvId id = (*iSelection)[0];
       
   658 		CSmsHeader* header = iSmsTest.GetHeaderLC(id);
       
   659 
       
   660 		if (header->Type() == CSmsPDU::ESmsDeliver)
       
   661 			{
       
   662 			if (Find(*iReceived, id) == KErrNotFound)
       
   663 				iReceived->AppendL(id);
       
   664 
       
   665 			PrintMessageL(id);
       
   666 			}
       
   667 
       
   668 		CleanupStack::PopAndDestroy(header);
       
   669 		iSelection->Delete(0,1);
       
   670 		}
       
   671 
       
   672 	if (recvCount != iReceived->Count())
       
   673 		ProcessReceivedL();
       
   674 	}
       
   675 
       
   676 void CSmcmRecvActive::ProcessReceivedL()
       
   677 /**
       
   678  * Determines whether received messages match the sent messages.
       
   679  * If two messages in iSent and iReceived match, then it is moved from iReceived to iMatched and deleted from iSent.
       
   680  */
       
   681 	{
       
   682 	TInt sentCount = iSent->Count();
       
   683 
       
   684 	while (sentCount--)
       
   685 		{
       
   686 		TInt recvCount = iReceived->Count();
       
   687 		
       
   688 		const TMsvId sentId = (*iSent)[sentCount];
       
   689 		CMsvEntry* sentEntry = iSmsTest.iMsvSession->GetEntryL(sentId);
       
   690 		CleanupStack::PushL(sentEntry);
       
   691 
       
   692 		while (recvCount--)
       
   693 			{
       
   694 			const TMsvId recvId = (*iReceived)[recvCount];
       
   695 			CMsvEntry* recvEntry = iSmsTest.iMsvSession->GetEntryL(recvId);
       
   696 			CleanupStack::PushL(recvEntry);
       
   697 			
       
   698 			if (IsMatchL(*sentEntry, *recvEntry))
       
   699 				{
       
   700 				iMatched->AppendL(recvId);
       
   701 				iSent->Delete(sentCount, 1);
       
   702 				iReceived->Delete(recvCount, 1);
       
   703 				}
       
   704 
       
   705 			CleanupStack::PopAndDestroy(recvEntry);
       
   706 			}
       
   707 
       
   708 		CleanupStack::PopAndDestroy(sentEntry);
       
   709 		}
       
   710 	}
       
   711 
       
   712 TBool CSmcmRecvActive::IsMatchL(CMsvEntry& aSent, CMsvEntry& aReceived)
       
   713 /**
       
   714  * Compares the body text of aSent and aReceived
       
   715  *
       
   716  * @return Returns ETrue if the body text matches
       
   717  */
       
   718 	{
       
   719 	HBufC* sentBody = GetBodyTextLC(aSent);
       
   720 	HBufC* recvBody = GetBodyTextLC(aReceived);
       
   721 	TBool retVal = (*sentBody == *recvBody);
       
   722 	CleanupStack::PopAndDestroy(recvBody);
       
   723 	CleanupStack::PopAndDestroy(sentBody);
       
   724 
       
   725 	// todo AA 28/2/2002 Is more checking required?
       
   726 
       
   727 	return retVal;
       
   728 	}
       
   729 
       
   730 CSmsHeader* CSmcmRecvActive::GetHeaderLC(CMsvEntry& aMessage) const
       
   731 /**
       
   732  * Returns the CSmsHeader restored from message aMessage.
       
   733  */
       
   734 	{
       
   735 	CSmsHeader* header = CSmsHeader::NewL(CSmsMessage::NewL(iSmsTest.FileSession(), CSmsPDU::ESmsDeliver, CSmsBuffer::NewL()));
       
   736 	CleanupStack::PushL(header);
       
   737 
       
   738 	CMsvStore* store = aMessage.ReadStoreL();
       
   739 	CleanupStack::PushL(store);
       
   740 	header->RestoreL(*store);
       
   741 	CleanupStack::PopAndDestroy(store);
       
   742 
       
   743 	return header;
       
   744 	}
       
   745 
       
   746 HBufC* CSmcmRecvActive::GetBodyTextLC(CMsvEntry& aMessage)
       
   747 /**
       
   748  * @return The body text of message aMessage
       
   749  */
       
   750 	{
       
   751 	iSmsTest.iRichText->Reset();
       
   752 	CMsvStore* store = aMessage.ReadStoreL();
       
   753 	CleanupStack::PushL(store);
       
   754 	store->RestoreBodyTextL(*iSmsTest.iRichText);
       
   755 	CleanupStack::PopAndDestroy(store);
       
   756 	
       
   757 	const TInt len = iSmsTest.iRichText->DocumentLength();
       
   758 	HBufC* buf = HBufC::NewLC(len);
       
   759 	TPtr ptr(buf->Des());
       
   760 	iSmsTest.iRichText->Extract(ptr);
       
   761 	return buf;
       
   762 	}
       
   763 
       
   764 TInt CSmcmRecvActive::Find(const CMsvEntrySelection& aSelection, TMsvId aId) const
       
   765 /**
       
   766  * Attempts to find a message in a selection (array).
       
   767  *
       
   768  * @param aSelection The selection of messages to search
       
   769  * @param aId The message to find in aSelection
       
   770  * @return The index of aId in aSelection or KErrNotFound if aId is not in aSelection
       
   771  */
       
   772 	{
       
   773 	TInt count = aSelection.Count();
       
   774 
       
   775 	while (count--)
       
   776 		{
       
   777 		const TMsvId id = aSelection[count];
       
   778 		if (id == aId)
       
   779 			return count;
       
   780 		}
       
   781 
       
   782 	return KErrNotFound;
       
   783 	}
       
   784 
       
   785 void CSmcmRecvActive::PrintMessageL(TMsvId aId)
       
   786 /**
       
   787  * Displays the received message aId
       
   788  */
       
   789 	{
       
   790 	iSmsTest.iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId);
       
   791 	iSmsTest.Printf(_L("\nReceived Message #%d of %d!! Inbox Count=%d\n"), Received(), Sent(), iSmsTest.iMsvEntry->Count());
       
   792 	iSmsTest.DisplayMessageL(aId);
       
   793 	}
       
   794 
       
   795 void CSmcmRecvActive::SentL(const CMsvEntrySelection& aSelection)
       
   796 /**
       
   797  * Copies aSelection into iSent. One entry is added to iSent for every receipient of each message in aSelection.
       
   798  */
       
   799 	{
       
   800 	TInt count = aSelection.Count();
       
   801 	while (count--)
       
   802 		{
       
   803 		const TMsvId id = aSelection[count];
       
   804 		CSmsHeader* header = iSmsTest.GetHeaderLC(id);
       
   805 		TInt recptCount = header->Recipients().Count();
       
   806 
       
   807 		while (recptCount--)
       
   808 			iSent->AppendL(id);
       
   809 
       
   810 		CleanupStack::PopAndDestroy(header);
       
   811 		}
       
   812 	}
       
   813 
       
   814 TInt CSmcmRecvActive::RunError(TInt aError)
       
   815 	{
       
   816 	iSmsTest.Printf(_L("WARNING: CSmcmRecvActive::RunL() left with %d\n"), aError);
       
   817 	iTimer.After(iStatus, KWaitAfterRecv);
       
   818 	SetActive();
       
   819 	return KErrNone;
       
   820 	}
       
   821 
       
   822 void CSmcmRecvActive::DoCancel()
       
   823 	{
       
   824 	iTimer.Cancel();
       
   825 	}
       
   826 
       
   827 void CSmcmRecvActive::DisplayUnmatched() const
       
   828 /**
       
   829  * Displays all messages that are yet to be matched
       
   830  */
       
   831 	{
       
   832 	_LIT(KDisplayFormat, "\nSent %d Received %d Matched %d Unmatched %d\n");
       
   833 
       
   834 	if (iSent->Count() != 0)
       
   835 		{
       
   836 		iSmsTest.Printf(_L("\nUnmatched Messages:\n"));
       
   837 		TRAPD(err, iSmsTest.DisplaySendingStatesL(*iSent));
       
   838 		iSmsTest.Printf(_L("\n"));
       
   839 		if (err != KErrNone)
       
   840 			iSmsTest.Printf(_L("WARNING: DisplaySendingStatesL left with %d\n"), err);
       
   841 		}
       
   842 
       
   843 	iSmsTest.Printf(KDisplayFormat, Sent(), Received(), iMatched->Count(), iSent->Count());
       
   844 	}