smsprotocols/smsstack/test/smsstackbaseteststeps.cpp
changeset 20 244d7c5f118e
child 24 6638e7f4bd8f
child 44 8b72faa1200f
equal deleted inserted replaced
19:1f776524b15c 20:244d7c5f118e
       
     1 // Copyright (c) 2009-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 "smsstackbaseteststeps.h"
       
    17 
       
    18 #include <testconfigfileparser.h>
       
    19 #include <simtsy.h>
       
    20 #include <commsdattypesv1_1.h>
       
    21 #include <gsmubuf.h>
       
    22 #include <Gsmumsg.h>
       
    23 #include <gsmuset.h>
       
    24 #include <es_sock.h>
       
    25 #include <smsustrm.h>
       
    26 #include <c32root.h>
       
    27 #include <sacls.h>
       
    28 #include <e32math.h>
       
    29 #include <smspver.h>
       
    30 
       
    31 #include "smsstacktestutilities.h"
       
    32 #include "smsstacktestconsts.h"
       
    33 #include "smsstacktestcase.h"
       
    34 #include "smspdudb.h"
       
    35 
       
    36 using namespace CommsDat;
       
    37 
       
    38 EXPORT_C CSmsBaseTestStep::CSmsBaseTestStep()
       
    39     {
       
    40     // empty
       
    41     }
       
    42 
       
    43 EXPORT_C CSmsBaseTestStep::~CSmsBaseTestStep()
       
    44     {
       
    45     // empty       
       
    46     }
       
    47 
       
    48 /**
       
    49     Creates the file server session and marks the heap
       
    50 */
       
    51 EXPORT_C TVerdict CSmsBaseTestStep::doTestStepPreambleL()
       
    52     {
       
    53     RDebug::Print(_L("%S"), &TestStepName());
       
    54     
       
    55     User::LeaveIfError(iFs.Connect());  
       
    56     
       
    57     __UHEAP_MARK;
       
    58     
       
    59     SetTestNumberFromConfigurationFileL();
       
    60     
       
    61     iSmsStackTestUtils = CSmsStackTestUtils::NewL(this,  iFs);
       
    62     
       
    63     iScheduler = new(ELeave) CActiveScheduler;
       
    64     CActiveScheduler::Install(iScheduler);
       
    65     
       
    66     TRAPD(ret, ParseSettingsFromFileL());
       
    67     TESTCHECK(ret, KErrNone, "ParseSettingsFromFileL");
       
    68     
       
    69 
       
    70     if (!iPartOfMultiStepTestCase)
       
    71         {
       
    72         ConnectSocketServerL(iSocketServer);
       
    73         }
       
    74     
       
    75     return TestStepResult();
       
    76     }
       
    77 
       
    78 /**
       
    79     Closes file server session and unmarks the heap 
       
    80 */
       
    81 EXPORT_C TVerdict CSmsBaseTestStep::doTestStepPostambleL()
       
    82     {
       
    83     if (!iPartOfMultiStepTestCase)
       
    84         {
       
    85         iSocketServer.Close();
       
    86         }
       
    87     
       
    88     delete iScheduler;
       
    89     iScheduler = NULL;
       
    90     
       
    91     delete iSmsStackTestUtils;
       
    92     iSmsStackTestUtils = NULL;
       
    93     
       
    94     __UHEAP_MARKEND;
       
    95     
       
    96     iFs.Close();
       
    97     
       
    98     if ( !iPartOfMultiStepTestCase && !iNotLastTestStep)
       
    99         {
       
   100         DoESockMemoryLeakTestL();
       
   101         }
       
   102     
       
   103     return TestStepResult();
       
   104     }
       
   105     
       
   106 // TODO Method not needed - should be removed and replaced where appropriate
       
   107 EXPORT_C void CSmsBaseTestStep::ParseSettingsFromFileL()
       
   108     {
       
   109     CTestConfig* configFile = CTestConfig::NewLC(iFs,KGmsSmsConfigFileDir,KGmsSmsConfigFileName);
       
   110     
       
   111     const CTestConfigSection* cfgFile = configFile->Section(KSetupTelNumbers);
       
   112     TESTCHECKCONDITIONL(cfgFile!=NULL, "Open SMS configuration file");
       
   113 
       
   114     const CTestConfigItem* item = cfgFile->Item(KServiceCenter,0);
       
   115     TESTCHECKCONDITIONL(item!=NULL, "Read ServiceCentre value from the configuration file");
       
   116 
       
   117     iServiceCenterNumber.Copy(item->Value());
       
   118 
       
   119     item = cfgFile->Item(KTelefoneNumber,0);
       
   120     TESTCHECKCONDITIONL(item!=NULL, "Read TelephoneNumber value from the configuration file");
       
   121     
       
   122     iTelephoneNumber.Copy(item->Value());
       
   123 
       
   124     CleanupStack::PopAndDestroy(configFile);
       
   125     }
       
   126 
       
   127 /**
       
   128  * Read the test number from  the configuration file.
       
   129  * The test number is passed via property KUidPSSimTsyCategory. 
       
   130  * The SIM tsy uses test number to parse correct script from config.txt
       
   131  * @return ETrue, if the test number has been assigned successfully, otherwise EFalse.
       
   132  */
       
   133 EXPORT_C void CSmsBaseTestStep::SetTestNumberFromConfigurationFileL()
       
   134     {
       
   135     TInt testNumber (0);
       
   136     if(GetIntFromConfig( ConfigSection(), KTestCaseNumber, testNumber))
       
   137         {
       
   138         SetSimTSYTestNumberL(testNumber);
       
   139         }
       
   140     }
       
   141 
       
   142 EXPORT_C void CSmsBaseTestStep::SetSimTSYTestNumberL(TInt aTestNumber)
       
   143 /**
       
   144     Set the SIM TSY Test number 
       
   145     @param aTestNumber is the test number in SIM TSY config file
       
   146 */
       
   147     {   
       
   148     SetTestNumberL(KPSSimTsyTestNumber, aTestNumber);
       
   149     }
       
   150 
       
   151 /**
       
   152  *  The test number is set with property aTestNumberProperty. This will notify the SIM tsy.
       
   153  *  SIM tsy uses test number to parse correct script from the configuration file.
       
   154  *  @param aTestNumberProperty The test number property UID
       
   155  *  @param aTestNumber The test number corresponding the test case
       
   156  */
       
   157 EXPORT_C void CSmsBaseTestStep::SetTestNumberL(TInt aTestNumberProperty, TInt aTestNumber)
       
   158     {
       
   159     //
       
   160     // Set the SIM.TSY test number...
       
   161     //
       
   162     RProperty testNumberProperty;
       
   163     User::LeaveIfError(testNumberProperty.Attach(KUidPSSimTsyCategory, aTestNumberProperty));
       
   164     CleanupClosePushL(testNumberProperty);
       
   165 
       
   166     TRequestStatus status;
       
   167     testNumberProperty.Subscribe(status);
       
   168     INFO_PRINTF3(_L("Setting SimTsy test number property (0x%X) to %d"), aTestNumberProperty, aTestNumber);
       
   169     User::LeaveIfError(testNumberProperty.Set(KUidPSSimTsyCategory, aTestNumberProperty, aTestNumber));
       
   170     User::WaitForRequest(status);
       
   171     TESTCHECK(status.Int(), KErrNone, "Setting SimTsy test number property ");
       
   172 
       
   173     TInt testNumberCheck;
       
   174     User::LeaveIfError(testNumberProperty.Get(testNumberCheck));
       
   175     TESTCHECK(aTestNumber, testNumberCheck, "Checking correct test number");
       
   176 
       
   177     CleanupStack::PopAndDestroy(&testNumberProperty);
       
   178     }
       
   179     
       
   180 EXPORT_C void CSmsBaseTestStep::ConnectSocketServerL(RSocketServ& aSocketServer)
       
   181     {
       
   182     INFO_PRINTF1(_L("Connecting to the Socket Server..."));
       
   183     
       
   184     TInt  ret = aSocketServer.Connect(KSocketMessageSlots);
       
   185     if (ret != KErrNone)
       
   186         {
       
   187         ERR_PRINTF2(_L("Connecting to socket server failed [ret=%d]"), ret);
       
   188         }
       
   189     
       
   190     INFO_PRINTF1(_L("Clearing private data..."));
       
   191 
       
   192     _LIT(KWapReassemblyStoreName, "C:\\Private\\101F7989\\sms\\wapreast.dat");
       
   193     ret = iFs.Delete(KWapReassemblyStoreName);
       
   194     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   195         {
       
   196         ERR_PRINTF2(_L("Deleted WAP reassembly Store failed [ret=%d]"), ret);
       
   197         }
       
   198 
       
   199     _LIT(KReassemblyStoreName, "C:\\Private\\101F7989\\sms\\smsreast.dat");
       
   200     ret = iFs.Delete(KReassemblyStoreName);
       
   201     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   202         {
       
   203         ERR_PRINTF2(_L("Deleted reassembly Store failed [ret=%d]"), ret);
       
   204         }
       
   205 
       
   206     _LIT(KSegmentationStoreName, "C:\\Private\\101F7989\\sms\\smssegst.dat");
       
   207     ret = iFs.Delete(KSegmentationStoreName);
       
   208     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   209         {
       
   210         ERR_PRINTF2(_L("Deleted segmentation Store failed [ret=%d]"), ret);
       
   211         }
       
   212 
       
   213     _LIT(KSmsClass0PreallocatedStoreName, "C:\\Private\\101F7989\\sms\\smsclass0preallocated.dat");
       
   214     ret = iFs.Delete(KSmsClass0PreallocatedStoreName);
       
   215     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   216         {
       
   217         ERR_PRINTF2(_L("Deleted SmsClass0Preallocated Store failed [ret=%d]"), ret);
       
   218         }
       
   219 
       
   220     _LIT(KSmsClass0ReassemblyStoreName, "C:\\Private\\101F7989\\sms\\smsclass0reast.dat");
       
   221     ret = iFs.Delete(KSmsClass0ReassemblyStoreName);
       
   222     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   223         {
       
   224         ERR_PRINTF2(_L("Deleted SmsClass0Reassembly Store failed [ret=%d]"), ret);
       
   225         }
       
   226 
       
   227     _LIT(KSmsUtilityResourceFileName, "C:\\Private\\101F7989\\sms\\smsu.rsc");
       
   228     ret = iFs.Delete(KSmsUtilityResourceFileName);
       
   229     if( ret != KErrNone && ret != KErrNotFound && ret != KErrPathNotFound )
       
   230         {
       
   231         ERR_PRINTF2(_L("Deleted SMS stack resource file failed [ret=%d]"), ret);
       
   232         }
       
   233     }
       
   234 
       
   235 EXPORT_C void CSmsBaseTestStep::ConnectSocketServerLC(RSocketServ& aSocketServer)
       
   236     {
       
   237     ConnectSocketServerL(aSocketServer);
       
   238     CleanupClosePushL(aSocketServer);
       
   239     }
       
   240     
       
   241 EXPORT_C CSmsMessage* CSmsBaseTestStep::CreateSmsMessageL(const TDesC& aDes, TSmsDataCodingScheme::TSmsAlphabet aAlphabet, CSmsPDU::TSmsPDUType aType)
       
   242 /**
       
   243  *  Create a uninitialised SMS message
       
   244  *  @param aDes contains text that will be inserted to the pdu
       
   245  *  @param aAlphabet describes the alphabet of the pdu
       
   246  *  @return CSmsMessage* :Pointer to the created CSmsMessage object.
       
   247  */
       
   248     {
       
   249     CSmsMessage* smsMessage = CreateSmsMessageLC(aDes, aAlphabet, aType);
       
   250     CleanupStack::Pop(smsMessage);
       
   251     return smsMessage;
       
   252     }
       
   253 
       
   254 EXPORT_C CSmsMessage* CSmsBaseTestStep::CreateSmsMessageLC(const TDesC& aDes, TSmsDataCodingScheme::TSmsAlphabet aAlphabet, CSmsPDU::TSmsPDUType aType)
       
   255 /**
       
   256  *  Create a uninitialised SMS message
       
   257  *  @param aDes contains text that will be inserted to the pdu
       
   258  *  @param aAlphabet describes the alphabet of the pdu
       
   259  *  @return CSmsMessage* :Pointer to the created CSmsMessage object.
       
   260  */
       
   261     {
       
   262     CSmsBuffer* buffer=CSmsBuffer::NewL();
       
   263     CSmsMessage* smsMessage=CSmsMessage::NewL(iFs, aType, buffer);
       
   264     CleanupStack::PushL(smsMessage);
       
   265 
       
   266     TSmsUserDataSettings smsSettings;
       
   267     smsSettings.SetAlphabet(aAlphabet);
       
   268     smsSettings.SetTextCompressed(EFalse);
       
   269     smsMessage->SetUserDataSettingsL(smsSettings);
       
   270 
       
   271     smsMessage->SetToFromAddressL(iTelephoneNumber);
       
   272     smsMessage->SmsPDU().SetServiceCenterAddressL(iServiceCenterNumber);
       
   273     buffer->InsertL(0,aDes);
       
   274     return smsMessage;
       
   275     }
       
   276 
       
   277 EXPORT_C CSmsMessage* CSmsBaseTestStep::CreateSmsWithStatusReportReqL(const TDesC& aDes, TSmsDataCodingScheme::TSmsAlphabet aAlphabet)
       
   278 /**
       
   279  *  Create a uninitialised SMS message with Status Report request
       
   280  *  @param aDes contains text that will be inserted to the pdu
       
   281  *  @param aAlphabet describes the alphabet of the pdu
       
   282  *  @return CSmsMessage* :Pointer to the created CSmsMessage object.
       
   283  */
       
   284     {
       
   285     CSmsMessage* smsMessage=CreateSmsMessageLC(aDes, aAlphabet);
       
   286 
       
   287     //Set Status report request
       
   288     CSmsSubmit& submitPdu=(CSmsSubmit&)smsMessage->SmsPDU();
       
   289     submitPdu.SetStatusReportRequest(ETrue);
       
   290 
       
   291     CleanupStack::Pop(smsMessage);
       
   292     return smsMessage;
       
   293     }
       
   294 
       
   295 EXPORT_C CSmsMessage* CSmsBaseTestStep::RecvSmsL(RSocket& aSocket, TInt aIoctl)
       
   296 /**
       
   297  *  Receive an Sms
       
   298  *  @param aSocket is used to stream the sms message from the socket server
       
   299  *  @return CSmsMessage* :Sms message from Sms stack
       
   300  *  @leave Leaves if streaming the message from the socket server doesn't succeed
       
   301  */
       
   302     {
       
   303     CSmsBuffer* buffer=CSmsBuffer::NewL();
       
   304     CSmsMessage* smsMessage=CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit,buffer);
       
   305     CleanupStack::PushL(smsMessage);
       
   306 
       
   307     RSmsSocketReadStream readstream(aSocket);
       
   308     TRAPD(ret, readstream >> *smsMessage);
       
   309  
       
   310     TPckgBuf<TUint> sbuf;
       
   311     TRequestStatus status;
       
   312 
       
   313     if(ret==KErrNone)
       
   314         {
       
   315         aSocket.Ioctl(aIoctl, status, &sbuf, KSolSmsProv);
       
   316         User::WaitForRequest(status);
       
   317         CleanupStack::Pop(smsMessage);
       
   318         TESTCHECK(status.Int(), KErrNone, "Notifying the SMS stack that message was received successfully");
       
   319         INFO_PRINTF1(_L("Message received successfully"));
       
   320         }
       
   321     //An error has occured, no message has been received
       
   322     else
       
   323         {
       
   324         aSocket.Ioctl(KIoctlReadMessageFailed, status, &sbuf, KSolSmsProv);
       
   325         User::WaitForRequest(status);
       
   326         TESTCHECK(status.Int(), KErrNone, "Notifying the SMS stack that message was not received");
       
   327         ERR_PRINTF2(_L("Receiving message failed %d"), ret);
       
   328         User::Leave(ret);
       
   329         }
       
   330     return smsMessage;  
       
   331     }
       
   332 
       
   333 EXPORT_C CSmsMessage* CSmsBaseTestStep::RecvSmsFailedL(RSocket& aSocket)
       
   334 /**
       
   335  *  Receive an Sms, first nack the receive several times before succeeding
       
   336  *  @param aSocket is used to stream the sms message from the socket server
       
   337  *  @return CSmsMessage* :Sms message from Sms stack
       
   338  *  @leave Leaves if streaming the message from the socket server doesn't succeed
       
   339  *  @leave Leaves if nack of receiving is completed with error code
       
   340  *  @leave Leaves if ack of receiving is completed with error code
       
   341  */
       
   342     {
       
   343     CSmsBuffer* buffer=CSmsBuffer::NewL();
       
   344     CSmsMessage* smsMessage=CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit,buffer);
       
   345     CleanupStack::PushL(smsMessage);
       
   346     RSmsSocketReadStream readstream(aSocket);
       
   347 
       
   348     TPckgBuf<TUint> sbuf;
       
   349     TRequestStatus status;
       
   350 
       
   351     for(TInt i=0; i<10; i++)
       
   352         {
       
   353         TRAPD(ret,readstream >> *smsMessage);
       
   354         TEST(ret == KErrNone);
       
   355         aSocket.Ioctl(KIoctlReadMessageFailed, status, &sbuf, KSolSmsProv);
       
   356         User::WaitForRequest(status);
       
   357         TEST(status.Int() == KErrNone);
       
   358         }
       
   359 
       
   360     TRAPD(ret,readstream >> *smsMessage);
       
   361     TEST(ret == KErrNone);
       
   362     aSocket.Ioctl(KIoctlReadMessageSucceeded, status, NULL, KSolSmsProv);
       
   363     User::WaitForRequest(status);
       
   364     TEST(status.Int() == KErrNone);
       
   365 
       
   366     CleanupStack::Pop(smsMessage);
       
   367     return smsMessage;
       
   368     }
       
   369 
       
   370 EXPORT_C void CSmsBaseTestStep::SendSmsL(const CSmsMessage* aSms, RSocket& aSocket, TInt aExpectedError/*=KErrNone*/, TInt aMaxRetries/*=3*/)
       
   371 /**
       
   372  *  Stream aSms out to the socket server
       
   373  *  @param aSms contains the sms tpdu that will be streamed to the sms stack
       
   374  *  @param aSocket is used to stream the aSms to the sms stack
       
   375  *  @param aExpectedError The error expected from the send request
       
   376  *  @param aMaxRetries The max number of retries is send request does not match expected error
       
   377  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   378  *  @leave Leaves if sending is completed with error code
       
   379  */
       
   380     {
       
   381     INFO_PRINTF1(_L("Sending SMS... "));
       
   382     PrintMessageL(aSms);
       
   383     
       
   384     TBool tryAgain = ETrue;
       
   385     TInt sendTry (0);
       
   386     TRequestStatus status = KErrNone;
       
   387 
       
   388     while( tryAgain && sendTry < aMaxRetries )
       
   389         {
       
   390         RSmsSocketWriteStream writestream(aSocket);
       
   391         TRAPD(ret,writestream << *aSms);
       
   392         TRAP(ret, writestream.CommitL());
       
   393 
       
   394         TPckgBuf<TUint> sbuf;
       
   395         aSocket.Ioctl(KIoctlSendSmsMessage,status,&sbuf, KSolSmsProv);
       
   396         User::WaitForRequest(status);
       
   397         INFO_PRINTF3(_L("SendSmsL [status=%d, aExpectedError=%d]"), status.Int(), aExpectedError);
       
   398         if ( status.Int() != aExpectedError )
       
   399             {
       
   400             tryAgain = ETrue;
       
   401             INFO_PRINTF1(_L("Try again... "));
       
   402             ++sendTry;
       
   403             }
       
   404         else tryAgain = EFalse;
       
   405         }
       
   406     
       
   407     TESTCHECKL(status.Int(), aExpectedError, "Sending Message with an expected error");
       
   408     }
       
   409 
       
   410 EXPORT_C void CSmsBaseTestStep::SendSmsCancelL(CSmsMessage* aSms, RSocket& aSocket1, RSocket& aSocket2)
       
   411 /**
       
   412  *  Stream Sms out to the socket server by two RSmsSocketWriteStream object.
       
   413  *  The first request is canceled and then the second request is completed with error code.
       
   414  *  @param aSms contains the sms tpdu that will be streamed to the sms stack
       
   415  *  @param aSocket1 The socket used with message that will be canceled
       
   416  *  @param aSocket2 The socket used with message that will be completed with error code
       
   417  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   418  *  @leave Leaves if sending is completed with KErrNone
       
   419  */
       
   420     {
       
   421     RSmsSocketWriteStream writestream(aSocket1);
       
   422     TRAPD(ret,writestream << *aSms);
       
   423     TEST(ret == KErrNone);
       
   424     TRAP(ret,writestream.CommitL());
       
   425     TEST(ret == KErrNone);
       
   426 
       
   427     TPckgBuf<TUint> sbuf;
       
   428     TRequestStatus status1,status2;
       
   429 
       
   430     //stream to socket2
       
   431     RSmsSocketWriteStream writestream2(aSocket2);
       
   432     TRAP(ret,writestream2 << *aSms);
       
   433     TEST(ret == KErrNone);
       
   434     TRAP(ret,writestream2.CommitL());
       
   435     TEST(ret == KErrNone);
       
   436 
       
   437     aSocket1.Ioctl(KIoctlSendSmsMessage,status1,&sbuf, KSolSmsProv);
       
   438     aSocket2.Ioctl(KIoctlSendSmsMessage,status2,&sbuf, KSolSmsProv);
       
   439 
       
   440     User::After(2000000);
       
   441 
       
   442     // Test cancel first
       
   443     aSocket1.CancelIoctl();
       
   444     User::WaitForRequest(status1);
       
   445     TEST(status1.Int()==KErrCancel);
       
   446 
       
   447     User::After(50000);
       
   448 
       
   449 
       
   450     User::WaitForRequest(status2);
       
   451 
       
   452     INFO_PRINTF2(_L("SendSmsL - sendSmsMessage returned %d"),status2.Int());
       
   453     PrintMessageL(aSms);
       
   454 
       
   455     //Ensure the request is completed with error code ;)
       
   456     TEST(status2.Int() != KErrNone);
       
   457     INFO_PRINTF2(_L("Sending failed! %d"), status2.Int());
       
   458     }
       
   459 
       
   460 EXPORT_C TInt CSmsBaseTestStep::SendSmsErrorL(CSmsMessage* aSms, RSocket& aSocket)
       
   461 /**
       
   462  *  Stream aSms out to the socket server. Sending is completed with error code.
       
   463  *  @param aSms contains the sms tpdu that will be streamed to the sms stack
       
   464  *  @param aSocket is used to stream the aSms to the sms stack
       
   465  *  @return error code
       
   466  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   467  *  @leave Leaves if sending is completed with KErrNone
       
   468  */
       
   469     {
       
   470     RSmsSocketWriteStream writestream(aSocket);
       
   471     TRAPD(ret,writestream << *aSms);
       
   472     TEST(ret == KErrNone);
       
   473     TRAP(ret,writestream.CommitL());
       
   474     TEST(ret == KErrNone);
       
   475 
       
   476     TPckgBuf<TUint> sbuf;
       
   477     TRequestStatus status;
       
   478 
       
   479     User::After(50000);
       
   480     // test cancel first
       
   481     aSocket.Ioctl(KIoctlSendSmsMessage,status,&sbuf, KSolSmsProv);
       
   482     aSocket.CancelIoctl();
       
   483     User::WaitForRequest(status);
       
   484     TEST(status.Int()==KErrCancel);
       
   485 
       
   486     //Now send again, completed with error
       
   487     TRAP(ret,writestream << *aSms);
       
   488     TEST(ret == KErrNone);
       
   489     TRAP(ret,writestream.CommitL());
       
   490     TEST(ret == KErrNone);
       
   491 
       
   492     aSocket.Ioctl(KIoctlSendSmsMessage,status,&sbuf, KSolSmsProv);
       
   493     User::WaitForRequest(status);
       
   494     INFO_PRINTF2(_L("SendSmsL - sendSmsMessage returned %d"), status.Int());
       
   495     PrintMessageL(aSms);
       
   496     INFO_PRINTF2(_L("Sending failed! %d"), status.Int());
       
   497     TEST(status.Int() != KErrNone);
       
   498     return status.Int();
       
   499     }
       
   500 
       
   501 EXPORT_C void CSmsBaseTestStep::SendCommandSmsL(CSmsMessage* aSms, RSocket& aSocket)
       
   502 /**
       
   503  *  Stream command message out to the socket server and wait for the return status
       
   504  *  @param aSms contains the sms tpdu that will be streamed to the sms stack
       
   505  *  @param aSocket is used to stream the aSms to the sms stack
       
   506  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   507  *  @leave Leaves if sending is completed with error code
       
   508  */
       
   509     {
       
   510     RSmsSocketWriteStream writestream(aSocket);
       
   511     TRAPD(ret,writestream << *aSms);
       
   512     TEST(ret == KErrNone);
       
   513     TRAP(ret,writestream.CommitL());
       
   514     TEST(ret == KErrNone);
       
   515 
       
   516     TRequestStatus status;
       
   517     TPckgBuf<TUint> sbuf;
       
   518     aSocket.Ioctl(KIoctlSendSmsMessage,status,&sbuf,KSolSmsProv);
       
   519 
       
   520     User::WaitForRequest(status);
       
   521 
       
   522     INFO_PRINTF2(_L("SendCommandSmsL, sendSms returned %d"), status.Int());
       
   523     User::After(1000000);
       
   524     TEST(status.Int() == KErrNone);
       
   525 
       
   526     }
       
   527 
       
   528 EXPORT_C void CSmsBaseTestStep::SendAndRecvTestMessageL(const TTestCase& aTestCase, RSocket& aSocket)
       
   529 /**
       
   530  *  Send a test message. This method is used to send and receive different DCS type messages
       
   531  *  @param aTestCase has information about the used test message, e.g. message data and DCS
       
   532  *  @leave Leaves if any of the leaving functions used at this function leaves
       
   533  */
       
   534     {
       
   535     SendTestMessageL(aTestCase, aSocket);
       
   536 
       
   537     WaitForRecvL(aSocket);
       
   538     CSmsMessage* smsMessage = RecvSmsL(aSocket);
       
   539     CleanupStack::PushL(smsMessage);
       
   540     
       
   541     TestMessageContentsL(smsMessage,aTestCase);
       
   542     CleanupStack::PopAndDestroy(smsMessage);
       
   543     }
       
   544 
       
   545 EXPORT_C void CSmsBaseTestStep::SendTestMessageL(const TTestCase& aTestCase, RSocket& aSocket)
       
   546 /**
       
   547  *  Send a test message
       
   548  *  Assumes recv is already done.
       
   549  *  @param aTestCase has information about the used test message, e.g. message data and DCS
       
   550  *  @leave Leaves if any of the leaving functions used at this function leaves
       
   551  */
       
   552     {
       
   553     CSmsMessage* smsMessage = CreateSmsMessageLC(aTestCase.iMsg, TSmsDataCodingScheme::ESmsAlphabet7Bit);
       
   554 
       
   555     CSmsPDU& pdu = smsMessage->SmsPDU();
       
   556     CSmsUserData& userData = pdu.UserData();
       
   557 
       
   558     if (aTestCase.iMatchType == ESmsAddrMatchIEI)
       
   559         userData.AddInformationElementL(aTestCase.iIdentifierMatch,_L8("98"));
       
   560 
       
   561     if (aTestCase.iTestSmsClass)
       
   562         {
       
   563         pdu.SetBits7To4(TSmsDataCodingScheme::ESmsDCSTextUncompressedWithClassInfo);
       
   564         pdu.SetClass(ETrue,aTestCase.iSmsClass);
       
   565         }
       
   566 
       
   567     if (aTestCase.iTestValidityPeriod && pdu.Type()==CSmsPDU::ESmsSubmit)
       
   568         {
       
   569         CSmsSubmit* submitPdu = REINTERPRET_CAST(CSmsSubmit*,&pdu);
       
   570         submitPdu->SetValidityPeriod(aTestCase.iValidityPeriod);
       
   571         }
       
   572 
       
   573     if (aTestCase.iTestIndicators && pdu.Type()==CSmsPDU::ESmsSubmit)
       
   574         {
       
   575         SetIndicatorL(aTestCase, smsMessage);
       
   576         }
       
   577 
       
   578     SendSmsL(smsMessage, aSocket);
       
   579     CleanupStack::PopAndDestroy(smsMessage);
       
   580     }
       
   581 
       
   582 EXPORT_C void CSmsBaseTestStep::SendSmsDontCheckReturnValueL(CSmsMessage* aSms, RSocket& aSocket)
       
   583 /**
       
   584  *  Stream aSms out to the socket server and don't check return value.
       
   585  *  @param aSms contains the sms tpdu that will be streamed to the sms stack
       
   586  *  @param aSocket is used to stream the aSms to the sms stack
       
   587  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   588  *  @leave Leaves if sending is completed with KErrNone
       
   589  */
       
   590     {
       
   591     RSmsSocketWriteStream writestream(aSocket);
       
   592     writestream << *aSms;
       
   593     writestream.CommitL();
       
   594 
       
   595     TPckgBuf<TUint> sbuf;
       
   596     TRequestStatus status;
       
   597     aSocket.Ioctl(KIoctlSendSmsMessage,status,&sbuf, KSolSmsProv);
       
   598     User::WaitForRequest(status);
       
   599     INFO_PRINTF2(_L("Send SMS message returned %d"), status.Int());
       
   600     if(status.Int() != KErrNone)
       
   601         {
       
   602         User::Leave(status.Int());
       
   603         }
       
   604     }
       
   605 
       
   606 EXPORT_C void CSmsBaseTestStep::SendAndRecvSms7BitL(const TDesC& aDes, RSocket& aSocket)
       
   607 /**
       
   608  *  Send and receive one 7bit sms
       
   609  *  @param aDes contains the text to be send
       
   610  *  @leave Leaves if DoSendAndRecvSmsL leaves
       
   611  */
       
   612     {
       
   613     DoSendAndRecvSmsL(aDes,TSmsDataCodingScheme::ESmsAlphabet7Bit, aSocket);
       
   614     }
       
   615 
       
   616 EXPORT_C void CSmsBaseTestStep::DoSendAndRecvSmsL(const TDesC& aDes, TSmsDataCodingScheme::TSmsAlphabet aAlphabet, RSocket& aSocket)
       
   617 /**
       
   618  *  Send and recv one sms,
       
   619  *  then check that the sent message corresponds with the received message
       
   620  *  @param aDes contains the text that will be inserted to the pdu at CreateSmsMessageL
       
   621  *  @param aAlphabet describes the alphabet of the pdu that will be created at CreateSmsMessageL
       
   622  *  @leave Leaves if any of the leaving functions used at this function leaves
       
   623  */
       
   624     {
       
   625     CSmsMessage* smsMessage=CreateSmsMessageLC(aDes, aAlphabet);
       
   626     SendSmsL(smsMessage, aSocket);
       
   627     CleanupStack::PopAndDestroy(smsMessage); //destroyed because created again in RecvSmsL
       
   628 
       
   629     WaitForRecvL( aSocket);
       
   630     smsMessage = RecvSmsL( aSocket);
       
   631     CleanupStack::PushL(smsMessage);
       
   632 
       
   633     TestSmsContentsL(smsMessage,aDes);
       
   634 
       
   635     // TODO: is this a way to go?
       
   636     User::After(1000000);
       
   637 
       
   638     CleanupStack::PopAndDestroy(smsMessage);
       
   639     }
       
   640 
       
   641 EXPORT_C void CSmsBaseTestStep::PrintMessageDetailedL(const CSmsMessage* aSms)
       
   642     {
       
   643     TPtrC from = aSms->ToFromAddress();
       
   644     INFO_PRINTF2(_L("ToFromAddress: %S"), &from);
       
   645     TPtrC sc = aSms->ServiceCenterAddress();
       
   646     INFO_PRINTF2(_L("ServiceCenterAddress: %S"), &sc);
       
   647 
       
   648     if(aSms->Storage() == CSmsMessage::ESmsSIMStorage)
       
   649         {
       
   650         INFO_PRINTF1(_L("Store: SIM"));
       
   651         }
       
   652     else if (aSms->Storage() == CSmsMessage::ESmsPhoneStorage)
       
   653         {
       
   654         INFO_PRINTF1(_L("Store: Phone"));
       
   655         }
       
   656     else if (aSms->Storage() == CSmsMessage::ESmsCombinedStorage)
       
   657         {
       
   658         INFO_PRINTF1(_L("Store: Combined"));
       
   659         }
       
   660     else
       
   661         {
       
   662         INFO_PRINTF1(_L("Store: Unknown"));
       
   663         }
       
   664 
       
   665     switch (aSms->Status())
       
   666         {
       
   667         case RMobileSmsStore::EStoredMessageUnread:
       
   668             INFO_PRINTF1(_L("Status: Unread"));
       
   669             break;
       
   670 
       
   671         case RMobileSmsStore::EStoredMessageRead:
       
   672             INFO_PRINTF1(_L("Status: Read"));
       
   673             break;
       
   674 
       
   675         case RMobileSmsStore::EStoredMessageUnsent:
       
   676             INFO_PRINTF1(_L("Status: Unsent"));
       
   677             break;
       
   678 
       
   679         case RMobileSmsStore::EStoredMessageSent:
       
   680             INFO_PRINTF1(_L("Status: Sent"));
       
   681             break;
       
   682 
       
   683         case RMobileSmsStore::EStoredMessageDelivered:
       
   684             INFO_PRINTF1(_L("Status: Delivered"));
       
   685             break;
       
   686 
       
   687         case RMobileSmsStore::EStoredMessageUnknownStatus:
       
   688         default:
       
   689             INFO_PRINTF1(_L("Status: Unknown"));
       
   690             break;
       
   691         }
       
   692     PrintMessageL(aSms);
       
   693     }
       
   694 
       
   695 EXPORT_C void CSmsBaseTestStep::PrintMessageL(const CSmsMessage* aSms)
       
   696 /**
       
   697  *  Print the content of SMS to the console
       
   698  */
       
   699     {
       
   700     if (aSms == NULL)
       
   701         {
       
   702         return;
       
   703         }
       
   704     
       
   705     CSmsBuffer& smsbuffer = (CSmsBuffer&)aSms->Buffer();
       
   706     const TInt len = smsbuffer.Length();
       
   707     HBufC* hbuf = HBufC::NewL(len);
       
   708     
       
   709     TPtr ptr = hbuf->Des();
       
   710     smsbuffer.Extract(ptr, 0, len);
       
   711 
       
   712     for (TInt j = 0; j < len; ++j)
       
   713         {
       
   714         if (ptr[j] < 0x20  ||  ptr[j] > 0xFF)
       
   715             {
       
   716             // Non-displayable character, print "." instead
       
   717             ptr[j] = 0x007F;
       
   718             }
       
   719         }
       
   720     INFO_PRINTF2(_L("SMS contains: %S"), &ptr);
       
   721 
       
   722     delete hbuf;
       
   723     }
       
   724 
       
   725 EXPORT_C TSmsStatus::TSmsStatusValue CSmsBaseTestStep::RecvStatusReportL(TSmsServiceCenterAddress& aRecipientNumber, RSocket& aSocket)
       
   726 /**
       
   727  * Receive a Status report
       
   728  * @param aRecipientNumber The supposed recipient number
       
   729  * @param aSocket is used to stream the sms message from the socket server
       
   730  */
       
   731     {
       
   732     //Receive SMS
       
   733     INFO_PRINTF1(_L("waiting for incoming status report...") );
       
   734     WaitForRecvL(aSocket);
       
   735     CSmsMessage* smsMessage = RecvSmsL(aSocket);
       
   736 
       
   737     //Check the status report
       
   738     CleanupStack::PushL(smsMessage);
       
   739     TBool isSR = (smsMessage->Type()==CSmsPDU::ESmsStatusReport);
       
   740 
       
   741     if (isSR)
       
   742         {
       
   743         INFO_PRINTF1(_L("Received status report"));
       
   744         TSmsServiceCenterAddress telephoneNumber=smsMessage->ToFromAddress();
       
   745         TEST(telephoneNumber==aRecipientNumber);
       
   746         INFO_PRINTF2(_L("Message delivered to %S"), &telephoneNumber);
       
   747         }
       
   748     else
       
   749         {
       
   750         INFO_PRINTF1(_L("Received SMS is NOT a Status report!"));
       
   751         }
       
   752 
       
   753     TEST(isSR);
       
   754     
       
   755     //Get the status report
       
   756     CSmsStatusReport& statusReport = STATIC_CAST(CSmsStatusReport&, smsMessage->SmsPDU()); 
       
   757     TSmsStatus::TSmsStatusValue status = statusReport.Status();
       
   758     
       
   759     CleanupStack::PopAndDestroy(smsMessage);
       
   760     return status;
       
   761     }
       
   762 
       
   763 EXPORT_C void CSmsBaseTestStep::WaitForRecvL(RSocket& aSocket)
       
   764 /**
       
   765  *  Wait for an Sms to be received
       
   766  *  @param aSocket The status is return to this socket
       
   767  *  @leave Leaves if receiving is completed with error code
       
   768  */
       
   769     {
       
   770     INFO_PRINTF1(_L("Waiting for incoming SMS...") );
       
   771     TPckgBuf<TUint> sbuf;
       
   772     sbuf()=KSockSelectRead;
       
   773     TRequestStatus status;
       
   774     aSocket.Ioctl(KIOctlSelect,status,&sbuf,KSOLSocket);
       
   775     User::WaitForRequest(status);
       
   776     TESTCHECK(status.Int(), KErrNone, "Waiting for incoming SMS");
       
   777     }
       
   778 
       
   779 EXPORT_C void CSmsBaseTestStep::TestSmsContentsL(CSmsMessage* aSms, const TDesC& aDes, TBool aIgnorePrintOutput)
       
   780 /**
       
   781  *  Check that aSms contains text that matches to aDes
       
   782  *  @param aSms SMS message that has been come from SMS stack
       
   783  *  @param aDes SMS message's text that is defined at client side
       
   784  *  @leave Leaves if aSms doesn't match to aDes
       
   785  */
       
   786     {
       
   787     CSmsBufferBase& smsBuffer=aSms->Buffer();
       
   788     TInt bufLen=smsBuffer.Length();
       
   789     
       
   790     INFO_PRINTF2(_L("Length of buffer is : %d"),bufLen);
       
   791         
       
   792     HBufC* textBuf=HBufC::NewL(bufLen);
       
   793     CleanupStack::PushL(textBuf);
       
   794     TPtr textPtr(textBuf->Des());
       
   795     smsBuffer.Extract(textPtr,0,bufLen);
       
   796 
       
   797     INFO_PRINTF1(_L("Comparing messages..."));
       
   798     TInt  compareResult = textPtr.Compare(aDes);
       
   799 
       
   800     if (!aIgnorePrintOutput)
       
   801         {
       
   802         TInt  bufLen2 = aDes.Length();
       
   803         HBufC*  textBuf2 = HBufC::NewL(aDes.Length());
       
   804         CleanupStack::PushL(textBuf2);
       
   805         TPtr textPtr2(textBuf2->Des());
       
   806         TInt  index;
       
   807         
       
   808         for (index = 0;  index < bufLen;  index++)
       
   809             {
       
   810             if (textPtr[index] < 0x20  ||  textPtr[index] > 0xff)
       
   811                 {
       
   812                 textPtr[index] = 0x007f;
       
   813                 }
       
   814             }
       
   815         INFO_PRINTF2(_L("%S"), &textPtr);
       
   816 
       
   817         INFO_PRINTF1(_L("with expected"));
       
   818 
       
   819         textPtr2.Copy(aDes);
       
   820         for (index = 0;  index < bufLen2;  index++)
       
   821             {
       
   822             if (textPtr2[index] < 0x20  ||  textPtr2[index] > 0xff)
       
   823                 {
       
   824                 textPtr2[index] = 0x007f;
       
   825                 }
       
   826             }
       
   827         INFO_PRINTF2(_L("%S"), &textPtr2);
       
   828 
       
   829         CleanupStack::PopAndDestroy(textBuf2);
       
   830         }
       
   831         
       
   832     if (compareResult != 0)
       
   833         {
       
   834         SetTestStepResult(EFail);
       
   835         ERR_PRINTF1(_L("Message content does not match the provided string")); 
       
   836         }
       
   837     else
       
   838         {
       
   839         INFO_PRINTF1(_L("Message content matches the provided string"));  
       
   840         }
       
   841     
       
   842     CleanupStack::PopAndDestroy(textBuf);
       
   843     }
       
   844 
       
   845 EXPORT_C void CSmsBaseTestStep::TestMessageContentsL(CSmsMessage* aSms, const TTestCase& aTestCase)
       
   846 /**
       
   847  *  Check the sms matches the expected test result
       
   848  *  @param aSms has the message to be tested with aTestCase.iMsg
       
   849  *  @param aTestCase has information about the used test message, e.g. message data and DCS
       
   850  *  @leave Leaves if TSmsClass isn't defined at the pdu
       
   851  *  @leave Leaves if class of pdu doesn't match to supposed class (aTestCase.iSmsClass)
       
   852  */
       
   853     {
       
   854     TestSmsContentsL(aSms,aTestCase.iMsg);
       
   855     CSmsPDU& pdu = aSms->SmsPDU();
       
   856 
       
   857     if (aTestCase.iTestSmsClass)
       
   858         {
       
   859         TSmsDataCodingScheme::TSmsClass smsClass;
       
   860         TBool isDefined = pdu.Class(smsClass);
       
   861         TEST(isDefined);
       
   862         TEST(smsClass == aTestCase.iSmsClass);
       
   863         }
       
   864     if (aTestCase.iTestIndicators)
       
   865         {
       
   866         TEST(pdu.Bits7To4() == aTestCase.iBits7To4);
       
   867         TEST(pdu.IndicationType() == aTestCase.iIndicationType);
       
   868         TEST(pdu.IndicationState() == aTestCase.iIndicationState);
       
   869         }
       
   870 
       
   871     }
       
   872 
       
   873 EXPORT_C void CSmsBaseTestStep::WriteSmsToSimL(CSmsMessage& aSms, RSocket& aSocket)
       
   874 /**
       
   875  *  This method stores SMS messages to the SMS storage.
       
   876  *  @param aSms SMS message that will be stored
       
   877  *  @param aSocket Used to stream SMS message to the sms stack
       
   878  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
   879  *  @leave Leaves if store request is completed with error code
       
   880  */
       
   881     {
       
   882     INFO_PRINTF1(_L("Write message to SIM"));
       
   883     TRequestStatus status;
       
   884     RSmsSocketWriteStream writestream(aSocket);
       
   885 
       
   886     TRAPD(ret,writestream << aSms);
       
   887     TESTCHECK(ret, KErrNone, "Write SMS to stream");
       
   888     TRAP(ret,writestream.CommitL());
       
   889     TESTCHECK(ret, KErrNone, "Commit the stream writing");
       
   890 
       
   891     aSocket.Ioctl(KIoctlWriteSmsMessage,status,NULL,KSolSmsProv);
       
   892     User::WaitForRequest(status);
       
   893     TESTCHECK(status.Int(), KErrNone, "Write message to SIM");
       
   894     }
       
   895 
       
   896 EXPORT_C void CSmsBaseTestStep::WriteSmsLeaveIfErrorL(const CSmsMessage& aSms, RSocket& aSocket)
       
   897 /**
       
   898  *  This method stores SMS messages to the SMS storage.
       
   899  *  @param aSms SMS message that will be stored
       
   900  *  @param aSocket Used to stream SMS message to the sms stack
       
   901  */
       
   902     {
       
   903     TRequestStatus status;
       
   904     RSmsSocketWriteStream writestream(aSocket);
       
   905     
       
   906     writestream << aSms;
       
   907     writestream.CommitL();
       
   908     
       
   909     aSocket.Ioctl(KIoctlWriteSmsMessage,status,NULL, KSolSmsProv);
       
   910     User::WaitForRequest(status);
       
   911     INFO_PRINTF2(_L("Write SMS message returned %d"), status.Int());
       
   912     if(status.Int() != KErrNone)
       
   913         {
       
   914         User::Leave(status.Int());
       
   915         }
       
   916     }
       
   917 
       
   918 EXPORT_C void CSmsBaseTestStep::ReadSmsStoreL(RSocket& aSocket, RPointerArray<CSmsMessage>& aMessages)
       
   919 /**
       
   920  *  This method retrieves SMS messages from SMS storage and print them out.
       
   921  *  @param aSocket Used to stream SMS messages from the socket server
       
   922  *  @param aMessages Sms messages will be streamed to this array
       
   923  *  @leave Leaves if first request is NOT completed with KErrCancel
       
   924  *  @leave Leaves if second request is completed with error code
       
   925  *  @leave Leaves if streaming the message from the socket server doesn't succeed
       
   926  *  @leave Leaves if nack of reading is completed with error code
       
   927  *  @leave Leaves if ack of reading is completed with error code
       
   928  */
       
   929     {
       
   930     TRequestStatus status;
       
   931     ReadSmsStoreL(aSocket, aMessages, status);
       
   932     }
       
   933 
       
   934 EXPORT_C void CSmsBaseTestStep::ReadSmsStoreL(RSocket& aSocket, RPointerArray<CSmsMessage>& aMessages, TRequestStatus& aStatus)
       
   935 /**
       
   936  *  This method retrieves SMS messages from SMS storage and print them out.
       
   937  *  @param aSocket Used to stream SMS messages from the socket server
       
   938  *  @param aMessages Sms messages will be streamed to this array
       
   939  *  @param aStatus Status of request to enumerate messages from store
       
   940  *  @leave Leaves if first request is NOT completed with KErrCancel
       
   941  *  @leave Leaves if second request is completed with error code
       
   942  *  @leave Leaves if streaming the message from the socket server doesn't succeed
       
   943  *  @leave Leaves if nack of reading is completed with error code
       
   944  *  @leave Leaves if ack of reading is completed with error code
       
   945  */
       
   946     {
       
   947     INFO_PRINTF1(_L("Enumerating messages"));
       
   948     TPckgBuf<TUint> sbuf;
       
   949     sbuf()=0;
       
   950     
       
   951     // Enumerate messages from store - NOTE - sometimes SIM.TSY returns
       
   952     // KErrInUse (strange timing things!). In this case wait and repeat.
       
   953     const TInt KMaxAttempts = 3;
       
   954     TInt attempts = 0;
       
   955     do
       
   956         {
       
   957         User::After(2000000);   // Wait a couple of seconds...
       
   958 
       
   959         aSocket.Ioctl(KIoctlEnumerateSmsMessages, aStatus, &sbuf, KSolSmsProv);
       
   960         User::WaitForRequest(aStatus);
       
   961         
       
   962         INFO_PRINTF3(_L("Enumerating completed [status=%d, attempts=%d]"), aStatus.Int(), ++attempts);        
       
   963         } while( aStatus.Int() == KErrInUse && attempts < KMaxAttempts );
       
   964     
       
   965     if( aStatus.Int() == KErrNone )
       
   966         {
       
   967         // sbuf() includes the count of messages on Store
       
   968         TInt count = sbuf();
       
   969         INFO_PRINTF2(_L("%d enumerated messages"), count);
       
   970         
       
   971         RSmsSocketReadStream readstream(aSocket);
       
   972         
       
   973         //Read each message from the stream
       
   974         for(TInt i=0; i< count; ++i)
       
   975             {
       
   976             CSmsBuffer* buffer=CSmsBuffer::NewL();
       
   977             CSmsMessage* smsmessage=CSmsMessage::NewL(iFs, CSmsPDU::ESmsDeliver,buffer);
       
   978             CleanupStack::PushL(smsmessage);
       
   979         
       
   980             TRAPD(ret,readstream >> *smsmessage);
       
   981             TEST(ret == KErrNone);
       
   982             aSocket.Ioctl(KIoctlReadMessageSucceeded, aStatus, NULL, KSolSmsProv);
       
   983             User::WaitForRequest(aStatus);
       
   984             TEST(aStatus.Int() == KErrNone);
       
   985             
       
   986             PrintMessageDetailedL(smsmessage);
       
   987             
       
   988             User::LeaveIfError(aMessages.Append(smsmessage));
       
   989             CleanupStack::Pop(smsmessage);
       
   990             }
       
   991         }
       
   992     else
       
   993         {
       
   994         ERR_PRINTF2(_L("Enumerating failed [status=%d]"), aStatus.Int());
       
   995         SetTestStepResult(EFail);
       
   996         }
       
   997     }
       
   998 
       
   999 EXPORT_C TInt CSmsBaseTestStep::DeleteSmsL(const CSmsMessage& aSms, RSocket& aSocket, TInt aExpectedError /*KErrNone*/)
       
  1000 /**
       
  1001  *  This method deletes SMS message from the SMS storage.
       
  1002  *  @param aSms SMS message that will be deleted
       
  1003  *  @param aSocket Used to stream SMS message to the sms stack
       
  1004  *  @return TInt :error code
       
  1005  */
       
  1006     {
       
  1007     INFO_PRINTF2(_L("Delete message from store [aExpectedError=%d]"), aExpectedError);
       
  1008 
       
  1009     TRequestStatus status;
       
  1010 
       
  1011     RSmsSocketWriteStream writestream(aSocket);
       
  1012     TRAPD(ret,writestream << aSms);
       
  1013     TEST(ret == KErrNone);
       
  1014     TRAP(ret,writestream.CommitL());
       
  1015     TEST(ret == KErrNone);
       
  1016 
       
  1017     aSocket.Ioctl(KIoctlDeleteSmsMessage, status, NULL, KSolSmsProv);
       
  1018     User::WaitForRequest(status);
       
  1019     TInt error = status.Int();
       
  1020     
       
  1021     INFO_PRINTF2(_L("Delete SMS message - returned %d"), error);    
       
  1022 
       
  1023     if( error != aExpectedError )
       
  1024         {
       
  1025         ERR_PRINTF3(_L("Delete SMS message failed [aExpectedError=%d, error=%d]"), aExpectedError, error);
       
  1026         SetTestStepResult(EFail);
       
  1027         }
       
  1028     return error;
       
  1029     }
       
  1030 
       
  1031 EXPORT_C void CSmsBaseTestStep::DeleteSmsLeaveIfErrorL(const CSmsMessage& aSms, RSocket& aSocket)
       
  1032 /**
       
  1033  *  This method deletes SMS message from the SMS storage.
       
  1034  *  @param aSms SMS message that will be deleted
       
  1035  *  @param aSocket Used to stream SMS message to the sms stack
       
  1036  */
       
  1037     {
       
  1038     TRequestStatus status;
       
  1039     RSmsSocketWriteStream writestream(aSocket);
       
  1040     writestream << aSms;
       
  1041     writestream.CommitL();
       
  1042     aSocket.Ioctl(KIoctlDeleteSmsMessage, status, NULL, KSolSmsProv);
       
  1043     User::WaitForRequest(status);
       
  1044     INFO_PRINTF2(_L("Delete SMS returned %d"), status.Int());
       
  1045     if(status.Int() != KErrNone)
       
  1046         {
       
  1047         User::Leave(status.Int());
       
  1048         }
       
  1049     }
       
  1050 
       
  1051 EXPORT_C void CSmsBaseTestStep::SetIndicatorL(const TTestCase& aTestCase, CSmsMessage* aSms)
       
  1052 /**
       
  1053  *  
       
  1054  */
       
  1055     {
       
  1056     TSmsDataCodingScheme::TSmsAlphabet alphabet;
       
  1057     if (aTestCase.iBits7To4 == TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2)
       
  1058         alphabet = TSmsDataCodingScheme::ESmsAlphabetUCS2;
       
  1059     else
       
  1060         alphabet = TSmsDataCodingScheme::ESmsAlphabet7Bit;
       
  1061 
       
  1062     TSmsUserDataSettings smsSettings;
       
  1063     smsSettings.SetAlphabet(alphabet);
       
  1064     smsSettings.SetTextCompressed(EFalse);
       
  1065     aSms->SetUserDataSettingsL(smsSettings);
       
  1066 
       
  1067     CSmsPDU& pdu = aSms->SmsPDU();
       
  1068     pdu.SetBits7To4(aTestCase.iBits7To4);
       
  1069     pdu.SetIndicationType(aTestCase.iIndicationType);
       
  1070     pdu.SetIndicationState(aTestCase.iIndicationState);
       
  1071 
       
  1072     }
       
  1073 
       
  1074 EXPORT_C void CSmsBaseTestStep::FillDes(TDes& aDes,TInt aLength)
       
  1075 /**
       
  1076  *  Fill aDes with randomly generated 7bit data
       
  1077  *  @param aDes will be filled with random data
       
  1078  *  @param aLength has the length to be set to aDes
       
  1079  */
       
  1080     {
       
  1081     TText baseChar='A';
       
  1082 
       
  1083     aDes.SetLength(aLength);
       
  1084     for (TInt i=0; i<aLength; i++)
       
  1085         {
       
  1086         aDes[i]=TText(baseChar + i%26);
       
  1087         }
       
  1088     }
       
  1089 
       
  1090 EXPORT_C TInt CSmsBaseTestStep::MakeReadSmsStoreRequestL(RSocket& aSocket)
       
  1091 /**
       
  1092  *  This method retrieves SMS messages from SMS storage.
       
  1093  *  Main purpose is to test out of memory conditions.
       
  1094  *  @param aSocket Used to stream SMS messages from the sms stack
       
  1095  *  @param aMessages reference to CSmsMessage pointer array.
       
  1096  */
       
  1097     {
       
  1098     TRequestStatus status;
       
  1099     TPckgBuf<TUint> sbuf;
       
  1100     sbuf()=0;
       
  1101 
       
  1102     //Now enumerate messages from SIM
       
  1103     aSocket.Ioctl(KIoctlEnumerateSmsMessages,status,&sbuf, KSolSmsProv);
       
  1104     User::WaitForRequest(status);
       
  1105     INFO_PRINTF2(_L("Read SMS returned %d"), status.Int());
       
  1106     if(status.Int() != KErrNone)
       
  1107         {
       
  1108         User::Leave(status.Int());
       
  1109         }
       
  1110 
       
  1111     //sbuf() includes the count of messages on SIM
       
  1112     return sbuf();
       
  1113     }
       
  1114 
       
  1115 EXPORT_C TBool CSmsBaseTestStep::TimedWaitForRecvL(RSocket& aSocket, TUint aDelay)
       
  1116 /**
       
  1117  *  Wait for up to the delay for an Sms to be received
       
  1118  *  @param aSocket The status is return to this socket
       
  1119  *  @param aDelay Maximum time to wait for receipt
       
  1120  *  @return ETrue if data received
       
  1121  *  @leave Leaves if receiving is completed with error code
       
  1122  */
       
  1123     {
       
  1124     TRequestStatus timerStatus;
       
  1125     RTimer timer;
       
  1126     timer.CreateLocal();
       
  1127     timer.After(timerStatus, TTimeIntervalMicroSeconds32(aDelay));
       
  1128 
       
  1129     TPckgBuf<TUint> sbuf;
       
  1130     sbuf()=KSockSelectRead;
       
  1131     TRequestStatus ioctlStatus;
       
  1132     aSocket.Ioctl(KIOctlSelect, ioctlStatus, &sbuf, KSOLSocket);
       
  1133     User::WaitForRequest(timerStatus, ioctlStatus);
       
  1134     TBool retval;
       
  1135     
       
  1136     if(ioctlStatus.Int() != KErrNone)
       
  1137         {
       
  1138         aSocket.CancelIoctl();
       
  1139         User::WaitForRequest(ioctlStatus);
       
  1140         retval = EFalse;
       
  1141         }
       
  1142     else
       
  1143         {
       
  1144         timer.Cancel();
       
  1145         User::WaitForRequest(timerStatus);
       
  1146         retval = ETrue;
       
  1147         }
       
  1148     timer.Close();
       
  1149     return retval;
       
  1150     }
       
  1151 
       
  1152 EXPORT_C TInt CSmsBaseTestStep::CancelWriteSmsToSimL(CSmsMessage& aSms, RSocket& aSocket, TInt aDelay)
       
  1153 /**
       
  1154  *  This method stores SMS messages to the SMS storage.
       
  1155  *  @param aSms SMS message that will be stored
       
  1156  *  @param aSocket Used to stream SMS message to the sms stack
       
  1157  *  @leave Leaves if streaming the message to the socket server doesn't succeed
       
  1158  *  @leave Leaves if store request is completed with error code
       
  1159  */
       
  1160     {
       
  1161     INFO_PRINTF1(_L("Write message"));
       
  1162 
       
  1163     TRequestStatus status;
       
  1164 
       
  1165     RSmsSocketWriteStream writestream(aSocket);
       
  1166     TRAPD(ret,writestream << aSms);
       
  1167     TEST(ret == KErrNone);
       
  1168     TRAP(ret,writestream.CommitL());
       
  1169     TEST(ret == KErrNone);
       
  1170 
       
  1171     aSocket.Ioctl(KIoctlWriteSmsMessage,status,NULL, KSolSmsProv);
       
  1172     INFO_PRINTF1(_L("Cancel"));
       
  1173     User::After(aDelay);
       
  1174     aSocket.CancelIoctl();
       
  1175     User::WaitForRequest(status);
       
  1176     INFO_PRINTF2(_L("WriteSmsToSimL - returned %d"), status.Int());
       
  1177 
       
  1178     return status.Int();
       
  1179     }
       
  1180 
       
  1181 EXPORT_C TBool CSmsBaseTestStep::DoSingleTestCaseL( const TDesC8& aSection, TInt aCount )
       
  1182     {
       
  1183     CTestConfig* configFile = CTestConfig::NewLC(iFs, KGmsSmsConfigFileDir, KConfigFilename);
       
  1184 
       
  1185     TBuf8<64> sectionName(aSection);
       
  1186     sectionName.AppendNum(aCount);
       
  1187     const CTestConfigSection* section = NULL;
       
  1188     TBool found( ETrue );
       
  1189 
       
  1190     if ( ( section = configFile->Section( sectionName ) ) != NULL )
       
  1191         {
       
  1192         if ( aSection == KTestSendAndRecvMsgsWithDifferentTON )
       
  1193             {
       
  1194             TInt num( 1 );
       
  1195             CArrayFixFlat<TInt>* alphabetArray = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
  1196             CleanupStack::PushL(alphabetArray);
       
  1197             CArrayFixFlat<TInt>* typeOfNumberArray = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
  1198             CleanupStack::PushL(typeOfNumberArray);
       
  1199 
       
  1200             TBuf8<32> itemName( KAlphabet );
       
  1201             itemName.AppendNum( num );
       
  1202 
       
  1203             TInt param  = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1204             while ( param != KErrNotFound )
       
  1205                 {
       
  1206                 alphabetArray->AppendL(param);
       
  1207                 itemName = KAlphabet;
       
  1208                 itemName.AppendNum( ++num );
       
  1209                 param = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1210                 }
       
  1211             num = 1;
       
  1212             itemName = KTypeOfNumber;
       
  1213             itemName.AppendNum( num );
       
  1214 
       
  1215             param  = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1216             while ( param != KErrNotFound )
       
  1217                 {
       
  1218                 typeOfNumberArray->AppendL(param);
       
  1219                 itemName = KTypeOfNumber;
       
  1220                 itemName.AppendNum( ++num );
       
  1221                 param = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1222                 }
       
  1223 
       
  1224             RPointerArray<CSmsPduDbMessage> array;
       
  1225             CleanupResetAndDestroyPushL(array);
       
  1226             ReadPduL( sectionName, array );
       
  1227             TestSendAndRecvMsgsWithDifferentTONL( array, alphabetArray, typeOfNumberArray );
       
  1228             CleanupStack::PopAndDestroy(&array);
       
  1229             CleanupStack::PopAndDestroy(typeOfNumberArray);
       
  1230             CleanupStack::PopAndDestroy(alphabetArray);
       
  1231             }
       
  1232         else if ( aSection == KTestSendAndReceiveIndicatorMsgs )
       
  1233             {
       
  1234             TInt num( 1 );
       
  1235             CArrayFixFlat<TInt>* indicationTypeArray = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
  1236             CleanupStack::PushL(indicationTypeArray);
       
  1237             CArrayFixFlat<TInt>* dcsBits7To4Array = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
  1238             CleanupStack::PushL(dcsBits7To4Array);
       
  1239             CArrayFixFlat<TInt>* indicationStateArray = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
  1240             CleanupStack::PushL(indicationStateArray);
       
  1241 
       
  1242             TBuf8<32> itemName( KIndicationType );
       
  1243             itemName.AppendNum( num );
       
  1244 
       
  1245             TInt param  = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1246             while ( param != KErrNotFound )
       
  1247                 {
       
  1248                 indicationTypeArray->AppendL(param);
       
  1249                 itemName = KIndicationType;
       
  1250                 itemName.AppendNum( ++num );
       
  1251                 param = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1252                 }
       
  1253             num = 1;
       
  1254             itemName = KDCSBits7To4;
       
  1255             itemName.AppendNum( num );
       
  1256 
       
  1257             param  = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1258             while ( param != KErrNotFound )
       
  1259                 {
       
  1260                 dcsBits7To4Array->AppendL(param);
       
  1261                 itemName = KDCSBits7To4;
       
  1262                 itemName.AppendNum( ++num );
       
  1263                 param = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1264                 }
       
  1265             num = 1;
       
  1266             itemName = KIndicationState;
       
  1267             itemName.AppendNum( num );
       
  1268 
       
  1269             param  = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1270             while ( param != KErrNotFound )
       
  1271                 {
       
  1272                 indicationStateArray->AppendL(param);
       
  1273                 itemName = KIndicationState;
       
  1274                 itemName.AppendNum( ++num );
       
  1275                 param = section->ItemValue( (TPtrC8)itemName, KErrNotFound );
       
  1276                 }
       
  1277 
       
  1278             RPointerArray<CSmsPduDbMessage> array;
       
  1279             CleanupResetAndDestroyPushL(array);
       
  1280             ReadPduL( sectionName, array );
       
  1281             TestSendAndReceiveIndicatorMsgsL( array, indicationStateArray, dcsBits7To4Array, indicationTypeArray );
       
  1282             CleanupStack::PopAndDestroy(&array);
       
  1283             CleanupStack::PopAndDestroy(indicationStateArray);
       
  1284             CleanupStack::PopAndDestroy(dcsBits7To4Array);
       
  1285             CleanupStack::PopAndDestroy(indicationTypeArray);
       
  1286             }
       
  1287         else
       
  1288             found = EFalse;
       
  1289         }
       
  1290     else
       
  1291         found = EFalse;
       
  1292 
       
  1293     CleanupStack::PopAndDestroy(configFile);//configFile
       
  1294     return found;
       
  1295     }
       
  1296 
       
  1297 EXPORT_C void CSmsBaseTestStep::TestSendAndRecvMsgsWithDifferentTONL( const RPointerArray<CSmsPduDbMessage>& aArray,
       
  1298                                                    const CArrayFixFlat<TInt>* aAlphabetArray,
       
  1299                                                    const CArrayFixFlat<TInt>* aTypeOfNumberArray )
       
  1300     {
       
  1301     INFO_PRINTF1(_L("Send and receive messages with different type of number"));
       
  1302     
       
  1303     const TInt testNumber = 39;
       
  1304     SetSimTSYTestNumberL(testNumber);
       
  1305     
       
  1306     RSocketServ socketServer;
       
  1307     ConnectSocketServerLC(socketServer);
       
  1308 
       
  1309     RSocket socket;
       
  1310     iSmsStackTestUtils->OpenSmsSocketLC(socketServer,socket,ESmsAddrRecvAny);
       
  1311 
       
  1312     TSmsDataCodingScheme::TSmsAlphabet alphabet = ( TSmsDataCodingScheme::TSmsAlphabet )aAlphabetArray->At(0);
       
  1313 
       
  1314     TInt bufLen=aArray[0]->iSmsMessage->Buffer().Length();
       
  1315     HBufC* textBuf=HBufC::NewL(bufLen);
       
  1316     CleanupStack::PushL(textBuf);
       
  1317     TPtr testText(textBuf->Des());
       
  1318     aArray[0]->iSmsMessage->Buffer().Extract(testText,0,bufLen);
       
  1319 
       
  1320     CSmsMessage* sendMessage=CreateSmsMessageLC(testText,alphabet);
       
  1321     CSmsSubmit& submitPdu=(CSmsSubmit&)sendMessage->SmsPDU();
       
  1322     TGsmSmsTelNumber gsmSmsTelNumber;
       
  1323     gsmSmsTelNumber.iTelNumber.Append(iTelephoneNumber);
       
  1324     if(gsmSmsTelNumber.iTelNumber.Length() > 0 && gsmSmsTelNumber.iTelNumber[0] == '+')
       
  1325     {
       
  1326         // Remove "+" sign from telephony number
       
  1327         gsmSmsTelNumber.iTelNumber.Delete(0,1);
       
  1328         gsmSmsTelNumber.iTelNumber.Trim();
       
  1329     }
       
  1330 
       
  1331     for ( TInt i = 0; i < aTypeOfNumberArray->Count(); i++ )
       
  1332         {
       
  1333         gsmSmsTelNumber.iTypeOfAddress.SetTON( ( TGsmSmsTypeOfNumber )aTypeOfNumberArray->At(i) );
       
  1334         sendMessage->SetParsedToFromAddressL(gsmSmsTelNumber);
       
  1335 
       
  1336         if ( ( TGsmSmsTypeOfNumber )aTypeOfNumberArray->At(i) == EGsmSmsTONSubscriberNumber )
       
  1337             {
       
  1338             submitPdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDShortMessageType);
       
  1339             submitPdu.SetShortMessageType(TSmsProtocolIdentifier::ESmsReturnCallMesage);
       
  1340             }
       
  1341         INFO_PRINTF2(_L("Send SMS message. Type of number is %d"), aTypeOfNumberArray->At(i) );
       
  1342         SendSmsL(sendMessage,socket);
       
  1343 
       
  1344         INFO_PRINTF1(_L("Waiting for incoming SMS...") );
       
  1345         WaitForRecvL(socket);
       
  1346         CSmsMessage* recvMessage = RecvSmsL(socket);
       
  1347         delete recvMessage;
       
  1348         }
       
  1349 
       
  1350     CleanupStack::PopAndDestroy(4, &socketServer); // socketServer, socket, textBuf, sendMessage
       
  1351     }
       
  1352 
       
  1353 EXPORT_C void CSmsBaseTestStep::TestSendAndReceiveIndicatorMsgsL( const RPointerArray<CSmsPduDbMessage>& aArray,
       
  1354                                                const CArrayFixFlat<TInt>* aIndicationStateArray,
       
  1355                                                const CArrayFixFlat<TInt>* aDcsBits7To4Array,
       
  1356                                                const CArrayFixFlat<TInt>* aIndicationTypeArray )
       
  1357 /**
       
  1358  *  @test Send and receive different indicator messages
       
  1359  *  TODO ESmsDCSMessageWaitingIndicationDiscardMessage test doesn't work with Nokia 6210 because phone
       
  1360  *  doesn't route incoming message to the MM TSY.
       
  1361  */
       
  1362     {
       
  1363 
       
  1364     INFO_PRINTF1(_L("Send and receive different indicator messages"));
       
  1365     
       
  1366     const TInt testNumber = 40;
       
  1367     SetSimTSYTestNumberL(testNumber);
       
  1368     
       
  1369     RSocketServ socketServer;
       
  1370     ConnectSocketServerLC(socketServer);
       
  1371 
       
  1372     RSocket socket;
       
  1373     iSmsStackTestUtils->OpenSmsSocketLC(socketServer,socket,ESmsAddrRecvAny);
       
  1374 
       
  1375     for ( TInt i = 0; i < aArray.Count(); i++ )
       
  1376         {
       
  1377 
       
  1378         TSmsDataCodingScheme::TSmsIndicationState indicationState =
       
  1379             ( TSmsDataCodingScheme::TSmsIndicationState )aIndicationStateArray->At(i);
       
  1380         TSmsDataCodingScheme::TSmsDCSBits7To4 dcsBits7To4Array =
       
  1381             ( TSmsDataCodingScheme::TSmsDCSBits7To4 )aDcsBits7To4Array->At(i);
       
  1382         TSmsDataCodingScheme::TSmsIndicationType indicationType =
       
  1383             ( TSmsDataCodingScheme::TSmsIndicationType )aIndicationTypeArray->At(i);
       
  1384 
       
  1385         TInt bufLen=aArray[i]->iSmsMessage->Buffer().Length();
       
  1386         HBufC* textBuf=HBufC::NewL(bufLen);
       
  1387         CleanupStack::PushL(textBuf);
       
  1388         TPtr testText(textBuf->Des());
       
  1389         aArray[i]->iSmsMessage->Buffer().Extract(testText,0,bufLen);
       
  1390 
       
  1391         TTestCase msg(testText, indicationType, dcsBits7To4Array, indicationState );
       
  1392 
       
  1393         SendAndRecvTestMessageL(msg,socket);
       
  1394 
       
  1395         CleanupStack::PopAndDestroy(textBuf);
       
  1396         }
       
  1397 
       
  1398     CleanupStack::PopAndDestroy(2, &socketServer); // socketServer, socket
       
  1399     }
       
  1400 
       
  1401 EXPORT_C void CSmsBaseTestStep::ReadPduL( TBuf8<64> aSectionName, RPointerArray<CSmsPduDbMessage>& aArray )
       
  1402     {
       
  1403     CSmsPduDatabase* db = CSmsPduDatabase::NewL(iFs, aSectionName, KConfigFilename, KConfigFileDir);
       
  1404     CleanupStack::PushL(db);
       
  1405 
       
  1406     db->GetMessageL(aArray, CSmsPDU::ESmsSubmit);
       
  1407 
       
  1408     CleanupStack::PopAndDestroy(db);
       
  1409     }
       
  1410 
       
  1411 EXPORT_C CSmsMessage* CSmsBaseTestStep::CreateSmsMessageLC(CSmsPDU::TSmsPDUType aType, CSmsBuffer* aBuffer, const TDesC& aAddress)
       
  1412     {
       
  1413     CSmsMessage* msg = CSmsMessage::NewL(iFs, aType, aBuffer);
       
  1414     CleanupStack::PushL(msg);
       
  1415 
       
  1416     if (aAddress.Length() != 0)
       
  1417         {
       
  1418         msg->SetToFromAddressL(aAddress);
       
  1419         }
       
  1420 
       
  1421     return msg;
       
  1422     }
       
  1423 
       
  1424 /*
       
  1425 These functions were grabbed from SMSStackTestUtils.dll
       
  1426 */
       
  1427 EXPORT_C void CSmsBaseTestStep::OpenSmsSocketL(RSocketServ& aSocketServer, RSocket& aSocket, TSmsAddrFamily aFamily)
       
  1428 /**
       
  1429  *  Initialise an RSocket for SMS, aSocket is NOT pushed to CleanupStack.
       
  1430  *  @param aSocketServer reference to the socket server object
       
  1431  *  @param aSocket The socket that will be opened
       
  1432  *  @param aFamily The sms address family
       
  1433  *  @param aDualSimAware Flag indicating that client is dual-SIM aware
       
  1434  */
       
  1435     {
       
  1436     TSmsAddr smsaddr;
       
  1437     smsaddr.SetSmsAddrFamily(aFamily);
       
  1438     OpenSmsSocketL(aSocketServer, aSocket, smsaddr);
       
  1439     }
       
  1440 
       
  1441 EXPORT_C void CSmsBaseTestStep::OpenSmsSocketL(RSocketServ& aSocketServer, RSocket& aSocket, TSmsAddr& aSmsAddr)
       
  1442 /*
       
  1443  *  Initialise an RSocket for SMS, aSocket is NOT pushed to CleanupStack.
       
  1444  *  @param aSocketServer reference to the socket server object
       
  1445  *  @param aSocket The socket that will be opened
       
  1446  *  @param aSmsAddr The sms address to bind to
       
  1447  */
       
  1448     {
       
  1449     INFO_PRINTF2(_L("Opening and binding socket [addrFamily=%d]"), aSmsAddr.SmsAddrFamily());
       
  1450     
       
  1451     TInt ret=aSocket.Open(aSocketServer,KSMSAddrFamily,KSockDatagram,KSMSDatagramProtocol);
       
  1452     TESTCHECK(ret, KErrNone, "Opening socket");
       
  1453 
       
  1454     ret=aSocket.Bind(aSmsAddr);
       
  1455     TESTCHECK(ret, KErrNone, "Binding to the socket");
       
  1456     
       
  1457     TProtocolDesc desc;
       
  1458     aSocket.Info(desc);
       
  1459     INFO_PRINTF2(_L("Protocol name: %S"), &desc.iName);
       
  1460 	
       
  1461     TTimeIntervalMicroSeconds32 InitPause=9000000;  //Required Pause to Allow SMSStack to Complete its Async Init
       
  1462     User::After(InitPause);                         //call to the TSY and finish its StartUp.
       
  1463 
       
  1464     }
       
  1465 
       
  1466 /*
       
  1467     Utility for creating a SMS message from test data (ini) file
       
  1468 */
       
  1469 EXPORT_C CSmsMessage* CSmsBaseTestStep::CreateSMSL()
       
  1470     {
       
  1471     INFO_PRINTF1(_L("Creating SMS...") );
       
  1472     
       
  1473     TInt codingScheme;
       
  1474     GetIntFromConfig(ConfigSection(), _L("messageCoding"), codingScheme);
       
  1475     
       
  1476     TCodingScheme dataCodingScheme = (TCodingScheme)codingScheme;   
       
  1477     
       
  1478     TSmsDataCodingScheme::TSmsAlphabet alphabet;
       
  1479     if (dataCodingScheme == ESevenBit)
       
  1480         {   
       
  1481         //8 bit coding scheme
       
  1482         alphabet = TSmsDataCodingScheme::ESmsAlphabet7Bit;
       
  1483         }
       
  1484 
       
  1485     else 
       
  1486         {
       
  1487         alphabet = TSmsDataCodingScheme::ESmsAlphabet8Bit;
       
  1488         }       
       
  1489     
       
  1490     TPtrC messageText;
       
  1491     GetStringFromConfig(ConfigSection(), _L("message"), messageText);
       
  1492     CSmsMessage *sms = CreateSmsMessageL(messageText, alphabet);
       
  1493     
       
  1494     INFO_PRINTF1(_L("SMS created") );
       
  1495     PrintMessageL(sms);
       
  1496     
       
  1497     return sms;
       
  1498     }
       
  1499 
       
  1500 /**
       
  1501  * Sets high and low limits in .RSC file and then reserves disk space to match requested levels.
       
  1502  * 
       
  1503  * Checks the current free space and then sets the high and low marks
       
  1504  * to be aHighDrop MB and aLowDrop MB below the current free space 
       
  1505  * level.
       
  1506  * 
       
  1507  * Then diskspace is reserved to aFreeDrop MB below the current free
       
  1508  * space level.
       
  1509  * 
       
  1510  * If the current free space level is greater then aMax then the 
       
  1511  * current free space level is set to aMax
       
  1512  * 
       
  1513  * If the current free space level is less than aLowDrop MB then this
       
  1514  * method leaves with KErrArgument.
       
  1515  * 
       
  1516  * @param   aHighDrop   The number of MB below the current free space level for the high level mark (in the .RSC file)
       
  1517  * @param   aLowDrop    The number of MB below the current free space level for the low level mark (in the .RSC file)  
       
  1518  * @param   aFreeDrop   The number of MB below the current free space level for the low level mark
       
  1519  * @param   aMax        The maximum level for the high limit allowed
       
  1520  * 
       
  1521  * @return  The max current free space level used.
       
  1522  * 
       
  1523  * @leave   KErrArgument if the current free diskspace level is less than aLowDrop MB
       
  1524  * @leave   KErrArgument if aMax is not greater than aLowDrop MB
       
  1525  * @leave   KErrArgument if aHighDrop >= aLowDrop  
       
  1526  */
       
  1527 EXPORT_C TUint64 CSmsBaseTestStep::SetHighLowLimitsAndDiskSpaceLevelL(TUint aHighDrop, TUint aLowDrop, TUint aFreeDrop, TUint64 aMax/*=0x7fffffff*/)
       
  1528     {
       
  1529     INFO_PRINTF5(_L("Setting High-Low limits and Free Diskspace levels [aHighDrop=%u, aLowDrop=%u, aFreeDrop=%u, aMax=%ld]"), aHighDrop, aLowDrop, aFreeDrop, aMax);
       
  1530     
       
  1531     __ASSERT_ALWAYS( (aMax > (aLowDrop*1024*1024)), User::Leave(KErrArgument));
       
  1532     __ASSERT_ALWAYS( (aLowDrop > aHighDrop), User::Leave(KErrArgument));
       
  1533     
       
  1534     ReleaseDiskSpaceL();
       
  1535    
       
  1536     TVolumeInfo  volumeInfo;
       
  1537     User::LeaveIfError(iFs.Volume(volumeInfo, EDriveC));
       
  1538     INFO_PRINTF2(_L("  Drive C currently has %ld bytes free."), volumeInfo.iFree);
       
  1539     
       
  1540     TUint64 current = volumeInfo.iFree;
       
  1541     if( current < (aLowDrop*1024*1024) )
       
  1542         {
       
  1543         INFO_PRINTF1(_L("  Drive C already has too little free space!"));
       
  1544         User::Leave(KErrArgument);
       
  1545         }
       
  1546     if( current > aMax )
       
  1547         {
       
  1548         current = aMax;
       
  1549         }
       
  1550     TUint64 high = current - (aHighDrop*1024*1024);
       
  1551     TUint64 low  = current - (aLowDrop*1024*1024);
       
  1552         
       
  1553     SetLowHighLimitsInSmsuRscL(low, high);
       
  1554     if( aFreeDrop != 0 )
       
  1555         {
       
  1556         TUint64 free = current - (aFreeDrop*1024*1024);
       
  1557         SetFreeDiskSpaceL(free);
       
  1558         }
       
  1559     
       
  1560     return current;
       
  1561     }
       
  1562 
       
  1563 /**
       
  1564  * Reserves disk space to match requested free space - a number MB below the current free space level.
       
  1565  * 
       
  1566  * Checks the current free space and diskspace is reserved to aFreeDrop
       
  1567  * MB below the current free space level.
       
  1568  * 
       
  1569  * If the current free space level is greater then aMax then the 
       
  1570  * current free space level is set to aMax
       
  1571  * 
       
  1572  * If the current free space level is less than aLowDrop MB then this
       
  1573  * method leaves with KErrArgument.
       
  1574  * 
       
  1575  * @param   aFreeDrop   The number of MB below the current free space level for the low level mark
       
  1576  * @param   aMax        The maximum level for the high limit allowed
       
  1577  * 
       
  1578  * @return  The max current free space level used.
       
  1579  * 
       
  1580  * @leave   KErrArgument if the current free diskspace level is less than aLowDrop MB
       
  1581  * @leave   KErrArgument if aMax is not greater than aLowDrop MB
       
  1582  * @leave   KErrArgument if aHighDrop >= aLowDrop  
       
  1583  */
       
  1584 EXPORT_C void CSmsBaseTestStep::SetFreeDiskSpaceFromDropLevelL(TUint aFreeDrop, TUint64 aMax/*=0x7fffffff*/)
       
  1585     {
       
  1586     INFO_PRINTF3(_L("Setting Free Diskspace level [aFreeDrop=%u, aMax=%ld]"), aFreeDrop, aMax);
       
  1587     
       
  1588     if( aFreeDrop == 0)
       
  1589         {
       
  1590         return;
       
  1591         }
       
  1592     
       
  1593     TVolumeInfo  volumeInfo;
       
  1594     User::LeaveIfError(iFs.Volume(volumeInfo, EDriveC));
       
  1595     TUint64 current = volumeInfo.iFree;
       
  1596     if( current > aMax )
       
  1597         {
       
  1598         current = aMax;
       
  1599         }    
       
  1600     TUint64 free = current - (aFreeDrop*1024*1024);
       
  1601     SetFreeDiskSpaceL(free);    
       
  1602     }
       
  1603 
       
  1604 /**
       
  1605  *  Reserves disk space so that a specified amount of free disk space is
       
  1606  *  available.
       
  1607  *
       
  1608  *  @param aNewFreeValue  Amount of free space required.
       
  1609  */
       
  1610 EXPORT_C void CSmsBaseTestStep::SetFreeDiskSpaceL(TInt64 aNewFreeValue)
       
  1611     {
       
  1612     
       
  1613 #ifndef _DEBUG
       
  1614     (void)aNewFreeValue; // added to aviod compiler warning, as only used in test mode
       
  1615     
       
  1616     ERR_PRINTF1(_L("Unexpected call: CSMSTestSteps::SetFreeDiskSpaceL() is expected to be called only in DEBUG mode."));
       
  1617     User::Leave(KErrNotSupported);
       
  1618 #else
       
  1619     INFO_PRINTF2(_L("Setting Drive C free disk space to %ld bytes."), aNewFreeValue);    
       
  1620     
       
  1621     __ASSERT_DEBUG( (aNewFreeValue <= 0x7fffffff), User::Leave(KErrArgument));
       
  1622 
       
  1623     TInt err = RProperty::Set(KUidPSSMSStackCategory, KUidPSSMSStackFreeDiskSpaceKey, (TInt)aNewFreeValue);
       
  1624     if (err != KErrNone)
       
  1625         {
       
  1626         ERR_PRINTF2(_L("RProperty::Set() failure [err=%d]"), err);
       
  1627         User::Leave(err);
       
  1628         }
       
  1629 #endif           
       
  1630     } // CSMSTestSteps::SetFreeDiskSpaceL
       
  1631 
       
  1632 
       
  1633 /**
       
  1634  *  Release all reserved disk space.
       
  1635  */
       
  1636 EXPORT_C void CSmsBaseTestStep::ReleaseDiskSpaceL()
       
  1637     {    
       
  1638 #ifndef _DEBUG
       
  1639     ERR_PRINTF1(_L("Unexpected call: CSMSTestSteps::ReleaseDiskSpaceL() is expected to be called only in DEBUG mode."));
       
  1640     User::Leave(KErrNotSupported);
       
  1641 #else
       
  1642     INFO_PRINTF1(_L("CSMSTestSteps::ReleaseDiskSpaceL()"));
       
  1643     
       
  1644     TVolumeInfo  volumeInfo;
       
  1645     User::LeaveIfError(iFs.Volume(volumeInfo, EDriveC));
       
  1646     TUint64 current = volumeInfo.iFree;
       
  1647     if( current > 0x7fffffff )
       
  1648         {
       
  1649         current = 0x7fffffff;
       
  1650         }
       
  1651     SetFreeDiskSpaceL(current);
       
  1652 #endif    
       
  1653     }
       
  1654 
       
  1655  /**
       
  1656   *  Set high and low limits in .RSC file. When the SMS Stack starts the limits
       
  1657   *  will be loaded as if set by the licensee.
       
  1658   *
       
  1659   *  @param aLowLimit   Low limit value.
       
  1660   *  @param aHighLimit  High limit value.
       
  1661   *
       
  1662   *  @note Only works in debug mode for security reasons.
       
  1663   */ 
       
  1664 EXPORT_C void CSmsBaseTestStep::SetLowHighLimitsInSmsuRscL(TInt64 aLowLimit, TInt64 aHighLimit)
       
  1665     {
       
  1666     INFO_PRINTF3(_L("Setting high and low .RSC limits to %ld and %ld."),
       
  1667                  aHighLimit, aLowLimit);
       
  1668 
       
  1669     __ASSERT_ALWAYS(aLowLimit  < 0x7fffffff, User::Leave(KErrArgument));
       
  1670     __ASSERT_ALWAYS(aHighLimit < 0x7fffffff, User::Leave(KErrArgument));
       
  1671     __ASSERT_ALWAYS(aLowLimit  < aHighLimit, User::Leave(KErrArgument));
       
  1672 
       
  1673     //
       
  1674     // Data for the SMSU resource file. The low limit is written at position
       
  1675     // 20 and the high limit at position 24.
       
  1676     //
       
  1677     const TInt  smsuRscSize = 34;
       
  1678     TChar  smsuRscData[smsuRscSize] =
       
  1679                 {0x6b, 0x4a, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00,
       
  1680                  0x00, 0x00, 0x00, 0x00, 0x19, 0xfd, 0x48, 0xe8,
       
  1681                  0x01, 0x04, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12,
       
  1682                  0x87, 0x65, 0x43, 0x21, 0x14, 0x00, 0x18, 0x00, 
       
  1683                  0x1c, 0x00};
       
  1684                               
       
  1685     smsuRscData[20] = (aLowLimit  >>  0) & 0xff;
       
  1686     smsuRscData[21] = (aLowLimit  >>  8) & 0xff;
       
  1687     smsuRscData[22] = (aLowLimit  >> 16) & 0xff;
       
  1688     smsuRscData[23] = (aLowLimit  >> 24) & 0xff;
       
  1689     smsuRscData[24] = (aHighLimit >>  0) & 0xff;
       
  1690     smsuRscData[25] = (aHighLimit >>  8) & 0xff;
       
  1691     smsuRscData[26] = (aHighLimit >> 16) & 0xff;
       
  1692     smsuRscData[27] = (aHighLimit >> 24) & 0xff;
       
  1693 
       
  1694     TBuf8<smsuRscSize>  smsuRscBuffer;
       
  1695 
       
  1696     for (TInt index = 0;  index < smsuRscSize;  index++)
       
  1697         {
       
  1698         smsuRscBuffer.Append(smsuRscData[index]);
       
  1699         }
       
  1700 
       
  1701     //
       
  1702     // Ensure the target directory exists...
       
  1703     //
       
  1704     TInt  ret;
       
  1705     
       
  1706     ret = iFs.MkDir(KSMSUResourceDir);
       
  1707     if (ret != KErrNone  &&  ret != KErrAlreadyExists)
       
  1708         {
       
  1709         User::Leave(ret);
       
  1710         }
       
  1711 
       
  1712     //
       
  1713     // Write the RSC file to the private C:\ directory...
       
  1714     //
       
  1715     RFile  file;
       
  1716 
       
  1717     User::LeaveIfError(file.Replace(iFs, KSMSUResourceFile, EFileWrite));
       
  1718     CleanupClosePushL(file);
       
  1719     User::LeaveIfError(file.Write(smsuRscSize, smsuRscBuffer));
       
  1720     CleanupStack::PopAndDestroy(&file);
       
  1721     } // CSmsBaseTestStep::SetLowHighLimitsInSmsuRscL
       
  1722 
       
  1723 
       
  1724 /**
       
  1725  *  Removes the low and high limits and returns the SMSU.RSC to defauls.
       
  1726  */
       
  1727 EXPORT_C void CSmsBaseTestStep::RemoveLowHighLimitsFromSmsuRscL()
       
  1728     {
       
  1729     INFO_PRINTF1(_L("Removing .RSC limits."));
       
  1730 
       
  1731     //
       
  1732     // Remove the RSC file...
       
  1733     //
       
  1734     TInt  ret;
       
  1735     
       
  1736     ret = iFs.Delete(KSMSUResourceFile);
       
  1737     if (ret != KErrNone  &&  ret != KErrNotFound)
       
  1738         {
       
  1739         User::Leave(ret);
       
  1740         }
       
  1741     } // CSmsBaseTestStep::RemoveLowHighLimitsFromSmsuRscL
       
  1742 
       
  1743 EXPORT_C void CSmsBaseTestStep::ChangeReceiveModeL(RMobileSmsMessaging::TMobileSmsReceiveMode aNewRcvMode)
       
  1744     {
       
  1745 
       
  1746     // Create comms database object
       
  1747     
       
  1748 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
  1749     CMDBSession* db = CMDBSession::NewL(KCDVersion1_2);
       
  1750 #else
       
  1751     CMDBSession* db = CMDBSession::NewL(KCDVersion1_1);
       
  1752 #endif
       
  1753     CleanupStack::PushL(db);
       
  1754 
       
  1755     INFO_PRINTF1(_L("Testing recvMode change to EReceiveUnstoredClientAck"));
       
  1756 
       
  1757     // EReceiveUnstoredClientAck
       
  1758     CMDBField<TUint32>* smsReceiveModeField = new(ELeave) CMDBField<TUint32>(KCDTIdSMSReceiveMode);
       
  1759     CleanupStack::PushL(smsReceiveModeField);
       
  1760     smsReceiveModeField->SetRecordId(1); //it's GlobalSettingsRecord
       
  1761     *smsReceiveModeField = aNewRcvMode;
       
  1762     smsReceiveModeField->ModifyL(*db);
       
  1763     CleanupStack::PopAndDestroy(smsReceiveModeField);
       
  1764     CleanupStack::PopAndDestroy(db);
       
  1765     }
       
  1766 
       
  1767 EXPORT_C TInt CSmsBaseTestStep::GetIntegerFromConfigL(const TDesC& aKey)
       
  1768     {
       
  1769     TInt value (0);
       
  1770     if(!GetIntFromConfig( ConfigSection(), aKey, value))
       
  1771         {
       
  1772         ERR_PRINTF2( _L("%S is missing in the configuration file!"),  &aKey);
       
  1773         User::Leave(KErrNotFound);     
       
  1774         }
       
  1775     return value;
       
  1776     }
       
  1777 
       
  1778 EXPORT_C TPtrC CSmsBaseTestStep::GetStringFromConfigL(const TDesC& aKey)
       
  1779     {
       
  1780     TPtrC value;
       
  1781     if(!GetStringFromConfig(ConfigSection(), aKey, value))
       
  1782         {
       
  1783         ERR_PRINTF2(_L("%S is missing in the configuration file!"), &aKey);
       
  1784         User::Leave(KErrNotFound);
       
  1785         }
       
  1786     return value;
       
  1787     }
       
  1788 
       
  1789 EXPORT_C void CSmsBaseTestStep::UpdatePhonePowerStatusL(RProperty& aPhonePowerProperty, TSAPhoneStatus aNewStatus)
       
  1790     {
       
  1791     INFO_PRINTF2(_L("Updating phone power status [aNewStatus=%d]"), aNewStatus);
       
  1792     
       
  1793     TInt currentStatus;
       
  1794     User::LeaveIfError(aPhonePowerProperty.Get(currentStatus));
       
  1795     
       
  1796     while( currentStatus != aNewStatus  )
       
  1797         {
       
  1798         TRequestStatus status;
       
  1799         aPhonePowerProperty.Subscribe(status);
       
  1800         User::LeaveIfError(aPhonePowerProperty.Set(KUidSystemCategory, KUidPhonePwr.iUid, aNewStatus));
       
  1801         User::After(5 * 1000000);   // sleep 5 secs;
       
  1802         User::WaitForRequest(status);
       
  1803         TEST(status.Int() == KErrNone);
       
  1804         User::LeaveIfError(aPhonePowerProperty.Get(currentStatus));
       
  1805         }
       
  1806     }
       
  1807 
       
  1808 // Build a list of instances of CPMs running ESOCKSVR.DLL
       
  1809 void CSmsBaseTestStep::BuildESockCPMListL(RRootServ& aRootServer, RUnloadInfoArray& aInfo, TDes8& aDispList)
       
  1810     {
       
  1811     TRSIter iter;
       
  1812     TCFModuleName modName;
       
  1813     TRSModuleInfo modInfo;
       
  1814     aInfo.ResetAndDestroy();
       
  1815     aDispList.SetLength(0);
       
  1816     
       
  1817     while (aRootServer.EnumerateModules(iter, modName) == KErrNone)
       
  1818         {
       
  1819         if (aRootServer.GetModuleInfo(modName, modInfo) == KErrNone  &&
       
  1820                 modInfo.iParams.iDll.MatchF(_L("*ESOCKSVR.DLL")) >= 0)
       
  1821             {
       
  1822             TESockSvrUnloadInfo* unloadInfo = new(ELeave) TESockSvrUnloadInfo;
       
  1823             unloadInfo->iName.Copy(modInfo.iParams.iName);
       
  1824             unloadInfo->iState=modInfo.iParams.iState;
       
  1825             unloadInfo->iStatus=KErrNone;
       
  1826             
       
  1827             aDispList.Append(unloadInfo->iName);
       
  1828             aDispList.Append(_L8(" "));
       
  1829             
       
  1830             TInt err = aInfo.Append(unloadInfo);
       
  1831             TESTCHECKL(err, KErrNone, "Appending unloading info");
       
  1832             }
       
  1833         }
       
  1834     }
       
  1835 
       
  1836 EXPORT_C void CSmsBaseTestStep::DoESockMemoryLeakTestL()
       
  1837     {
       
  1838     INFO_PRINTF1(_L("Checking for ESock memory leaks..."));
       
  1839     TInt  ret, startLeakCounter;
       
  1840 
       
  1841     // Find the current number of leaked cells in ESock
       
  1842     ret = RProperty::Get(KUidCommsProcess, KUidCommsModuleLeakCounter, startLeakCounter);
       
  1843     if (ret == KErrNotFound)
       
  1844         {
       
  1845         // No variable to monitor, ESock is probably not in debug mode.
       
  1846         INFO_PRINTF1(_L("<font size=2 color=00FFCC><B>ESock is probably not in debug mode.</B></font>"));       
       
  1847         return;
       
  1848         }
       
  1849     
       
  1850     TESTCHECKL(ret, KErrNone, "Get the Comms Module Leak Counter")
       
  1851 
       
  1852     // With the Staged Start-up Architecture it is likely that ESOCK modules continue to load after the ECoreComponentsStarted
       
  1853     // state which releases StartC32() and RSocketServ::Connect(). So here we wait until the RootServer is fully configured before
       
  1854     // starting the shutdown, which avoids various races (modules may not be bound yet, or even loaded at all by the Configurator
       
  1855     // and hence invisible to this unloading code)
       
  1856     RProperty configurationProperty;
       
  1857     CleanupClosePushL(configurationProperty);
       
  1858     
       
  1859     configurationProperty.Attach(KUidSystemCategory, KUidC32StartPropertyKey.iUid); // needs the KEY
       
  1860     TInt propertyValue = EInitialising; // set to safe state
       
  1861     TInt propertyResult = configurationProperty.Get(propertyValue);
       
  1862     TRequestStatus propertyStatus;
       
  1863     while(propertyValue < EConfigurationComplete)
       
  1864         {
       
  1865         configurationProperty.Subscribe(propertyStatus);
       
  1866         
       
  1867         if(configurationProperty.Get(propertyValue) == KErrNone && propertyValue == EConfigurationComplete)
       
  1868             {
       
  1869             configurationProperty.Cancel();
       
  1870             }
       
  1871         User::WaitForRequest(propertyStatus);
       
  1872         }
       
  1873     
       
  1874     RRootServ  rootserver;
       
  1875     User::LeaveIfError(rootserver.Connect());
       
  1876     CleanupClosePushL(rootserver);
       
  1877 
       
  1878     // Find all instances of CPMs running ESOCKSVR.DLL
       
  1879     RUnloadInfoArray unloadArray(16);
       
  1880     CleanupClosePushL(unloadArray);
       
  1881     TBuf8<256> modList;
       
  1882     
       
  1883     BuildESockCPMListL(rootserver, unloadArray, modList);
       
  1884 
       
  1885     // Start by asking all of the ESOCK threads to unload when there are no sessions
       
  1886     TInt index = unloadArray.Count();
       
  1887     while( index-- > 0 )
       
  1888         {
       
  1889         TESockSvrUnloadInfo* info = unloadArray[index];
       
  1890         rootserver.UnloadCpm(info->iStatus, info->iName, EGraceful);
       
  1891         }
       
  1892 
       
  1893     // Start polling to see when they all complete unloading
       
  1894     const TInt KPollPeriod = 2000 * 1000;
       
  1895     TUint maxPolls = 15;
       
  1896     
       
  1897     RUnloadInfoArray pollUnloadArray(16);
       
  1898     BuildESockCPMListL(rootserver, pollUnloadArray, modList);
       
  1899     
       
  1900     while( maxPolls-- > 0 && pollUnloadArray.Count() > 0 )
       
  1901         {
       
  1902         User::After(KPollPeriod);
       
  1903         BuildESockCPMListL(rootserver, pollUnloadArray, modList);
       
  1904         }
       
  1905     pollUnloadArray.ResetAndDestroy();
       
  1906     
       
  1907     // Cancel any remaining unloads and eat the events
       
  1908     index = unloadArray.Count();
       
  1909     while( index-- >0 )
       
  1910         {
       
  1911         TESockSvrUnloadInfo* info = unloadArray[index];
       
  1912         rootserver.CancelUnloadCpm(info->iName);
       
  1913         User::WaitForRequest(info->iStatus);
       
  1914         }
       
  1915 
       
  1916     // See what's left
       
  1917     BuildESockCPMListL(rootserver, unloadArray, modList);
       
  1918 
       
  1919     TInt err = KErrNone; // Will use this to catch first error below
       
  1920     TInt count = unloadArray.Count();
       
  1921     
       
  1922     if(count > 0)
       
  1923         {
       
  1924         // No more waiting; we order immediate unloads
       
  1925         for(TInt i = 0; i < count; ++i)
       
  1926             {
       
  1927             TESockSvrUnloadInfo* info = unloadArray[i];
       
  1928             rootserver.UnloadCpm(info->iStatus, info->iName, EImmediate);
       
  1929             }
       
  1930             
       
  1931         // Wait for them all to return
       
  1932         for(TInt i = 0; i < count; ++i)
       
  1933             {
       
  1934             TESockSvrUnloadInfo* info = unloadArray[i];
       
  1935             User::WaitForRequest(info->iStatus);
       
  1936             }
       
  1937         
       
  1938         // Display the status of any remaining modules
       
  1939         for(TInt i = count - 1; i >= 0; --i)
       
  1940             {
       
  1941             TESockSvrUnloadInfo* info = unloadArray[i];
       
  1942             TBuf16<32> tmp;
       
  1943             tmp.Copy(info->iName);
       
  1944             if(info->iStatus.Int() != KErrNone && info->iStatus.Int() != KErrRSModuleNotLoaded)
       
  1945                 {
       
  1946                 err = info->iStatus.Int();
       
  1947                 INFO_PRINTF4(_L("%S cannot be gracefully or immediatly unloaded due to error %d and is stuck in state %d"), &tmp, info->iStatus.Int(), info->iState);
       
  1948                 }
       
  1949             else
       
  1950                 {
       
  1951                 INFO_PRINTF4(_L("%S could not be gracefully unloaded and had to be immediatly unloaded while it was stuck in state %d, status %d"), &tmp, info->iState, info->iStatus.Int());
       
  1952                 }
       
  1953             }
       
  1954         }
       
  1955     CleanupStack::PopAndDestroy(3, &configurationProperty); // configurationProperty, rootserver, unloadArray
       
  1956     
       
  1957     // Leave with last seen error, if any
       
  1958     TESTCHECKL(err, KErrNone, "Unloading CPM modules");
       
  1959     
       
  1960     // Get the latest number of leaked cells in ESock
       
  1961     TInt  finalLeakCounter;
       
  1962 
       
  1963     ret = RProperty::Get(KUidCommsProcess, KUidCommsModuleLeakCounter, finalLeakCounter);
       
  1964     TESTCHECKL(ret, KErrNone, "Getting Comms Module leak counter");
       
  1965 
       
  1966     TESTCHECKCONDITION(finalLeakCounter <= startLeakCounter, "A memory leak has been detected inside ESock");
       
  1967     
       
  1968     // TODO: reviewers - why is it here?
       
  1969     // Restart C32...
       
  1970     _LIT(KDummyCMI, "");
       
  1971     WarmBootC32(KDummyCMI);
       
  1972     }