telephonyprotocols/pdplayer/umts/test/te_spudNetworkSide/src/te_spudNetworkSideSteps.cpp
branchRCL_3
changeset 74 9200f38b1324
parent 66 07a122eea281
child 82 042fd2753b8f
--- a/telephonyprotocols/pdplayer/umts/test/te_spudNetworkSide/src/te_spudNetworkSideSteps.cpp	Tue Sep 14 23:33:57 2010 +0300
+++ b/telephonyprotocols/pdplayer/umts/test/te_spudNetworkSide/src/te_spudNetworkSideSteps.cpp	Wed Sep 15 13:30:43 2010 +0300
@@ -32,6 +32,9 @@
 #include <comms-infras/es_config.h>
 #include <nifman.h>
 
+#define SYMBIAN_COMMSFW_MBUF_GOBBLER // include MACRO defined in mbufgobblerproviders.mmp, used to differentiate the MBUFGOBBLER component from the pass through layer which it is based on.
+#include <comms-infras/mbufgobblerpubsub.h>
+
 #ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
 #include <networking/qoslib.h>
 #else
@@ -2491,3 +2494,178 @@
 
     return EPass;
     }
+
+
+enum TVerdict CRawIpMBufExhaustionRx::RunTestStepL()
+    {    
+    /*
+      * This test checks that the PDP flow can handle the scenario when it receives a packet but finds that
+      * the MBuf pool is exhausted.
+      * 
+      * The test has the following form:
+      * 
+      *  1) Initialisation
+      *  1.1) Connections conn1 and conn2 are started.
+      *  1.2) Socket sock1 is opened against conn1 and socket sock2 is opened against conn2;
+      *     The sockets are logically joined by the packet loopback csy; data which is written by 
+      *     sock1 is read by sock2.
+      *  1.3) Connection conn3 is started. It creates a stack within ESOCK which contains the MBufGobbler layer;
+      *     this is a layer which contains a publish and subscribe function which allows the ESOCK client to control the 
+      *     number of MBufs that are available in the MBuf pool.
+      *  
+      *  2) Test Scenario
+      *  2.1) The client writes data to sock1 successfully; the packetloopback csy delays forwarding the data to sock2.
+      *  2.2) The client configures a publish and subscribe attribute which exhausts ESOCK's MBuf pool. 
+      *       It uses the MBufGobbler publish / subscribe function contained in the MBufGobbler layer started by conn3.
+      *  2.3) The packet loopback csy forwards the data to the flow associated with sock2. 
+      *  2.4) The flow is unable to obtain a MBuf from the MBuf pool as the pool is exhausted, so it discards the packet
+      *       and posts a request to receive the next packet.  
+      *  2.5) The client cancels the read request from sock2.
+      *  2.6) The client configures a publish and subscribe attribute to replenish ESocks's MBuf pool.
+      *  2.7) The client writes data to sock1 successfully and reads data from sock2 successfully.
+      *  
+      */
+     
+    //Start 1st context
+    RConnection* conn1 = new (ELeave) RConnection();
+    CleanupClosePushL<RConnection>(*conn1);
+
+    TInt primaryIapId;
+    if (!GetIntFromConfig(ConfigSection(), _L("PrimaryIapId1"), primaryIapId))
+        {
+        User::Leave(KErrNotFound);
+        }
+
+    TCommDbConnPref conn1Pref;
+    conn1Pref.SetIapId(primaryIapId);
+    
+    INFO_PRINTF2(_L("Test starting Interface IAP ID == %d"), primaryIapId);  
+    TestL(conn1->Open(iEsock), _L("RConnection::Open the interface"));
+    TestL(conn1->Start(conn1Pref), _L("RConnection::Start the interface"));
+
+    //Start 2nd context
+    RConnection* conn2 = new (ELeave) RConnection();
+    CleanupClosePushL<RConnection>(*conn2);
+
+    if (!GetIntFromConfig(ConfigSection(), _L("PrimaryIapId2"), primaryIapId))
+        {
+        User::Leave(KErrNotFound);
+        }
+
+    TCommDbConnPref conn2Pref;
+    conn2Pref.SetIapId(primaryIapId);
+    
+    INFO_PRINTF2(_L("Test starting Interface IAP ID == %d"), primaryIapId);     
+    TestL(conn2->Open(iEsock), _L("RConnection::Open the interface"));
+    TestL(conn2->Start(conn2Pref), _L("RConnection::Start the interface"));
+    
+    TRequestStatus status;
+    RConnection* conn3 = new (ELeave) RConnection();
+    CleanupClosePushL<RConnection>(*conn3);   
+    TestL(conn3->Open(iEsock), _L("RConnection::Open the interface"));
+    conn3->Start(status);
+    User::WaitForRequest(status);
+    TestL(status.Int(), _L("RConnection::Start - start connection containing MBuf Gobbler layer"));
+    
+    //Open & Connect 1st Socket
+    RSocket sock1;
+    TestL(sock1.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, *conn1), _L("RSocket::Open"));
+    CleanupClosePushL<RSocket>(sock1);
+    TInetAddr localAddr;
+    localAddr.SetPort(KConfiguredTftFilter1DestPort);
+    TestL(sock1.Bind(localAddr), _L("Binding the local Socket"));
+    
+    TInetAddr dstAddr;
+    dstAddr.SetPort(KConfiguredTftFilter1SrcPort);
+    dstAddr.Input(KConfiguredTftFilter1SrcAddr);
+    sock1.Connect(dstAddr, status);
+    User::WaitForRequest(status);
+    TestL(status.Int(), _L("RSocket::Connect status opening 1st socket"));
+
+    //Open & Bind 2nd Socket
+    RSocket sock2;
+    TestL(sock2.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, *conn2), _L("RSocket::Open"));
+    CleanupClosePushL<RSocket>(sock2);
+    localAddr.SetPort(KConfiguredTftFilter1SrcPort);
+    TestL(sock2.Bind(localAddr), _L("Binding the local Socket"));
+
+    //then send & receive data.
+    const TInt KMaxMMU = 4000;
+    TBuf8<KMaxMMU> *sendBuf = new(ELeave) TBuf8<KMaxMMU>();
+    CleanupStack::PushL(sendBuf);
+    
+    TBuf8<KMaxMMU> *recvBuf = new(ELeave) TBuf8<KMaxMMU>();
+    CleanupStack::PushL(recvBuf);
+
+    TBuf8<KMaxMMU> *recvBuf2 = new(ELeave) TBuf8<KMaxMMU>();
+    CleanupStack::PushL(recvBuf2);
+
+    TRequestStatus readStatus;
+
+    const TInt KOneSecond = 1000000;
+    const TInt KOneUs     = 1;
+    
+    sendBuf->Zero();
+    sendBuf->Append(Math::Random() & 0x7f); // add a token character
+        
+    sock1.Write(*sendBuf, status); // Allow packet to be sent
+    User::After( KOneSecond ); // Wait for a second to allow time for server/protocol to send
+        
+    sock1.CancelSend();
+
+    User::WaitForRequest(status);
+    
+    TInt result = RProperty::Set(TUid::Uid(EMBufGobbler ), EAdjustNumberOfMBufsRemainingInPool , EGobbleAllMBufs); // Allocate all MBuffs
+    if (result != KErrNone)
+        {
+        INFO_PRINTF2(_L("Unable to set gobber publish/subscribe %d"), result);
+        User::Leave(result);
+        }
+    User::After(KOneUs); // Relinquish CPU, to give time for        
+    
+    sock2.Read(*recvBuf, readStatus);    
+    User::After( KOneSecond ); 
+
+    sock2.CancelRecv();
+            
+    User::WaitForRequest( readStatus );
+    
+    if ((status != KErrNone) && (readStatus != KErrCancel))         
+        {
+        INFO_PRINTF3(_L("Unexpected error status tx= %d, rx = %d"), status.Int(), readStatus.Int());
+        User::Leave(readStatus.Int());
+        }
+   
+    result = RProperty::Set(TUid::Uid(EMBufGobbler), EAdjustNumberOfMBufsRemainingInPool, EReleaseAllMBufs);  // Free all buffers
+    if (result != KErrNone)
+        {
+        INFO_PRINTF2(_L("Unable to set gobber publish/subscribe %d"), result);
+        User::Leave(result);
+        }
+    User::After(KOneUs); // Relinquish CPU to allow time for MBufs to be returned to the pool.
+
+    sock1.Write(*sendBuf, status);        
+    
+    User::After( KOneSecond ); // Wait for a second to allow time for server/protocol to send
+        
+    sock1.CancelSend();
+
+    User::WaitForRequest(status);
+    
+    sock2.Read(*recvBuf, readStatus);    
+    User::After( KOneSecond ); 
+
+    sock2.CancelRecv();
+            
+    User::WaitForRequest( readStatus );
+    
+    if ((status != KErrNone) && (readStatus != KErrNone))         
+        {
+        INFO_PRINTF3(_L("Unexpected error status tx = %d rx = %d"), status.Int(), readStatus.Int());
+        User::Leave(readStatus.Int());
+        }     
+        
+    CleanupStack::PopAndDestroy(8); //conn1, conn2, conn3, sock1, sock2, sendBuf, recvBuf, recvBuf2
+    
+    return EPass;
+    }