Fixes to close session, added special cases Full Green Block or Full Red block, + more tests
--- 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);
}