src/routing/olsr/olsr-agent-impl.cc
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue Dec 02 18:42:24 2008 +0000 (2008-12-02)
changeset 3970 8658841e4782
parent 3853 f04e7f61b1ed
child 4218 debf1a8a96d3
permissions -rw-r--r--
Fix a couple of OLSR bugs (#415)

- Added a lot more logging messages;

- When "link sensing" tries to update a link tuple for a neighbor that has been removed, just re-add the neighbor, rather than silently failing;

- The optimization of not recomputing the routing table if we think no state has changed has been removed: it turned out to be just too buggy and the code base makes it difficult to catch all places where a state mofication is done. Instead now we just recompute the table for any message processed, like the RFC says.
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2004 Francisco J. Ros 
     4  * Copyright (c) 2007 INESC Porto
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License version 2 as
     8  * published by the Free Software Foundation;
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program; if not, write to the Free Software
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18  *
    19  * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    20  *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    21  */
    22 
    23 
    24 ///
    25 /// \file	OLSR.cc
    26 /// \brief	Implementation of OLSR agent and related classes.
    27 ///
    28 /// This is the main file of this software because %OLSR's behaviour is
    29 /// implemented here.
    30 ///
    31 
    32 #define NS_LOG_APPEND_CONTEXT                                   \
    33   if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
    34 
    35 
    36 #include "olsr-agent-impl.h"
    37 #include "ns3/socket-factory.h"
    38 #include "ns3/udp-socket-factory.h"
    39 #include "ns3/simulator.h"
    40 #include "ns3/log.h"
    41 #include "ns3/random-variable.h"
    42 #include "ns3/inet-socket-address.h"
    43 #include "ns3/boolean.h"
    44 #include "ns3/uinteger.h"
    45 #include "ns3/enum.h"
    46 #include "ns3/trace-source-accessor.h"
    47 
    48 /********** Useful macros **********/
    49 
    50 ///
    51 /// \brief Gets the delay between a given time and the current time.
    52 ///
    53 /// If given time is previous to the current one, then this macro returns
    54 /// a number close to 0. This is used for scheduling events at a certain moment.
    55 ///
    56 #define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
    57                      (time - Simulator::Now () + Seconds (0.000001)))
    58 
    59 
    60 
    61 ///
    62 /// \brief Period at which a node must cite every link and every neighbor.
    63 ///
    64 /// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
    65 ///
    66 #define OLSR_REFRESH_INTERVAL	Seconds (2)
    67 
    68 
    69 /********** Holding times **********/
    70 
    71 /// Neighbor holding time.
    72 #define OLSR_NEIGHB_HOLD_TIME	(Scalar (3) * OLSR_REFRESH_INTERVAL)
    73 /// Top holding time.
    74 #define OLSR_TOP_HOLD_TIME	(Scalar (3) * m_tcInterval)
    75 /// Dup holding time.
    76 #define OLSR_DUP_HOLD_TIME	Seconds (30)
    77 /// MID holding time.
    78 #define OLSR_MID_HOLD_TIME	(Scalar (3) * m_midInterval)
    79 
    80 
    81 /********** Link types **********/
    82 
    83 /// Unspecified link type.
    84 #define OLSR_UNSPEC_LINK	0
    85 /// Asymmetric link type.
    86 #define OLSR_ASYM_LINK		1
    87 /// Symmetric link type.
    88 #define OLSR_SYM_LINK		2
    89 /// Lost link type.
    90 #define OLSR_LOST_LINK		3
    91 
    92 /********** Neighbor types **********/
    93 
    94 /// Not neighbor type.
    95 #define OLSR_NOT_NEIGH		0
    96 /// Symmetric neighbor type.
    97 #define OLSR_SYM_NEIGH		1
    98 /// Asymmetric neighbor type.
    99 #define OLSR_MPR_NEIGH		2
   100 
   101 
   102 /********** Willingness **********/
   103 
   104 /// Willingness for forwarding packets from other nodes: never.
   105 #define OLSR_WILL_NEVER		0
   106 /// Willingness for forwarding packets from other nodes: low.
   107 #define OLSR_WILL_LOW		1
   108 /// Willingness for forwarding packets from other nodes: medium.
   109 #define OLSR_WILL_DEFAULT	3
   110 /// Willingness for forwarding packets from other nodes: high.
   111 #define OLSR_WILL_HIGH		6
   112 /// Willingness for forwarding packets from other nodes: always.
   113 #define OLSR_WILL_ALWAYS	7
   114 
   115 
   116 /********** Miscellaneous constants **********/
   117 
   118 /// Maximum allowed jitter.
   119 #define OLSR_MAXJITTER		(m_helloInterval.GetSeconds () / 4)
   120 /// Maximum allowed sequence number.
   121 #define OLSR_MAX_SEQ_NUM	65535
   122 /// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
   123 #define JITTER (Seconds (UniformVariable::GetSingleValue (0, OLSR_MAXJITTER)))
   124 
   125 
   126 #define OLSR_PORT_NUMBER 698
   127 /// Maximum number of messages per packet.
   128 #define OLSR_MAX_MSGS		64
   129 
   130 /// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
   131 #define OLSR_MAX_HELLOS		12
   132 
   133 /// Maximum number of addresses advertised on a message.
   134 #define OLSR_MAX_ADDRS		64
   135 
   136 
   137 namespace ns3 {
   138 namespace olsr {
   139 
   140 NS_LOG_COMPONENT_DEFINE ("OlsrAgent");
   141 
   142 
   143 /********** OLSR class **********/
   144 
   145 NS_OBJECT_ENSURE_REGISTERED (AgentImpl);
   146 
   147 TypeId 
   148 AgentImpl::GetTypeId (void)
   149 {
   150   static TypeId tid = TypeId ("ns3::olsr::AgentImpl")
   151     .SetParent<Agent> ()
   152     .AddConstructor<AgentImpl> ()
   153     .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
   154                    TimeValue (Seconds (2)),
   155                    MakeTimeAccessor (&AgentImpl::m_helloInterval),
   156                    MakeTimeChecker ())
   157     .AddAttribute ("TcInterval", "TC messages emission interval.",
   158                    TimeValue (Seconds (5)),
   159                    MakeTimeAccessor (&AgentImpl::m_tcInterval),
   160                    MakeTimeChecker ())
   161     .AddAttribute ("MidInterval", "MID messages emission interval.  Normally it is equal to TcInterval.",
   162                    TimeValue (Seconds (5)),
   163                    MakeTimeAccessor (&AgentImpl::m_midInterval),
   164                    MakeTimeChecker ())
   165     .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
   166                    EnumValue (OLSR_WILL_DEFAULT),
   167                    MakeEnumAccessor (&AgentImpl::m_willingness),
   168                    MakeEnumChecker (OLSR_WILL_NEVER, "never",
   169                                     OLSR_WILL_LOW, "low",
   170                                     OLSR_WILL_DEFAULT, "default",
   171                                     OLSR_WILL_HIGH, "high",
   172                                     OLSR_WILL_ALWAYS, "always"))
   173     .AddTraceSource ("Rx", "Receive OLSR packet.",
   174                      MakeTraceSourceAccessor (&AgentImpl::m_rxPacketTrace))
   175     .AddTraceSource ("Tx", "Send OLSR packet.",
   176                      MakeTraceSourceAccessor (&AgentImpl::m_txPacketTrace))
   177     .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
   178 		     MakeTraceSourceAccessor (&AgentImpl::m_routingTableChanged))
   179     ;
   180   return tid;
   181 }
   182 
   183 
   184 AgentImpl::AgentImpl ()
   185   :
   186   m_helloTimer (Timer::CANCEL_ON_DESTROY),
   187   m_tcTimer (Timer::CANCEL_ON_DESTROY),
   188   m_midTimer (Timer::CANCEL_ON_DESTROY)
   189 {}
   190 
   191 AgentImpl::~AgentImpl ()
   192 {}
   193 
   194 void
   195 AgentImpl::SetNode (Ptr<Node> node)
   196 {
   197   NS_LOG_DEBUG ("Created olsr::AgentImpl");
   198   m_helloTimer.SetFunction (&AgentImpl::HelloTimerExpire, this);
   199   m_tcTimer.SetFunction (&AgentImpl::TcTimerExpire, this);
   200   m_midTimer.SetFunction (&AgentImpl::MidTimerExpire, this);
   201   m_queuedMessagesTimer.SetFunction (&AgentImpl::SendQueuedMessages, this);
   202 
   203   m_packetSequenceNumber = OLSR_MAX_SEQ_NUM;
   204   m_messageSequenceNumber = OLSR_MAX_SEQ_NUM;
   205   m_ansn = OLSR_MAX_SEQ_NUM;
   206 
   207   m_linkTupleTimerFirstTime = true;
   208 
   209   m_ipv4 = node->GetObject<Ipv4> ();
   210   NS_ASSERT (m_ipv4);
   211 }
   212 
   213 void AgentImpl::DoDispose ()
   214 {
   215   m_ipv4 = 0;
   216 
   217   for (std::map< Ptr<Socket>, Ipv4Address >::iterator iter = m_socketAddresses.begin ();
   218        iter != m_socketAddresses.end (); iter++)
   219     {
   220       iter->first->Dispose ();
   221     }
   222   m_socketAddresses.clear ();
   223 
   224   if (m_routingTable)
   225     {
   226       m_routingTable->Dispose ();
   227       m_routingTable = 0;
   228     }
   229 
   230   Object::DoDispose ();
   231 }
   232 
   233 void AgentImpl::Start ()
   234 {
   235   if (m_mainAddress == Ipv4Address ())
   236     {
   237       Ipv4Address loopback ("127.0.0.1");
   238       for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   239         {
   240           Ipv4Address addr = m_ipv4->GetAddress (i);
   241           if (addr != loopback)
   242             {
   243               m_mainAddress = addr;
   244               break;
   245             }
   246         }
   247 
   248       NS_ASSERT (m_mainAddress != Ipv4Address ());
   249     }
   250 
   251   NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
   252 
   253   m_routingTable = CreateObject<RoutingTable> ();
   254   m_routingTable->SetIpv4 (m_ipv4);
   255   m_routingTable->SetMainAddress (m_mainAddress);
   256   // Add OLSR as routing protocol, with slightly higher priority than
   257   // static routing.
   258   m_ipv4->AddRoutingProtocol (m_routingTable, 10);
   259   
   260   Ipv4Address loopback ("127.0.0.1");
   261   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   262     {
   263       Ipv4Address addr = m_ipv4->GetAddress (i);
   264       if (addr == loopback)
   265         continue;
   266 
   267       if (addr != m_mainAddress)
   268         {
   269           // Create never expiring interface association tuple entries for our
   270           // own network interfaces, so that GetMainAddress () works to
   271           // translate the node's own interface addresses into the main address.
   272           IfaceAssocTuple tuple;
   273           tuple.ifaceAddr = addr;
   274           tuple.mainAddr = m_mainAddress;
   275           AddIfaceAssocTuple (tuple);
   276           NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
   277         }
   278 
   279       // Create a socket to listen only on this interface
   280       Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (), 
   281         UdpSocketFactory::GetTypeId()); 
   282       socket->SetRecvCallback (MakeCallback (&AgentImpl::RecvOlsr,  this));
   283       if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER)))
   284         {
   285           NS_FATAL_ERROR ("Failed to bind() OLSR receive socket");
   286         }
   287       socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER));
   288       m_socketAddresses[socket] = addr;
   289     }
   290 
   291   HelloTimerExpire ();
   292   TcTimerExpire ();
   293   MidTimerExpire ();
   294 
   295   NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
   296 }
   297 
   298 void AgentImpl::SetMainInterface (uint32_t interface)
   299 {
   300   m_mainAddress = m_ipv4->GetAddress (interface);
   301 }
   302 
   303 
   304 //
   305 // \brief Processes an incoming %OLSR packet following RFC 3626 specification.
   306 void
   307 AgentImpl::RecvOlsr (Ptr<Socket> socket)
   308 {
   309   Ptr<Packet> receivedPacket;
   310   Address sourceAddress;
   311   receivedPacket = socket->RecvFrom (sourceAddress);
   312 
   313   InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
   314   Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
   315   Ipv4Address receiverIfaceAddr = m_socketAddresses[socket];
   316   NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
   317   NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
   318                 << senderIfaceAddr << " to " << receiverIfaceAddr);
   319   
   320   // All routing messages are sent from and to port RT_PORT,
   321   // so we check it.
   322   NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
   323   
   324   Ptr<Packet> packet = receivedPacket;
   325 
   326   olsr::PacketHeader olsrPacketHeader;
   327   packet->RemoveHeader (olsrPacketHeader);
   328   NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
   329   uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
   330 
   331   MessageList messages;
   332   
   333   while (sizeLeft)
   334     {
   335       MessageHeader messageHeader;
   336       if (packet->RemoveHeader (messageHeader) == 0)
   337         NS_ASSERT (false);
   338       
   339       sizeLeft -= messageHeader.GetSerializedSize ();
   340 
   341       NS_LOG_DEBUG ("Olsr Msg received with type "
   342                 << std::dec << int (messageHeader.GetMessageType ())
   343                 << " TTL=" << int (messageHeader.GetTimeToLive ())
   344                 << " origAddr=" << messageHeader.GetOriginatorAddress ());
   345       messages.push_back (messageHeader);
   346     }
   347 
   348   m_rxPacketTrace (olsrPacketHeader, messages);
   349 
   350   for (MessageList::const_iterator messageIter = messages.begin ();
   351        messageIter != messages.end (); messageIter++)
   352     {
   353       const MessageHeader &messageHeader = *messageIter;
   354       // If ttl is less than or equal to zero, or
   355       // the receiver is the same as the originator,
   356       // the message must be silently dropped
   357       if (messageHeader.GetTimeToLive () == 0
   358           || messageHeader.GetOriginatorAddress () == m_mainAddress)
   359         {
   360           packet->RemoveAtStart (messageHeader.GetSerializedSize ()
   361                                  - messageHeader.GetSerializedSize ());
   362           continue;
   363         }
   364 
   365       // If the message has been processed it must not be processed again
   366       bool do_forwarding = true;
   367       DuplicateTuple *duplicated = m_state.FindDuplicateTuple
   368         (messageHeader.GetOriginatorAddress (),
   369          messageHeader.GetMessageSequenceNumber ());
   370 
   371       // Get main address of the peer, which may be different from the packet source address
   372 //       const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
   373 //       Ipv4Address peerMainAddress;
   374 //       if (ifaceAssoc != NULL)
   375 //         {
   376 //           peerMainAddress = ifaceAssoc->mainAddr;
   377 //         }
   378 //       else
   379 //         {
   380 //           peerMainAddress = inetSourceAddr.GetIpv4 () ;
   381 //         }
   382       
   383       if (duplicated == NULL)
   384         {
   385           switch (messageHeader.GetMessageType ())
   386             {
   387             case olsr::MessageHeader::HELLO_MESSAGE:
   388               NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   389                             << "s OLSR node " << m_mainAddress
   390                             << " received HELLO message of size " << messageHeader.GetSerializedSize ());
   391               ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
   392               break;
   393 
   394             case olsr::MessageHeader::TC_MESSAGE:
   395               NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   396                             << "s OLSR node " << m_mainAddress
   397                             << " received TC message of size " << messageHeader.GetSerializedSize ());
   398               ProcessTc (messageHeader, senderIfaceAddr);
   399               break;
   400 
   401             case olsr::MessageHeader::MID_MESSAGE:
   402               NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   403                             << "s OLSR node " << m_mainAddress
   404                             <<  " received MID message of size " << messageHeader.GetSerializedSize ());
   405               ProcessMid (messageHeader, senderIfaceAddr);
   406               break;
   407 
   408             default:
   409               NS_LOG_DEBUG ("OLSR message type " <<
   410                         int (messageHeader.GetMessageType ()) <<
   411                         " not implemented");
   412             }
   413         }
   414       else
   415         {
   416           NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
   417       
   418           // If the message has been considered for forwarding, it should
   419           // not be retransmitted again
   420           for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
   421                it != duplicated->ifaceList.end(); it++)
   422             {
   423               if (*it == receiverIfaceAddr)
   424                 {
   425                   do_forwarding = false;
   426                   break;
   427                 }
   428             }
   429         }
   430       
   431       if (do_forwarding)
   432         {
   433           // HELLO messages are never forwarded.
   434           // TC and MID messages are forwarded using the default algorithm.
   435           // Remaining messages are also forwarded using the default algorithm.
   436           if (messageHeader.GetMessageType ()  != olsr::MessageHeader::HELLO_MESSAGE)
   437             {
   438               ForwardDefault (messageHeader, duplicated,
   439                               receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
   440             }
   441         }
   442 	
   443     }
   444 
   445   // After processing all OLSR messages, we must recompute the routing table
   446   RoutingTableComputation ();
   447 }
   448 
   449 ///
   450 /// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
   451 ///
   452 /// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to.
   453 /// \return the degree of the node.
   454 ///
   455 int
   456 AgentImpl::Degree (NeighborTuple const &tuple)
   457 {
   458   int degree = 0;
   459   for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
   460        it != m_state.GetTwoHopNeighbors ().end (); it++)
   461     {
   462       TwoHopNeighborTuple const &nb2hop_tuple = *it;
   463       if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
   464         {
   465           const NeighborTuple *nb_tuple =
   466             m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
   467           if (nb_tuple == NULL)
   468             degree++;
   469         }
   470     }
   471   return degree;
   472 }
   473 
   474 ///
   475 /// \brief Computates MPR set of a node following RFC 3626 hints.
   476 ///
   477 void
   478 AgentImpl::MprComputation()
   479 {
   480   NS_LOG_FUNCTION (this);
   481   
   482   // MPR computation should be done for each interface. See section 8.3.1
   483   // (RFC 3626) for details.
   484   MprSet mprSet;
   485 	
   486   
   487   // N is the subset of neighbors of the node, which are
   488   // neighbor "of the interface I"
   489   NeighborSet N;
   490   for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin();
   491        neighbor != m_state.GetNeighbors ().end (); neighbor++)
   492     {
   493       if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
   494         {
   495           N.push_back (*neighbor);
   496         }
   497     }
   498 	
   499   // N2 is the set of 2-hop neighbors reachable from "the interface
   500   // I", excluding:
   501   // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
   502   // (ii)  the node performing the computation
   503   // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   504   //       link to this node on some interface.
   505   TwoHopNeighborSet N2;
   506   for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
   507        twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
   508     {
   509       // excluding:
   510       // (ii)  the node performing the computation
   511       if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
   512         {
   513           continue;
   514         }
   515 
   516       //  excluding:
   517       // (i)   the nodes only reachable by members of N with willingness WILL_NEVER      
   518       bool ok = false;
   519       for (NeighborSet::const_iterator neigh = N.begin ();
   520            neigh != N.end (); neigh++)
   521         {
   522           if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   523             {
   524               if (neigh->willingness == OLSR_WILL_NEVER)
   525                 {
   526                   ok = false;
   527                   break;
   528                 }
   529               else
   530                 {
   531                   ok = true;
   532                   break;
   533                 }
   534             }
   535         }
   536       if (!ok)
   537         {
   538           continue;
   539         }
   540       
   541       // excluding:
   542       // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   543       //       link to this node on some interface.
   544       for (NeighborSet::const_iterator neigh = N.begin ();
   545            neigh != N.end (); neigh++)
   546         {
   547           if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
   548             {
   549               ok = false;
   550               break;
   551             }
   552         }
   553 
   554       if (ok)
   555         {
   556           N2.push_back (*twoHopNeigh);
   557         }
   558     }
   559 
   560   NS_LOG_DEBUG ("Size of N2: " << N2.size ());  
   561 
   562   // 1. Start with an MPR set made of all members of N with
   563   // N_willingness equal to WILL_ALWAYS
   564   for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
   565     {
   566       if (neighbor->willingness == OLSR_WILL_ALWAYS)
   567         {
   568           mprSet.insert (neighbor->neighborMainAddr);
   569           // (not in RFC but I think is needed: remove the 2-hop
   570           // neighbors reachable by the MPR from N2)
   571           for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   572                twoHopNeigh != N2.end (); )
   573             {
   574               if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr)
   575                 {
   576                   twoHopNeigh = N2.erase (twoHopNeigh);
   577                 }
   578               else
   579                 {
   580                   twoHopNeigh++;
   581                 }
   582             }
   583         }
   584     }
   585   
   586   // 2. Calculate D(y), where y is a member of N, for all nodes in N.
   587   // (we do this later)
   588 	
   589   // 3. Add to the MPR set those nodes in N, which are the *only*
   590   // nodes to provide reachability to a node in N2.
   591   std::set<Ipv4Address> coveredTwoHopNeighbors;
   592   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
   593     {
   594       NeighborSet::const_iterator onlyNeighbor = N.end ();
   595       
   596       for (NeighborSet::const_iterator neighbor = N.begin ();
   597            neighbor != N.end (); neighbor++)
   598         {
   599           if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   600             {
   601               if (onlyNeighbor == N.end ())
   602                 {
   603                   onlyNeighbor = neighbor;
   604                 }
   605               else
   606                 {
   607                   onlyNeighbor = N.end ();
   608                   break;
   609                 }
   610             }
   611         }
   612       if (onlyNeighbor != N.end ())
   613         {
   614           mprSet.insert (onlyNeighbor->neighborMainAddr);
   615           coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
   616         }
   617     }
   618   // Remove the nodes from N2 which are now covered by a node in the MPR set.
   619   for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   620        twoHopNeigh != N2.end (); )
   621     {
   622       if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
   623         {
   624           twoHopNeigh = N2.erase (twoHopNeigh);
   625         }
   626       else
   627         {
   628           twoHopNeigh++;
   629         }
   630     }
   631 	
   632   // 4. While there exist nodes in N2 which are not covered by at
   633   // least one node in the MPR set:
   634   while (N2.begin () != N2.end ())
   635     {
   636       // 4.1. For each node in N, calculate the reachability, i.e., the
   637       // number of nodes in N2 which are not yet covered by at
   638       // least one node in the MPR set, and which are reachable
   639       // through this 1-hop neighbor
   640       std::map<int, std::vector<const NeighborTuple *> > reachability;
   641       std::set<int> rs;
   642       for (NeighborSet::iterator it = N.begin(); it != N.end(); it++)
   643         {
   644           NeighborTuple const &nb_tuple = *it;
   645           int r = 0;
   646           for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
   647             {
   648               TwoHopNeighborTuple const &nb2hop_tuple = *it2;
   649               if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
   650                 r++;
   651             }
   652           rs.insert (r);
   653           reachability[r].push_back (&nb_tuple);
   654         }
   655       
   656       // 4.2. Select as a MPR the node with highest N_willingness among
   657       // the nodes in N with non-zero reachability. In case of
   658       // multiple choice select the node which provides
   659       // reachability to the maximum number of nodes in N2. In
   660       // case of multiple nodes providing the same amount of
   661       // reachability, select the node as MPR whose D(y) is
   662       // greater. Remove the nodes from N2 which are now covered
   663       // by a node in the MPR set.
   664       NeighborTuple const *max = NULL;
   665       int max_r = 0;
   666       for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
   667         {
   668           int r = *it;
   669           if (r == 0)
   670             {
   671               continue;
   672             }
   673           for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
   674                it2 != reachability[r].end (); it2++)
   675             {
   676               const NeighborTuple *nb_tuple = *it2;
   677               if (max == NULL || nb_tuple->willingness > max->willingness)
   678                 {
   679                   max = nb_tuple;
   680                   max_r = r;
   681                 }
   682               else if (nb_tuple->willingness == max->willingness)
   683                 {
   684                   if (r > max_r)
   685                     {
   686                       max = nb_tuple;
   687                       max_r = r;
   688                     }
   689                   else if (r == max_r)
   690                     {
   691                       if (Degree (*nb_tuple) > Degree (*max))
   692                         {
   693                           max = nb_tuple;
   694                           max_r = r;
   695                         }
   696                     }
   697                 }
   698             }
   699         }
   700 
   701       if (max != NULL)
   702         {
   703           mprSet.insert (max->neighborMainAddr);
   704           for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   705                twoHopNeigh != N2.end (); )
   706             {
   707               if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
   708                 {
   709                   twoHopNeigh = N2.erase (twoHopNeigh);
   710                 }
   711               else
   712                 {
   713                   twoHopNeigh++;
   714                 }
   715             }
   716         }
   717     }
   718 
   719 #ifdef NS3_LOG_ENABLE
   720   {
   721     std::ostringstream os;
   722     os << "[";
   723     for (MprSet::const_iterator iter = mprSet.begin ();
   724          iter != mprSet.end (); iter++)
   725       {
   726         MprSet::const_iterator next = iter;
   727         next++;
   728         os << *iter;
   729         if (next != mprSet.end ())
   730           os << ", ";
   731       }
   732     os << "]";
   733     NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
   734   }
   735 #endif
   736 
   737   m_state.SetMprSet (mprSet);
   738 }
   739 
   740 ///
   741 /// \brief Gets the main address associated with a given interface address.
   742 ///
   743 /// \param iface_addr the interface address.
   744 /// \return the corresponding main address.
   745 ///
   746 Ipv4Address
   747 AgentImpl::GetMainAddress (Ipv4Address iface_addr) const
   748 {
   749   const IfaceAssocTuple *tuple =
   750     m_state.FindIfaceAssocTuple (iface_addr);
   751   
   752   if (tuple != NULL)
   753     return tuple->mainAddr;
   754   else
   755     return iface_addr;
   756 }
   757 
   758 ///
   759 /// \brief Creates the routing table of the node following RFC 3626 hints.
   760 ///
   761 void
   762 AgentImpl::RoutingTableComputation ()
   763 {
   764   NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
   765                 << ": RoutingTableComputation begin...");
   766 
   767   // 1. All the entries from the routing table are removed.
   768   m_routingTable->Clear ();
   769 	
   770   // 2. The new routing entries are added starting with the
   771   // symmetric neighbors (h=1) as the destination nodes.
   772   const NeighborSet &neighborSet = m_state.GetNeighbors ();
   773   for (NeighborSet::const_iterator it = neighborSet.begin ();
   774        it != neighborSet.end(); it++)
   775     {
   776       NeighborTuple const &nb_tuple = *it;
   777       NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
   778       if (nb_tuple.status == NeighborTuple::STATUS_SYM)
   779         {
   780           bool nb_main_addr = false;
   781           const LinkTuple *lt = NULL;
   782           const LinkSet &linkSet = m_state.GetLinks ();
   783           for (LinkSet::const_iterator it2 = linkSet.begin();
   784                it2 != linkSet.end(); it2++)
   785             {
   786               LinkTuple const &link_tuple = *it2;
   787               NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
   788                             << (link_tuple.time >= Simulator::Now ()? "" : " (expired)"));
   789               if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
   790                   && link_tuple.time >= Simulator::Now ())
   791                 {
   792                   NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
   793                                 << " => adding routing table entry to neighbor");
   794                   lt = &link_tuple;
   795                   m_routingTable->AddEntry (link_tuple.neighborIfaceAddr,
   796                                             link_tuple.neighborIfaceAddr,
   797                                             link_tuple.localIfaceAddr,
   798                                             1);
   799                   if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
   800                     {
   801                       nb_main_addr = true;
   802                     }
   803                 }
   804               else
   805                 {
   806                   NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
   807                                 << "; neighborMainAddr =  " << nb_tuple.neighborMainAddr
   808                                 << "; expired=" << int (link_tuple.time < Simulator::Now ())
   809                                 << " => IGNORE");
   810                 }
   811             }
   812 
   813           // If, in the above, no R_dest_addr is equal to the main
   814           // address of the neighbor, then another new routing entry
   815           // with MUST be added, with:
   816           //      R_dest_addr  = main address of the neighbor;
   817           //      R_next_addr  = L_neighbor_iface_addr of one of the
   818           //                     associated link tuple with L_time >= current time;
   819           //      R_dist       = 1;
   820           //      R_iface_addr = L_local_iface_addr of the
   821           //                     associated link tuple.
   822           if (!nb_main_addr && lt != NULL)
   823             {
   824               NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
   825                             "=> adding additional routing entry");
   826               m_routingTable->AddEntry(nb_tuple.neighborMainAddr,
   827                                        lt->neighborIfaceAddr,
   828                                        lt->localIfaceAddr,
   829                                        1);
   830             }
   831         }
   832     }
   833   
   834   //  3. for each node in N2, i.e., a 2-hop neighbor which is not a
   835   //  neighbor node or the node itself, and such that there exist at
   836   //  least one entry in the 2-hop neighbor set where
   837   //  N_neighbor_main_addr correspond to a neighbor node with
   838   //  willingness different of WILL_NEVER,
   839   const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
   840   for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
   841        it != twoHopNeighbors.end (); it++)
   842     {
   843       TwoHopNeighborTuple const &nb2hop_tuple = *it;
   844 
   845       NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
   846 
   847       // a 2-hop neighbor which is not a neighbor node or the node itself
   848       if (m_state.FindNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
   849         {
   850           NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
   851           continue;
   852         }
   853 
   854       if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
   855         {
   856           NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
   857           continue;
   858         }
   859 
   860       // ...and such that there exist at least one entry in the 2-hop
   861       // neighbor set where N_neighbor_main_addr correspond to a
   862       // neighbor node with willingness different of WILL_NEVER...
   863       bool nb2hopOk = false;
   864       for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
   865            neighbor != neighborSet.end(); neighbor++)
   866         {
   867           if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
   868               && neighbor->willingness != OLSR_WILL_NEVER)
   869             {
   870               nb2hopOk = true;
   871               break;
   872             }
   873         }
   874       if (!nb2hopOk)
   875         {
   876           NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
   877                         << nb2hop_tuple.twoHopNeighborAddr
   878                         << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
   879                         << ", which was not found in the Neighbor Set.");
   880           continue;
   881         }
   882       
   883       // one selects one 2-hop tuple and creates one entry in the routing table with:
   884       //                R_dest_addr  =  the main address of the 2-hop neighbor;
   885       //                R_next_addr  = the R_next_addr of the entry in the
   886       //                               routing table with:
   887       //                                   R_dest_addr == N_neighbor_main_addr
   888       //                                                  of the 2-hop tuple;
   889       //                R_dist       = 2;
   890       //                R_iface_addr = the R_iface_addr of the entry in the
   891       //                               routing table with:
   892       //                                   R_dest_addr == N_neighbor_main_addr
   893       //                                                  of the 2-hop tuple;
   894       RoutingTableEntry entry;
   895       bool foundEntry = m_routingTable->Lookup (nb2hop_tuple.neighborMainAddr, entry);
   896       if (foundEntry)
   897         {
   898           NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
   899           m_routingTable->AddEntry (nb2hop_tuple.twoHopNeighborAddr,
   900                                     entry.nextAddr,
   901                                     entry.interface,
   902                                     2);
   903         }
   904       else
   905         {
   906           NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
   907                         << nb2hop_tuple.twoHopNeighborAddr
   908                         << " not found in the routing table)");
   909         }
   910     }
   911   
   912   for (uint32_t h = 2; ; h++)
   913     {
   914       bool added = false;
   915 		
   916       // 3.1. For each topology entry in the topology table, if its
   917       // T_dest_addr does not correspond to R_dest_addr of any
   918       // route entry in the routing table AND its T_last_addr
   919       // corresponds to R_dest_addr of a route entry whose R_dist
   920       // is equal to h, then a new route entry MUST be recorded in
   921       // the routing table (if it does not already exist)
   922       const TopologySet &topology = m_state.GetTopologySet ();
   923       for (TopologySet::const_iterator it = topology.begin ();
   924            it != topology.end (); it++)
   925         {
   926           const TopologyTuple &topology_tuple = *it;
   927           NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
   928 
   929           RoutingTableEntry destAddrEntry, lastAddrEntry;
   930           bool have_destAddrEntry = m_routingTable->Lookup (topology_tuple.destAddr, destAddrEntry);
   931           bool have_lastAddrEntry = m_routingTable->Lookup (topology_tuple.lastAddr, lastAddrEntry);
   932           if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
   933             {
   934               NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
   935               // then a new route entry MUST be recorded in
   936               //                the routing table (if it does not already exist) where:
   937               //                     R_dest_addr  = T_dest_addr;
   938               //                     R_next_addr  = R_next_addr of the recorded
   939               //                                    route entry where:
   940               //                                    R_dest_addr == T_last_addr
   941               //                     R_dist       = h+1; and
   942               //                     R_iface_addr = R_iface_addr of the recorded
   943               //                                    route entry where:
   944               //                                       R_dest_addr == T_last_addr.
   945               m_routingTable->AddEntry (topology_tuple.destAddr,
   946                                         lastAddrEntry.nextAddr,
   947                                         lastAddrEntry.interface,
   948                                         h + 1);
   949               added = true;
   950             }
   951           else
   952             {
   953               NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
   954                             "have_destAddrEntry=" << have_destAddrEntry
   955                             << " have_lastAddrEntry=" << have_lastAddrEntry
   956                             << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
   957                             << " (h=" << h << ")");
   958             }
   959         }
   960       
   961       if (!added)
   962         break;
   963     }
   964 
   965   // 4. For each entry in the multiple interface association base
   966   // where there exists a routing entry such that:
   967   //	R_dest_addr  == I_main_addr  (of the multiple interface association entry)
   968   // AND there is no routing entry such that:
   969   //	R_dest_addr  == I_iface_addr
   970   const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
   971   for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
   972        it != ifaceAssocSet.end (); it++)
   973     {
   974       IfaceAssocTuple const &tuple = *it;
   975       RoutingTableEntry entry1, entry2;
   976       bool have_entry1 = m_routingTable->Lookup (tuple.mainAddr, entry1);
   977       bool have_entry2 = m_routingTable->Lookup (tuple.ifaceAddr, entry2);
   978       if (have_entry1 && !have_entry2)
   979         {
   980           // then a route entry is created in the routing table with:
   981           //       R_dest_addr  =  I_iface_addr (of the multiple interface
   982           //                                     association entry)
   983           //       R_next_addr  =  R_next_addr  (of the recorded route entry)
   984           //       R_dist       =  R_dist       (of the recorded route entry)
   985           //       R_iface_addr =  R_iface_addr (of the recorded route entry).
   986           m_routingTable->AddEntry (tuple.ifaceAddr,
   987                                     entry1.nextAddr,
   988                                     entry1.interface,
   989                                     entry1.distance);
   990         }
   991     }
   992 
   993   NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
   994   m_routingTableChanged (m_routingTable->GetSize ());
   995 }
   996 
   997 
   998 ///
   999 /// \brief Processes a HELLO message following RFC 3626 specification.
  1000 ///
  1001 /// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR
  1002 /// Selector Set are performed.
  1003 ///
  1004 /// \param msg the %OLSR message which contains the HELLO message.
  1005 /// \param receiver_iface the address of the interface where the message was received from.
  1006 /// \param sender_iface the address of the interface where the message was sent from.
  1007 ///
  1008 void
  1009 AgentImpl::ProcessHello (const olsr::MessageHeader &msg,
  1010                          const Ipv4Address &receiverIface,
  1011                          const Ipv4Address &senderIface)
  1012 {
  1013   const olsr::MessageHeader::Hello &hello = msg.GetHello ();
  1014 
  1015   LinkSensing (msg, hello, receiverIface, senderIface);
  1016 
  1017 #ifdef NS3_LOG_ENABLE
  1018   {
  1019     const LinkSet &links = m_state.GetLinks ();
  1020     NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  1021                   << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
  1022     for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
  1023       {
  1024         NS_LOG_DEBUG(*link);
  1025       }
  1026     NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
  1027 
  1028     const NeighborSet &neighbors = m_state.GetNeighbors ();
  1029     NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  1030                   << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
  1031     for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
  1032       {
  1033         NS_LOG_DEBUG(*neighbor);
  1034       }
  1035     NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
  1036   }
  1037 #endif
  1038 
  1039   PopulateNeighborSet (msg, hello);
  1040   PopulateTwoHopNeighborSet (msg, hello);
  1041 
  1042 #ifdef NS3_LOG_ENABLE
  1043   {
  1044     const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  1045     NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  1046                   << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  1047     for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
  1048          tuple != twoHopNeighbors.end (); tuple++)
  1049       {
  1050         NS_LOG_DEBUG(*tuple);
  1051       }
  1052     NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  1053   }
  1054 #endif
  1055 
  1056   MprComputation ();
  1057   PopulateMprSelectorSet (msg, hello);
  1058 }
  1059 
  1060 ///
  1061 /// \brief Processes a TC message following RFC 3626 specification.
  1062 ///
  1063 /// The Topology Set is updated (if needed) with the information of
  1064 /// the received TC message.
  1065 ///
  1066 /// \param msg the %OLSR message which contains the TC message.
  1067 /// \param sender_iface the address of the interface where the message was sent from.
  1068 ///
  1069 void
  1070 AgentImpl::ProcessTc (const olsr::MessageHeader &msg,
  1071                       const Ipv4Address &senderIface)
  1072 {
  1073   const olsr::MessageHeader::Tc &tc = msg.GetTc ();
  1074   Time now = Simulator::Now ();
  1075 	
  1076   // 1. If the sender interface of this message is not in the symmetric
  1077   // 1-hop neighborhood of this node, the message MUST be discarded.
  1078   const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
  1079   if (link_tuple == NULL)
  1080     return;
  1081 	
  1082   // 2. If there exist some tuple in the topology set where:
  1083   // 	T_last_addr == originator address AND
  1084   // 	T_seq       >  ANSN,
  1085   // then further processing of this TC message MUST NOT be
  1086   // performed.
  1087   const TopologyTuple *topologyTuple =
  1088     m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
  1089   if (topologyTuple != NULL)
  1090     return;
  1091 	
  1092   // 3. All tuples in the topology set where:
  1093   //	T_last_addr == originator address AND
  1094   //	T_seq       <  ANSN
  1095   // MUST be removed from the topology set.
  1096   m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
  1097 
  1098   // 4. For each of the advertised neighbor main address received in
  1099   // the TC message:
  1100   for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
  1101        i != tc.neighborAddresses.end (); i++)
  1102     {
  1103       const Ipv4Address &addr = *i;
  1104       // 4.1. If there exist some tuple in the topology set where:
  1105       // 	T_dest_addr == advertised neighbor main address, AND
  1106       // 	T_last_addr == originator address,
  1107       // then the holding time of that tuple MUST be set to:
  1108       // 	T_time      =  current time + validity time.
  1109       TopologyTuple *topologyTuple =
  1110         m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
  1111 
  1112       if (topologyTuple != NULL)
  1113         {
  1114           topologyTuple->expirationTime = now + msg.GetVTime ();
  1115         }
  1116       else
  1117         {
  1118           // 4.2. Otherwise, a new tuple MUST be recorded in the topology
  1119           // set where:
  1120           //	T_dest_addr = advertised neighbor main address,
  1121           //	T_last_addr = originator address,
  1122           //	T_seq       = ANSN,
  1123           //	T_time      = current time + validity time.
  1124           TopologyTuple topologyTuple;;
  1125           topologyTuple.destAddr = addr;
  1126           topologyTuple.lastAddr = msg.GetOriginatorAddress ();
  1127           topologyTuple.sequenceNumber = tc.ansn;
  1128           topologyTuple.expirationTime = now + msg.GetVTime ();
  1129           AddTopologyTuple (topologyTuple);
  1130 
  1131           // Schedules topology tuple deletion
  1132           m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime),
  1133                                                &AgentImpl::TopologyTupleTimerExpire,
  1134                                                this,
  1135                                                topologyTuple.destAddr,
  1136                                                topologyTuple.lastAddr));
  1137         }
  1138     }
  1139 
  1140 #ifdef NS3_LOG_ENABLE
  1141   {
  1142     const TopologySet &topology = m_state.GetTopologySet ();
  1143     NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  1144                   << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
  1145     for (TopologySet::const_iterator tuple = topology.begin ();
  1146          tuple != topology.end (); tuple++)
  1147       {
  1148         NS_LOG_DEBUG (*tuple);
  1149       }
  1150     NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
  1151   }
  1152 #endif
  1153 }
  1154 
  1155 ///
  1156 /// \brief Processes a MID message following RFC 3626 specification.
  1157 ///
  1158 /// The Interface Association Set is updated (if needed) with the information
  1159 /// of the received MID message.
  1160 ///
  1161 /// \param msg the %OLSR message which contains the MID message.
  1162 /// \param sender_iface the address of the interface where the message was sent from.
  1163 ///
  1164 void
  1165 AgentImpl::ProcessMid (const olsr::MessageHeader &msg,
  1166                        const Ipv4Address &senderIface)
  1167 {
  1168   const olsr::MessageHeader::Mid &mid = msg.GetMid ();
  1169   Time now = Simulator::Now ();
  1170   
  1171   NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
  1172   // 1. If the sender interface of this message is not in the symmetric
  1173   // 1-hop neighborhood of this node, the message MUST be discarded.
  1174   const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
  1175   if (linkTuple == NULL)
  1176     {
  1177       NS_LOG_LOGIC ("Node " << m_mainAddress <<
  1178                     ": the sender interface of this message is not in the "
  1179                     "symmetric 1-hop neighborhood of this node,"
  1180                     " the message MUST be discarded.");
  1181       return;
  1182     }
  1183 	
  1184   // 2. For each interface address listed in the MID message
  1185   for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
  1186        i != mid.interfaceAddresses.end (); i++)
  1187     {
  1188       bool updated = false;
  1189       IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable ();
  1190       for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin();
  1191            tuple != ifaceAssoc.end(); tuple++)
  1192         {
  1193           if (tuple->ifaceAddr == *i
  1194               && tuple->mainAddr == msg.GetOriginatorAddress ())
  1195             {
  1196               NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
  1197               tuple->time = now + msg.GetVTime ();
  1198               updated = true;
  1199             }
  1200         }
  1201       if (!updated)
  1202         {
  1203           IfaceAssocTuple tuple;
  1204           tuple.ifaceAddr = *i;
  1205           tuple.mainAddr = msg.GetOriginatorAddress ();
  1206           tuple.time = now + msg.GetVTime ();
  1207           AddIfaceAssocTuple (tuple);
  1208           NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
  1209           // Schedules iface association tuple deletion
  1210           Simulator::Schedule (DELAY (tuple.time),
  1211                                &AgentImpl::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr);
  1212         }
  1213     }
  1214 
  1215   // 3. (not part of the RFC) iterate over all NeighborTuple's and
  1216   // TwoHopNeighborTuples, update the neighbor addresses taking into account
  1217   // the new MID information.
  1218   NeighborSet &neighbors = m_state.GetNeighbors ();
  1219   for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end(); neighbor++)
  1220     {
  1221       neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
  1222     }
  1223 
  1224   TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  1225   for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
  1226        twoHopNeighbor != twoHopNeighbors.end(); twoHopNeighbor++)
  1227     {
  1228       twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
  1229       twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
  1230     }
  1231   NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
  1232 }
  1233 
  1234 
  1235 ///
  1236 /// \brief OLSR's default forwarding algorithm.
  1237 ///
  1238 /// See RFC 3626 for details.
  1239 ///
  1240 /// \param p the %OLSR packet which has been received.
  1241 /// \param msg the %OLSR message which must be forwarded.
  1242 /// \param dup_tuple NULL if the message has never been considered for forwarding,
  1243 /// or a duplicate tuple in other case.
  1244 /// \param local_iface the address of the interface where the message was received from.
  1245 ///
  1246 void
  1247 AgentImpl::ForwardDefault (olsr::MessageHeader olsrMessage,
  1248                                DuplicateTuple *duplicated,
  1249                                const Ipv4Address &localIface,
  1250                                const Ipv4Address &senderAddress)
  1251 {
  1252   Time now = Simulator::Now ();
  1253   
  1254   // If the sender interface address is not in the symmetric
  1255   // 1-hop neighborhood the message must not be forwarded
  1256   const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
  1257   if (linkTuple == NULL)
  1258     return;
  1259 
  1260   // If the message has already been considered for forwarding,
  1261   // it must not be retransmitted again
  1262   if (duplicated != NULL && duplicated->retransmitted)
  1263     {
  1264       NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
  1265                     " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
  1266       return;
  1267     }
  1268 	
  1269   // If the sender interface address is an interface address
  1270   // of a MPR selector of this node and ttl is greater than 1,
  1271   // the message must be retransmitted
  1272   bool retransmitted = false;
  1273   if (olsrMessage.GetTimeToLive () > 1)
  1274     {
  1275       const MprSelectorTuple *mprselTuple =
  1276         m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
  1277       if (mprselTuple != NULL)
  1278         {
  1279           olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
  1280           olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
  1281           // We have to introduce a random delay to avoid
  1282           // synchronization with neighbors.
  1283           QueueMessage (olsrMessage, JITTER);
  1284           retransmitted = true;
  1285         }
  1286     }
  1287 	
  1288   // Update duplicate tuple...
  1289   if (duplicated != NULL)
  1290     {
  1291       duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
  1292       duplicated->retransmitted = retransmitted;
  1293       duplicated->ifaceList.push_back (localIface);
  1294     }
  1295   // ...or create a new one
  1296   else
  1297     {
  1298       DuplicateTuple newDup;
  1299       newDup.address = olsrMessage.GetOriginatorAddress ();
  1300       newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
  1301       newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
  1302       newDup.retransmitted = retransmitted;
  1303       newDup.ifaceList.push_back (localIface);
  1304       AddDuplicateTuple (newDup);
  1305       // Schedule dup tuple deletion
  1306       Simulator::Schedule (OLSR_DUP_HOLD_TIME,
  1307                            &AgentImpl::DupTupleTimerExpire, this,
  1308                            newDup.address, newDup.sequenceNumber);
  1309     }
  1310 }
  1311 
  1312 ///
  1313 /// \brief Enques an %OLSR message which will be sent with a delay of (0, delay].
  1314 ///
  1315 /// This buffering system is used in order to piggyback several %OLSR messages in
  1316 /// a same %OLSR packet.
  1317 ///
  1318 /// \param msg the %OLSR message which must be sent.
  1319 /// \param delay maximum delay the %OLSR message is going to be buffered.
  1320 ///
  1321 void
  1322 AgentImpl::QueueMessage (const olsr::MessageHeader &message, Time delay)
  1323 {
  1324   m_queuedMessages.push_back (message);
  1325   if (not m_queuedMessagesTimer.IsRunning ())
  1326     {
  1327       m_queuedMessagesTimer.SetDelay (delay);
  1328       m_queuedMessagesTimer.Schedule ();
  1329     }
  1330 }
  1331 
  1332 void
  1333 AgentImpl::SendPacket (Ptr<Packet> packet, 
  1334                        const MessageList &containedMessages)
  1335 {
  1336   NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
  1337 
  1338   // Add a header
  1339   olsr::PacketHeader header;
  1340   header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
  1341   header.SetPacketSequenceNumber (GetPacketSequenceNumber ());
  1342   packet->AddHeader (header);
  1343 
  1344   // Trace it
  1345   m_txPacketTrace (header, containedMessages);
  1346 
  1347   // Send it
  1348   m_socketAddresses.begin ()->first->Send (packet);
  1349 }
  1350 
  1351 ///
  1352 /// \brief Creates as many %OLSR packets as needed in order to send all buffered
  1353 /// %OLSR messages.
  1354 ///
  1355 /// Maximum number of messages which can be contained in an %OLSR packet is
  1356 /// dictated by OLSR_MAX_MSGS constant.
  1357 ///
  1358 void
  1359 AgentImpl::SendQueuedMessages ()
  1360 {
  1361   Ptr<Packet> packet = Create<Packet> ();
  1362   int numMessages = 0;
  1363 
  1364   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
  1365 
  1366   MessageList msglist;
  1367 
  1368   for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
  1369        message != m_queuedMessages.end ();
  1370        message++)
  1371     {
  1372       Ptr<Packet> p = Create<Packet> ();
  1373       p->AddHeader (*message);
  1374       packet->AddAtEnd (p);
  1375       msglist.push_back (*message);
  1376       if (++numMessages == OLSR_MAX_MSGS)
  1377         {
  1378           SendPacket (packet, msglist);
  1379           msglist.clear ();
  1380           // Reset variables for next packet
  1381           numMessages = 0;
  1382           packet = Create<Packet> ();
  1383         }
  1384     }
  1385 
  1386   if (packet->GetSize ())
  1387     {
  1388       SendPacket (packet, msglist);
  1389     }
  1390 
  1391   m_queuedMessages.clear ();
  1392 }
  1393 
  1394 ///
  1395 /// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on.
  1396 ///
  1397 void
  1398 AgentImpl::SendHello ()
  1399 {
  1400   NS_LOG_FUNCTION (this);
  1401   
  1402   olsr::MessageHeader msg;
  1403   Time now = Simulator::Now ();
  1404 
  1405   msg.SetVTime (OLSR_NEIGHB_HOLD_TIME);
  1406   msg.SetOriginatorAddress (m_mainAddress);
  1407   msg.SetTimeToLive (1);
  1408   msg.SetHopCount (0);
  1409   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  1410   olsr::MessageHeader::Hello &hello = msg.GetHello ();
  1411 
  1412   hello.SetHTime (Scalar (3) * m_helloInterval);
  1413   hello.willingness = m_willingness;
  1414 
  1415   std::vector<olsr::MessageHeader::Hello::LinkMessage>
  1416     &linkMessages = hello.linkMessages;
  1417 	
  1418   const LinkSet &links = m_state.GetLinks ();
  1419   for (LinkSet::const_iterator link_tuple = links.begin ();
  1420        link_tuple != links.end (); link_tuple++)
  1421     {
  1422       if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
  1423             && link_tuple->time >= now))
  1424         {
  1425           continue;
  1426         }
  1427 
  1428       uint8_t link_type, nb_type = 0xff;
  1429 			
  1430       // Establishes link type
  1431       if (link_tuple->symTime >= now)
  1432         {
  1433           link_type = OLSR_SYM_LINK;
  1434         }
  1435       else if (link_tuple->asymTime >= now)
  1436         {
  1437           link_type = OLSR_ASYM_LINK;
  1438         }
  1439       else
  1440         {
  1441           link_type = OLSR_LOST_LINK;
  1442         }
  1443       // Establishes neighbor type.
  1444       if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
  1445         {
  1446           nb_type = OLSR_MPR_NEIGH;
  1447           NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  1448                         << " to be MPR_NEIGH.");
  1449         }
  1450       else
  1451         {
  1452           bool ok = false;
  1453           for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
  1454                nb_tuple != m_state.GetNeighbors ().end ();
  1455                nb_tuple++)
  1456             {
  1457               if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
  1458                 {
  1459                   if (nb_tuple->status == NeighborTuple::STATUS_SYM)
  1460                     {
  1461                       NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  1462                                     << " to be SYM_NEIGH.");
  1463                       nb_type = OLSR_SYM_NEIGH;
  1464                     }
  1465                   else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
  1466                     {
  1467                       nb_type = OLSR_NOT_NEIGH;
  1468                       NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  1469                                     << " to be NOT_NEIGH.");
  1470                     }
  1471                   else
  1472                     {
  1473                       NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
  1474                     }
  1475                   ok = true;
  1476                   break;
  1477                 }
  1478             }
  1479           if (!ok)
  1480             {
  1481               NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
  1482               continue;
  1483             }
  1484         }
  1485 
  1486       olsr::MessageHeader::Hello::LinkMessage linkMessage;
  1487       linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
  1488       linkMessage.neighborInterfaceAddresses.push_back
  1489         (link_tuple->neighborIfaceAddr);
  1490 
  1491       std::vector<Ipv4Address> interfaces =
  1492         m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
  1493 
  1494       linkMessage.neighborInterfaceAddresses.insert
  1495         (linkMessage.neighborInterfaceAddresses.end (),
  1496          interfaces.begin (), interfaces.end ());
  1497 
  1498       linkMessages.push_back (linkMessage);
  1499     }
  1500   NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
  1501                 << " (with " << int (linkMessages.size ()) << " link messages)");
  1502   QueueMessage (msg, JITTER);
  1503 }
  1504 
  1505 ///
  1506 /// \brief Creates a new %OLSR TC message which is buffered for being sent later on.
  1507 ///
  1508 void
  1509 AgentImpl::SendTc ()
  1510 {
  1511   NS_LOG_FUNCTION (this);
  1512   
  1513   olsr::MessageHeader msg;
  1514 
  1515   msg.SetVTime (OLSR_TOP_HOLD_TIME);
  1516   msg.SetOriginatorAddress (m_mainAddress);
  1517   msg.SetTimeToLive (255);
  1518   msg.SetHopCount (0);
  1519   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  1520   
  1521   olsr::MessageHeader::Tc &tc = msg.GetTc ();
  1522   tc.ansn = m_ansn;
  1523   for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin();
  1524        mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++)
  1525     {
  1526       tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
  1527     }
  1528   QueueMessage (msg, JITTER);
  1529 }
  1530 
  1531 ///
  1532 /// \brief Creates a new %OLSR MID message which is buffered for being sent later on.
  1533 ///
  1534 void
  1535 AgentImpl::SendMid ()
  1536 {
  1537   olsr::MessageHeader msg;
  1538   olsr::MessageHeader::Mid &mid = msg.GetMid ();
  1539 
  1540   // A node which has only a single interface address participating in
  1541   // the MANET (i.e., running OLSR), MUST NOT generate any MID
  1542   // message.
  1543 
  1544   // A node with several interfaces, where only one is participating
  1545   // in the MANET and running OLSR (e.g., a node is connected to a
  1546   // wired network as well as to a MANET) MUST NOT generate any MID
  1547   // messages.
  1548 
  1549   // A node with several interfaces, where more than one is
  1550   // participating in the MANET and running OLSR MUST generate MID
  1551   // messages as specified.
  1552 
  1553   // [ Note: assuming here that all interfaces participate in the
  1554   // MANET; later we may want to make this configurable. ]
  1555 
  1556   Ipv4Address loopback ("127.0.0.1");
  1557   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
  1558     {
  1559       Ipv4Address addr = m_ipv4->GetAddress (i);
  1560       if (addr != m_mainAddress && addr != loopback)
  1561         mid.interfaceAddresses.push_back (addr);
  1562     }
  1563   if (mid.interfaceAddresses.size () == 0)
  1564     return;
  1565   
  1566   msg.SetVTime (OLSR_MID_HOLD_TIME);
  1567   msg.SetOriginatorAddress (m_mainAddress);
  1568   msg.SetTimeToLive (255);
  1569   msg.SetHopCount (0);
  1570   msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  1571 
  1572   QueueMessage (msg, JITTER);
  1573 }
  1574 
  1575 ///
  1576 /// \brief	Updates Link Set according to a new received HELLO message (following RFC 3626
  1577 ///		specification). Neighbor Set is also updated if needed.
  1578 void
  1579 AgentImpl::LinkSensing (const olsr::MessageHeader &msg,
  1580                         const olsr::MessageHeader::Hello &hello,
  1581                         const Ipv4Address &receiverIface,
  1582                         const Ipv4Address &senderIface)
  1583 {
  1584   Time now = Simulator::Now ();
  1585   bool updated = false;
  1586   bool created = false;
  1587   NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  1588                 << ": LinkSensing(receiverIface=" << receiverIface
  1589                 << ", senderIface=" << senderIface << ") BEGIN");
  1590 	
  1591   NS_ASSERT (msg.GetVTime () > Seconds (0));
  1592   LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
  1593   if (link_tuple == NULL)
  1594     {
  1595       LinkTuple newLinkTuple;
  1596       // We have to create a new tuple
  1597       newLinkTuple.neighborIfaceAddr = senderIface;
  1598       newLinkTuple.localIfaceAddr = receiverIface;
  1599       newLinkTuple.symTime = now - Seconds (1);
  1600       newLinkTuple.time = now + msg.GetVTime ();
  1601       link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
  1602       created = true;
  1603       NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
  1604     }
  1605   else
  1606     {
  1607       NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
  1608       updated = true;
  1609     }
  1610 	
  1611   link_tuple->asymTime = now + msg.GetVTime ();
  1612   for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
  1613          hello.linkMessages.begin ();
  1614        linkMessage != hello.linkMessages.end ();
  1615        linkMessage++)
  1616     {
  1617       int lt = linkMessage->linkCode & 0x03; // Link Type
  1618       int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
  1619 
  1620 #ifdef NS3_LOG_ENABLE
  1621       const char *linkTypeName;
  1622       switch (lt)
  1623         {
  1624         case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
  1625         case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
  1626         case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
  1627         case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
  1628         default: linkTypeName = "(invalid value!)";
  1629         }
  1630 
  1631       const char *neighborTypeName;
  1632       switch (nt)
  1633         {
  1634         case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
  1635         case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
  1636         case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
  1637         default: neighborTypeName = "(invalid value!)";
  1638         }
  1639 
  1640       NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
  1641                     << lt << " (" << linkTypeName
  1642                     << ") and Neighbor Type " << nt
  1643                     << " (" << neighborTypeName << ")");
  1644 #endif
  1645 
  1646       // We must not process invalid advertised links
  1647       if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
  1648           (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
  1649            && nt != OLSR_NOT_NEIGH))
  1650         {
  1651           NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
  1652           continue;
  1653         }
  1654       
  1655       for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
  1656              linkMessage->neighborInterfaceAddresses.begin ();
  1657            neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
  1658            neighIfaceAddr++)
  1659         {
  1660           NS_LOG_DEBUG ("   -> Neighbor: " << *neighIfaceAddr);
  1661           if (*neighIfaceAddr == receiverIface)
  1662             {
  1663               if (lt == OLSR_LOST_LINK)
  1664                 {
  1665                   NS_LOG_LOGIC ("link is LOST => expiring it");
  1666                   link_tuple->symTime = now - Seconds (1);
  1667                   updated = true;
  1668                 }
  1669               else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
  1670                 {
  1671                   NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
  1672                                 " (symTime being increased to " << now + msg.GetVTime ());
  1673                   link_tuple->symTime = now + msg.GetVTime ();
  1674                   link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
  1675                   updated = true;
  1676                 }
  1677               else
  1678                 {
  1679                   NS_FATAL_ERROR ("bad link type");
  1680                 }
  1681               break;
  1682             }
  1683           else
  1684             {
  1685               NS_LOG_DEBUG ("     \\-> *neighIfaceAddr (" << *neighIfaceAddr
  1686                             << " != receiverIface (" << receiverIface << ") => IGNORING!");
  1687             }
  1688         }
  1689       NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
  1690     }
  1691   link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime);
  1692 
  1693   if (updated)
  1694     {
  1695       LinkTupleUpdated (*link_tuple, hello.willingness);
  1696     }
  1697 
  1698   // Schedules link tuple deletion
  1699   if (created && link_tuple != NULL)
  1700     {
  1701       LinkTupleAdded (*link_tuple, hello.willingness);
  1702       m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
  1703                                            &AgentImpl::LinkTupleTimerExpire, this,
  1704                                            link_tuple->neighborIfaceAddr));
  1705     }
  1706   NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  1707                 << ": LinkSensing END");
  1708 }
  1709 
  1710 ///
  1711 /// \brief	Updates the Neighbor Set according to the information contained in a new received
  1712 ///		HELLO message (following RFC 3626).
  1713 void
  1714 AgentImpl::PopulateNeighborSet (const olsr::MessageHeader &msg,
  1715                                 const olsr::MessageHeader::Hello &hello)
  1716 {
  1717   NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
  1718   if (nb_tuple != NULL)
  1719     {
  1720       nb_tuple->willingness = hello.willingness;
  1721     }
  1722 }
  1723 
  1724 
  1725 ///
  1726 /// \brief	Updates the 2-hop Neighbor Set according to the information contained in a new
  1727 ///		received HELLO message (following RFC 3626).
  1728 void
  1729 AgentImpl::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
  1730                                       const olsr::MessageHeader::Hello &hello)
  1731 {
  1732   Time now = Simulator::Now ();
  1733 
  1734   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
  1735 	
  1736   for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
  1737        link_tuple != m_state.GetLinks ().end (); link_tuple++)
  1738     {
  1739       NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
  1740       if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
  1741         {
  1742           NS_LOG_LOGIC ("Link tuple ignored: "
  1743                         "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
  1744           NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
  1745                         << GetMainAddress (link_tuple->neighborIfaceAddr)
  1746                         << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
  1747           continue;
  1748         }
  1749 
  1750       if (link_tuple->symTime < now)
  1751         {
  1752           NS_LOG_LOGIC ("Link tuple ignored: expired.");
  1753           continue;
  1754         }
  1755 
  1756       typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  1757       for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  1758            linkMessage != hello.linkMessages.end (); linkMessage++)
  1759         {
  1760           int neighborType = (linkMessage->linkCode >> 2) & 0x3;
  1761 #ifdef NS3_LOG_ENABLE
  1762           const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
  1763           const char *neighborTypeName = ((neighborType < 3)?
  1764                                           neighborTypeNames[neighborType]
  1765                                           : "(invalid value)");
  1766           NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
  1767                         << neighborType << " (" << neighborTypeName << ")");
  1768 #endif
  1769 
  1770           for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
  1771                  linkMessage->neighborInterfaceAddresses.begin ();
  1772                nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
  1773                nb2hop_addr_iter++)
  1774             {
  1775               Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
  1776               NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
  1777                             << *nb2hop_addr_iter
  1778                             << " (main address is " << nb2hop_addr << ")");
  1779               if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
  1780                 {
  1781                   // If the main address of the 2-hop neighbor address == main address
  1782                   // of the receiving node, silently discard the 2-hop
  1783                   // neighbor address.
  1784                   if (nb2hop_addr == m_routingAgentAddr)
  1785                     {
  1786                       NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
  1787                       continue;
  1788                     }
  1789 
  1790                   // Otherwise, a 2-hop tuple is created
  1791                   TwoHopNeighborTuple *nb2hop_tuple =
  1792                     m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr);
  1793                   NS_LOG_LOGIC ("Adding the 2-hop neighbor"
  1794                                 << (nb2hop_tuple? " (refreshing existing entry)" : ""));
  1795                   if (nb2hop_tuple == NULL)
  1796                     {
  1797                       TwoHopNeighborTuple new_nb2hop_tuple;
  1798                       new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
  1799                       new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
  1800                       new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
  1801                       AddTwoHopNeighborTuple (new_nb2hop_tuple);
  1802                       // Schedules nb2hop tuple deletion
  1803                       m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
  1804                                                            &AgentImpl::Nb2hopTupleTimerExpire, this,
  1805                                                            new_nb2hop_tuple.neighborMainAddr,
  1806                                                            new_nb2hop_tuple.twoHopNeighborAddr));
  1807                     }
  1808                   else
  1809                     {
  1810                       nb2hop_tuple->expirationTime = now + msg.GetVTime ();
  1811                     }
  1812                 }
  1813               else if (neighborType == OLSR_NOT_NEIGH)
  1814                 {
  1815                   // For each 2-hop node listed in the HELLO message
  1816                   // with Neighbor Type equal to NOT_NEIGH all 2-hop
  1817                   // tuples where: N_neighbor_main_addr == Originator
  1818                   // Address AND N_2hop_addr == main address of the
  1819                   // 2-hop neighbor are deleted.
  1820                   NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
  1821                   m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr);
  1822                 }
  1823               else
  1824                 {
  1825                   NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
  1826                                 " neighbor type value: " << neighborType);
  1827                 }
  1828             }
  1829         }
  1830     }
  1831 
  1832   NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
  1833 }
  1834 
  1835 
  1836 
  1837 ///
  1838 /// \brief	Updates the MPR Selector Set according to the information contained in a new
  1839 ///		received HELLO message (following RFC 3626).
  1840 void
  1841 AgentImpl::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
  1842                                        const olsr::MessageHeader::Hello &hello)
  1843 {
  1844   NS_LOG_FUNCTION (this);
  1845   
  1846   Time now = Simulator::Now ();
  1847 	
  1848   typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  1849   for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  1850        linkMessage != hello.linkMessages.end ();
  1851        linkMessage++)
  1852     {
  1853       int nt = linkMessage->linkCode >> 2;
  1854       if (nt == OLSR_MPR_NEIGH)
  1855         {
  1856           NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
  1857           
  1858           for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
  1859                  linkMessage->neighborInterfaceAddresses.begin ();
  1860                nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
  1861                nb_iface_addr++)
  1862             {
  1863               if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
  1864                 {
  1865                   NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
  1866                   
  1867                   // We must create a new entry into the mpr selector set
  1868                   MprSelectorTuple *existing_mprsel_tuple =
  1869                     m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
  1870                   if (existing_mprsel_tuple == NULL)
  1871                     {
  1872                       MprSelectorTuple mprsel_tuple;
  1873 
  1874                       mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
  1875                       mprsel_tuple.expirationTime = now + msg.GetVTime ();
  1876                       AddMprSelectorTuple (mprsel_tuple);
  1877 
  1878                       // Schedules mpr selector tuple deletion
  1879                       m_events.Track (Simulator::Schedule
  1880                                       (DELAY (mprsel_tuple.expirationTime),
  1881                                        &AgentImpl::MprSelTupleTimerExpire, this,
  1882                                        mprsel_tuple.mainAddr));
  1883                     }
  1884                   else
  1885                     {
  1886                       existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
  1887                     }
  1888                 }
  1889             }
  1890         }
  1891     }
  1892   NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
  1893 }
  1894 
  1895 
  1896 #if 0
  1897 ///
  1898 /// \brief	Drops a given packet because it couldn't be delivered to the corresponding
  1899 ///		destination by the MAC layer. This may cause a neighbor loss, and appropiate
  1900 ///		actions are then taken.
  1901 ///
  1902 /// \param p the packet which couldn't be delivered by the MAC layer.
  1903 ///
  1904 void
  1905 OLSR::mac_failed(Ptr<Packet> p) {
  1906 	double now		= Simulator::Now ();
  1907 	struct hdr_ip* ih	= HDR_IP(p);
  1908 	struct hdr_cmn* ch	= HDR_CMN(p);
  1909 	
  1910 	debug("%f: Node %d MAC Layer detects a breakage on link to %d\n",
  1911 		now,
  1912 		OLSR::node_id(ra_addr()),
  1913 		OLSR::node_id(ch->next_hop()));
  1914 	
  1915 	if ((u_int32_t)ih->daddr() == IP_BROADCAST) {
  1916 		drop(p, DROP_RTR_MAC_CALLBACK);
  1917 		return;
  1918 	}
  1919 	
  1920 	OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop());
  1921 	if (link_tuple != NULL) {
  1922 		link_tuple->lost_time()	= now + OLSR_NEIGHB_HOLD_TIME;
  1923 		link_tuple->time()	= now + OLSR_NEIGHB_HOLD_TIME;
  1924 		nb_loss(link_tuple);
  1925 	}
  1926 	drop(p, DROP_RTR_MAC_CALLBACK);
  1927 }
  1928 #endif
  1929 
  1930 
  1931 
  1932 
  1933 ///
  1934 /// \brief Performs all actions needed when a neighbor loss occurs.
  1935 ///
  1936 /// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated.
  1937 ///
  1938 /// \param tuple link tuple with the information of the link to the neighbor which has been lost.
  1939 ///
  1940 void
  1941 AgentImpl::NeighborLoss (const LinkTuple &tuple)
  1942 {
  1943   NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  1944                 << "s: OLSR Node " << m_mainAddress
  1945                 << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
  1946   LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
  1947   m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
  1948   m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
  1949   
  1950   MprComputation ();
  1951   RoutingTableComputation ();
  1952 }
  1953 
  1954 ///
  1955 /// \brief Adds a duplicate tuple to the Duplicate Set.
  1956 ///
  1957 /// \param tuple the duplicate tuple to be added.
  1958 ///
  1959 void
  1960 AgentImpl::AddDuplicateTuple (const DuplicateTuple &tuple)
  1961 {
  1962 	/*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
  1963 		Simulator::Now (),
  1964 		OLSR::node_id(ra_addr()),
  1965 		OLSR::node_id(tuple->addr()),
  1966 		tuple->seq_num());*/
  1967   m_state.InsertDuplicateTuple (tuple);
  1968 }
  1969 
  1970 ///
  1971 /// \brief Removes a duplicate tuple from the Duplicate Set.
  1972 ///
  1973 /// \param tuple the duplicate tuple to be removed.
  1974 ///
  1975 void
  1976 AgentImpl::RemoveDuplicateTuple (const DuplicateTuple &tuple)
  1977 {
  1978   /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
  1979     Simulator::Now (),
  1980     OLSR::node_id(ra_addr()),
  1981     OLSR::node_id(tuple->addr()),
  1982     tuple->seq_num());*/
  1983   m_state.EraseDuplicateTuple (tuple);
  1984 }
  1985 
  1986 void
  1987 AgentImpl::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
  1988 {
  1989   // Creates associated neighbor tuple
  1990   NeighborTuple nb_tuple;
  1991   nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr);
  1992   nb_tuple.willingness = willingness;
  1993 
  1994   if (tuple.symTime >= Simulator::Now ())
  1995     {
  1996       nb_tuple.status = NeighborTuple::STATUS_SYM;
  1997     }
  1998   else
  1999     {
  2000       nb_tuple.status = NeighborTuple::STATUS_NOT_SYM;
  2001     }
  2002 
  2003   AddNeighborTuple (nb_tuple);
  2004 }
  2005 
  2006 ///
  2007 /// \brief Removes a link tuple from the Link Set.
  2008 ///
  2009 /// \param tuple the link tuple to be removed.
  2010 ///
  2011 void
  2012 AgentImpl::RemoveLinkTuple (const LinkTuple &tuple)
  2013 {
  2014   NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  2015                 << "s: OLSR Node " << m_mainAddress
  2016                 << " LinkTuple " << tuple << " REMOVED.");
  2017 
  2018   m_state.EraseLinkTuple (tuple);
  2019   m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  2020 
  2021 }
  2022 
  2023 ///
  2024 /// \brief	This function is invoked when a link tuple is updated. Its aim is to
  2025 ///		also update the corresponding neighbor tuple if it is needed.
  2026 ///
  2027 /// \param tuple the link tuple which has been updated.
  2028 ///
  2029 void
  2030 AgentImpl::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
  2031 {
  2032   // Each time a link tuple changes, the associated neighbor tuple must be recomputed
  2033 
  2034   NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  2035                 << "s: OLSR Node " << m_mainAddress
  2036                 << " LinkTuple " << tuple << " UPDATED.");
  2037 
  2038   NeighborTuple *nb_tuple =
  2039     m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  2040   
  2041   if (nb_tuple == NULL)
  2042     {
  2043       LinkTupleAdded (tuple, willingness);
  2044       nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  2045     }
  2046 
  2047   if (nb_tuple != NULL)
  2048     {
  2049 #ifdef NS3_LOG_ENABLE
  2050       int statusBefore = nb_tuple->status;
  2051 #endif
  2052       if (tuple.symTime >= Simulator::Now ())
  2053         {
  2054           nb_tuple->status = NeighborTuple::STATUS_SYM;
  2055           NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
  2056                         << int (statusBefore != nb_tuple->status));
  2057         }
  2058       else
  2059         {
  2060           nb_tuple->status = NeighborTuple::STATUS_NOT_SYM;
  2061           NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
  2062                         << int (statusBefore != nb_tuple->status));
  2063         }
  2064     }
  2065   else
  2066     {
  2067       NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
  2068     }
  2069 }
  2070 
  2071 ///
  2072 /// \brief Adds a neighbor tuple to the Neighbor Set.
  2073 ///
  2074 /// \param tuple the neighbor tuple to be added.
  2075 ///
  2076 void
  2077 AgentImpl::AddNeighborTuple (const NeighborTuple &tuple)
  2078 {
  2079 //   debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
  2080 //         Simulator::Now (),
  2081 //         OLSR::node_id(ra_addr()),
  2082 //         OLSR::node_id(tuple->neighborMainAddr),
  2083 //         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  2084   
  2085   m_state.InsertNeighborTuple (tuple);
  2086   IncrementAnsn ();
  2087 }
  2088 
  2089 ///
  2090 /// \brief Removes a neighbor tuple from the Neighbor Set.
  2091 ///
  2092 /// \param tuple the neighbor tuple to be removed.
  2093 ///
  2094 void
  2095 AgentImpl::RemoveNeighborTuple (const NeighborTuple &tuple)
  2096 {
  2097 //   debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
  2098 //         Simulator::Now (),
  2099 //         OLSR::node_id(ra_addr()),
  2100 //         OLSR::node_id(tuple->neighborMainAddr),
  2101 //         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  2102 	
  2103   m_state.EraseNeighborTuple (tuple);
  2104   IncrementAnsn ();
  2105 }
  2106 
  2107 ///
  2108 /// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
  2109 ///
  2110 /// \param tuple the 2-hop neighbor tuple to be added.
  2111 ///
  2112 void
  2113 AgentImpl::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  2114 {
  2115 //   debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  2116 //         Simulator::Now (),
  2117 //         OLSR::node_id(ra_addr()),
  2118 //         OLSR::node_id(tuple->neighborMainAddr),
  2119 //         OLSR::node_id(tuple->twoHopNeighborAddr));
  2120   
  2121   m_state.InsertTwoHopNeighborTuple (tuple);
  2122 }
  2123 
  2124 ///
  2125 /// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
  2126 ///
  2127 /// \param tuple the 2-hop neighbor tuple to be removed.
  2128 ///
  2129 void
  2130 AgentImpl::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  2131 {
  2132 //   debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  2133 //         Simulator::Now (),
  2134 //         OLSR::node_id(ra_addr()),
  2135 //         OLSR::node_id(tuple->neighborMainAddr),
  2136 //         OLSR::node_id(tuple->twoHopNeighborAddr));
  2137 
  2138   m_state.EraseTwoHopNeighborTuple (tuple);
  2139 }
  2140 
  2141 void
  2142 AgentImpl::IncrementAnsn ()
  2143 {
  2144   m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
  2145 }
  2146 
  2147 ///
  2148 /// \brief Adds an MPR selector tuple to the MPR Selector Set.
  2149 ///
  2150 /// Advertised Neighbor Sequence Number (ANSN) is also updated.
  2151 ///
  2152 /// \param tuple the MPR selector tuple to be added.
  2153 ///
  2154 void
  2155 AgentImpl::AddMprSelectorTuple (const MprSelectorTuple  &tuple)
  2156 {
  2157 //   debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
  2158 //         Simulator::Now (),
  2159 //         OLSR::node_id(ra_addr()),
  2160 //         OLSR::node_id(tuple->main_addr()));
  2161   
  2162   m_state.InsertMprSelectorTuple (tuple);
  2163   IncrementAnsn ();
  2164 }
  2165 
  2166 ///
  2167 /// \brief Removes an MPR selector tuple from the MPR Selector Set.
  2168 ///
  2169 /// Advertised Neighbor Sequence Number (ANSN) is also updated.
  2170 ///
  2171 /// \param tuple the MPR selector tuple to be removed.
  2172 ///
  2173 void
  2174 AgentImpl::RemoveMprSelectorTuple (const MprSelectorTuple &tuple)
  2175 {
  2176 //   debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
  2177 //         Simulator::Now (),
  2178 //         OLSR::node_id(ra_addr()),
  2179 //         OLSR::node_id(tuple->main_addr()));
  2180   
  2181   m_state.EraseMprSelectorTuple (tuple);
  2182   IncrementAnsn ();
  2183 }
  2184 
  2185 ///
  2186 /// \brief Adds a topology tuple to the Topology Set.
  2187 ///
  2188 /// \param tuple the topology tuple to be added.
  2189 ///
  2190 void
  2191 AgentImpl::AddTopologyTuple (const TopologyTuple &tuple)
  2192 {
  2193 //   debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  2194 //         Simulator::Now (),
  2195 //         OLSR::node_id(ra_addr()),
  2196 //         OLSR::node_id(tuple->dest_addr()),
  2197 //         OLSR::node_id(tuple->last_addr()),
  2198 //         tuple->seq());
  2199 
  2200   m_state.InsertTopologyTuple(tuple);
  2201 }
  2202 
  2203 ///
  2204 /// \brief Removes a topology tuple from the Topology Set.
  2205 ///
  2206 /// \param tuple the topology tuple to be removed.
  2207 ///
  2208 void
  2209 AgentImpl::RemoveTopologyTuple (const TopologyTuple &tuple)
  2210 {
  2211 //   debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  2212 //         Simulator::Now (),
  2213 //         OLSR::node_id(ra_addr()),
  2214 //         OLSR::node_id(tuple->dest_addr()),
  2215 //         OLSR::node_id(tuple->last_addr()),
  2216 //         tuple->seq());
  2217 
  2218   m_state.EraseTopologyTuple (tuple);
  2219 }
  2220 
  2221 ///
  2222 /// \brief Adds an interface association tuple to the Interface Association Set.
  2223 ///
  2224 /// \param tuple the interface association tuple to be added.
  2225 ///
  2226 void
  2227 AgentImpl::AddIfaceAssocTuple (const IfaceAssocTuple &tuple)
  2228 {
  2229 //   debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
  2230 //         Simulator::Now (),
  2231 //         OLSR::node_id(ra_addr()),
  2232 //         OLSR::node_id(tuple->main_addr()),
  2233 //         OLSR::node_id(tuple->iface_addr()));
  2234 
  2235   m_state.InsertIfaceAssocTuple (tuple);
  2236 }
  2237 
  2238 ///
  2239 /// \brief Removes an interface association tuple from the Interface Association Set.
  2240 ///
  2241 /// \param tuple the interface association tuple to be removed.
  2242 ///
  2243 void
  2244 AgentImpl::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
  2245 {
  2246 //   debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
  2247 //         Simulator::Now (),
  2248 //         OLSR::node_id(ra_addr()),
  2249 //         OLSR::node_id(tuple->main_addr()),
  2250 //         OLSR::node_id(tuple->iface_addr()));
  2251 
  2252   m_state.EraseIfaceAssocTuple (tuple);
  2253 }
  2254 
  2255 
  2256 uint16_t AgentImpl::GetPacketSequenceNumber ()
  2257 {
  2258   m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  2259   return m_packetSequenceNumber;
  2260 }
  2261 
  2262 /// Increments message sequence number and returns the new value.
  2263 uint16_t AgentImpl::GetMessageSequenceNumber ()
  2264 {
  2265   m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  2266   return m_messageSequenceNumber;
  2267 }
  2268 
  2269 
  2270 ///
  2271 /// \brief Sends a HELLO message and reschedules the HELLO timer.
  2272 /// \param e The event which has expired.
  2273 ///
  2274 void
  2275 AgentImpl::HelloTimerExpire ()
  2276 {
  2277   SendHello ();
  2278   m_helloTimer.Schedule (m_helloInterval);
  2279 }
  2280 
  2281 ///
  2282 /// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
  2283 /// \param e The event which has expired.
  2284 ///
  2285 void
  2286 AgentImpl::TcTimerExpire ()
  2287 {
  2288   if (m_state.GetMprSelectors ().size () > 0)
  2289     {
  2290       SendTc ();
  2291     }
  2292   else
  2293     {
  2294       NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
  2295     }
  2296   m_tcTimer.Schedule (m_tcInterval);
  2297 }
  2298 
  2299 ///
  2300 /// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer.
  2301 /// \warning Currently it does nothing because there is no support for multiple interfaces.
  2302 /// \param e The event which has expired.
  2303 ///
  2304 void
  2305 AgentImpl::MidTimerExpire ()
  2306 {
  2307   SendMid ();
  2308   m_midTimer.Schedule (m_midInterval);
  2309 }
  2310 
  2311 ///
  2312 /// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
  2313 ///
  2314 /// The task of actually removing the tuple is left to the OLSR agent.
  2315 ///
  2316 /// \param tuple The tuple which has expired.
  2317 ///
  2318 void
  2319 AgentImpl::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber)
  2320 {
  2321   DuplicateTuple *tuple =
  2322     m_state.FindDuplicateTuple (address, sequenceNumber);
  2323   if (tuple == NULL)
  2324     {
  2325       return;
  2326     }
  2327   if (tuple->expirationTime < Simulator::Now ())
  2328     {
  2329       RemoveDuplicateTuple (*tuple);
  2330     }
  2331   else
  2332     {
  2333       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  2334                                            &AgentImpl::DupTupleTimerExpire, this,
  2335                                            address, sequenceNumber));
  2336     }
  2337 }
  2338 
  2339 ///
  2340 /// \brief Removes tuple_ if expired. Else if symmetric time
  2341 /// has expired then it is assumed a neighbor loss and agent_->nb_loss()
  2342 /// is called. In this case the timer is rescheduled to expire at
  2343 /// tuple_->time(). Otherwise the timer is rescheduled to expire at
  2344 /// the minimum between tuple_->time() and tuple_->sym_time().
  2345 ///
  2346 /// The task of actually removing the tuple is left to the OLSR agent.
  2347 ///
  2348 /// \param e The event which has expired.
  2349 ///
  2350 void
  2351 AgentImpl::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr)
  2352 {
  2353   Time now = Simulator::Now ();
  2354 
  2355   // the tuple parameter may be a stale copy; get a newer version from m_state
  2356   LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
  2357   if (tuple == NULL)
  2358     {
  2359       return;
  2360     }
  2361   if (tuple->time < now)
  2362     {
  2363       RemoveLinkTuple (*tuple);
  2364     }
  2365   else if (tuple->symTime < now)
  2366     {
  2367       if (m_linkTupleTimerFirstTime)
  2368         m_linkTupleTimerFirstTime = false;
  2369       else
  2370         NeighborLoss (*tuple);
  2371 
  2372       m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  2373                                            &AgentImpl::LinkTupleTimerExpire, this,
  2374                                            neighborIfaceAddr));
  2375     }
  2376   else
  2377     {
  2378       m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
  2379                                            &AgentImpl::LinkTupleTimerExpire, this,
  2380                                            neighborIfaceAddr));
  2381     }
  2382 }
  2383 
  2384 ///
  2385 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  2386 ///
  2387 /// The task of actually removing the tuple is left to the OLSR agent.
  2388 ///
  2389 /// \param e The event which has expired.
  2390 ///
  2391 void
  2392 AgentImpl::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
  2393 {
  2394   TwoHopNeighborTuple *tuple;
  2395   tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
  2396   if (tuple == NULL)
  2397     {
  2398       return;
  2399     }
  2400   if (tuple->expirationTime < Simulator::Now ())
  2401     {
  2402       RemoveTwoHopNeighborTuple (*tuple);
  2403     }
  2404   else
  2405     {
  2406       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  2407                                            &AgentImpl::Nb2hopTupleTimerExpire,
  2408                                            this, neighborMainAddr, twoHopNeighborAddr));
  2409     }
  2410 }
  2411 
  2412 ///
  2413 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  2414 ///
  2415 /// The task of actually removing the tuple is left to the OLSR agent.
  2416 ///
  2417 /// \param e The event which has expired.
  2418 ///
  2419 void
  2420 AgentImpl::MprSelTupleTimerExpire (Ipv4Address mainAddr)
  2421 {
  2422   MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
  2423   if (tuple == NULL)
  2424     {
  2425       return;
  2426     }
  2427   if (tuple->expirationTime < Simulator::Now ())
  2428     {
  2429       RemoveMprSelectorTuple (*tuple);
  2430     }
  2431   else
  2432     {
  2433       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  2434                                            &AgentImpl::MprSelTupleTimerExpire,
  2435                                            this, mainAddr));
  2436     }
  2437 }
  2438 
  2439 ///
  2440 /// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  2441 ///
  2442 /// The task of actually removing the tuple is left to the OLSR agent.
  2443 ///
  2444 /// \param e The event which has expired.
  2445 ///
  2446 void
  2447 AgentImpl::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr)
  2448 {
  2449   TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
  2450   if (tuple == NULL)
  2451     {
  2452       return;
  2453     }
  2454   if (tuple->expirationTime < Simulator::Now ())
  2455     {
  2456       RemoveTopologyTuple (*tuple);
  2457     }
  2458   else
  2459     {
  2460       m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  2461                                            &AgentImpl::TopologyTupleTimerExpire,
  2462                                            this, tuple->destAddr, tuple->lastAddr));
  2463     }
  2464 }
  2465 
  2466 ///
  2467 /// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().
  2468 /// \warning Actually this is never invoked because there is no support for multiple interfaces.
  2469 /// \param e The event which has expired.
  2470 ///
  2471 void
  2472 AgentImpl::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
  2473 {
  2474   IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
  2475   if (tuple == NULL)
  2476     {
  2477       return;
  2478     }
  2479   if (tuple->time < Simulator::Now ())
  2480     {
  2481       RemoveIfaceAssocTuple (*tuple);
  2482     }
  2483   else
  2484     {
  2485       m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  2486                                            &AgentImpl::IfaceAssocTupleTimerExpire,
  2487                                            this, ifaceAddr));
  2488     }
  2489 }
  2490 
  2491 Ptr<const olsr::RoutingTable>
  2492 AgentImpl::GetRoutingTable () const
  2493 {
  2494   return m_routingTable;
  2495 }
  2496 
  2497 }} // namespace olsr, ns3
  2498 
  2499