diff -uprN ./12325/aodv-routing-protocol.cc ./bug1188/aodv-routing-protocol.cc --- ./12325/aodv-routing-protocol.cc 2016-09-19 12:19:57.310533000 +0200 +++ ./bug1188/aodv-routing-protocol.cc 2016-09-19 14:58:31.830698949 +0200 @@ -2052,16 +2052,31 @@ void RoutingProtocol::DoInitialize (void) { NS_LOG_FUNCTION (this); - uint32_t startTime; if (m_enableHello) { m_htimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this); - startTime = m_uniformRandomVariable->GetInteger (0, 100); - NS_LOG_DEBUG ("Starting at time " << startTime << "ms"); - m_htimer.Schedule (MilliSeconds (startTime)); + m_routingTable.SetActiveRouteCallback (MakeCallback (&RoutingProtocol::ScheduleHello, this)); + m_routingTable.SetNoActiveRouteCallback (MakeCallback (&RoutingProtocol::CancelHello, this)); } Ipv4RoutingProtocol::DoInitialize (); } +void +RoutingProtocol::ScheduleHello () +{ + NS_LOG_FUNCTION (this); + uint32_t startTime; + startTime = m_uniformRandomVariable->GetInteger (0, 100); + NS_LOG_DEBUG ("Starting in " << startTime << "ms"); + m_htimer.Schedule (MilliSeconds (startTime)); +} + +void +RoutingProtocol::CancelHello () +{ + NS_LOG_FUNCTION (this); + m_htimer.Cancel (); +} + } //namespace aodv } //namespace ns3 diff -uprN ./12325/aodv-routing-protocol.h ./bug1188/aodv-routing-protocol.h --- ./12325/aodv-routing-protocol.h 2016-09-19 12:19:57.310533000 +0200 +++ ./bug1188/aodv-routing-protocol.h 2016-09-19 12:24:23.062537000 +0200 @@ -269,6 +269,10 @@ private: void RouteRequestTimerExpire (Ipv4Address dst); /// Mark link to neighbor node as unidirectional for blacklistTimeout void AckTimerExpire (Ipv4Address neighbor, Time blacklistTimeout); + /// Schedule hello transmission + void ScheduleHello (); + /// Cancel hello transmission + void CancelHello (); /// Provides uniform random variables. Ptr m_uniformRandomVariable; diff -uprN ./12325/aodv-rtable.cc ./bug1188/aodv-rtable.cc --- ./12325/aodv-rtable.cc 2016-09-19 12:19:50.030533000 +0200 +++ ./bug1188/aodv-rtable.cc 2016-09-19 14:46:59.246686000 +0200 @@ -236,6 +236,9 @@ RoutingTable::DeleteRoute (Ipv4Address d { NS_LOG_FUNCTION (this << dst); Purge (); + // DeleteRoute called only when no route is found after a route request, deleted entry is never in VALID state + RoutingTableEntry rt; + NS_ASSERT (LookupValidRoute (dst, rt) == false); if (m_ipv4AddressEntry.erase (dst) != 0) { NS_LOG_LOGIC ("Route deletion to " << dst << " successful"); @@ -254,6 +257,7 @@ RoutingTable::AddRoute (RoutingTableEntr rt.SetRreqCnt (0); std::pair::iterator, bool> result = m_ipv4AddressEntry.insert (std::make_pair (rt.GetDestination (), rt)); + UpdateActiveRoutes (rt); return result.second; } @@ -268,6 +272,7 @@ RoutingTable::Update (RoutingTableEntry NS_LOG_LOGIC ("Route update to " << rt.GetDestination () << " fails; not found"); return false; } + UpdateActiveRoutes (rt); i->second = rt; if (i->second.GetFlag () != IN_SEARCH) { @@ -290,6 +295,7 @@ RoutingTable::SetEntryState (Ipv4Address } i->second.SetFlag (state); i->second.SetRreqCnt (0); + UpdateActiveRoutes (i->second); NS_LOG_LOGIC ("Route set entry state to " << id << ": new state is " << state); return true; } @@ -326,12 +332,31 @@ RoutingTable::InvalidateRoutesWithDst (c { NS_LOG_LOGIC ("Invalidate route with destination address " << i->first); i->second.Invalidate (m_badLinkLifetime); + UpdateActiveRoutes (i->second); } } } } void +RoutingTable::UpdateActiveRoutes (RoutingTableEntry & rt) +{ + NS_LOG_FUNCTION (this); + if ((rt.GetFlag () != VALID || rt.IsPrecursorListEmpty () == true) && m_activeRoutes.erase (rt.GetDestination ()) > 0 + && m_activeRoutes.empty () == true && m_narc.IsNull () == false) + { + NS_LOG_LOGIC ("Calling not in active route callback"); + m_narc (); + } + else if (rt.GetFlag () == VALID && rt.IsPrecursorListEmpty() == false && m_activeRoutes.insert (rt.GetDestination ()).second == true + && m_activeRoutes.size () == 1 && m_arc.IsNull () == false) + { + NS_LOG_LOGIC ("Calling in active route callback"); + m_arc (); + } +} + +void RoutingTable::DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface) { NS_LOG_FUNCTION (this); @@ -372,39 +397,7 @@ RoutingTable::Purge () { NS_LOG_LOGIC ("Invalidate route with destination address " << i->first); i->second.Invalidate (m_badLinkLifetime); - ++i; - } - else - ++i; - } - else - { - ++i; - } - } -} - -void -RoutingTable::Purge (std::map &table) const -{ - NS_LOG_FUNCTION (this); - if (table.empty ()) - return; - for (std::map::iterator i = - table.begin (); i != table.end ();) - { - if (i->second.GetLifeTime () < Seconds (0)) - { - if (i->second.GetFlag () == INVALID) - { - std::map::iterator tmp = i; - ++i; - table.erase (tmp); - } - else if (i->second.GetFlag () == VALID) - { - NS_LOG_LOGIC ("Invalidate route with destination address " << i->first); - i->second.Invalidate (m_badLinkLifetime); + UpdateActiveRoutes (i->second); ++i; } else @@ -439,7 +432,6 @@ void RoutingTable::Print (Ptr stream) const { std::map table = m_ipv4AddressEntry; - Purge (table); *stream->GetStream () << "\nAODV Routing table\n" << "Destination\tGateway\t\tInterface\tFlag\tExpire\t\tHops\n"; for (std::map::const_iterator i = diff -uprN ./12325/aodv-rtable.h ./bug1188/aodv-rtable.h --- ./12325/aodv-rtable.h 2016-09-19 12:19:50.030533000 +0200 +++ ./bug1188/aodv-rtable.h 2016-09-19 14:46:11.822686000 +0200 @@ -31,10 +31,12 @@ #include #include #include +#include #include #include "ns3/ipv4.h" #include "ns3/ipv4-route.h" #include "ns3/timer.h" +#include "ns3/callback.h" #include "ns3/net-device.h" #include "ns3/output-stream-wrapper.h" @@ -229,6 +231,12 @@ public: * 3. The Lifetime field is updated to current time plus DELETE_PERIOD. */ void InvalidateRoutesWithDst (std::map const & unreachable); + /// Update active routes (used for hello transmission) + void UpdateActiveRoutes (RoutingTableEntry & rt); + /// Set callback for in active route + void SetActiveRouteCallback (Callback cb) { m_arc = cb; } + /// Set callback for not in active route + void SetNoActiveRouteCallback (Callback cb) { m_narc = cb; } /// Delete all route from interface with address iface void DeleteAllRoutesFromInterface (Ipv4InterfaceAddress iface); /// Delete all entries from routing table @@ -248,8 +256,12 @@ private: std::map m_ipv4AddressEntry; /// Deletion time for invalid routes Time m_badLinkLifetime; - /// const version of Purge, for use by Print() method - void Purge (std::map &table) const; + /// Set of active routes (used for hello transmission) + std::set m_activeRoutes; + /// Callback for in active route + Callback m_arc; + /// Callback for not in active route + Callback m_narc; }; }