diff -r 000000000000 -r 72b543305e3a mobilemessaging/smsmtm/test/src/t_smcmrecvmanual.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobilemessaging/smsmtm/test/src/t_smcmrecvmanual.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,844 @@ +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "t_smcmrecvmanual.h" +#include +#include +#include +#include +#include + +_LIT(KSmcmRecvOnlyTestName, "Receive SMS Messages"); +_LIT(KHelpText, "\n[1] Start Watchers\n[2] Stop Watchers\n[3] Send myself message\n[D] Display Unmatched Messages\ne[X]it\n"); +_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"); +_LIT(KSmsScript, "sendrecv.script"); +_LIT(KDefaultScript, "defaults.script"); +_LIT(KRecipients, "Recipients"); +_LIT(KServiceCenter, "SC"); +const TInt KWaitAfterRecv = 100000; //< 0.1 second + +RTest test(_L("T_SmcmRecvManual: Receive SMS Messages")); +CTrapCleanup* theCleanup; + +LOCAL_C void doMainL() + { + CActiveScheduler* scheduler = new (ELeave) CActiveScheduler; + CleanupStack::PushL(scheduler); + CActiveScheduler::Install( scheduler ); + + CSmsTestUtils* smsTest = CSmsTestUtils::NewL(test); + CleanupStack::PushL(smsTest); + TInt nextTest = 0; + + smsTest->NotifySaPhoneOnL(); + + CSmcmRecvOnly* scTest = CSmcmRecvOnly::NewLC(*smsTest, KSmsScript, nextTest); + + scTest->StartL(); + + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(3); //SmsTest, scheduler + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + test.Start(_L("Setup")); + theCleanup = CTrapCleanup::New(); + TRAPD(ret,doMainL()); + test(ret==KErrNone); + delete theCleanup; + test.Console()->SetPos(0, 13); + test.End(); + test.Close(); + __UHEAP_MARKEND; + return(KErrNone); + } + +CSmcmRecvOnly::~CSmcmRecvOnly() +/** + * CSmcmRecvOnly destructor + */ + { + Cancel(); + delete iRecvActive; + delete iWatchers; + delete iOperation; + iOperation = NULL; + + delete iRecipient; + delete iServiceCenter; + + delete iSelection; + iSelection = NULL; + } + +CSmcmRecvOnly* CSmcmRecvOnly::NewLC(CSmsTestUtils& aSmsTest, const TDesC& aScriptFile, TInt& aNextTest) +/** + * CSmcmRecvOnly factory function + */ + { + CSmcmRecvOnly* self = new (ELeave) CSmcmRecvOnly(aSmsTest, aScriptFile, aNextTest); + CleanupStack::PushL(self); + + self->ConstructL(); + return self; + } + +CSmcmRecvOnly::CSmcmRecvOnly(CSmsTestUtils& aSmsTest, const TDesC& aScriptFile, TInt& aNextTest) +: CSmsTestBase(aSmsTest, aScriptFile, aNextTest) +/** + * CSmcmRecvOnly constructor + */ + { + CActiveScheduler::Add(this); + } + +void CSmcmRecvOnly::DisplayAndRead(const TDesC& aText) +/** + * Displays aText then issues a read on the console + */ + { + iSmsTest.Printf(aText); + Read(); + } + +void CSmcmRecvOnly::RunAutoL() + { + DisplayAndRead(KHelpText); + } + +void CSmcmRecvOnly::ConstructL() + { + iSmsTest.NotifySaPhoneOnL(); + SetTestNameL(KSmcmRecvOnlyTestName); + iSmsTest.InstantiateClientMtmsL(); + + iSmsTest.SetLogToFile(); + iRecvActive = CSmcmRecvActive::NewL(iSmsTest, Priority()-1); + iSelection = new (ELeave) CMsvEntrySelection; + + User::After(1000000); + + CScriptFile* script = CScriptFile::NewLC(iSmsTest, KSmsComponent); + script->ReadScriptL(KDefaultScript); + + iRecipient = script->ItemValue(KDefaults, KRecipients, KNullDesC).AllocL(); + iServiceCenter = script->ItemValue(KDefaults, KServiceCenter, KNullDesC).AllocL(); + + CleanupStack::PopAndDestroy(script); + + User::After(1000000); + + iSmsTest.Printf(_L("Deleting SMS messages in outbox...")); + iSmsTest.DeleteSmsMessagesL(KMsvGlobalOutBoxIndexEntryId); + + User::After(1000000); + + iSmsTest.Printf(_L("Done\nDeleting SMS messages in sent...")); + iSmsTest.DeleteSmsMessagesL(KMsvSentEntryId); + + User::After(1000000); + + iSmsTest.Printf(_L("Done\nDeleting SMS messages in inbox...")); + iSmsTest.DeleteSmsMessagesL(KMsvGlobalInBoxIndexEntryId); + + iSmsTest.Printf(_L("Done\n")); + } + +void CSmcmRecvOnly::ShowMenuL() + { + RunAutoL(); + } + +void CSmcmRecvOnly::DoRunMainMenuL(TKeyCode aCode) +/** + * Called by RunL when iState == EMainMenu, when there is a key press event. + * Acts on the user's request. + */ + { + const TChar ch = TChar(aCode); + const TDesC* text = &KHelpText(); + + switch (ch) + { + case '1': + + iSmsTest.Printf(_L("\nStarting Watchers\n")); + + if (iWatchers == NULL) + iWatchers = CTestUtilsWatcherStarter::NewL(Priority()); + else + iSmsTest.Printf(_L("OOPS: Watchers already started!!\n")); + + break; + + case '2': + + iSmsTest.Printf(_L("\nStopping Watchers\n")); + + if (iWatchers == NULL) + iSmsTest.Printf(_L("OOPS: Watchers not started yet!!\n")); + else + { + delete iWatchers; + iWatchers = NULL; + } + break; + + case '3': + + text = &KMessageText(); + iState = ESendingMenu; + break; + + case 'D': + case 'd': + + iRecvActive->DisplayUnmatched(); + break; + + case 'x': + case 'X': + case EKeyEscape: + + text = NULL; + Complete(KErrNone); + break; + + case EKeySpace: + + ReshowMenu(); + break; + + default: + + Read(); + break; + } + + if (!IsActive() && text != NULL) + DisplayAndRead(*text); + } + +void CSmcmRecvOnly::Read() +/** + * Issues an asynchronous read on the console + */ + { + Cancel(); + iSmsTest.Test().Console()->Read(iStatus); + SetActive(); + } + +void CSmcmRecvOnly::SendReplaceTypeL() + { + iSmsTest.Printf(_L("\nSendReplaceTypeL\n")); + _LIT(KShortMessage, "Replace Type %d"); + TBuf<64> buf; + buf.AppendFormat(KShortMessage, iReplaceTypeCount++); + + const TMsvId id = CreateMessageLC(buf); + + CSmsHeader* header = iSmsTest.GetHeaderLC(id); + + CSmsSubmit& submit = header->Submit(); + submit.SetPIDType(TSmsProtocolIdentifier::ESmsPIDShortMessageType); + submit.SetShortMessageType(TSmsProtocolIdentifier::ESmsReplaceShortMessageType1); + StoreMessageL(id, *header); + CleanupStack::PopAndDestroy(header); + + iSelection->Reset(); + iSelection->AppendL(id); + ScheduleSendL(); + iSmsTest.iMsvSession->CleanupEntryPop(); //id + } + +void CSmcmRecvOnly::DoRunSendingMenuL(TKeyCode aCode) +/** + * Called by RunL when iState == ESendingMenu, when there is a key press event. + * Acts on the user's sending request. + */ + { + const TChar ch = TChar(aCode); + + switch (ch) + { + case '1': + SendShortMessageL(); + break; + case '2': + SendLongMessageL(); + break; + case '3': + SendMessageIndicationL(); + break; + + case '4': + SendReplaceTypeL(); + break; + + case '5': + SendFromScriptL(); + break; + + case 'D': + case 'd': + + iRecvActive->DisplayUnmatched(); + ReshowMenu(); + break; + + case 'x': + case 'X': + case EKeyEscape: + + DisplayAndRead(KHelpText); + iState = EMainMenu; + break; + + case EKeySpace: + + ReshowMenu(); + break; + + default: + + Read(); + break; + } + } + +void CSmcmRecvOnly::ReshowMenu() +/** + * Redisplays the current menu + */ + { + const TDesC* menu = NULL; + + switch (iState) + { + case EMainMenu: + menu = &KHelpText(); + break; + case ESendingMenu: + menu = &KMessageText(); + break; + + default: + break; + } + + if (menu != NULL) + { + DisplayAndRead(*menu); + } + } + +void CSmcmRecvOnly::SendFromScriptL() +/** + * Sends SMS messages from sendrecv.script + */ + { + iSmsTest.Printf(_L("\nSendFromScriptL\n")); + iSelection->Reset(); + TTime now; + now.HomeTime(); + iSmsTest.ReadScriptL(iScriptFile, KMsvGlobalOutBoxIndexEntryId, *iSelection, now); + ScheduleSendL(); + } + +void CSmcmRecvOnly::SendLongMessageL() +/** + * Sends a 2-part concatenated SMS message + */ + { + iSmsTest.Printf(_L("\nSendLongMessageL\n")); + + _LIT(KLongMessage, "LungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungoLungo"); + const TMsvId id = CreateMessageLC(KLongMessage); + iSelection->Reset(); + iSelection->AppendL(id); + ScheduleSendL(); + iSmsTest.iMsvSession->CleanupEntryPop(); //id + } + +TMsvId CSmcmRecvOnly::CreateMessageLC(const TDesC& aBody) +/** + * Creates a message in the outbox with body text aBody + * + * @param aBody Body text of the new message + * @return ID of the new message + */ + { + const TMsvId id = iSmsTest.CreateDummyMessageToSendL(); + iSmsTest.iMsvSession->CleanupEntryPushL(id); + + CSmsHeader* header = iSmsTest.GetHeaderLC(id); + + header->Recipients().ResetAndDestroy(); + CSmsNumber* number = CSmsNumber::NewL(); + CleanupStack::PushL(number); + number->SetAddressL(*iRecipient); + number->SetNameL(*iRecipient); + header->Recipients().AppendL(number); + CleanupStack::Pop(number); + + header->Submit().SetServiceCenterAddressL(*iServiceCenter); + + TMsvEntry entry(iSmsTest.Entry()); + entry.iDate.HomeTime(); + iSmsTest.ChangeEntryL(entry); + + + _LIT(KDateFormat, " %-B%:0%J%:1%T%:2%S%.%*C4%:3%+B %D%M%Y%/0%1%/1%2%/2%3%/3"); + TBuf<64> dateString; + entry.iDate.FormatL(dateString, KDateFormat); + iSmsTest.iRichText->Reset(); + iSmsTest.iRichText->InsertL(0, dateString); + iSmsTest.iRichText->InsertL(0, aBody); + + StoreMessageL(id, *header); + + CleanupStack::PopAndDestroy(header); + + return id; + } + +void CSmcmRecvOnly::SendShortMessageL() +/** + * Sends a single-part SMS message + */ + { + iSmsTest.Printf(_L("\nSendShortMessageL\n")); + _LIT(KShortMessage, "ridere"); + const TMsvId id = CreateMessageLC(KShortMessage); + iSelection->Reset(); + iSelection->AppendL(id); + ScheduleSendL(); + iSmsTest.iMsvSession->CleanupEntryPop(); //id + } + +void CSmcmRecvOnly::StoreMessageL(TMsvId aId, const CSmsHeader& aHeader) +/** + * Stores the header against a message + * + * @param aId ID of the message + * @param aHeader The CSmsHeader to store against the message + */ + { + iSmsTest.SetEntryL(aId); + CMsvStore* store = iSmsTest.EditStoreL(); + CleanupStack::PushL(store); + aHeader.StoreL(*store); + store->StoreBodyTextL(*iSmsTest.iRichText); + store->CommitL(); + CleanupStack::PopAndDestroy(store); + } + +void CSmcmRecvOnly::ScheduleSendL() +/** + * Sends all messages in iSelection + * @note Messages are actually scheduled. Actual ending occurs a few seconds later. + */ + { + iState = ESending; + delete iOperation; + iOperation = NULL; + iOperation = iSmsTest.iMsvSession->TransferCommandL(*iSelection, ESmsMtmCommandScheduleCopy, KNullDesC8, iStatus); + SetActive(); + } + +void CSmcmRecvOnly::SendMessageIndicationL(TUint8 aMessageType, TUint8 aMessageCount) +/** + * Sends an SMS message with Special SMS Message Indication set in the user data header. + * + * @param aMessageType The type of the Special SMS Message Indication + * @param aMessageCount The number of "messages" waiting + */ + { + iSmsTest.Printf(_L("\nSendMessageIndicationL\n")); + _LIT(KShortMessage, "SMI"); + const TMsvId id = CreateMessageLC(KShortMessage); + + CSmsHeader* header = iSmsTest.GetHeaderLC(id); + + TBuf8<2> data; + data.SetLength(2); + data[0] = aMessageType; + data[1] = aMessageCount; + + header->Submit().UserData().AddInformationElementL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication, data); + StoreMessageL(id, *header); + CleanupStack::PopAndDestroy(header); + + iSelection->Reset(); + iSelection->AppendL(id); + ScheduleSendL(); + iSmsTest.iMsvSession->CleanupEntryPop(); //id + } + +void CSmcmRecvOnly::DoRunSendingL() +/** + * Called by CSmcmRecvOnly::RunL() when sending has completed. + * Displays the current state of all sent messages (in iSelection) and determines whether there was and error. + */ + { + iSmsTest.SetProgressL(*iOperation); + delete iOperation; + iOperation = NULL; + + iSmsTest.Printf(_L("\nDoRunSendingL [iStatus=%d Progress.iError=%d]\n"), iStatus.Int(), iSmsTest.iProgress.iError); + + iSmsTest.DisplaySendingStatesL(*iSelection); + + TInt error = KErrNone; + const TBool sendingComplete = iSmsTest.SendingCompleteL(*iSelection, error); + + iSmsTest.Printf(_L("[sendingCompete=%d error=%d]\n"), sendingComplete, error); + + if (iStatus.Int() == KErrNone && iSmsTest.iProgress.iError == KErrNone && error == KErrNone) + iRecvActive->SentL(*iSelection); + + iState = ESendingMenu; + DisplayAndRead(KMessageText); + } + +void CSmcmRecvOnly::RunL() + { + User::LeaveIfError(iStatus.Int()); + + const TKeyCode keyCode = iSmsTest.Test().Console()->KeyCode(); + + switch (iState) + { + case EMainMenu: + DoRunMainMenuL(keyCode); + break; + case ESendingMenu: + DoRunSendingMenuL(keyCode); + break; + case ESending: + DoRunSendingL(); + break; + } + } + +TInt CSmcmRecvOnly::RunError(TInt aError) + { + Complete(aError); + return KErrNone; + } + +void CSmcmRecvOnly::Complete(TInt aStatus) + { + iSmsTest.Printf(_L("CSmcmRecvOnly Completed with %d\n"), aStatus); + CActiveScheduler::Stop(); + } + +void CSmcmRecvOnly::DoCancel() + { + iSmsTest.Test().Console()->ReadCancel(); + if (iOperation != NULL) + iOperation->Cancel(); + } + +// + +CSmcmRecvActive* CSmcmRecvActive::NewL(CSmsTestUtils& aSmsTest, TInt aPriority) +/** + * CSmcmRecvActive factory function + */ + { + CSmcmRecvActive* self = new (ELeave) CSmcmRecvActive(aSmsTest, aPriority); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CSmcmRecvActive::CSmcmRecvActive(CSmsTestUtils& aSmsTest, TInt aPriority) +: CActive(aPriority), iSmsTest(aSmsTest) +/** + * CSmcmRecvActive constructor + */ + { + CActiveScheduler::Add(this); + } + +CSmcmRecvActive::~CSmcmRecvActive() +/** + * CSmcmRecvActive destructor + */ + { + Cancel(); + iTimer.Close(); + iSmsTest.iMsvSession->RemoveObserver(*this); + delete iSelection; + delete iReceived; + delete iSent; + delete iMatched; + } + +void CSmcmRecvActive::ConstructL() + { + User::LeaveIfError(iTimer.CreateLocal()); + iSelection = new (ELeave) CMsvEntrySelection; + iSent = new (ELeave) CMsvEntrySelection; + iReceived = new (ELeave) CMsvEntrySelection; + iMatched = new (ELeave) CMsvEntrySelection; + iSmsTest.iMsvSession->AddObserverL(*this); + } + +void CSmcmRecvActive::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* , TAny* ) +/** + * Called by CMsvSession when a messaging event has occurred. It is used here to find out if any new messages have been created. + */ + { + CMsvEntrySelection* entries = NULL; + + switch (aEvent) + { + case EMsvEntriesCreated: + entries = STATIC_CAST(CMsvEntrySelection*, aArg1); + break; + default: + break; + } + + if (entries != NULL) + { + TInt count = entries->Count(); + + while (count--) + { + const TMsvId id = (*entries)[count]; + iSmsTest.SetEntryL(id); + + const TMsvEntry& entry = iSmsTest.Entry(); + + if ((entry.iMtm == KUidMsgTypeSMS || entry.iBioType != 0) && entry.iType == KUidMsvMessageEntry) + iSelection->AppendL(id); + } + + if (iSelection->Count() != 0) + { + Cancel(); + iTimer.After(iStatus, KWaitAfterRecv); + SetActive(); + } + } + } + +void CSmcmRecvActive::RunL() +/** + * Called after the timer completes, which was started when a new message arrived (in CSmcmRecvActive::HandleSessionEventL()). + * Displays all new messages then determines whether they match sent messages. + */ + { + const TInt recvCount = iReceived->Count(); + TInt count = iSelection->Count(); + + while (count--) + { + const TMsvId id = (*iSelection)[0]; + CSmsHeader* header = iSmsTest.GetHeaderLC(id); + + if (header->Type() == CSmsPDU::ESmsDeliver) + { + if (Find(*iReceived, id) == KErrNotFound) + iReceived->AppendL(id); + + PrintMessageL(id); + } + + CleanupStack::PopAndDestroy(header); + iSelection->Delete(0,1); + } + + if (recvCount != iReceived->Count()) + ProcessReceivedL(); + } + +void CSmcmRecvActive::ProcessReceivedL() +/** + * Determines whether received messages match the sent messages. + * If two messages in iSent and iReceived match, then it is moved from iReceived to iMatched and deleted from iSent. + */ + { + TInt sentCount = iSent->Count(); + + while (sentCount--) + { + TInt recvCount = iReceived->Count(); + + const TMsvId sentId = (*iSent)[sentCount]; + CMsvEntry* sentEntry = iSmsTest.iMsvSession->GetEntryL(sentId); + CleanupStack::PushL(sentEntry); + + while (recvCount--) + { + const TMsvId recvId = (*iReceived)[recvCount]; + CMsvEntry* recvEntry = iSmsTest.iMsvSession->GetEntryL(recvId); + CleanupStack::PushL(recvEntry); + + if (IsMatchL(*sentEntry, *recvEntry)) + { + iMatched->AppendL(recvId); + iSent->Delete(sentCount, 1); + iReceived->Delete(recvCount, 1); + } + + CleanupStack::PopAndDestroy(recvEntry); + } + + CleanupStack::PopAndDestroy(sentEntry); + } + } + +TBool CSmcmRecvActive::IsMatchL(CMsvEntry& aSent, CMsvEntry& aReceived) +/** + * Compares the body text of aSent and aReceived + * + * @return Returns ETrue if the body text matches + */ + { + HBufC* sentBody = GetBodyTextLC(aSent); + HBufC* recvBody = GetBodyTextLC(aReceived); + TBool retVal = (*sentBody == *recvBody); + CleanupStack::PopAndDestroy(recvBody); + CleanupStack::PopAndDestroy(sentBody); + + // todo AA 28/2/2002 Is more checking required? + + return retVal; + } + +CSmsHeader* CSmcmRecvActive::GetHeaderLC(CMsvEntry& aMessage) const +/** + * Returns the CSmsHeader restored from message aMessage. + */ + { + CSmsHeader* header = CSmsHeader::NewL(CSmsMessage::NewL(iSmsTest.FileSession(), CSmsPDU::ESmsDeliver, CSmsBuffer::NewL())); + CleanupStack::PushL(header); + + CMsvStore* store = aMessage.ReadStoreL(); + CleanupStack::PushL(store); + header->RestoreL(*store); + CleanupStack::PopAndDestroy(store); + + return header; + } + +HBufC* CSmcmRecvActive::GetBodyTextLC(CMsvEntry& aMessage) +/** + * @return The body text of message aMessage + */ + { + iSmsTest.iRichText->Reset(); + CMsvStore* store = aMessage.ReadStoreL(); + CleanupStack::PushL(store); + store->RestoreBodyTextL(*iSmsTest.iRichText); + CleanupStack::PopAndDestroy(store); + + const TInt len = iSmsTest.iRichText->DocumentLength(); + HBufC* buf = HBufC::NewLC(len); + TPtr ptr(buf->Des()); + iSmsTest.iRichText->Extract(ptr); + return buf; + } + +TInt CSmcmRecvActive::Find(const CMsvEntrySelection& aSelection, TMsvId aId) const +/** + * Attempts to find a message in a selection (array). + * + * @param aSelection The selection of messages to search + * @param aId The message to find in aSelection + * @return The index of aId in aSelection or KErrNotFound if aId is not in aSelection + */ + { + TInt count = aSelection.Count(); + + while (count--) + { + const TMsvId id = aSelection[count]; + if (id == aId) + return count; + } + + return KErrNotFound; + } + +void CSmcmRecvActive::PrintMessageL(TMsvId aId) +/** + * Displays the received message aId + */ + { + iSmsTest.iMsvEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId); + iSmsTest.Printf(_L("\nReceived Message #%d of %d!! Inbox Count=%d\n"), Received(), Sent(), iSmsTest.iMsvEntry->Count()); + iSmsTest.DisplayMessageL(aId); + } + +void CSmcmRecvActive::SentL(const CMsvEntrySelection& aSelection) +/** + * Copies aSelection into iSent. One entry is added to iSent for every receipient of each message in aSelection. + */ + { + TInt count = aSelection.Count(); + while (count--) + { + const TMsvId id = aSelection[count]; + CSmsHeader* header = iSmsTest.GetHeaderLC(id); + TInt recptCount = header->Recipients().Count(); + + while (recptCount--) + iSent->AppendL(id); + + CleanupStack::PopAndDestroy(header); + } + } + +TInt CSmcmRecvActive::RunError(TInt aError) + { + iSmsTest.Printf(_L("WARNING: CSmcmRecvActive::RunL() left with %d\n"), aError); + iTimer.After(iStatus, KWaitAfterRecv); + SetActive(); + return KErrNone; + } + +void CSmcmRecvActive::DoCancel() + { + iTimer.Cancel(); + } + +void CSmcmRecvActive::DisplayUnmatched() const +/** + * Displays all messages that are yet to be matched + */ + { + _LIT(KDisplayFormat, "\nSent %d Received %d Matched %d Unmatched %d\n"); + + if (iSent->Count() != 0) + { + iSmsTest.Printf(_L("\nUnmatched Messages:\n")); + TRAPD(err, iSmsTest.DisplaySendingStatesL(*iSent)); + iSmsTest.Printf(_L("\n")); + if (err != KErrNone) + iSmsTest.Printf(_L("WARNING: DisplaySendingStatesL left with %d\n"), err); + } + + iSmsTest.Printf(KDisplayFormat, Sent(), Received(), iMatched->Count(), iSent->Count()); + }