Fixes to close session, added special cases Full Green Block or Full Red block, + more tests
authorRub?n Mart?nez
Sun, 10 Aug 2014 18:01:59 +0200
changeset 10845 541ccfbd40d5
parent 10844 92e358ecc206
child 10846 4fbecd557aae
Fixes to close session, added special cases Full Green Block or Full Red block, + more tests
src/ltp-protocol/model/ltp-protocol.cc
src/ltp-protocol/model/ltp-session-state-record.cc
src/ltp-protocol/model/ltp-session-state-record.h
src/ltp-protocol/test/ltp-protocol-channel-loss-test-suite.cc
--- a/src/ltp-protocol/model/ltp-protocol.cc	Sun Aug 10 00:44:56 2014 +0200
+++ b/src/ltp-protocol/model/ltp-protocol.cc	Sun Aug 10 18:01:59 2014 +0200
@@ -242,10 +242,20 @@
   entry = std::make_pair (id, DynamicCast< SessionStateRecord > (ssr) );
   m_activeSessions.insert (m_activeSessions.begin (),entry);
 
+  if (rdSize == 0)
+    {
+      ssr->SetFullGreen ();
+    }
+  else if (rdSize == data.size ())
+    {
+      ssr->SetFullRed ();
+    }
+
   Ptr<LtpConvergenceLayerAdapter> link = GetDatalink (dstLtpEngine);
   link->SetSessionId (id);
   EncapsulateBlockData (dstClientService, ssr, data, rdSize);
 
+
   std::vector<uint8_t>::const_iterator start = data.begin ();
   std::vector<uint8_t>::const_iterator end = data.begin () + rdSize;
   std::vector<uint8_t> redData (start,end);
@@ -272,48 +282,48 @@
   NS_LOG_FUNCTION (this << id.GetSessionNumber () << id.GetSessionOriginator ());
   SessionStateRecords::iterator it = m_activeSessions.find (id);
 
-  if (it != m_activeSessions.end())
-  {
+  if (it != m_activeSessions.end ())
+    {
 
-  ClientServiceInstances::iterator itCls = m_activeClients.find (it->second->GetLocalClientServiceId ());
+      ClientServiceInstances::iterator itCls = m_activeClients.find (it->second->GetLocalClientServiceId ());
 
-  std::vector<uint8_t> blockData;
-  bool EOB = false;
-  uint64_t remoteLtp = it->second->GetPeerLtpEngineId ();
+      std::vector<uint8_t> blockData;
+      bool EOB = false;
+      uint64_t remoteLtp = it->second->GetPeerLtpEngineId ();
 
-  if (it->second->GetInstanceTypeId () == ReceiverSessionStateRecord::GetTypeId ())
-    {
-      Ptr<ReceiverSessionStateRecord> ssr = DynamicCast<ReceiverSessionStateRecord> (it->second);
+      if (it->second->GetInstanceTypeId () == ReceiverSessionStateRecord::GetTypeId ())
+        {
+          Ptr<ReceiverSessionStateRecord> ssr = DynamicCast<ReceiverSessionStateRecord> (it->second);
+
+          Ptr<Packet> p = 0;
+          LtpHeader header;
+          LtpContentHeader contentHeader;
 
-      Ptr<Packet> p = 0;
-      LtpHeader header;
-      LtpContentHeader contentHeader;
+          while (p = ssr->RemoveRedDataSegment ())
+            {
+              p->RemoveHeader (header);
+              contentHeader.SetSegmentType (header.GetSegmentType ());
+              p->RemoveHeader (contentHeader);
+
+              uint32_t size = p->GetSize ();
+              uint8_t *raw_data = new uint8_t[size];
+              p->CopyData (raw_data, size);
 
-      while (p = ssr->RemoveRedDataSegment ())
-        {
-          p->RemoveHeader (header);
-          contentHeader.SetSegmentType (header.GetSegmentType ());
-          p->RemoveHeader (contentHeader);
+              std::vector<uint8_t> packetData ( raw_data, raw_data + size);
 
-          uint32_t size = p->GetSize ();
-          uint8_t *raw_data = new uint8_t[size];
-          p->CopyData (raw_data, size);
+              blockData.insert ( blockData.end (), packetData.begin (), packetData.end () );
+              delete raw_data;
+            }
 
-          std::vector<uint8_t> packetData ( raw_data, raw_data + size);
-
-          blockData.insert ( blockData.end (), packetData.begin (), packetData.end () );
-          delete raw_data;
+          if (header.GetSegmentType () == LTPTYPE_RD_CP_EORP_EOB)
+            {
+              EOB = true;
+            }
         }
 
-      if (header.GetSegmentType () == LTPTYPE_RD_CP_EORP_EOB)
-        {
-          EOB = true;
-        }
+      itCls->second->ReportStatus (id,RED_PART_RCV, blockData, blockData.size (), EOB,  remoteLtp);
     }
 
-  itCls->second->ReportStatus (id,RED_PART_RCV, blockData, blockData.size (), EOB,  remoteLtp);
-  }
-
 }
 
 void LtpProtocol::SignifyGreenPartSegmentArrival (SessionId id)
@@ -347,6 +357,12 @@
 
           offset = contentHeader.GetOffset ();
 
+          // No better way to determine if this is a full Green block on the receiver side
+          if (offset == 0)
+            {
+              ssr->SetFullGreen ();
+            }
+
           if (header.GetSegmentType () == LTPTYPE_GD_EOB)
             {
               EOB = true;
@@ -376,9 +392,9 @@
 
   SessionStateRecords::iterator it = m_activeSessions.find (id);
 
-  if (it != m_activeSessions.end())
+  if (it != m_activeSessions.end ())
     {
-	  Ptr<SessionStateRecord> ssr = it->second;
+      Ptr<SessionStateRecord> ssr = it->second;
       ssr->SetBlockFinished ();
 
 
@@ -613,7 +629,12 @@
               NS_LOG_DEBUG (ss.str ());
               srecv->SetBlockFinished ();
               SignifyGreenPartSegmentArrival (id);
-              if (srecv->IsRedPartFinished () && srecv->IsBlockFinished ())
+
+              if (
+                ( srecv->IsRedPartFinished () && srecv->IsBlockFinished ()  )
+                ||
+                srecv->IsFullGreen ()
+                )
                 {
                   CloseSession (id);    // Stop Transmission procedure
                 }
@@ -920,7 +941,7 @@
 void
 LtpProtocol::EncapsulateBlockData (uint64_t dstClientService, Ptr<SessionStateRecord> ssr, std::vector<uint8_t> data, uint64_t rdSize, bool rtx)
 {
-  NS_LOG_FUNCTION (this);
+  NS_LOG_FUNCTION (this << rdSize);
 
   SessionId id = ssr->GetSessionId ();
 
@@ -974,8 +995,14 @@
           size = headerSize +  contentHeader.GetSerializedSize () + length;
         }
 
-      /* If it is the last segment from the red part mark it as a checkpoint*/
-      if ((offset < rdSize) && (offset + length > rdSize))
+      if (rdSize == 0) /* If this a full green block*/
+        {
+          type = LTPTYPE_GD;
+          header.SetSegmentType (type);
+          contentHeader.SetSegmentType (type);
+
+        }
+      else if ((offset < rdSize) && (offset + length > rdSize))   /* If it is the last segment from the red part mark it as a checkpoint*/
         {
           NS_LOG_DEBUG ("Last segment from red part");
 
@@ -995,17 +1022,9 @@
                 }
             }
 
-          if (rdSize == 0)
+          if ( rdSize > 0)   // Last Segment from red part smaller than MTU
             {
 
-              type = LTPTYPE_GD;
-
-              NS_LOG_DEBUG ("No red part");
-
-            }
-          else
-            {
-              // Last Segment from red part smaller than MTU
               length = rdSize - offset;
               contentHeader.SetLength (length);
             }
@@ -1015,8 +1034,6 @@
           contentHeader.SetSegmentType (type);
           contentHeader.SetCpSerialNumber (ssr->GetCpCurrentSerialNumber ());
 
-
-
           type = LTPTYPE_GD;                       // Set type to green segment for next iteration
         }
 
--- a/src/ltp-protocol/model/ltp-session-state-record.cc	Sun Aug 10 00:44:56 2014 +0200
+++ b/src/ltp-protocol/model/ltp-session-state-record.cc	Sun Aug 10 18:01:59 2014 +0200
@@ -38,6 +38,7 @@
     m_redpartSucces (false),
     m_blockSuccess (false),
     m_fullRedData(false),
+    m_fullGreenData(false),
     m_redPartLength(0),
     m_lowBound(0),
     m_highBound(0),
@@ -65,6 +66,7 @@
     m_redpartSucces (false),
     m_blockSuccess (false),
     m_fullRedData(false),
+    m_fullGreenData(false),
     m_redPartLength(0),
     m_lowBound(0),
     m_highBound(0),
@@ -804,6 +806,18 @@
 	return m_fullRedData;
 }
 
+void
+SessionStateRecord::SetFullGreen()
+{
+	NS_LOG_FUNCTION (this);
+	m_fullGreenData = true;
+}
+bool
+SessionStateRecord::IsFullGreen() const
+{
+	NS_LOG_FUNCTION (this);
+	return m_fullGreenData;
+}
 
 
 } // namespace ltp
--- a/src/ltp-protocol/model/ltp-session-state-record.h	Sun Aug 10 00:44:56 2014 +0200
+++ b/src/ltp-protocol/model/ltp-session-state-record.h	Sun Aug 10 18:01:59 2014 +0200
@@ -274,6 +274,9 @@
   void SetFullRed();
   bool IsFullRed() const;
 
+  void SetFullGreen();
+  bool IsFullGreen() const;
+
   /*
    * \return Reason for cancellation.
    */
@@ -350,6 +353,7 @@
   bool m_redpartSucces;                 //!< Red part Transmitted/Received successfully
   bool m_blockSuccess;                  //!< Full block Transmitted/Received successfully
   bool m_fullRedData;					//!< True if the block only contains red data
+  bool m_fullGreenData;					//!< True if the block only contains green data
 
   uint32_t m_redPartLength;				//!< Length of the red part
   uint32_t m_lowBound; 					//!< Smallest non acknowledged offset
--- a/src/ltp-protocol/test/ltp-protocol-channel-loss-test-suite.cc	Sun Aug 10 00:44:56 2014 +0200
+++ b/src/ltp-protocol/test/ltp-protocol-channel-loss-test-suite.cc	Sun Aug 10 18:01:59 2014 +0200
@@ -120,11 +120,11 @@
                                                                    uint32_t offset )
 {
   m_rcvData += dataLength;
-  std::cout << "Code :" << code << std::endl;
+  std::cout << "Code :" << code << " " << dataLength << " " << m_rcvData << " " << endFlag << std::endl;
 
   if (code == ns3::ltp::SESSION_END)
     {
-      std::cout << m_rcvData << std::endl;
+      std::cout << "Total" <<  m_rcvData << std::endl;
       NS_TEST_ASSERT_MSG_EQ (m_rcvData, m_expectedData, "Wrong amount of data received");
     }
 }
@@ -193,6 +193,7 @@
   std::vector<uint8_t> data ( m_sentData, 65);
 
   // Transmit if from n0 to n1.
+  std::cout << "RedPartSize" << m_redPartSz << std::endl;
   uint64_t receiverLtpId = nodes.Get (1)->GetObject<LtpProtocol> ()->GetLocalEngineId ();
   nodes.Get (0)->GetObject<LtpProtocol> ()->StartTransmission (ClientServiceId,ClientServiceId,receiverLtpId,data,m_redPartSz);
 
@@ -235,33 +236,34 @@
   std::list<uint32_t> receiver_losses;
   std::list<uint32_t> sender_losses;
 
+
   // Test 1: No losses
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len , receiver_losses, sender_losses), TestCase::QUICK);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   // Test 2: Red Segment lost
-  receiver_losses.push_back(0);
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.push_back (0);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   // Test 3: Red Segment CP lost
-  receiver_losses.clear();
-  receiver_losses.push_back(1);
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.clear ();
+  receiver_losses.push_back (1);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   // Test 4: Both red segments are lost.
-  receiver_losses.clear();
-  receiver_losses.push_back(0);
-  receiver_losses.push_back(1);
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.clear ();
+  receiver_losses.push_back (0);
+  receiver_losses.push_back (1);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   // Test 5: Report segment is lost.
-  receiver_losses.clear();
-  sender_losses.push_back(0);
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.clear ();
+  sender_losses.push_back (0);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   //Test 6: Report ACK segment is lost
-  receiver_losses.clear();
-  receiver_losses.push_back(5);
-  AddTestCase (new LtpProtocolRetransTestCase(block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.clear ();
+  receiver_losses.push_back (5);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
   // Test 7: Both Report segment and ACK are lost.
   receiver_losses.clear ();
@@ -316,26 +318,50 @@
 
   // TODO: The RFC does not specify how to deal with this case.
   /* CCDS 743.1-R2: 3.4.2 Notes: Green-part data is not reliably transmitted under LTP. In particular, if there is green-
-	  part data in a block, the LTP segment containing the EOB marker may not be
-	  delivered to the destination. As a consequence, if the session contains green-part data
-	  there is no way for an LTP sender to know when an LTP receiver has closed a
-	  session.*/
+          part data in a block, the LTP segment containing the EOB marker may not be
+          delivered to the destination. As a consequence, if the session contains green-part data
+          there is no way for an LTP sender to know when an LTP receiver has closed a
+          session.*/
+
   //Test 14: A Green EOB Segment is lost -- Session in receiver side is not closed, remains in a waiting for EOB state.
-/*   receiver_losses.clear ();
-   receiver_losses.push_back (4);
-   expected = 3537;
-   AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+  receiver_losses.clear ();
+  receiver_losses.push_back (4);
+  expected = 3537;
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
 
-   // Test 15: Full Red Part.
-   red_len = 5000;
-   expected = 5000;
-   receiver_losses.clear ();
-   receiver_losses.push_back (0);
-   receiver_losses.push_back (1);
+  // Test 15: Full Red Part No Loss
+  red_len = 5000;
+  expected = 5000;
+  receiver_losses.clear ();
+  sender_losses.clear ();
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+
+  // Test 16: Full Red Part - Red Segments are lost
+  red_len = 5000;
+  expected = 5000;
+  receiver_losses.clear ();
+  sender_losses.clear ();
+  receiver_losses.push_back (0);
+  receiver_losses.push_back (1);
 
-   AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
-*/
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+
+  // Test 17: Full Green Part.
+  red_len = 0;
+  expected = 5000;
+  receiver_losses.clear ();
+  sender_losses.clear ();
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
+
+  // Test 18: Full Green Part - Green Segments are lost
+  red_len = 0;
+  expected = 2074;
+  receiver_losses.clear ();
+  sender_losses.clear ();
+  receiver_losses.push_back (1);
+  receiver_losses.push_back (2);
+  AddTestCase (new LtpProtocolRetransTestCase (block_len, expected, red_len, receiver_losses, sender_losses), TestCase::QUICK);
 
 }