diff --git a/src/point-to-point/model/point-to-point-channel.cc b/src/point-to-point/model/point-to-point-channel.cc index 91bb4d503a1..35e1edad76c 100644 --- a/src/point-to-point/model/point-to-point-channel.cc +++ b/src/point-to-point/model/point-to-point-channel.cc @@ -36,9 +36,14 @@ PointToPointChannel::GetTypeId (void) .SetParent () .SetGroupName ("PointToPoint") .AddConstructor () - .AddAttribute ("Delay", "Transmission delay through the channel", + .AddAttribute ("AlternateDelay", + "Transmission delay through the channel in the other direction: has to be set after Delay", + TimeValue (Seconds (42)), + MakeTimeAccessor (&PointToPointChannel::m_alternateDelay), + MakeTimeChecker ()) + .AddAttribute ("Delay", "Transmission delay through the channel in one direction", TimeValue (Seconds (0)), - MakeTimeAccessor (&PointToPointChannel::m_delay), + MakeTimeAccessor ( (Time (PointToPointChannel::*)() const)&PointToPointChannel::GetDelay, &PointToPointChannel::SetDelay), MakeTimeChecker ()) .AddTraceSource ("TxRxPointToPoint", "Trace source indicating transmission of packet " @@ -57,6 +62,7 @@ PointToPointChannel::PointToPointChannel() : Channel (), m_delay (Seconds (0.)), + m_alternateDelay (Seconds (0.)), m_nDevices (0) { NS_LOG_FUNCTION_NOARGS (); @@ -80,6 +86,8 @@ PointToPointChannel::Attach (Ptr device) m_link[1].m_dst = m_link[0].m_src; m_link[0].m_state = IDLE; m_link[1].m_state = IDLE; + m_link[0].m_delay = m_delay; + m_link[1].m_delay = m_alternateDelay; } } @@ -97,12 +105,13 @@ PointToPointChannel::TransmitStart ( uint32_t wire = src == m_link[0].m_src ? 0 : 1; - Simulator::ScheduleWithContext (m_link[wire].m_dst->GetNode ()->GetId (), - txTime + m_delay, &PointToPointNetDevice::Receive, - m_link[wire].m_dst, p); + Simulator::ScheduleWithContext (GetDestination(wire)->GetNode ()->GetId (), + txTime + GetDelay(wire), + &PointToPointNetDevice::Receive, + GetDestination(wire), p); // Call the tx anim callback on the net device - m_txrxPointToPoint (p, src, m_link[wire].m_dst, txTime, txTime + m_delay); + m_txrxPointToPoint (p, src, GetDestination(wire), txTime, txTime + GetDelay(wire)); return true; } @@ -125,33 +134,56 @@ Ptr PointToPointChannel::GetDevice (uint32_t i) const { NS_LOG_FUNCTION_NOARGS (); + NS_ASSERT (i < 2); return GetPointToPointDevice (i); } Time -PointToPointChannel::GetDelay (void) const +PointToPointChannel::GetDelay () const +{ + return GetDelay(0); +} + + +Time +PointToPointChannel::GetDelay (uint32_t i) const { - return m_delay; + NS_ASSERT (i < 2); + return m_link[i].m_delay; +} + +void +PointToPointChannel::SetDelay (Time owd) +{ + NS_ASSERT(!IsInitialized()); + m_delay = owd; + + /* if m_alternateDelay set to its default value than we update it */ + struct TypeId::AttributeInformation info; + if(GetTypeId().LookupAttributeByName("AlternateDelay", &info) && info.originalInitialValue == info.initialValue) { + m_alternateDelay = owd; + } + } Ptr PointToPointChannel::GetSource (uint32_t i) const { + NS_ASSERT (i < 2); return m_link[i].m_src; } Ptr PointToPointChannel::GetDestination (uint32_t i) const { + NS_ASSERT (i < 2); return m_link[i].m_dst; } bool PointToPointChannel::IsInitialized (void) const { - NS_ASSERT (m_link[0].m_state != INITIALIZING); - NS_ASSERT (m_link[1].m_state != INITIALIZING); - return true; + return (m_link[0].m_state != INITIALIZING && m_link[1].m_state != INITIALIZING); } } // namespace ns3 diff --git a/src/point-to-point/model/point-to-point-channel.h b/src/point-to-point/model/point-to-point-channel.h index e53bfe14129..c90c94a9ca6 100644 --- a/src/point-to-point/model/point-to-point-channel.h +++ b/src/point-to-point/model/point-to-point-channel.h @@ -100,12 +100,22 @@ class PointToPointChannel : public Channel */ virtual Ptr GetDevice (uint32_t i) const; -protected: /** * \brief Get the delay associated with this channel + * \param i Between 0 and 1: select the link * \returns Time delay */ Time GetDelay (void) const; + Time GetDelay (uint32_t i) const; + + /** + * Must be called before link initialization + * \param t duration of packet transfer in both directions + */ + void SetDelay (Time t) ; + +protected: + /** * \brief Check to make sure the link is initialized @@ -137,19 +147,18 @@ class PointToPointChannel : public Channel * \param [in] rxDevice the Receiving NetDevice. * \param [in] duration The amount of time to transmit the packet. * \param [in] lastBitTime Last bit receive time (relative to now) - * \deprecated The non-const \c Ptr argument is deprecated - * and will be changed to \c Ptr in a future release. */ typedef void (* TxRxAnimationCallback) - (Ptr packet, - Ptr txDevice, Ptr rxDevice, - Time duration, Time lastBitTime); - + (const Ptr packet, + const Ptr txDevice, const Ptr rxDevice, + const Time duration, const Time lastBitTime); + private: /** Each point to point link has exactly two net devices. */ static const int N_DEVICES = 2; - Time m_delay; //!< Propagation delay + Time m_delay; //!< Propagation delay + Time m_alternateDelay; //!< Propagation delay int32_t m_nDevices; //!< Devices of this channel /** @@ -194,11 +203,12 @@ class PointToPointChannel : public Channel /** \brief Create the link, it will be in INITIALIZING state * */ - Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {} + Link() : m_state (INITIALIZING), m_src (0), m_dst (0), m_delay(0) {} WireState m_state; //!< State of the link Ptr m_src; //!< First NetDevice Ptr m_dst; //!< Second NetDevice + Time m_delay; //!< Propagation delay }; Link m_link[N_DEVICES]; //!< Link model diff --git a/src/point-to-point/test/point-to-point-test.cc b/src/point-to-point/test/point-to-point-test.cc index 211e6584f68..2e7cf59ef61 100644 --- a/src/point-to-point/test/point-to-point-test.cc +++ b/src/point-to-point/test/point-to-point-test.cc @@ -26,6 +26,9 @@ using namespace ns3; +static const Time testStartTime = Seconds (1.0); +static const Time tolerance = MilliSeconds(5); + /** * \brief Test class for PointToPoint model * @@ -38,24 +41,38 @@ class PointToPointTest : public TestCase /** * \brief Create the test */ - PointToPointTest (); + PointToPointTest (Time forwardDelay, Time backwardDelay); /** * \brief Run the test */ virtual void DoRun (void); -private: + + +protected: + + Time m_forwardDelay; + Time m_backwardDelay; + + Time m_packetArrival[2]; + + Ptr m_devA; + Ptr m_devB; + /** * \brief Send one packet to the device specified * * \param device NetDevice to send to */ void SendOnePacket (Ptr device); + bool RecvOnePacket ( Ptr dev, Ptr p, uint16_t protocol, const Address & sender); }; -PointToPointTest::PointToPointTest () - : TestCase ("PointToPoint") +PointToPointTest::PointToPointTest (Time forwardDelay, Time backwardDelay) + : TestCase ("PointToPoint"), + m_forwardDelay(forwardDelay), + m_backwardDelay(backwardDelay) { } @@ -66,31 +83,63 @@ PointToPointTest::SendOnePacket (Ptr device) device->Send (p, device->GetBroadcast (), 0x800); } +bool +PointToPointTest::RecvOnePacket ( Ptr dev, Ptr p, uint16_t protocol, const Address & sender) +{ +// if(dev == this->de) + static int counter=0; + m_packetArrival[counter] = Simulator::Now(); + + if(counter==0) { + Simulator::ScheduleNow( &PointToPointTest::SendOnePacket, this, m_devB); + } + + counter++; + return true; +} void PointToPointTest::DoRun (void) { - Ptr a = CreateObject (); - Ptr b = CreateObject (); - Ptr devA = CreateObject (); - Ptr devB = CreateObject (); + Ptr nodeA = CreateObject (); + Ptr nodeB = CreateObject (); + m_devA = CreateObject (); + m_devB = CreateObject (); Ptr channel = CreateObject (); + channel->SetAttribute("Delay", TimeValue(m_forwardDelay)); + channel->SetAttribute("AlternateDelay", TimeValue(m_backwardDelay)); + + m_devA->Attach (channel); + m_devA->SetAddress (Mac48Address::Allocate ()); + m_devA->SetQueue (CreateObject ()); + m_devB->Attach (channel); + m_devB->SetAddress (Mac48Address::Allocate ()); + m_devB->SetQueue (CreateObject ()); - devA->Attach (channel); - devA->SetAddress (Mac48Address::Allocate ()); - devA->SetQueue (CreateObject ()); - devB->Attach (channel); - devB->SetAddress (Mac48Address::Allocate ()); - devB->SetQueue (CreateObject ()); - a->AddDevice (devA); - b->AddDevice (devB); + nodeA->AddDevice (m_devA); + nodeB->AddDevice (m_devB); - Simulator::Schedule (Seconds (1.0), &PointToPointTest::SendOnePacket, this, devA); + m_devA->SetReceiveCallback( MakeCallback(&PointToPointTest::RecvOnePacket, this) ); + m_devB->SetReceiveCallback( MakeCallback(&PointToPointTest::RecvOnePacket, this) ); + Simulator::Schedule (testStartTime, &PointToPointTest::SendOnePacket, this, m_devA); + +// NS_TEST_ASSERT_MSG_EQ(true, false, "toto"); Simulator::Run (); Simulator::Destroy (); + + std::cout << "1st packet arrival=" << m_packetArrival[0].As(Time::MS) + << " (=" << (testStartTime + m_forwardDelay).As(Time::MS) << " ?)" + << std::endl; + std::cout << "2nd packet arrival=" << m_packetArrival[1].As(Time::MS) + << " to compare with :" << testStartTime + m_forwardDelay + m_backwardDelay + << std::endl; + + NS_TEST_ASSERT_MSG_EQ_TOL( m_packetArrival[0], testStartTime + m_forwardDelay, tolerance, "Forward delay out of bounds"); + NS_TEST_ASSERT_MSG_EQ_TOL( m_packetArrival[1], testStartTime + m_forwardDelay + m_backwardDelay, tolerance, "Backward delay out of bounds"); + } /** @@ -108,7 +157,7 @@ class PointToPointTestSuite : public TestSuite PointToPointTestSuite::PointToPointTestSuite () : TestSuite ("devices-point-to-point", UNIT) { - AddTestCase (new PointToPointTest, TestCase::QUICK); + AddTestCase (new PointToPointTest(MilliSeconds(50), MilliSeconds(150)), TestCase::QUICK); } static PointToPointTestSuite g_pointToPointTestSuite; //!< The testsuite diff --git a/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc b/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc index 539413969b8..fd1ea3d1445 100644 --- a/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc +++ b/src/test/ns3tcp/ns3tcp-no-delay-test-suite.cc @@ -167,13 +167,12 @@ Ns3TcpNoDelayTestCase::DoRun (void) if (m_noDelay) { oss << "tcp-no-delay-on-test-case"; - pointToPoint.EnablePcapAll (oss.str ()); } else { oss << "tcp-no-delay-off-test-case"; - pointToPoint.EnablePcapAll (oss.str ()); } + pointToPoint.EnablePcapAll (oss.str ()); } Simulator::Stop (simStopTimeObj);